text:
@testset "test_reader" begin
    @testset "parse latitude" begin
        s_lat = "5117983N"
        parsed_lat = parse(IGCLatitude, s_lat)
        expected_lat = IGCLatitude(51.29971666666667)
        @test parsed_lat == expected_lat

        s_lat = "3356767S"
        parsed_lat = parse(IGCLatitude, s_lat)
        expected_lat = IGCLatitude(-33.94611666666667)
        @test parsed_lat == expected_lat
    end

    @testset "parse longitude" begin
        s_long = "00657383E"
        parsed_long = parse(IGCLongitude, s_long)
        expected_long = IGCLongitude(6.956383333333333)
        @test parsed_long == expected_long

        s_long = "09942706W"
        parsed_long = parse(IGCLongitude, s_long)
        expected_long = IGCLongitude(-99.71176666666666)
        @test parsed_long == expected_long
    end

    @testset "empty A record" begin
        rec = A_record()
        @test isempty(rec)

        rec = A_record("XXX", "ABC", "FLIGHT:1")
        @test !isempty(rec)
    end

    @testset "parse A record" begin
        line = "AXXXABC FLIGHT:1\r\n"
        parsed_result = parse(Abstract_IGC_record, line)
        expected_result = A_record(
            "XXX",
            "ABC",
            "FLIGHT:1"
        )
        @test flc(parsed_result) == 'A'
        # @test parsed_result == expected_result  # ToFix
        @test parsed_result.manufacturer == expected_result.manufacturer
        @test parsed_result.id == expected_result.id
        @test parsed_result.id_addition == expected_result.id_addition
    end

    @testset "Empty Time" begin
        t = EmptyTime()
        @test t == Time(0, 0, 0)
    end

    @testset "parse time" begin
        s = "160245"
        expected_result = Time(16, 2, 45)

        parsed_result = parse(Time, s, IGCTimeFormat)
        @test parsed_result == expected_result

        @test string(parsed_result, IGCTimeFormat) == s
    end

    @testset "Empty Date" begin
        d = EmptyDate()
        @test d == Date(0, 1, 1)
    end

    @testset "parse date" begin
        s = "200819"
        expected_result = Date(2019, 8, 20)

        parsed_result = parse(Date, s, IGCDateFormat)
        @test parsed_result == expected_result

        @test string(parsed_result, IGCDateFormat) == s
    end

    @testset "parse/write ZonedDateTime" begin
        s_d = "200819"
        d = parse(Date, s_d, IGCDateFormat)
        s_t = "160245"
        t = parse(Time, s_t, IGCTimeFormat)
        dt = ZonedDateTime(d + t, TZ)
        @test dt == ZonedDateTime(2019, 8, 20, 16, 2, 45, TZ)
        @test string(dt, IGCDateFormat) == s_d
        @test string(dt, IGCTimeFormat) == s_t
    end

    @testset "parse pressure altitude" begin
        @test parse(IGCPressureAltitude, "00288") == IGCPressureAltitude(288)
    end

    @testset "parse GPS altitude" begin
        @test parse(IGCGpsAltitude, "00429") == IGCGpsAltitude(429)
    end

    @testset "parse FixValidity" begin
        @test FixValidity.parse('A') == FixValidity.Fix3D
        @test FixValidity.parse('V') == FixValidity.Fix2D
    end

    @testset "parse B record" begin
        line = "B1602455107126N00149300WA002880042919509020\r\n"
        expected_result = B_record(
            Time(16, 2, 45),
            IGCLatitude(51.118766666666666),
            IGCLongitude(-1.8216666666666668),
            FixValidity.parse('A'),
            IGCPressureAltitude(288),
            IGCGpsAltitude(429),
            36,
            "19509020"
        )
        parsed_result = parse(Abstract_IGC_record, line)

        @test flc(parsed_result) == 'B'

        # @test parsed_result == expected_result  # tofix because of extensions

        @test parsed_result.time == expected_result.time
        @test parsed_result.latitude == expected_result.latitude
        @test parsed_result.longitude == expected_result.longitude
        @test parsed_result.validity == expected_result.validity
        @test parsed_result.pressure_alt == expected_result.pressure_alt
        @test parsed_result.gps_alt == expected_result.gps_alt
        @test parsed_result.start_index_extensions == parsed_result.start_index_extensions
        @test parsed_result.extensions_string == parsed_result.extensions_string
    end

    @testset "process B record" begin
        """Check whether correct extension information is taken from B record"""

        s_i_record = join(["I08", "3638FXA", "3941ENL", "4246TAS", "4751GSP", "5254TRT", "5559VAT", "6063OAT", "6467ACZ"])

        fix_record_extensions = parse(I_record, s_i_record)

        # split up per 10 to enable easy counting
        s_b_record = join(["B093232520", "2767N00554", "786EA00128", "0019600600", "1145771529", "3177005930", "2770090"])

        decoded_b_record = parse(B_record, s_b_record)
        processed_b_record = update(decoded_b_record, fix_record_extensions)

        # split per extension: 006 001 14577 15293 177 00593 0277 0090
        expected_values = [
            ("FXA", 36:38, 6),
            ("ENL", 39:41, 1),
            ("TAS", 42:46, 14577),
            ("GSP", 47:51, 15293),
            ("TRT", 52:54, 177),
            ("VAT", 55:59, 593),
            ("OAT", 60:63, 277),
            ("ACZ", 64:67, 90),
        ]

        # ToDo!!!!

        for (extension_tlc, bytes, expected_value) in expected_values
            extension = IGCExtension(bytes, extension_tlc)
            @test extension in fix_record_extensions.extensions
            #@test extension_tlc in processed_b_record.extensions
            #@test expected_value == processed_b_record[extension_tlc]
        end

    end

    @testset "decode C record task info" begin
        line = "C150701213841160701000102 500K Tri\r\n"
        expected_result = C_record_task_info(
            Date(2001, 7, 15),  # declaration_date
            Time(21, 38, 41),  # declaration_time
            Date(2001, 7, 16),  # flight_date
            "0001",  # number
            2,  # num_turnpoints
            "500K Tri"  # description
        )
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'C'
        @test parsed_result == expected_result

        @test ZonedDateTime(parsed_result.declaration, TZ) == ZonedDateTime(2001, 7, 15, 21, 38, 41, TZ)
    end

    @testset "decode C record waypoint info" begin
        line = "C5111359N00101899W Lasham Clubhouse\r\n"
        expected_result = C_record_waypoint_info(
            IGCLatitude(51.18931666666667),  # latitude
            IGCLongitude(-1.03165),  # longitude
            "Lasham Clubhouse"  # description
        )
        @test parse(Abstract_IGC_record, line) == expected_result
    end

    @testset "parse/decode GpsQualifier" begin
        @test GpsQualifier.parse('1') == GpsQualifier.GPS
        @test GpsQualifier.parse('2') == GpsQualifier.DGPS
        @test GpsQualifier.decode(1) == GpsQualifier.GPS
        @test GpsQualifier.decode(2) == GpsQualifier.DGPS
    end

    @testset "decode D record" begin
        line = "D20331\r\n"
        expected_result = D_record(
            GpsQualifier.DGPS,  # qualifier
            "0331"  # station_id
        )
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'D'
        @test parsed_result == expected_result

        line = "D19999\r\n"
        expected_result = D_record(
            GpsQualifier.GPS,  # qualifier
            "9999"  # station_id
        )
        parsed_result = parse(Abstract_IGC_record, line)
        @test parsed_result == expected_result
    end

    @testset "decode E record" begin
        line = "E160245PEV\r\n"
        expected_result = E_record(
            Time(16, 2, 45),  # time
            "PEV",  # tlc
            ""  # extension_string
        )
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'E'
        @test parsed_result == expected_result
    end

    @testset "decode F record" begin
        line = "F160240040609123624221821\r\n"
        expected_result = F_record(
            Time(16, 2, 40),  # time
            ["04", "06", "09", "12", "36", "24", "22", "18", "21"]  # satellites
        )
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'F'
        # @test parse(F_record, line) == expected_result  # ToFix doesn't work - replaced by 2 tests
        @test parsed_result.time == expected_result.time
        @test parsed_result.satellites == expected_result.satellites
    end

    @testset "decode G record" begin
        line = "GREJNGJERJKNJKRE31895478537H43982FJN9248F942389T433T\r\n"
        expected_result = G_record(
            "REJNGJERJKNJKRE31895478537H43982FJN9248F942389T433T"
        )
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'G'
        @test parsed_result == expected_result
    end

    @testset "decode I record" begin
        line = "I033638FXA3940SIU4143ENL\r\n"
        expected_extensions = [
            IGCExtension(36:38, "FXA"),
            IGCExtension(39:40, "SIU"),
            IGCExtension(41:43, "ENL")
        ]
        expected_result = I_record(expected_extensions)
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'I'
        @test length(parsed_result.extensions) == 3
        # @test parsed_result == expected_result
        for (i, extension) in enumerate(parsed_result.extensions)
            @test extension.bytes == expected_extensions[i].bytes
            @test extension.type == expected_extensions[i].type
        end
    end

    @testset "decode J record" begin
        line = "J010812HDT\r\n"
        expected_extensions = [
            IGCExtension(8:12, "HDT")
        ]
        expected_result = J_record(expected_extensions)
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'J'
        @test length(parsed_result.extensions) == 1
        # @test parsed_result == expected_result  # ToFix
        for (i, extension) in enumerate(parsed_result.extensions)
            @test extension.bytes == expected_extensions[i].bytes
            @test extension.type == expected_extensions[i].type
        end
    end

    @testset "decode H record fix accuracy" begin
        line = "HFFXA035\r\n"
        parsed_result = parse(Abstract_IGC_record, line)
        expected_result = H_record_FiXAccuracy(35)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result

        line = "HFFXA\r\n"
        expected_result = H_record_FiXAccuracy(missing)
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
        @test parsed_result.source == DEFAULT_SOURCE
        @test ismissing(parsed_result.value)
    end

    @testset "decode H record utc date" begin
        line = "HFDTE160701\r\n"
        expected_result = H_record_DaTE(2001, 7, 16)
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record pilot" begin
        line = "HFPLTPILOTINCHARGE: Bloggs Bill D\r\n"
        expected_result = H_record_PiLoT("Bloggs Bill D")
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record pilot pwca header" begin
        line = "HFPLTPILOT: Bloggs Bill D\r\n"
        expected_result = H_record_PiLoT("Bloggs Bill D")
        parsed_result = parse(Abstract_IGC_record, line)
        @test parsed_result == expected_result
    end

    @testset "decode H record pilot unknown header" begin
        line = "HFPLT XXX : Bloggs Bill D\r\n"
        expected_result = H_record_PiLoT("Bloggs Bill D")
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record copilot" begin
        line = "HFCM2CREW2: Smith-Barry John A\r\n"
        expected_result = H_record_Copilot("Smith-Barry John A")
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record glider type" begin
        line = "HFGTYGLIDERTYPE: Schleicher ASH-25\r\n"
        expected_result = H_record_GliderType("Schleicher ASH-25")
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record glider registration" begin
        line = "HFGIDGLIDERID: ABCD-1234\r\n"
        expected_result = H_record_GliderRegistration("ABCD-1234")
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record gps datum" begin
        line = "HFDTM100GPSDATUM: WGS-1984\r\n"
        expected_result = H_record_GpsDatum("WGS-1984")
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record firmware revision" begin
        line = "HFRFWFIRMWAREVERSION:6.4\r\n"
        expected_result = H_record_FirmwareRevision("6.4")
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record hardware revision" begin
        line = "HFRHWHARDWAREVERSION:3.0\r\n"
        expected_result = H_record_HardwareRevision("3.0")
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record manufacturer model" begin
        line = "HFFTYFRTYPE: Manufacturer, Model\r\n"
        expected_result = H_record_ManufacturerModel("Manufacturer", "Model")
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record gps receiver" begin
        line = "HFGPS:MarconiCanada, Superstar, 12ch, max10000m\r\n"
        parsed_result = parse(Abstract_IGC_record, line)
        expected_result = H_record_GpsReceiver(
            "MarconiCanada",
            "Superstar",
            12,
            MaxAlt(10000, "m")
        )
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record gps receiver2" begin
        line = "HFGPS:GLOBALTOP,FGPMMOPA6,66,max18000m\r\n"
        expected_result = H_record_GpsReceiver(
            "GLOBALTOP",
            "FGPMMOPA6",
            66,
            MaxAlt(18000, "m")
        )
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H_record gps receiver3" begin
        line = "HFGPS:GlobalTopPA6B,66ch,max18000m\r\n"
        expected_result = H_record_GpsReceiver(
            "GlobalTopPA6B",
            "",
            66,
            MaxAlt(18000, "m")
        )
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record gps receiver4" begin
        line = "HFGPS:UBLOX,NEO-6G,16Ch,50000\r\n"
        expected_result = H_record_GpsReceiver(
            "UBLOX",
            "NEO-6G",
            16,
            MaxAlt(50000, "m")
        )
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record gps receiver5" begin
        line = "HFGPS:LX\r\n"
        expected_result = H_record_GpsReceiver(
            "LX",
            "",
            missing,
            MaxAlt(missing, "")
        )
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record gps receiver6" begin
        line = "HFGPS:Cambridge 302,\r\n"
        expected_result = H_record_GpsReceiver(
            "Cambridge 302",
            "",
            missing,
            MaxAlt()
        )
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record pressure sensor" begin
        line = "HFPRSPRESSALTSENSOR: Sensyn, XYZ1111, max11000m\r\n"
        expected_result = H_record_PressureAltitudeSensor(
            "Sensyn",
            "XYZ1111",
            MaxAlt(11000, "m")
        )
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record pressure sensor2" begin
        line = "HFPRSPressAltSensor:Intersema MS5534B,8191\r\n"
        expected_result = H_record_PressureAltitudeSensor(
            "Intersema MS5534B",
            "8191",
            MaxAlt()
        )
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record competition id" begin
        line = "HFCIDCOMPETITIONID: XYZ-78910\r\n"
        expected_result = H_record_CompetitionId("XYZ-78910")
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record competition class" begin
        line = "HFCCLCOMPETITIONCLASS:15m Motor Glider\r\n"
        expected_result = H_record_CompetitionClass("15m Motor Glider")
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record time zone offset" begin
        line = "HFTZNTIMEZONE:3\r\n"
        expected_result = H_record_TimeZoneOffset(3 * 60)
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record time zone offset2" begin
        line = "HFTZNTIMEZONE:11.00\r\n"
        expected_result = H_record_TimeZoneOffset(11 * 60)
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record time zone offset3" begin
        line = "HFTZNTIMEZONE:-3.30\r\n"
        expected_result = H_record_TimeZoneOffset(-(3 * 60 + 30))
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record mop sensor" begin
        line = "HFMOPSENSOR:MOP-(SN:1,ET=1375,0,1375,0,3.05V,p=0),Ver:0\r\n"
        expected_result = H_record_MeansOfPropulsion("MOP-(SN:1,ET=1375,0,1375,0,3.05V,p=0),Ver:0")
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record site" begin
        line = "HFSITSite: lk15comp\r\n"
        expected_result = H_record_Site("lk15comp")
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result == expected_result
    end

    @testset "decode H record units of measure" begin
        line = "HFUNTUnits: km,ft,kt"
        expected_result = H_record_UnitsOfMeasure(["km", "ft", "kt"])
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'H'
        @test parsed_result.value == expected_result.value
    end

    @testset "decode K record" begin
        line = "K16024800090\r\n"
        expected_result = K_record(
            Time(16, 2, 48),
            "00090",
            7
        )
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'K'
        @test parsed_result == expected_result
    end

    @testset "decode L record" begin
        line = "LXXXRURITANIAN STANDARD NATIONALS DAY 1\r\n"
        expected_result = L_record(
            "XXX",
            "RURITANIAN STANDARD NATIONALS DAY 1"
        )
        parsed_result = parse(Abstract_IGC_record, line)
        @test flc(parsed_result) == 'L'
        @test parsed_result == expected_result
    end

    @testset "read igc file" begin
        fname = joinpath("data", "example.igc")
        igcdoc = read(fname, IGCDocument, store_all_records=true)

        for err in igcdoc.errors
            # println(err)
            showerror(stdout, err); println()
        end
        @test length(igcdoc.errors) == 0  # when every line are parsed correctly

        # A record
        record = igcdoc.logger_id
        @test record.manufacturer == "XXX"
        @test record.id == "ABC"
        @test record.id_addition == "FLIGHT:1"

        # B records
        records = igcdoc.fix_records
        @test length(records) == 9
        # tofix : because of vector of extensions test of equality
        # @test records[1] == B_record(Time(16, 02, 40), IGCLatitude(54.11868333333334), IGCLongitude(-2.8223666666666665), FixValidity.Fix3D, IGCPressureAltitude(280), IGCGpsAltitude(421), 36, "20509950")
        # @test records[2] == B_record(Time(16, 02, 45), IGCLatitude(51.118766666666666), IGCLongitude(-1.8216666666666668), FixValidity.Fix3D, IGCPressureAltitude(288), IGCGpsAltitude(429), 36, "19509020", IGCExtension[])
        # @test records[3] == B_record(Time(16, 02, 50), IGCLatitude(51.1189), IGCLongitude(-1.8213833333333334), FixValidity.Fix3D, IGCPressureAltitude(290), IGCGpsAltitude(432), 36, "21009015", IGCExtension[])
        # @test records[4] == B_record(Time(16, 02, 55), IGCLatitude(51.119), IGCLongitude(-1.82035), FixValidity.Fix3D, IGCPressureAltitude(290), IGCGpsAltitude(430), 36, "20009012", IGCExtension[])
        # @test records[5] == B_record(Time(16, 03, 00), IGCLatitude(51.119166666666665), IGCLongitude(-1.8200333333333334), FixValidity.Fix3D, IGCPressureAltitude(291), IGCGpsAltitude(432), 36, "25608009", IGCExtension[])
        # @test records[6] == B_record(Time(16, 03, 05), IGCLatitude(51.11966666666667), IGCLongitude(-1.81975), FixValidity.Fix3D, IGCPressureAltitude(291), IGCGpsAltitude(435), 36, "21008015", IGCExtension[])
        # @test records[7] == B_record(Time(16, 03, 10), IGCLatitude(51.1202), IGCLongitude(-1.8195666666666668), FixValidity.Fix3D, IGCPressureAltitude(293), IGCGpsAltitude(435), 36, "19608024", IGCExtension[])
        # @test records[8] == B_record(Time(16, 02, 48), IGCLatitude(51.120333333333335), IGCLongitude(-1.8191666666666666), FixValidity.Fix3D, IGCPressureAltitude(494), IGCGpsAltitude(436), 36, "19008018", IGCExtension[])
        # @test records[9] == B_record(Time(16, 02, 52), IGCLatitude(51.122166666666665), IGCLongitude(-1.8187833333333334), FixValidity.Fix3D, IGCPressureAltitude(496), IGCGpsAltitude(439), 36, "19508015", IGCExtension[])

        # C records
        # task = igcdoc.tasks[1]
        # @test length(igcdoc.tasks) == 1
        task = igcdoc.task
        @test task.info.declaration.date == Date(2001, 7, 15)
        @test task.info.declaration.time == Time(21, 38, 41)
        @test task.info.flight_date == Date(2001, 7, 16)
        @test task.info.number == "0001"
        @test task.info.num_turnpoints == 2
        @test task.info.description == "500K Tri"
        @test length(task.waypoints) == 6
        @test task.waypoints[1] == C_record_waypoint_info(IGCLatitude(51.18931666666667), IGCLongitude(-1.03165), "Lasham Clubhouse")
        @test task.waypoints[2] == C_record_waypoint_info(IGCLatitude(51.16965), IGCLongitude(-1.0440666666666667), "Lasham Start S, Start")
        @test task.waypoints[3] == C_record_waypoint_info(IGCLatitude(52.15153333333333), IGCLongitude(-2.9204499999999998), "Sarnesfield, TP1")
        @test task.waypoints[4] == C_record_waypoint_info(IGCLatitude(52.50245), IGCLongitude(-0.2935333333333333), "Norman Cross, TP2")
        @test task.waypoints[5] == C_record_waypoint_info(IGCLatitude(51.16965), IGCLongitude(-1.0440666666666667), "Lasham Start S, Finish")
        @test task.waypoints[6] == C_record_waypoint_info(IGCLatitude(51.18931666666667), IGCLongitude(-1.03165), "Lasham Clubhouse")

        # D records
        records = igcdoc.dgps_records
        @test length(records) == 1
        @test records[1] ==  D_record(GpsQualifier.DGPS, "0331")

        # E records
        records = igcdoc.event_records
        @test length(records) == 2
        @test records[1] == E_record(Time(16, 02, 45), "PEV", "")
        @test records[2] == E_record(Time(16, 03, 05), "PEV", "")

        # F records
        records = igcdoc.satellite_records
        @test length(records) == 2
        #@test records[1] == F_record(Time(16, 02, 40), ["04", "06", "09", "12", "36", "24", "22", "18", "21"])
        #@test records[2] == F_record(Time(16, 03, 00), ["06", "09", "12", "36", "24", "22", "18", "21"])

        # G records
        records = igcdoc.security_records
        @test length(records) == 5
        @test records[1].value == "REJNGJERJKNJKRE31895478537H43982FJN9248F942389T433T"
        @test records[2].value == "JNJK2489IERGNV3089IVJE9GO398535J3894N358954983O0934"
        @test records[3].value == "SKTO5427FGTNUT5621WKTC6714FT8957FGMKJ134527FGTR6751"
        @test records[4].value == "K2489IERGNV3089IVJE39GO398535J3894N358954983FTGY546"
        @test records[5].value == "12560DJUWT28719GTAOL5628FGWNIST78154INWTOLP7815FITN"

        # H records
        header = igcdoc.header
        @test header.competition_class.value == "15m Motor Glider"
        @test header.competition_id.value == "XYZ-78910"
        @test header.crew2.value == "Smith-Barry John A"
        @test header.firmware_version.value == "6.4"
        @test header.fix_accuracy.value == 35
        @test header.glider_type.value == "Schleicher ASH-25"
        @test header.glider_id.value == "ABCD-1234"
        @test header.gps_datum.value == "WGS-1984"
        @test header.gps_receiver.channels == 12
        @test header.gps_receiver.manufacturer == "MarconiCanada"
        @test header.gps_receiver.model == "Superstar"
        @test header.gps_receiver.max_alt.value == 10000
        @test header.gps_receiver.max_alt.unit == "m"
        @test header.hardware_version.value == "3.0"
        @test header.flight_recorder_type.manufacturer == "Manufacturer"
        @test header.flight_recorder_type.model == "Model"
        @test header.pilot_in_charge.value == "Bloggs Bill D"
        @test header.pressure_altitude_sensor.model == "XYZ1111"
        @test header.pressure_altitude_sensor.manufacturer == "Sensyn"
        @test header.pressure_altitude_sensor.max_alt.value == 11000
        @test header.pressure_altitude_sensor.max_alt.unit == "m"
        @test header.date.value == Date(2001, 7, 16)

        # I record
        extensions = igcdoc.fix_record_extensions.extensions
        @test length(extensions) == 3
        @test extensions[1] == IGCExtension(36:38, "FXA")
        @test extensions[2] == IGCExtension(39:40, "SIU")
        @test extensions[3] == IGCExtension(41:43, "ENL")

        # J records
        extensions = igcdoc.k_record_extensions.extensions
        @test length(extensions) == 1
        @test extensions[1] == IGCExtension(8:12, "HDT")

        # K records
        records = igcdoc.k_records
        @test length(records) == 1
        @test records[1] == K_record(Time(16, 02, 48), "00090", 7)

        # L records
        records = igcdoc.comment_records
        @test length(records) == 2
        @test records[1] == L_record("XXX", "RURITANIAN STANDARD NATIONALS DAY 1")
        @test records[2] == L_record("XXX", "FLIGHT TIME: 4:14:25, TASK SPEED:58.48KTS")

        # all_records (in file order)
        @test length(igcdoc.all_records) == 46

        # End of file / statistics
        #@test igcdoc.dt_first == ZonedDateTime(2001, 7, 16, 16, 2, 24, TZ)
        #@test igcdoc.dt_last == ZonedDateTime(2001, 7, 16, 16, 2, 52, TZ)
    end

    @testset "low level parse to vector of records" begin
        fname = joinpath("data", "example.igc")

        lines = readlines(fname)
        records = parse.(Abstract_IGC_record, lines)
        @test length(records) == 46

        lines = read(fname, String)
        records = parse(Vector{Abstract_IGC_record}, lines)
        @test length(records) == 46
    end

end


text:
# Simple ridge regression based upon the sindy-mpc
# repository, see https://arxiv.org/abs/1711.05501
# and https://github.com/eurika-kaiser/SINDY-MPC/blob/master/LICENSE
function STRridge(A::AbstractArray, Y::AbstractArray; ϵ::Number = 1e-3, maxiter::Int64 = 100)
    # Initial guess
    Ξ = A \ Y
    for i in 1:maxiter
        smallinds = abs.(Ξ) .<= ϵ
        Ξ[smallinds] .= 0.0
        for (j, y) in enumerate(eachcol(Y))
            biginds = @. ! smallinds[:, j]
            Ξ[biginds, j] = A[:, biginds] \ y
        end
    end
    return Ξ
end

function sparseConvex(A::AbstractArray, Y::AbstractArray; ϵ::Float64 = 1e-3)
    # Performs ~5 times faster than STRRidge
    # Get the getdimensions
    n_states, n_measurements = size(Y)
    n_basis = size(A)[2]
    # Preallocate the weights
    Ξ = zeros(n_basis, n_states)

    # Initialize the mixed integer programming
    t = Convex.Variable(n_basis)
    x = Convex.Variable(n_basis)
    dx = Convex.Variable(n_measurements)
    # Has always the same form
    p = Convex.minimize(Convex.dot(ones(n_basis),t))
    p.constraints += A*x == dx
    p.constraints += x <= t
    p.constraints += x >= -t

    # Iterate over all variables
    for i in 1:n_states
        # Fix the value for dx
        dx.value = Y[i,:]
        Convex.fix!(dx)
        # Solve
        Convex.solve!(p, GLPKMathProgInterface.GLPKSolverMIP())
        # TODO Warmstarting the solver is not an option right now
        #, warmstart = i > 1 ? true : false, verbose = false)
        Ξ[:, i] = x.value
    end

    Ξ[abs.(Ξ) .<= ϵ] .= 0.0

    return Ξ'
end

# Returns a basis for the differential state
function SInDy(X::AbstractArray, Ẋ::AbstractArray, Ψ::Basis; p::AbstractArray = [], ϵ::Number = 1e-1)
    θ = hcat([Ψ(xi, p = p) for xi in eachcol(X)]...)
    Ξ = sparseConvex(θ', Ẋ, ϵ = ϵ)
    return Basis(simplify_constants.(Ξ*Ψ.basis), variables(Ψ), parameters = p)
end

ext: jl


text:
using ResumableFunctions
@resumable function generator1()
    for i = 0:2
        @yield i
    end
end

@resumable function generator2()
    for j = 3:4
        @yield j
    end
end

@resumable function yield_from()
    for v in generator1()
        @yield v
    end
    for v in generator2()
        @yield v
    end
end

if abspath(PROGRAM_FILE) == @__FILE__
    arr = []
    for i in yield_from()
        push!(arr, i)
    end
    @assert(arr == [0, 1, 2, 3, 4])
end


text:
root_dir = dirname(pwd())
dados_processados_file_prefix = "COTAHIST"
dados_reduzidos_file_prefix = "COTAHIST_REDUCED"
extension = ".jld2"
path_sufix = "/Datasets/Dataset_Bovespa/Unzipped/"

dados_processados = root_dir * path_sufix * dados_processados_file_prefix * extension
dados_reduzidos = root_dir * path_sufix * dados_reduzidos_file_prefix * extension

if isfile(dados_processados)
    data_to_reduced_matrix_jld2 = "data_to_reduced_matrix_jld2.jl"
    run(`julia $data_to_reduced_matrix_jld2`)

    if isfile(dados_reduzidos)
        reduced_matrix_to_single_dataframe = "reduced_matrix_to_single_dataframe.jl"
        run(`julia $reduced_matrix_to_single_dataframe`)
    else
        println("Arquivo com dados reduzidos não foi encontrado! Abortando operação.")
    end
else
    println("Arquivo com dados processados não encontrado! Abortando operação.")
end


text:
####
#### Defines list of tutorials given `generated_dir`
####

generate_tutorials = true

tutorials = []

# Allow flag to skip generated
# tutorials since this is by
# far the slowest part of the
# docs build.
if generate_tutorials

    # generate tutorials
    import Literate

    include("pages_helper.jl")

    tutorials_dir = joinpath(@__DIR__, "..", "tutorials")

    tutorials = [
        "Atmos" => ["Dry Idealized GCM" => "Atmos/heldsuarez.jl"],
        "Ocean" => [],
        "Land" => ["Heat" => ["Heat Equation" => "Land/Heat/heat_equation.jl"]],
        "Numerics" => [
            "System Solvers" => [
                "Conjugate Gradient" => "Numerics/SystemSolvers/cg.jl",
                "Batched Generalized Minimal Residual" =>
                    "Numerics/SystemSolvers/bgmres.jl",
            ],
            "DG Methods" => ["Topology" => "topo.jl"],
        ],
        "Diagnostics" => [
            "Debug" => [
                "State Statistics Regression" =>
                    "Diagnostics/Debug/StateCheck.jl",
            ],
        ],
        "Contributing" => ["Notes on Literate" => "literate_markdown.jl"],
    ]

    # Prepend tutorials_dir
    tutorials_jl = flatten_to_array_of_strings(get_second(tutorials))
    println("Building literate tutorials:")
    for tutorial in tutorials_jl
        println("    $(tutorial)")
    end
    transform(x) = joinpath(basename(generated_dir), replace(x, ".jl" => ".md"))
    tutorials = transform_second(x -> transform(x), tutorials)

    tutorials_jl = map(x -> joinpath(tutorials_dir, x), tutorials_jl)

    for tutorial in tutorials_jl
        gen_dir =
            joinpath(generated_dir, relpath(dirname(tutorial), tutorials_dir))
        input = abspath(tutorial)
        script = Literate.script(input, gen_dir)
        code = strip(read(script, String))
        mdpost(str) = replace(str, "@__CODE__" => code)
        Literate.markdown(input, gen_dir, postprocess = mdpost)
        Literate.notebook(input, gen_dir, execute = true)
    end

end

max_stars_repo_name: leios/CLIMA

max_issues_repo_name: leios/CLIMA

max_forks_repo_name: leios/CLIMA


text:
using FindSteadyStates
using Test
using Parameters
using DifferentialEquations
using LabelledArrays
using Random
using Plots
using NLsolve

@testset "FindSteadyStates.jl" begin

    @testset "Solve ODE" begin
         include("solveODE.jl")
    end

    @testset "Multi-thread for steady states" begin
         include("multithread_SteadyStateProblem.jl")
    end

    @testset "Sampling vector" begin
        include("sampling_vector.jl")
    end

    @testset "Search functions" begin
        include("search.jl")
    end

    @testset "Solve with grid search" begin
        include("solve_with_grid_search.jl")
    end

    @testset "Jacobian and Stability" begin
        include("jacobian/jacobian.jl")
        include("jacobian/generate_jac.jl")
    end

    @testset "Solve roots for unstabe system" begin
        include("steadystates_unstable_model.jl")
    end

    @testset "Rootfinding with boundaries" begin
        include("rootfinding_bounded.jl")
    end
end


text:
module Entropies
    include("core.jl")
    include("histogram_estimation.jl")
    include("counting_based/CountOccurrences.jl")
    include("symbolic/symbolic.jl")
    include("binning_based/rectangular/rectangular_estimators.jl")
    include("kerneldensity/kerneldensity.jl")
    include("wavelet/wavelet.jl")
    include("nearest_neighbors/nearest_neighbors.jl")
end


text:
## Copyright (c) 2015, Júlio Hoffimann Mendes <juliohm@stanford.edu>
##
## Permission to use, copy, modify, and/or distribute this software for any
## purpose with or without fee is hereby granted, provided that the above
## copyright notice and this permission notice appear in all copies.
##
## THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
## WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
## MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
## ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
## WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
## ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
## OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

datadir = joinpath(Pkg.dir(),"GeoStatsImages","src","data")
datafiles = filter(s -> ismatch(r".*\.dat", s), readdir(datadir))

database = Dict()
for fname in datafiles
  push!(database, fname[1:end-4] => joinpath(datadir, fname))
end

available = sort(collect(keys(database)))

function training_image(identifier::AbstractString)
  @assert identifier ∈ available "training image not available"

  datafile = database[identifier]

  f = open(datafile)
  kind, nx, ny, nz = split(strip(readline(f)))
  nx = parse(Int, nx)
  ny = parse(Int, ny)
  nz = parse(Int, nz)
  data = readdlm(f)
  close(f)

  reshape(data, nx, ny, nz)
end


text:
@testset "execution" begin

@testset "generic values" begin

let
    val = GenericValue(LLVM.Int32Type(), -1)
    @test intwidth(val) == 32
    @test convert(Int, val) == -1
    dispose(val)
end

let
    val = GenericValue(LLVM.Int32Type(), UInt(1))
    @test convert(Int, val) == 1
    @test convert(UInt, val) == 1
    dispose(val)
end

let
    val = GenericValue(LLVM.DoubleType(), Float32(1.1))
    @test convert(Float32, val, LLVM.DoubleType()) == Float32(1.1)
    @test convert(Float64, val, LLVM.DoubleType()) == Float64(Float32(1.1))
    dispose(val)
end

let
    val = GenericValue(LLVM.DoubleType(), 1.1)
    @test convert(Float32, val, LLVM.DoubleType()) == Float32(1.1)
    @test convert(Float64, val, LLVM.DoubleType()) == 1.1
    dispose(val)
end

let
    obj = "whatever"
    val = GenericValue(pointer(obj))
    @test convert(Ptr{Cvoid}, val) == pointer(obj)
    dispose(val)
end

end

@testset "execution engine" begin

Context() do ctx
    mod = LLVM.Module("SomeModule", ctx)
    ExecutionEngine(mod) do mod end
end

function emit_sum(ctx::Context)
    mod = LLVM.Module("SomeModule", ctx)

    param_types = [LLVM.Int32Type(ctx), LLVM.Int32Type(ctx)]
    ret_type = LLVM.FunctionType(LLVM.Int32Type(ctx), param_types)

    sum = LLVM.Function(mod, "SomeFunctionSum", ret_type)

    entry = BasicBlock(sum, "entry")

    Builder(ctx) do builder
        position!(builder, entry)

        tmp = add!(builder, parameters(sum)[1], parameters(sum)[2])
        ret!(builder, tmp)

        verify(mod)
    end

    return mod
end

function emit_retint(ctx::Context, val)
    mod = LLVM.Module("SomeModule", ctx)

    ret_type = LLVM.FunctionType(LLVM.Int32Type(ctx))

    fn = LLVM.Function(mod, "SomeFunction", ret_type)

    entry = BasicBlock(fn, "entry")

    Builder(ctx) do builder
        position!(builder, entry)

        ret!(builder, ConstantInt(LLVM.Int32Type(ctx), val))

        verify(mod)
    end

    return mod
end

function emit_phi(ctx::Context)
    # if %1 > %2 then %1+2 else %2-5
    mod = LLVM.Module("sommod", ctx)
    params = [LLVM.Int32Type(ctx), LLVM.Int32Type(ctx)]

    ft = LLVM.FunctionType(LLVM.Int32Type(ctx), params)
    fn = LLVM.Function(mod, "gt", ft)

    entry = BasicBlock(fn, "entry")
    then = BasicBlock(fn, "then")
    elsee = BasicBlock(fn, "else")
    merge = BasicBlock(fn, "ifcont")

    Builder(ctx) do builder
        position!(builder, entry)

        cond = LLVM.icmp!(builder, LLVM.API.LLVMIntSGT, parameters(fn)[1], parameters(fn)[2], "ifcond")
        br!(builder, cond, then, elsee)

        position!(builder, then)
        thencg = add!(builder, parameters(fn)[1], ConstantInt(LLVM.Int32Type(ctx), 2))
        br!(builder, merge)

        position!(builder, elsee)
        elsecg = sub!(builder, LLVM.parameters(fn)[2], LLVM.ConstantInt(LLVM.Int32Type(ctx), 5))
        br!(builder, merge)

        position!(builder, merge)
        phi = phi!(builder, LLVM.Int32Type(ctx), "iftmp")

        append!(LLVM.incoming(phi), [(thencg, then), (elsecg, elsee)])

        @test length(LLVM.incoming(phi)) == 2
        @test_throws BoundsError LLVM.incoming(phi)[3]

        ret!(builder, phi)
    end
    verify(mod)
    return mod
end

Context() do ctx
    mod = emit_sum(ctx)

    args = [GenericValue(LLVM.Int32Type(), 1),
            GenericValue(LLVM.Int32Type(), 2)]

    let mod = LLVM.Module(mod)
        fn = functions(mod)["SomeFunctionSum"]
        Interpreter(mod) do engine
            res = LLVM.run(engine, fn, args)
            @test convert(Int, res) == 3
            dispose(res)
        end
        @test_throws UndefRefError show(mod)
    end

    dispose.(args)

    let mod = emit_retint(ctx, 42)
        fn = functions(mod)["SomeFunction"]
        JIT(mod) do engine
            res = LLVM.run(engine, fn)
            @test convert(Int, res) == 42
            dispose(res)
        end
        @test_throws UndefRefError show(mod)
    end

    let mod = emit_retint(ctx, 42)
        fn = functions(mod)["SomeFunction"]
        ExecutionEngine(mod) do engine
            res = LLVM.run(engine, fn)
            @test convert(Int, res) == 42
            dispose(res)
        end
        @test_throws UndefRefError show(mod)
    end

    args1 =
    [GenericValue(LLVM.Int32Type(ctx), 1),
    GenericValue(LLVM.Int32Type(ctx), 2)]

    args2 =
    [GenericValue(LLVM.Int32Type(ctx), 2),
    GenericValue(LLVM.Int32Type(ctx), 1)]

    for (args, true_res) in ((args1, -3), (args2, 4))
        let mod = emit_phi(ctx)
            fn = functions(mod)["gt"]
            Interpreter(mod) do engine
                res = LLVM.run(engine, fn, args)
                @test convert(Int, res) == true_res
                dispose(res)
            end
        end
        dispose.(args)
    end

    let mod1 = emit_sum(ctx), mod2 = emit_retint(ctx, 42)
        Interpreter(mod1) do engine
            @test_throws ErrorException collect(functions(engine))
            @test haskey(functions(engine), "SomeFunctionSum")
            @test functions(engine)["SomeFunctionSum"] isa LLVM.Function
            delete!(engine, mod1)
            @test_throws KeyError functions(engine)["SomeFunctionSum"]
            @test !haskey(functions(engine), "SomeFunctionSum")
            dispose(mod1)
            push!(engine, mod2)
            @test haskey(functions(engine), "SomeFunction")
            @test functions(engine)["SomeFunction"] isa LLVM.Function

            res = LLVM.run(engine, functions(engine)["SomeFunction"])
            @test convert(Int, res) == 42
            dispose(res)
        end
    end
end

end

end


text:
using DataInterpolations, FileIO, CSV, DataFrames, Dates, Statistics
using StatsPlots, JLD2, Flux, ForwardDiff, GalacticOptim, LinearAlgebra
using Parameters, Distributions, OrdinaryDiffEq, DiffEqCallbacks, LogExpFunctions
using RecursiveArrayTools, Interpolations, MCMCChains, Suppressor, Interpolations
import KenyaCoVaccines

##Load methods and group data into correct age groups

include("generation_methods.jl");
include("inference_methods.jl");
@load("data/p_ID.jld2")
@load("data/cleaned_linelist20211109_deaths_c_age__date_of_lab_confirmation.jld2")

t0 = findfirst(deaths_data.dates .== Date(2020, 12, 2))
t1 = findfirst(deaths_data.dates .== Date(2021, 9, 27))

deathsdata = cat(sum(deaths_data.deaths[t0:t1, :, 1:4], dims = 3),
    sum(deaths_data.deaths[t0:t1, :, 5:10], dims = 3),
    sum(deaths_data.deaths[t0:t1, :, 11:12], dims = 3),
    sum(deaths_data.deaths[t0:t1, :, 13:14], dims = 3),
    sum(deaths_data.deaths[t0:t1, :, 15:16], dims = 3),
    sum(deaths_data.deaths[t0:t1, :, 17], dims = 3), dims = 3)

deathsdata_vect = [Matrix(deathsdata[:, k, :][:, :]') for k = 1:47]

prev_deaths_vect = [[sum(deaths_data.deaths[1:(t0+30), k, 1:4])
    sum(deaths_data.deaths[1:(t0+30), k, 5:10])
    sum(deaths_data.deaths[1:(t0+30), k, 11:12])
    sum(deaths_data.deaths[1:(t0+30), k, 13:14])
    sum(deaths_data.deaths[1:(t0+30), k, 15:16])
    sum(deaths_data.deaths[1:(t0+30), k, 17])] for k = 1:47]

##Gather infection predictions by county

fitfiles = readdir("modelfits", join = true)
inf_predictions = Vector{NamedTuple}(undef, 47)
prev_inf_predictions = Vector{Vector}(undef, 47)

for (i, filename) in enumerate(fitfiles)
    model = @suppress_err load(filename)["model"]
    KenyaCoVaccines.change_prob!(model, zeros(500); startdate = Date(2020, 12, 1), enddate = Date(2021, 9, 27))
    println("Making infection predictions for county $(model.areaname)")
    inf_predictions[i] = gather_post_mean_infection_rates_by_type_novac(model, Date(2021, 9, 27))
    prev_inf_predictions[i] = model.init_sero .* mean(model.MCMC_results.chain[:init_scale]) .* model.N
end

##
function regularization(mort_scales, mort_age, mort_var, η)
    T = eltype(mort_scales)
    total_prior = T(0.0)
    for k = 1:29
        total_prior -= logpdf(Beta(10, 90), mort_scales[k])
    end
    for k = 31:47
        total_prior -= logpdf(Beta(10, 90), mort_scales[k])
    end
    total_prior -= logpdf(Normal(0, 0.01), log(mort_scales[30]))
    total_prior -= logpdf(Beta(0.0001 * 50, (1 - 0.0001) * 50), mort_age[1])
    total_prior -= logpdf(Beta(0.00002 * 50, (1 - 0.00002) * 50), mort_age[2])
    total_prior -= logpdf(Beta(0.00002 * 50, (1 - 0.00002) * 50), mort_age[3])
    total_prior -= logpdf(Beta(0.001 * 50, (1 - 0.001) * 50), mort_age[4])
    total_prior -= logpdf(Beta(0.01 * 20, (1 - 0.01) * 20), mort_age[5])
    total_prior -= logpdf(Beta(0.01 * 20, (1 - 0.01) * 20), mort_age[6])
    total_prior -= logpdf(Normal(log(1.2), 0.2), mort_var[1])
    total_prior -= logpdf(Normal(log(1.2), 0.2), mort_var[2])
    total_prior -= logpdf(Normal(0.0, 0.05), η)
    return total_prior
end

function poisson_loss_death_pred(mort_scales, mort_age, mort_var, mort_reinf, deathsdata_vect, prev_deaths_vect, prev_inf_predictions, predictions_vect, η, p_ID)
    T = eltype(mort_scales)
    total_loss = T(0.0)
    n = length(inf_predictions[1].infections_by_age_first_pred[1])
    overall_pred = zeros(T,n)

    for k = 1:47
        for a = 1:6
            total_loss -= logpdf(Poisson(mort_age[a] * mort_scales[k] * prev_inf_predictions[k][a]), prev_deaths_vect[k][a]) #Loss due to previous infections
        end
        _loss, _pred = poisson_loss_death_pred_county(deathsdata_vect[k], mort_scales[k], mort_age, mort_var, mort_reinf, predictions_vect[k], η, p_ID) #loss due to
        total_loss += _loss
        overall_pred .+= _pred
    end
    total_loss += regularization(mort_scales, mort_age, mort_var, η)
    return total_loss, overall_pred
end

x = ones(47)
x[30] = 0.0
y = zeros(47)
y[30] = 1.0
scales_guess = 0.1 * x + y

deaths_loss_data = (; deathsdata_vect, prev_deaths_vect, prev_inf_predictions, inf_predictions, p_ID)

function deaths_loss(x, p)
    @unpack deathsdata_vect, prev_deaths_vect, prev_inf_predictions, inf_predictions, p_ID = deaths_loss_data
    mort_scales = [logistic.(x[1:29]); exp(x[30]); logistic.(x[31:47])]
    mort_age = logistic.(x[(47+1):47+6])
    mort_var = exp.(x[54:55])
    η = x[56]
    return poisson_loss_death_pred(mort_scales, mort_age, mort_var, 0.15, deathsdata_vect, prev_deaths_vect, prev_inf_predictions, inf_predictions, η, p_ID)
end
##

recorded_losses = Any[]

function plot_deaths(x, loss, pred)
    println("loss = $(loss)")
    push!(recorded_losses,loss)
    plt = scatter(sum(deathsdata, dims = [2, 3])[:], lab = "data")
    plot!(plt, pred, lw = 3, lab = "pred")
    display(plt)
    return false
end

plot_deaths(loss, pred)

x = ones(47)
x[30] = 0.0
y = zeros(47)
y[30] = 1.0
scales = 0.1 * x + y
x₀ = [logit.(scales[1:29])
    log.(scales[30])
    logit.(scales[31:47])
    logit.(fill(0.001, 6))
    log.([1.2, 1.2])
    0.0]

loss, pred = deaths_loss(x₀, deaths_loss_data)

##

f = OptimizationFunction(deaths_loss, GalacticOptim.AutoForwardDiff())
prob = OptimizationProblem(f, x₀, deaths_loss_data)
sol = solve(prob, Flux.ADAM(0.01); cb = plot_deaths,maxiters = 200)

##

loss, pred = poisson_loss_death_pred(scales, fill(0.001, 6), [1.2, 1.2], 0.15, deathsdata_vect, prev_deaths_vect, prev_inf_predictions, inf_predictions, 0.0, p_ID)

plot!(pred)
scatter!(sum(deathsdata, dims = [2, 3])[:])
vline!([30])


text:
# Autogenerated wrapper script for libcint_jll for x86_64-linux-gnu
export libcint

using OpenBLAS32_jll
JLLWrappers.@generate_wrapper_header("libcint")
JLLWrappers.@declare_library_product(libcint, "libcint.so.5")
function __init__()
    JLLWrappers.@generate_init_header(OpenBLAS32_jll)
    JLLWrappers.@init_library_product(
        libcint,
        "lib/libcint.so",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()


text:
using JuMP
using Cbc
using Dates

function readData()
    arr = Array{Int, 2}(undef, 0,0 )
    if isfile("instances/temp.txt")
        myFile = open("instances/temp.txt")
        data = readlines(myFile)
        n = length(data)
        arr = fill(0,(n - 3, n -10))

        i = 0
        for line in data
            if line == ""
                continue
            end
            i += 1
            var = split(line, " ")
            for j in 1:length(var)
                arr[i, j] = parse(Int, var[j])
            end
        end
    end
    return arr
end

function square(n::Int64)
    return n*n
end

function solve_TSP(d::Array{Int, 2})
    numOfAero = d[1,1]#number of aerodromes
    start = d[2,1]
    endP = d[3,1]
    numOfMust = d[4,1]#number of points must be visited
    numOfRegion = d[5,1]#number of regions
    maxDistance = d[7,1]#max distance travel without landing

    tempstart = start
    tempend = endP

    lines = size(d, 1) #return the number of lines of array d

    # let startPoint at the first, lastPoint at the last
    for j in 1:2
        temp = d[start+7,j]
        d[start+7,j] = d[8,j]
        d[8,j] = temp
        temp = d[endP+7,j]
        d[endP+7,j] = d[numOfAero+7,j]
        d[numOfAero+7,j] = temp
    end
    #n -> the size of the coordinate matrix
    n = lines - 7

    regOfEach = Array{Int}(zeros(n))#an array used to store the information of region for each aerodrome
    for j in 1:n
        regOfEach[j] = d[6,j]
    end

    #because of the swap between the first point and the end point, the position of the region array need to be changed correspondingly
    temp = regOfEach[1] #temp is used to store the value needed to be swapped
    regOfEach[1] = regOfEach[start]
    regOfEach[start] = temp

    temp = regOfEach[numOfAero]
    regOfEach[numOfAero] = regOfEach[endP]
    regOfEach[endP] = temp

    start = 1#reset the start and end point
    endP = numOfAero

    disArr = Array{Int, 2}(undef, n, n)#an array used to store the information of the distance between each point
    for i in 1:n
        for j in 1:n
            disArr[i, j] = round(sqrt(square(d[i+7,1]-d[j+7,1]) + square(d[i+7,2]-d[j+7,2])))
        end
    end

    Model
    m = Model(Cbc.Optimizer)
    set_optimizer_attribute(m, "threads", 16)

    #Variables
    @variable(m, x[i in 1:n, j in 1:n], Bin)
    @variable(m, visited[i in 1:n], Bin)
    @variable(m, u[j in 1:n] >= 0)

    #Objective function
    @objective(m, Min, sum(disArr[i,j]*x[i,j] for i in 1:n, j in 1:n))

    #Constraints for preventing self-loop
    @constraint(m, loopsForbidden[i in 1:n], x[i,i] == 0)

    #start from startPoint
    @constraint(m, fromStartOut, sum(x[start, j] for j in 1:n) == 1)
    @constraint(m, fromStartIn, sum(x[i, start] for i in 1:n) == 0)
    @constraint(m, visited[1] == 1)

    #end at endPoint
    @constraint(m, toEndOut, sum(x[endP, j] for j in 1:n) == 0)
    @constraint(m, toEndIn, sum(x[i, endP] for i in 1:n) == 1)
    @constraint(m, visited[numOfAero] == 1)

    #number of point must be visited
    @constraint(m, sum(x[i,j] for i in 1:n, j in 1:n) >= numOfMust-1)

    #the max distance travel without landing
    @constraint(m, maxDis[i in 1:n, j in 1:n], x[i,j]*disArr[i,j] <= maxDistance)

    #constraint for middle points
    #each middle point could only have one out-degree
    @constraint(m, noMoreThanOne1[i in 2:n-1], sum(x[i,j] for j in 2:n) <= 1)
    #each middle point could only have one in-degree
    @constraint(m, noMoreThanOne2[j in 2:n-1], sum(x[i,j] for i in 1:n-1) <= 1)
    #build the relation between variable x and visited, and ensure that in-degree == out-degree
    @constraint(m, middlePoint1[i in 2:n-1], sum(x[i,j] for j in 1:n) == visited[i])
    @constraint(m, middlePoint2[j in 2:n-1], sum(x[i,j] for i in 1:n) == visited[j])

    #region constraint that ensure that each region must be visited once
    @constraint(m, [i in 2:n-1], visited[i] == sum(x[i,j] for j in 1:n))
    @constraint(m, region1[i in 1:numOfRegion], sum(visited[j] for j in 1:n if regOfEach[j] == i) >= 1)

    #MTZ
    @constraint(m, mtz[i in 1:n, j in 2:n], u[j] >= u[i]+1-n+n*x[i,j]+(n-2)*x[j,i])
    @constraint(m, mtz2[j in 1:n], u[j] <= n)
    @constraint(m, mtz3[j in 1:n], u[j] >= 1)

    #Solve the problem
    set_silent(m)
    optimize!(m)

    # return to origin for the proposed outcome
    for i in 1:n
        temp = x[i,tempstart]
        x[i,tempstart] = x[i,start]
        x[i,start] = temp
        temp = x[tempstart,i]
        x[tempstart,i] = x[start,i]
        x[start,i] = temp
        temp = x[i,tempend]
        x[i,tempend] = x[i,endP]
        x[i,endP] = temp
        temp = x[tempend,i]
        x[tempend,i] = x[endP,i]
        x[endP,i] = temp
    end
    println("Result - Optimal solution found")
    println("")
    println(" Distance travelled = ", JuMP.objective_value(m))
    print("Edges used in the solutin :")
    for i in 1:n
        for j in 1:n
            valij =  JuMP.value(x[i,j])
            if valij <= 1.000001 && valij >= 0.999999
                print(i, "->", j, " ")
            end
        end
    end
    println()

end

d1=now(Dates.UTC)
D = readData()
solve_TSP(D)
d2=now(Dates.UTC)
println(d2-d1)


text:
using FvCFD

# All file paths are relative to the repository's main directory, 'include' this script from there

### Freestream Conditions ###
P = 100000
T = 300
U = [ 694.26, 0, 0 ]
Cp = 1005
R = 287.05
gamma = 1.4
fluid = Fluid(Cp, R, gamma)

### Choose a mesh ###
meshPath = "test/OFflaredConeMesh"
boundaryConditions = [ supersonicInletBoundary, [P, T, U...], zeroGradientBoundary, [], wallBoundary, [] ]

### Solve ###
mesh = OpenFOAMMesh(meshPath)
cellPrimitives = initializeUniformSolution3D(mesh, P, T, U...)
solve(mesh, meshPath, cellPrimitives, boundaryConditions, LTSEuler, initDt=0.00000001, endTime=18000, outputInterval=9.3, targetCFL=0.1, silent=false, restart=false, fluid=fluid)

max_stars_repo_name: henrystoldt/fvCFD


text:
module App

using bearingDistributions
using WebSockets
using Sockets
using Interact
using Blink
using Plots
using Mux

const bd = bearingDistributions

export julia_main

"""
    julia_main()

    Wrapper for PackageCompiler.jl
"""
function julia_main()
    try
        t = launchApp(8000)
    catch
        Base.invokelatest(Base.display_error, Base.catch_stack())
        t.state = :done
        return 1
    end
    t.state = :done
    return 0
end

"""
    launchApp(port)

    Serves up the application via Interact.WebIO
"""
function launchApp(port)
    WebIO.webio_serve(page("/", app), port)
end

"""
    app(req)

    The main application. Implements sliders that set parameters for the contour graphs.
"""
function app(req)
    θᵣ = 0:π/100:2π;
    Δθᵣ = .02:.01:.2;
    αᵣ = .5:.01:1
    len = 101:100:1001
    @manipulate throttle = .1 for x₁=slider(0:.1:1.4; value = 0, label = "x₁"),
        x₂=slider(1.5:.1:3.0; value = 3, label = "x₂"),
        θ₁=slider(θᵣ; value = π/4, label = "θ₁"),
        θ₂=slider(θᵣ; value = 3π/4, label = "θ₂"),
        Δθ₁=slider(Δθᵣ; value = .18, label = "Δθ₁"),
        Δθ₂=slider(Δθᵣ; value = .18, label = "Δθ₂"),
        α=slider(αᵣ; value = .95, label = "α"),
        len=slider(len; value = 101, label = "Resolution")

        b1 = Bearing(θ₁, Δθ₁, x₁, 0);
        b2 = Bearing(θ₂, Δθ₂, x₂, 0);
        x,y,Pᵢ,P₁,P₂ = intersectGrid(b1, b2; length=len);
        P = (Pᵢ,P₁,P₂)
        handle = plotConfidenceInterval(α,x,y,P...)
    end
end

function blinkApp()
    θᵣ = 0:π/100:2π;
    Δθᵣ = .02:.01:.2;
    αᵣ = .5:.01:1
    len = 101:100:1001
    ui = @manipulate throttle = .1 for x₁=slider(0:.1:1.4; value = 0, label = "x₁"),
        x₂=slider(1.5:.1:3.0; value = 3, label = "x₂"),
        θ₁=slider(θᵣ; value = π/4, label = "θ₁"),
        θ₂=slider(θᵣ; value = 3π/4, label = "θ₂"),
        Δθ₁=slider(Δθᵣ; value = .18, label = "Δθ₁"),
        Δθ₂=slider(Δθᵣ; value = .18, label = "Δθ₂"),
        α=slider(αᵣ; value = .95, label = "α"),
        len=slider(len; value = 101, label = "Resolution")

        b1 = Bearing(θ₁, Δθ₁, x₁, 0);
        b2 = Bearing(θ₂, Δθ₂, x₂, 0);
        x,y,Pᵢ,P₁,P₂ = intersectGrid(b1, b2; length=len);
        P = (Pᵢ,P₁,P₂)
        handle = plotConfidenceInterval(α,x,y,P...)
    end
    w = Window()
    body!(w, ui)
    return w
end

end


text:
# ------------------------------------------------------------------
# Licensed under the MIT License. See LICENSE in the project root.
# ------------------------------------------------------------------

"""
    Variogram

A theoretical variogram model (e.g. Gaussian variogram).
"""
abstract type Variogram end

"""
    sill(γ)

Return the sill of the variogram `γ` when defined.
"""
sill(γ::Variogram) = γ.sill

"""
    nugget(γ)

Return the nugget of the variogram `γ` when defined.
"""
nugget(γ::Variogram) = γ.nugget

"""
    range(γ)

Return the maximum range of the variogram `γ` when defined.
"""
Base.range(γ::Variogram) = maximum(radii(γ.ball))

"""
    γ(u, v)

Evaluate the variogram at points `u` and `v`.
"""
function (γ::Variogram)(u::Point, v::Point)
  d = metric(γ.ball)
  x = coordinates(u)
  y = coordinates(v)
  h = evaluate(d, x, y)
  γ(h)
end

"""
    γ(U, v)

Evaluate the variogram at geometry `U` and point `v`.
"""
function (γ::Variogram)(U::Geometry, v::Point)
  us = _sample(γ, U)
  mean(γ(u, v) for u in us)
end

"""
    γ(u, V)

Evaluate the variogram at point `u` and geometry `V`.
"""
(γ::Variogram)(u::Point, V::Geometry) = γ(V, u)

"""
    γ(U, V)

Evaluate the variogram at geometries `U` and `V`.
"""
function (γ::Variogram)(U::Geometry, V::Geometry)
  us = _sample(γ, U)
  vs = _sample(γ, V)
  mean(γ(u, v) for u in us, v in vs)
end

"""
    result_type(γ, u, v)

Return result type of γ(u, v).
"""
result_type(γ::Variogram, u, v) = typeof(γ(u, v))

"""
    isstationary(γ)

Check if variogram `γ` possesses the 2nd-order stationary property.
"""
isstationary(γ::Variogram) = isstationary(typeof(γ))

"""
    isisotropic(γ)

Tells whether or not variogram `γ` is isotropic.
"""
isisotropic(γ::Variogram) = isisotropic(γ.ball)

# -----------
# IO METHODS
# -----------

function Base.show(io::IO, γ::Variogram)
  T = typeof(γ)
  O = IOContext(io, :compact => true)
  name   = string(nameof(T))
  params = String[]
  for fn in fieldnames(T)
    val = getfield(γ, fn)
    if val isa MetricBall
      if isisotropic(val)
        r = first(radii(val))
        push!(params, "range=$r")
      else
        r = Tuple(radii(val))
        push!(params, "ranges=$r")
      end
      m = nameof(typeof(metric(val)))
      push!(params, "metric=$m")
    else
      push!(params, "$fn=$val")
    end
  end
  print(O, name, "(", join(params, ", "), ")")
end

function Base.show(io::IO, ::MIME"text/plain", γ::Variogram)
  T = typeof(γ)
  O = IOContext(io, :compact => true)
  name   = string(nameof(T))
  header = isisotropic(γ) ? name : name*" (anisotropic)"
  params = String[]
  for fn in fieldnames(T)
    val = getfield(γ, fn)
    if val isa MetricBall
      if isisotropic(val)
        r = first(radii(val))
        push!(params, "  └─range ⇨ $r")
      else
        r = Tuple(radii(val))
        push!(params, "  └─ranges ⇨ $r")
      end
      m = nameof(typeof(metric(val)))
      push!(params, "  └─metric ⇨ $m")
    else
      push!(params, "  └─$fn ⇨ $val")
    end
  end
  println(O, header)
  print(O, join(params, "\n"))
end

# ----------------
# IMPLEMENTATIONS
# ----------------

include("theoretical/gaussian.jl")
include("theoretical/exponential.jl")
include("theoretical/spherical.jl")
include("theoretical/matern.jl")
include("theoretical/cubic.jl")
include("theoretical/pentaspherical.jl")
include("theoretical/sinehole.jl")
include("theoretical/power.jl")
include("theoretical/nugget.jl")


text:
#!/usr/bin/env julia

function cost(X, Y, S)
    c = 0
    for i in eachindex(S)
        i == firstindex(S) && continue
        S[i - 1] == 'C' && S[i] == 'J' && (c += X)
        S[i - 1] == 'J' && S[i] == 'C' && (c += Y)
    end
    c
end

Base.isless(::Nothing, ::Nothing) = true
Base.isless(::Nothing, x) = false
Base.isless(x, ::Nothing) = true

function solve!(X, Y, S, i)
    c = cost(X, Y, S)
    function recurse!(ii, depth)
        _ii = findnext(==('?'), S, ii)
        (_ii === nothing || depth == 0) && return S, cost(X, Y, S)
        save = copy(S)
        S[_ii] = 'C'
        Scand1, Scost1 = recurse!(_ii, depth - 1)
        S = save
        S[_ii] = 'J'
        Scand2, Scost2 = recurse!(_ii, depth - 1)
        Scost1 < Scost2 ? (Scand1, Scost1) : (Scand2, Scost2)
    end

    while i !== nothing
        S, c = recurse!(i, min(3, findnext(==('C'), S, i), findnext(==('J'), S, i)))
        i = findnext(==('?'), S, i)
    end
    S, c
end

function solve(case, X, Y, S)
    S, c = solve!(X, Y, S, firstindex(S))
    @assert findfirst(==('?'), S) === nothing
    println("Case #$case: $c")
end

function main()
    T = parse(Int, readline())
    for case in 1:T
        _X, _Y, _S = split(readline())
        X = parse(Int, _X)
        Y = parse(Int, _Y)
        S = Vector{Char}(_S)
        solve(case, X, Y, S)
    end
end

isinteractive() || main()

max_stars_repo_name: AnAverageHuman/competitive

max_issues_repo_name: AnAverageHuman/competitive

max_forks_repo_name: AnAverageHuman/competitive


text:
# adapted from http://www.gis.usu.edu/~chrisg/python/2009/lectures/ospy_hw1b.py

import GDALUtils; const GU = GDALUtils

GU.registerdrivers() do
    GU.read("ospy/data1/sites.shp") do input
        GU.create("tmp/hw1b.shp", "ESRI Shapefile") do output
            # get the layer for the input data source
            inlayer = GU.fetchlayer(input, 0)
            # create the layer for the output data source
            outlayer = GU.createlayer(output, "hw1b", GDAL.wkbPoint)

            # get FieldDefn's for the id and cover fields in the input shapefile
            inlayerdefn = GU.getlayerdefn(inlayer)
            idfielddefn = GU.fetchfielddefn(inlayerdefn, 0)
            coverfielddefn = GU.fetchfielddefn(inlayerdefn, 1)

            # create new id and cover fields in the output shapefile
            GU.createfield(outlayer, idfielddefn)
            GU.createfield(outlayer, coverfielddefn)

            # get the FeatureDefn for the output layer
            outlayerdefn = GU.getlayerdefn(outlayer)

            # loop through the input features
            for infeature in inlayer
                # get the input feature attributes
                id = GU.fetchfield(infeature, 0)
                cover = GU.fetchfield(infeature, 1)
                if cover == "trees"
                    GU.createfeature(outlayerdefn) do outfeature
                        # set the geometry
                        geom = GU.getgeom(infeature)
                        GU.setgeom(outfeature, geom)

                        # set the attributes
                        GU.setfield(outfeature, 0, id)
                        GU.setfield(outfeature, 1, cover)

                        # add the feature to the output layer
                        GU.createfeature(outlayer, outfeature)
                    end
                end
            end
        end
    end
end

# version 2
GU.registerdrivers() do
    GU.read("ospy/data1/sites.shp") do input
        GU.create("tmp/hw1b.shp", "ESRI Shapefile") do output
            # get the layer for the input data source
            inlayer = GU.fetchlayer(input, 0)
            # create the layer for the output data source
            outlayer = GU.createlayer(output, "hw1b", GDAL.wkbPoint)

            inlayerdefn = GU.getlayerdefn(inlayer)
            GU.createfield(outlayer, GU.fetchfielddefn(inlayerdefn, 0))
            GU.createfield(outlayer, GU.fetchfielddefn(inlayerdefn, 1))

            # loop through the input features
            for infeature in inlayer
                id = GU.fetchfield(infeature, 0)
                cover = GU.fetchfield(infeature, 1)
                if cover == "trees"
                    GU.createfeature(outlayer) do outfeature
                        GU.setgeom(outfeature, GU.getgeom(infeature))
                        GU.setfield(outfeature, 0, id)
                        GU.setfield(outfeature, 1, cover)
                    end
                end
            end
        end
    end
end

# version 3
GU.registerdrivers() do
    GU.read("ospy/data1/sites.shp") do input
        GU.create("tmp/hw1b.shp", "ESRI Shapefile") do output
            GU.executesql(input, """SELECT * FROM sites
                                    WHERE cover = 'trees' """) do results
                GU.copylayer(output, results, "hw1b")
            end
        end
    end
end;


text:
using Behavior
using CoffeeMachine

@given("a machine filled with coffee beans") do context
    context[:machine] = Machine(coffee=5.0)
end

@when("a user makes a cup of coffee") do context
    m = context[:machine]
    cup = makecoffee!(m)
    context[:cup] = cup
end

@then("the cup contains coffee") do context
    cup = context[:cup]

    @expect cup.coffee > 0.0
end

@given("that the machine also has milk") do context
    m = context[:machine]
    fillwith!(m, milk=5.0)
end

@when("a user makes a cup of coffee with milk") do context
    m = context[:machine]
    cup = makecoffee!(m, withmilk=true)
    context[:cup] = cup
end

@then("the cup contains milk") do context
    cup = context[:cup]

    @expect cup.milk > 0.0
end


text:
using DataDeps

register(DataDep(
  "parkinsons-telemonitoring-motor",
  "https://archive.ics.uci.edu/ml/datasets/Parkinsons+Telemonitoring",
  "https://archive.ics.uci.edu/ml/machine-learning-databases/parkinsons/telemonitoring/parkinsons_updrs.data",
  "f2c7d5025dec4e92e7feae367a5f7ccf58789a10ac6b54bdf15976c599f9dd39",
  post_fetch_method=(path -> begin
    UCIData.process_dataset(path,
        target_index=5,
        feature_indices=7:22,
        skipto=2,
    )
  end),
))

max_stars_repo_name: JackDunnNZ/uci-data

max_issues_repo_name: JackDunnNZ/uci-data

max_forks_repo_name: JackDunnNZ/uci-data


text:
using SpinSim
using Test

@testset "SpinSim.jl" begin
    # Write your tests here.
end

max_stars_repo_name: abraemer/SpinSim

max_issues_repo_name: abraemer/SpinSim

max_forks_repo_name: abraemer/SpinSim


text:
module TinySparse
    # Required modules
    using TinyInt
    using LinearMaps
    # Overloaded functions
    import Base: size, nnz, issymmetric, ishermitian, isposdef, A_mul_B!, *, At_mul_B!, Ac_mul_B!, Ac_mul_B
    import TinyInt: pack
    # Type definition and overloaded functions
    include("tinysparsemat.jl")
    # Function to pack sparse matrices
    include("compress.jl")

    export TinySparseMat, pack
end


text:
using Turing, MCMCChains, KernelDensity, StatsBase, Test, Statistics

#@testset "sampling api" begin

  @model gdemo(x) = begin
      m ~ Normal(1, 0.01)
      s ~ Normal(5, 0.01)
  end

  model = gdemo([1.5, 2.0])
  sampler = HMC(500, 0.01, 5)
  chn = sample(model, sampler, save_state=true);

  chn_sample = sample(chn, 5)
  @test range(chn_sample) == 1:1:5

  c = kde(Array(chn[:s]))
  chn_weighted_sample = sample(c.x, Weights(c.density), 100000)

  @test mean(Array(chn[:s])) ≈ 5.0 atol=0.1

  #end


text:
using IsotopicCalc
using Test

@testset "IsotopicCalc.jl" begin
    # Write your tests here.
end


text:
###
  Name     : c5_28_run_program.jl
  Book     : Hands-on Data Science with Anaconda )
  Publisher: Packt Publishing Ltd.
  Author   : Yuxing Yan and James Yan
  Date     : 1/25/2018
  email    : yany@canisius.edu
             paulyxy@hotmail.com
###

# assume that helloworld.jl has the following one line.
# println("Hello world")

 include("c:/temp/helloWorld.jl")


text:
import Distances: pairwise

"""
    DeltaSumMean{Tϕ, Tg, TZ} <: MeanFunction

"""
struct DeltaSumMean{Tϕ, Tg} <: MeanFunction
    ϕ::Tϕ
    μ::MeanFunction
    g::Tg
end
(μ::DeltaSumMean)(x::Number) = _map(μ, [x])[1]
(μ::DeltaSumMean)(X::AV) = _map(μ, ColsAreObs(reshape(X, :, 1)))[1]
function _map(μ::DeltaSumMean, X::AV)
    return pairwise(μ.ϕ, :, X)' * map(μ.μ, :) + map(μ.g, X)
end
length(μ::DeltaSumMean) = length(μ.g)
eachindex(μ::DeltaSumMean) = eachindex(μ.g)

"""
    DeltaSumKernel{Tϕ} <: Kernel

"""
struct DeltaSumKernel{Tϕ} <: Kernel
    ϕ::Tϕ
    k::Kernel
end
(k::DeltaSumKernel)(x::Number, x′::Number) = map(k, [x], [x′])[1]
(k::DeltaSumKernel)(x::Number) = map(k, [x])[1]
function (k::DeltaSumKernel)(x::AV, x′::AV)
    return map(k, ColsAreObs(reshape(x, :, 1)), ColsAreObs(reshape(x′, :, 1)))[1]
end
(k::DeltaSumKernel)(x::AV) = map(k, ColsAreObs(reshape(x, :, 1)))[1]
length(k::DeltaSumKernel) = size(k.ϕ, 2)
eachindex(k::DeltaSumKernel) = eachindex(k.ϕ, 2)

_map(k::DeltaSumKernel, X::AV) = diag_Xᵀ_A_X(pairwise(k.k, :), pairwise(k.ϕ, :, X))
function _map(k::DeltaSumKernel, X::AV, X′::AV)
    return diag_Xᵀ_A_Y(pairwise(k.ϕ, :, X), pairwise(k.k, :), pairwise(k.ϕ, :, X′))
end
@noinline function _pairwise(k::DeltaSumKernel, X::AV)
    return Xt_A_X(pairwise(k.k, :), pairwise(k.ϕ, :, X))
end
function _pairwise(k::DeltaSumKernel, X::AV, X′::AV)
    return Xt_A_Y(pairwise(k.ϕ, :, X), pairwise(k.k, :), pairwise(k.ϕ, :, X′))
end

"""
    LhsDeltaSumCrossKernel{Tϕ} <: CrossKernel

"""
struct LhsDeltaSumCrossKernel{Tϕ} <: CrossKernel
    ϕ::Tϕ
    k::CrossKernel
end
(k::LhsDeltaSumCrossKernel)(x::Number, x′::Number) = map(k, [x], [x′])[1]
function (k::LhsDeltaSumCrossKernel)(x::AV, x′::AV)
    return map(k, ColsAreObs(reshape(x, : ,1)), ColsAreObs(reshape(x′, :, 1)))[1]
end
size(k::LhsDeltaSumCrossKernel, N::Int) = N == 1 ? size(k.ϕ, 2) : size(k.k, 2)
function eachindex(k::LhsDeltaSumCrossKernel, dim::Int)
    return dim == 1 ? eachindex(k.ϕ, 2) : eachindex(k.k, 2)
end

function _map(k::LhsDeltaSumCrossKernel, X::AV, X′::AV)
    return diag_AᵀB(pairwise(k.ϕ, :, X), pairwise(k.k, :, X′))
end
function _pairwise(k::LhsDeltaSumCrossKernel, X::AV, X′::AV)
    return pairwise(k.ϕ, :, X)' * pairwise(k.k, :, X′)
end

"""
    RhsDeltaSumCrossKernel{Tϕ} <: CrossKernel

"""
struct RhsDeltaSumCrossKernel{Tϕ} <: CrossKernel
    k::CrossKernel
    ϕ::Tϕ
end
(k::RhsDeltaSumCrossKernel)(x::Number, x′::Number) = map(k, [x], [x′])[1]
function (k::RhsDeltaSumCrossKernel)(x::AV, x′::AV)
    return map(k, ColsAreObs(reshape(x, :, 1)), ColsAreObs(reshape(x′, :, 1)))[1]
end
size(k::RhsDeltaSumCrossKernel, N::Int) = N == 1 ? size(k.k, 2) : size(k.ϕ, 2)
function eachindex(k::RhsDeltaSumCrossKernel, dim::Int)
    return dim == 1 ? eachindex(k.k, 2) : eachindex(k.ϕ, 2)
end

function _map(k::RhsDeltaSumCrossKernel, X::AV, X′::AV)
    return diag_AᵀB(pairwise(k.k, :, X), pairwise(k.ϕ, :, X′))
end
function _pairwise(k::RhsDeltaSumCrossKernel, X::AV, X′::AV)
    return pairwise(k.k, :, X)' * pairwise(k.ϕ, :, X′)
end


text:
module ParticleFilters

using POMDPs
import POMDPs: pdf, mode, update, initialize_belief, support
import POMDPs: statetype, isterminal, observation
import POMDPs: action, value

using POMDPLinter: @implemented

import POMDPModelTools: obs_weight
using StatsBase
using Random
using Statistics
using POMDPPolicies: AlphaVectorPolicy, alphavectors
using POMDPModelTools: weighted_iterator

import Random: rand, gentype
import Statistics: mean

export
    AbstractParticleBelief,
    ParticleCollection,
    WeightedParticleBelief,
    BasicParticleFilter,
    ImportanceResampler,
    LowVarianceResampler,
    UnweightedParticleFilter,
    ParticleFilterModel,
    PredictModel,
    BootstrapFilter,
    ReweightModel

export
    resample,
    predict,
    predict!,
    reweight,
    reweight!,
    particle_memory

export
    n_particles,
    particles,
    weighted_particles,
    weight_sum,
    weight,
    particle,
    weights,
    obs_weight,
    n_init_samples,
    runfilter

export
    pdf,
    mode,
    update,
    support,
    initialize_belief

# deprecated
export
    SIRParticleFilter

include("beliefs.jl")
include("basic.jl")
include("resamplers.jl")
include("unweighted.jl")
include("models.jl")
include("bootstrap.jl")
include("pomdps.jl")
include("policies.jl")
include("runfilter.jl")
include("deprecated.jl")

end # module


text:
using DEBmicroTrait
using Roots
using CSV, DataFrames
using GLM
using Statistics
using JLD

df_isolates     = CSV.read("/Users/glmarschmann/.julia/dev/DEBmicroTrait/files/isolates2traits.csv", DataFrame, missingstring="N/A")
df_metabolites  = CSV.read("/Users/glmarschmann/.julia/dev/DEBmicroTrait/files/exudation_properties.csv", DataFrame, missingstring="N/A")

Genome_size     = convert(Array{Float64,1}, df_isolates.Genome_size)
rrn_copies      = convert(Array{Float64,1}, df_isolates.rRNA_genes)
Min_gen_time    = df_isolates.Min_gen_time
gmax            = log(2)./Min_gen_time
Gram_stain      = convert(Array{String}, df_isolates.gram_stain)
V_cell          = DEBmicroTrait.genome_size_to_cell_volume(Genome_size)
y_EM            = ones(size(V_cell,1))
α               = (df_isolates.z_hydrolases./df_isolates.Genome_size*1e6)./maximum(df_isolates.z_hydrolases./df_isolates.Genome_size*1e6)
z_sugars        = reshape(convert(Array{Float64,1}, df_isolates.z_sugars./df_isolates.Genome_size*1e6),1,39)
z_organics      = reshape(convert(Array{Float64,1}, df_isolates.z_organic_acids./df_isolates.Genome_size*1e6),1,39)
z_aminos        = reshape(convert(Array{Float64,1}, df_isolates.z_amino_acids./df_isolates.Genome_size*1e6), 1,39)
z_fattys        = reshape(convert(Array{Float64,1}, df_isolates.z_fatty_acids./df_isolates.Genome_size*1e6),1,39)
z_nucleos       = reshape(convert(Array{Float64,1}, df_isolates.z_nucleotides./df_isolates.Genome_size*1e6),1,39)
z_auxins        = reshape(convert(Array{Float64,1}, df_isolates.z_auxins./df_isolates.Genome_size*1e6),1,39)
genome_distr    = vcat(z_sugars, z_organics, z_aminos, z_fattys, z_nucleos, z_auxins)
ρ_ps            = zeros(size(V_cell,1))
y_DEs           = zeros(size(V_cell,1), 83)
FCR             = zeros(size(V_cell,1), 83)
Yrmax           = zeros(size(V_cell,1), 83)
yield           = zeros(size(V_cell,1), 100000)
rate            = zeros(size(V_cell,1), 100000)
N_C             = DEBmicroTrait.extract_composition(df_metabolites.Formula[29])[1]

for j in 1:83
    for i in 1:size(V_cell,1)
        find_ρ(x) = DEBmicroTrait.constrain_transporter_density_cost(x, [V_cell[i]], [Min_gen_time[i]], [Gram_stain[i]], [rrn_copies[i]], [y_EM[i]], df_metabolites.Formula[j])
        ρ_p = Roots.find_zero(find_ρ, 1.0)
        closure = genome_distr[:,i]./sum(genome_distr[:,i])
        if df_metabolites.Ontology[j] == "Sugars"
            ρ_ps[i] = ρ_p[1].*closure[1]
        elseif df_metabolites.Ontology[j] == "Organic acids"
            ρ_ps[i] = ρ_p[1].*closure[2]
        elseif df_metabolites.Ontology[j] == "Amino acids"
            ρ_ps[i] = ρ_p[1].*closure[3]
        elseif df_metabolites.Ontology[j] == "Fatty acids"
            ρ_ps[i] = ρ_p[1].*closure[4]
        elseif df_metabolites.Ontology[j] == "Nucleotides"
            ρ_ps[i] = ρ_p[1].*closure[5]
        else
            ρ_ps[i] = ρ_p[1].*closure[6]
        end
        y_DE = DEBmicroTrait.yield_transporter_density_cost(ρ_ps[i], [V_cell[i]], [Min_gen_time[i]], [Gram_stain[i]], [rrn_copies[i]], [y_EM[i]], df_metabolites.Formula[j])
        y_DEs[i,j] = y_DE[1]
        N_C             = DEBmicroTrait.extract_composition(df_metabolites.Formula[j])[1]
        yield_tmp, rate_tmp = DEBmicroTrait.rate_yield_trade_off(ρ_ps[i]*ones(1,1), [α[i]],[V_cell[i]], [Min_gen_time[i]], [Gram_stain[i]], [rrn_copies[i]], y_DE, N_C, [y_EM[i]])
        for h in 1:size(rate_tmp,1)
            yield[i,h] = yield_tmp[h]
            rate[i,h] = rate_tmp[h]
        end

        rmax, rid = findmax(rate[i,:])
        Ymax, Yid = findmax(yield[i,:])
        FCR[i,j] = Ymax - yield[i,rid]
        Yrmax[i,j] = yield[i,rid]
    end
end

FCR = zeros(size(V_cell,1))
FCR_50 = zeros(size(V_cell,1))
for i in 1:39
    rmax, rid = findmax(rate[i,:])
    Ymax, Yid = findmax(yield[i,:])
    FCR[i] = Ymax - yield[i,rid]
    FCR_50[i] = yield[i,rid]
end

Ymaxmed  = 78.5
median(FCR_50*100)

df_out = DataFrame()
df_out.Vcell = V_cell
df_out.FCR = FCR
df_out.response = df_isolates.Rhizosphere_response

linearRegressor = lm(@formula(log(FCR) ~ log(Vcell)), df_out)
r2(linearRegressor)
summary(linearRegressor)

CSV.write("/Users/glmarschmann/.julia/dev/DEBmicroTrait/first_manuscript/files_pub/isolates_power_yield.csv", df_out)

# Bionumber  	116954
L_DNA = collect(range(0.1, 13.5, length=100)).*1e6
V_cell = DEBmicroTrait.genome_size_to_cell_volume(L_DNA)
rrn_copies = DEBmicroTrait.genome_size_to_rRNA_copy_number(L_DNA)
min_gentime = DEBmicroTrait.gmax_regression(rrn_copies)
gmax = log(2)./min_gentime
Gram_stain = repeat(["+"], 1000)

V_P = DEBmicroTrait.cell_volume_to_protein_volume(V_cell)
V_R = DEBmicroTrait.cell_volume_to_ribosome_volume(V_cell, gmax)
k_E = DEBmicroTrait.translation_power(V_P, V_R, min_gentime)
y_EV = DEBmicroTrait.relative_translation_efficiency_regression(rrn_copies)
k_M = DEBmicroTrait.cell_volume_to_specific_maintenance_rate(V_cell, min_gentime, Gram_stain)

minimum(k_E)
maximum(k_E)

minimum(y_EV)
maximum(y_EV)

minimum(k_M)
maximum(k_M)
median(k_M)

save("/Users/glmarschmann/.julia/dev/DEBmicroTrait/files/power_yield_tradeoff.jld", "gmax", gmax, "kE", k_E, "yEV", y_EV, "kM", k_M, "rrn", rrn_copies, "Ldna", L_DNA)

max_stars_repo_name: giannamars/DEBMicroTrait

max_issues_repo_name: giannamars/DEBMicroTrait

max_forks_repo_name: giannamars/DEBMicroTrait


text:
using ColorTypes
using GeometryTypes, Reactive, GLAbstraction, ModernGL
import Quaternions
using FileIO
using GLVisualize, GLWindow, ModernGL, Colors

w, r = glscreen();

area_msg, area3d = x_partition(w.area, 30.0);
screen3D         = Screen(w, area=area3d);
screenMSG        = Screen(w, area=area_msg);

cs = cubecamera(screen3D);

using Benchmarks
function GLVisualize.visualize(b::Vector{Benchmarks.Statistics{Float64}})
    t = Float64[elem.average_time for elem in b]
    m = maximum(t)
    l = length(t)

    scale_up 	= Vec3f0[Vec3f0(0.02,0.02, (elem.interval[2]-elem.average_time) / m ) for elem in b]
    scale_down  = Vec3f0[Vec3f0(0.02,0.02, (elem.interval[1]-elem.average_time) / m ) for elem in b]

    ps = Point3f0[Point3f0(i*3f0/l, 0f0, x/m) for (i,x) in enumerate(t)]
    colors 	= map(RGBA{U8}, distinguishable_colors(l, RGB{U8}(0,0,1)))

    robj5 = map(enumerate(b)) do args
    	i, stats = args
        cap(x) = min(max(stats.interval[1], x), stats.interval[2])
        positions = Point3f0[Point3f0(0f0, k/l, cap(x)/m) for (k,x) in enumerate(stats.all_samples)]
    	visualize(
            positions,
            color=RGBA{Float32}(colors[i]),
    		scale=Vec3f0(0.01),
    		model=translationmatrix(Vec3f0(i*3f0/l, 0f0,0f0))
    	)
    end

    robj1 	= visualize(ps, color=colors, scale=Vec3f0(0.03), primitive=GLNormalMesh(Sphere{Float32}(Point3f0(0), 1f0)))
    robj2 	= visualize(robj1[:positions], color=robj1[:color], scale=Texture(scale_up))
    robj3 	= visualize(robj1[:positions], color=robj1[:color], scale=Texture(scale_down))
    robj4 	= visualize(robj1[:positions], color=robj1[:color], scale=Texture(scale_down))
    Context(robj1, robj2, robj3, robj5...)
end
glClearColor(1,1,1,1)

benches = Benchmarks.Results[]

for i=1:20
	try
		push!(benches, @benchmark(rand(i*100)))
	end
end
benchstats = map(Benchmarks.Statistics, benches)

vizz = visualize(benchstats)
view(vizz, screen3D)
view(visualize(boundingbox(vizz).value, :grid), screen3D)

r()

#is it normal that error(...) results in a single line of stack trace and throw(SomeErrorType(...)) result in a lengthy one?!


text:
using GenieDiscordBot
using Test

@testset "GenieDiscordBot.jl" begin
    # Write your tests here.
end


text:
"""
Power nonlinearity, with energy C ∫ρ^α where ρ is the total density
"""
struct PowerNonlinearity
    C::Real
    α::Real
end
(P::PowerNonlinearity)(basis) = TermPowerNonlinearity(basis, P.C, P.α)

struct TermPowerNonlinearity <: Term
    basis::PlaneWaveBasis
    C::Real
    α::Real
end

function ene_ops(term::TermPowerNonlinearity, ψ, occ; ρ, kwargs...)
    basis = term.basis
    dVol = basis.model.unit_cell_volume / prod(basis.fft_size)

    E = term.C * sum(ρ.real .^ term.α) * dVol
    potential = @. term.C * term.α * ρ.real^(term.α-1)

    ops = [RealSpaceMultiplication(basis, kpoint, potential) for kpoint in basis.kpoints]
    (E=E, ops=ops)
end

_pnl_kernel(C, α, ρ) = @. C * α * (α-1) * ρ^(α-2)

function compute_kernel(term::TermPowerNonlinearity, dρspin=nothing;
                        ρ::RealFourierArray, ρspin=nothing, kwargs...)
    @assert term.basis.model.spin_polarization in (:none, :spinless, :collinear)
    K = Diagonal(vec(_pnl_kernel(term.C, term.α, ρ.real)))

    # PNL kernel is independent of spin, so to apply it to (ρtot, ρspin)^T
    # and obtain the same contribution to Vα and Vβ the operator has the block structure
    #     ( K 0 )
    #     ( K 0 )
    n_spin = term.basis.model.n_spin_components
    n_spin == 1 ? K : [K 0I; K 0I]
end

function apply_kernel(term::TermPowerNonlinearity, dρ, dρspin=nothing;
                      ρ::RealFourierArray, ρspin=nothing, kwargs...)
    @assert term.basis.model.spin_polarization in (:none, :spinless, :collinear)
    kernel = from_real(term.basis, _pnl_kernel(term.C, term.α, ρ.real) .* dρ.real)
    n_spin = term.basis.model.n_spin_components
    n_spin == 1 ? (kernel, ) : (kernel, kernel)  # PNL term does not care about spin
end


text:
# using Revise
using Test
using Logging
using LarSurf
# using Base.Test

# write your own tests here
# @test 1 == 2

# @test hello("Julia") == "Hello, Julia"

include("arr_test.jl")
include("block_test.jl")
include("boundary_matrix_test.jl")
include("datasets_test.jl")
# include("dicom_test.jl")
include("face_id_reconstruction.jl")
include("parallel_surf_experiment_test.jl")
include("inner_block_test.jl")
include("smoothing_test.jl")
include("support_test.jl")
# include("surface_parallel_channel_test.jl")
include("surface_parallel_pmap_test.jl")
include("surface_parallel_test.jl")
include("surface_per_voxel.jl")
include("surface_test.jl")
include("triangulate_test.jl")
# include("dicom_test.jl")


text:
include("../src/RandomField.jl")
using .RandomField

# choose parameters:
## remember, we need that 4|n_i for i=1,...,d
N = [400,400]		# number pixels per dimension
L = [20.0,80.0]		# real space box is [-l,l]^d
f(V::Vector{T} where T<:Real) = gaus_rf(V)
					# spectral density
n_real = 100		# number of realizations

# derived parameters
d = length(N) 		# dimension
H = (pi/2) .* N ./L
var_y(V::Vector{T} where T<:Real) = 2*(2pi)^(d/2)*prod(L)/pi^d*f(V)

# allocate memory
V = Cloud(d,N)
X = Cloud(d,N)
Y = Cscalar(V)
Z = Cscalar(X)
C_est = Cscalar(X)	# estimated stationary covariance
C_tru = Cscalar(X)	# true stationary covariance

# initialize grids
init!(X,L)
init!(V,H)

# estimate stationary covariance
## (we assume here that the mean is 0 to save time)
@. C_est.values = 0
i_o = get_originindex(X)
for i=1:n_real
	draw_realization!(Y,var_y)
	ift!(Z,Y)	# Y ↦ Z
	@. C_est.values += 0.5 * Z.values * conj(Z.values[i_o])
end
@. C_est.values /= n_real

sample!(C_tru,gaus_rf)

# print:
tovtk(C_est, "../data/x.c.vtk")
#tocsv(slice(Z,1), "../data/x.z1.csv")
tocsv(slice(C_est,1), "../data/x.c1.csv")
tocsv(slice(C_tru,1), "../data/x.ctru1.csv")


text:
########## Basin ##########

mutable struct Basin
    spread::Int
end

spread(basin::Basin) = basin.spread
spread(::Nothing) = 0

Basin() = Basin(1)

########## Location ##########

mutable struct Location
    height::Int
    neighbors::Vector{Location}
    basin::Union{Basin, Nothing, Missing}
end

height(location::Location) = location.height
neighbors(location::Location) = location.neighbors
basin(location::Location) = location.basin

Location(height::Int) =
    Location(height, Vector{Location}(undef, 0), missing)

link!(location::Location, neighbor::Location) =
    append!(neighbors(location), [neighbor])

function process!(locations::Matrix{Location})
    bottom_pits = Location[]
    for (x, y) in Tuple.(CartesianIndices(locations))
        location = locations[x, y]
        x > firstindex(locations, 1) && link!(location, locations[x - 1, y])
        x < lastindex(locations, 1)  && link!(location, locations[x + 1, y])
        y > firstindex(locations, 2) && link!(location, locations[x, y - 1])
        y < lastindex(locations, 2)  && link!(location, locations[x, y + 1])

        if all(height(location) .< height.(neighbors(location)))
            location.basin = Basin()
            append!(bottom_pits, [location])
        elseif height(location) == 9
            location.basin = nothing
        end
    end
    return bottom_pits
end

function check!(location::Location, local_basin::Basin)
    !ismissing(basin(location)) && return false
    local_basin.spread += 1
    location.basin = local_basin
    return true
end

function measure!(bottom_pit::Location)
    local_basin = basin(bottom_pit)
    locations = [bottom_pit]
    while !isempty(locations)
        locations = [neighbor
            for location in locations
            for neighbor in neighbors(location)
            if check!(neighbor, local_basin)]
    end
    return spread(local_basin)
end

########## Script ##########

function main()

    # open file and store content into an input string
    input = open("inputs//day9.txt", "r") do io
        read(io, String)
    end

    # split input into a data vector of vector of integers
    data = [parse.(Int, collect(row))
        for row in String.(split(input, "\r\n"))]

    # parse data into a matrix of locations
    locations = Location.([data[i][j]
        for i = 1:length(data), j = 1:length(data[1])])

    # establish neighbors and extract bottom pits
    # (and then forget about coordinates forever)
    bottom_pits = process!(locations)

    # part 1
    risk_level = sum(height.(bottom_pits) .+ 1)
    println("Part 1: ", risk_level)

    # part 2
    basins_spreads = sort(measure!.(bottom_pits))
    result = prod(basins_spreads[(end - 2):end])
    println("Part 2: ", result)

    # for a nice bonus drawing
    return spread.(basin.(locations))

end

main();


text:
"""
    centrality_katz(N::Unipartite; a::Float64=0.1, k::Int64=5)

This measure can work on different path length (`k`), and give a different
weight to every subsequent connection (`a`). `k` must be at least 1 (only
immediate neighbors are considered). `a` (being a weight), must be positive.

> Katz, L., 1953. A new status index derived from sociometric analysis.
> Psychometrika 18, 39–43. doi:10.1007/bf02289026

"""
function centrality_katz(N::Union{UnipartiteNetwork, UnipartiteProbabilisticNetwork}; a::Float64=0.1, k::Int64=5)
	@assert a <= 1.0
	@assert a >= 0.0
	@assert k >= 1
	centr = sum(hcat(map((x) -> vec(sum((a^x).*(N.A^x); dims=1)), [1:k;])...); dims=2)
	return Dict(zip(species(N), centr ./ sum(centr)))
end

"""
    centrality_closeness(N::UnipartiteNetwork; nmax::Int64=100)

The function calls `shortest_path` internally -- the `nmax` argument is the
maximal path length that wil be tried.

> Bavelas, A., 1950. Communication Patterns in Task‐Oriented Groups. The Journal
> of the Acoustical Society of America 22, 725–730. doi:10.1121/1.1906679
"""
function centrality_closeness(N::UnipartiteNetwork; nmax::Int64=100)
  d = shortest_path(N, nmax=nmax)
  n = richness(N)-1
  d[diagind(d)] .= 0
  interm = sum(d; dims=2)
  interm = vec(n ./ interm)
  for i in eachindex(interm)
    interm[i] = interm[i] == Inf ? 0.0 : interm[i]
  end
  return Dict(zip(species(N), interm))
end

"""
    centrality_degree(N::UnipartiteNetwork)

Degree centrality, corrected by the maximum degree (the most central species has
a degree of 1).
"""
function centrality_degree(N::UnipartiteNetwork)
  d = degree(N)
  dm = maximum(values(d))
  return Dict([p.first=>p.second/dm for p in d])
end


text:
# This file was generated by the Julia Swagger Code Generator
# Do not modify this file directly. Modify the swagger specification instead.

mutable struct IoK8sApiRbacV1ClusterRole <: SwaggerModel
    aggregationRule::Any # spec type: Union{ Nothing, IoK8sApiRbacV1AggregationRule } # spec name: aggregationRule
    apiVersion::Any # spec type: Union{ Nothing, String } # spec name: apiVersion
    kind::Any # spec type: Union{ Nothing, String } # spec name: kind
    metadata::Any # spec type: Union{ Nothing, IoK8sApimachineryPkgApisMetaV1ObjectMeta } # spec name: metadata
    rules::Any # spec type: Union{ Nothing, Vector{IoK8sApiRbacV1PolicyRule} } # spec name: rules

    function IoK8sApiRbacV1ClusterRole(;aggregationRule=nothing, apiVersion=nothing, kind=nothing, metadata=nothing, rules=nothing)
        o = new()
        validate_property(IoK8sApiRbacV1ClusterRole, Symbol("aggregationRule"), aggregationRule)
        setfield!(o, Symbol("aggregationRule"), aggregationRule)
        validate_property(IoK8sApiRbacV1ClusterRole, Symbol("apiVersion"), apiVersion)
        setfield!(o, Symbol("apiVersion"), apiVersion)
        validate_property(IoK8sApiRbacV1ClusterRole, Symbol("kind"), kind)
        setfield!(o, Symbol("kind"), kind)
        validate_property(IoK8sApiRbacV1ClusterRole, Symbol("metadata"), metadata)
        setfield!(o, Symbol("metadata"), metadata)
        validate_property(IoK8sApiRbacV1ClusterRole, Symbol("rules"), rules)
        setfield!(o, Symbol("rules"), rules)
        o
    end
end # type IoK8sApiRbacV1ClusterRole

const _property_map_IoK8sApiRbacV1ClusterRole = Dict{Symbol,Symbol}(Symbol("aggregationRule")=>Symbol("aggregationRule"), Symbol("apiVersion")=>Symbol("apiVersion"), Symbol("kind")=>Symbol("kind"), Symbol("metadata")=>Symbol("metadata"), Symbol("rules")=>Symbol("rules"))
const _property_types_IoK8sApiRbacV1ClusterRole = Dict{Symbol,String}(Symbol("aggregationRule")=>"IoK8sApiRbacV1AggregationRule", Symbol("apiVersion")=>"String", Symbol("kind")=>"String", Symbol("metadata")=>"IoK8sApimachineryPkgApisMetaV1ObjectMeta", Symbol("rules")=>"Vector{IoK8sApiRbacV1PolicyRule}")
Base.propertynames(::Type{ IoK8sApiRbacV1ClusterRole }) = collect(keys(_property_map_IoK8sApiRbacV1ClusterRole))
Swagger.property_type(::Type{ IoK8sApiRbacV1ClusterRole }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_IoK8sApiRbacV1ClusterRole[name]))}
Swagger.field_name(::Type{ IoK8sApiRbacV1ClusterRole }, property_name::Symbol) =  _property_map_IoK8sApiRbacV1ClusterRole[property_name]

function check_required(o::IoK8sApiRbacV1ClusterRole)
    true
end

function validate_property(::Type{ IoK8sApiRbacV1ClusterRole }, name::Symbol, val)
end