text:
module Wizard
    using REPL.TerminalMenus
    import ..System_parameters:Params_set,print_parameters,Params

    function print_wizard_logo(outs)
        blue    = "\033[34m"
        red     = "\033[31m"
        green   = "\033[32m"
        magenta = "\033[35m"
        normal  = "\033[0m\033[0m"

        logo = raw"""
    --------------------------------------------------------------------------------
    run_wizard
    　　　　　格　　　　　　　格
    　　　　　色　　　　　　　格
    　　　　色色色　　　　　　格
    　子子色色色色色子子子子子格子子子子
    　　　　色色色　　　　　　格
    　　　　　色　　　　　　　格
    　　　　　格　　　　　　　格
    　　　　　力　　　　　　　学　　　　　　LatticeQCD.jl
    　　　　力力力　　　　　学学学
    　子子力力力力力子子子学学学学学子子
    　　　　力力力　　　　　学学学
    　　　　　力　　　　　　　学
    　　　　　格　　　　　　　格
        """

        logo = replace(logo, "Q" => "$(red)Q$(normal)")
        logo = replace(logo, "C" => "$(blue)C$(normal)")
        logo = replace(logo, "D" => "$(green)D$(normal)")
        logo = replace(logo, "色" => "$(red)色$(normal)")
        logo = replace(logo, "力" => "$(blue)力$(normal)")
        logo = replace(logo, "学" => "$(green)学$(normal)")

        println(outs, logo)
        println(outs,
            "Welcome to a wizard for Lattice QCD.\n",
            "We'll get you set up simulation parameters in no time."
        )
        println("--------------------------------------------------------------------------------")
        println("If you leave the prompt empty, a default value will be used.")
        println("To exit, press Ctrl + c.")
    end

    function run_wizard()
        print_wizard_logo(stdout)
        simple = request("Choose wizard mode",RadioMenu([
            "simple",
            "expert",
        ]))
        if simple == 1
            isexpert = false
            #return run_wizard_simple()
        else
            isexpert = true
        end

        system,md,actions = initialize()
        filename = Base.prompt("put the name of the parameter file you make", default="my_parameters.jl")
        set_verboselevel!(system,isexpert)
        set_randomseed!(system,isexpert)
        set_Lattice_size!(system,isexpert)
        set_gaugegroup!(system,isexpert)
        set_beta!(system,isexpert)

        system["initialtrj"] = 1

        if check_isfileloading()
            wilson,cg,staggered = set_loadingformat!(system)
        else
            set_initialconfs!(system)

            wilson,cg,staggered,system = set_dynamicalfermion!(system,isexpert)
            set_update_method!(system,isexpert)
            set_nthermalization!(system,isexpert)
            set_totaltrajectoy!(system,isexpert)

            if system["update_method"] == "HMC" || system["update_method"] == "IntegratedHMC" || system["update_method"] == "SLHMC"
                set_MDparams!(system,md,isexpert)
            end
        end

        measurement = Dict()
        options = ["Plaquette","Polyakov_loop","Topological_charge","Chiral_condensate","Pion_correlator"]

        set_measurementmethods!(system,measurement,staggered,wilson,options,isexpert)

        headername = make_headername(system,staggered,wilson)

        set_measurementdir!(measurement,headername)
        set_logdir!(system,headername)
        set_saveU!(system,headername,isexpert)

        params_set = Params_set(system,actions,md,cg,wilson,staggered,measurement)

        print_parameters(filename,params_set)

        #p = Params(params_set)

        println("""
        --------------------------------------------------------------------------------
        run_wizard is done.

        The returned value in this run_wizard() is params_set.
        If you want to run a simulation in REPL or other Julia codes,  just do

        run_LQCD(params_set)

        or

        run_LQCD("$filename")

        The output parameter file is $filename.
        If you want to run a simulation, just do

        julia run.jl $filename

        --------------------------------------------------------------------------------
        """)

        return params_set
    end

    function wilson_wizard_simple!(system)
        wilson = Dict()
        cg = Dict()
        staggered = Dict()
        wtype = 1

        if wtype == 1
            println("Standard Wilson fermion action will be used")
            system["Dirac_operator"] = "Wilson"
        else
            println("Wilson+Clover fermion action will be used")
            system["Dirac_operator"] = "WilsonClover"
        end

        #println("Inut the hopping parameter κ: typical value = 0.141139")
        hop = parse(Float64,Base.prompt("Input the hopping parameter κ", default="0.141139"))
        #hop = parse(Float64,readline(stdin))
        if hop <= 0
            error("Invalid value for κ=$hop. This has to be strictly positive.")
        end
        wilson["hop"] = hop
        println("κ = $hop")
        wilson["r"] = 1
        wilson["Clover_coefficient"] = 1.5612

        eps = 1e-19
        MaxCGstep = 3000

        cg["eps"] = eps
        cg["MaxCGstep"] =MaxCGstep
        return wilson,cg,staggered,system
    end

    function wilson_wizard!(system)
        wilson = Dict()
        cg = Dict()
        staggered = Dict()
        wtype = request("Choose Wilson fermion type",RadioMenu([
                    "Standard Wilson fermion action",
                    "Wilson+Clover fermion action",
                ]))
        if wtype == 1
            println("Standard Wilson fermion action will be used")
            system["Dirac_operator"] = "Wilson"
        else
            println("Wilson+Clover fermion action will be used")
            system["Dirac_operator"] = "WilsonClover"
        end

        #println("Inut the hopping parameter κ: typical value = 0.141139")
        hop = parse(Float64,Base.prompt("Input the hopping parameter κ", default="0.141139"))
        #hop = parse(Float64,readline(stdin))
        if hop <= 0
            error("Invalid value for κ=$hop. This has to be strictly positive.")
        end
        wilson["hop"] = hop
        println("κ = $hop")
        wilson["r"] = 1
        wilson["Clover_coefficient"] = 1.5612

        eps = parse(Float64,Base.prompt("relative error in CG loops", default="1e-19"))
        MaxCGstep = parse(Int64,Base.prompt("Maximum iteration steps in CG loops", default="3000"))
        if eps<=0
            error("Invalid value for eps=$eps. This has to be strictly positive.")
        end
        if MaxCGstep<=0
            error("Invalid value for MaxCGstep=$MaxCGstep. This has to be strictly positive.")
        end
        cg["eps"] = eps
        cg["MaxCGstep"] =MaxCGstep
        return wilson,cg,staggered,system
    end

    function staggered_wizard!(system)
        wilson = Dict()
        cg = Dict()
        staggered = Dict()
        system["Dirac_operator"] = "Staggered"

        mass = parse(Float64,Base.prompt("Input mass", default="0.5"))
        if mass<=0
            error("Invalid value for mass=$mass. This has to be strictly positive.")
        end
        staggered["mass"] = mass
        Nftype = request("Choose the number of flavors(tastes)",RadioMenu([
                    "2 (RHMC will be used)",
                    "3 (RHMC will be used)",
                    "4 (HMC will be used)",
                    "8 (HMC will be used)",
                    "1 (RHMC will be used)"
                ]))

        if Nftype == 1
            staggered["Nf"] = 2
        elseif Nftype == 2
            staggered["Nf"] = 3
        elseif Nftype == 3
            staggered["Nf"] = 4
        elseif Nftype == 4
            staggered["Nf"] = 8
        elseif Nftype == 5
            staggered["Nf"] = 1
        end

        eps = parse(Float64,Base.prompt("relative error in CG loops", default="1e-19"))
        MaxCGstep = parse(Int64,Base.prompt("Maximum iteration steps in CG loops", default="3000"))
        if eps<=0
            error("Invalid value for eps=$eps. This has to be strictly positive.")
        end
        if MaxCGstep<=0
            error("Invalid value for MaxCGstep=$MaxCGstep. This has to be strictly positive.")
        end
        cg["eps"] = eps
        cg["MaxCGstep"] = MaxCGstep
        return wilson,cg,staggered,system
    end

    function simple_wizard()
        system,md,actions = initialize()

        filename = Base.prompt("put the name of the parameter file you make", default="my_parameters.jl")

        system["verboselevel"] = 1

    end

    function initialize()
        system = Dict()
        md = Dict()
        actions = Dict()
        actions["use_autogeneratedstaples"] = false
        actions["couplinglist"] = []
        actions["couplingcoeff"] = []
        system["BoundaryCondition"] = [1,1,1,-1]
        system["Nwing"] = 1

        return system,md,actions
    end

    function set_verboselevel!(system,isexpert)
        if isexpert
            verboselevel = parse(Int64,Base.prompt("verbose level ?", default="2"))
        else
            verboselevel = 1
        end

        if 1 ≤ verboselevel ≤ 3
            println("verbose level = ",verboselevel)
        else
            error("verbose level should be 1 ≤ verboselevel ≤ 3")
        end
        system["verboselevel"] = verboselevel
    end

    function set_randomseed!(system,isexpert)
        if isexpert
            system["randomseed"] = parse(Int64,Base.prompt("Input random seed.", default="111"))
        else
            system["randomseed"] = 111
        end
    end

    function set_Lattice_size!(system,isexpert)
        if isexpert
            println("Input Lattice size, L=(Nx,Ny,Nz,Nt)")
            NX = parse(Int64,Base.prompt("Nx ?", default="4"))
            NY = parse(Int64,Base.prompt("Ny ?", default="4"))
            NZ = parse(Int64,Base.prompt("Nz ?", default="4"))
            NT = parse(Int64,Base.prompt("Nt ?", default="4"))
            #NT = parse(Int64,readline(stdin))
            L = (NX,NY,NZ,NT)
            system["L"] = L
            if (NX<= 0)|(NY<= 0)|(NZ<= 0)|(NT<= 0)
                error("Invalid parameter L=$L, elements must be positive integers")
            end
        else
            NX = parse(Int64,Base.prompt("Input spatial lattice size ", default="4"))
            NT = parse(Int64,Base.prompt("Input temporal lattice size ", default="4"))
            L = (NX,NX,NX,NT)
            system["L"] = L
            if (NX<= 0)|(NT<= 0)
                error("Invalid parameter L=$L, elements must be positive integers")
            end
        end
        println("Lattice is $L")
    end

    function set_gaugegroup!(system,isexpert)
        if isexpert
            SNC = request("Choose a gauge group",RadioMenu([
                        "SU(3)",
                        "SU(2)",
                    ]))
            NC = ifelse(SNC == 1,3,2)
        else
            NC = 3
        end
        system["NC"] = NC
        println("SU($NC) will be used")
    end

    function set_beta!(system,isexpert)
        NC = system["NC"]
        if NC == 3
            β = parse(Float64,Base.prompt("β ?", default="5.7"))
        elseif NC == 2
            β = parse(Float64,Base.prompt("β ?", default="2.7"))
        end
        system["β"] = β
        if β<0
            error("Invalid value for β=$β. This has to be positive or zero")
        end
    end

    function check_isfileloading()
        fileloading = request("Do you perform only measurements on configurations in a directory? (no update)",RadioMenu([
            "No",
            "Yes",
        ]))
        if fileloading == 2
            isfileloading = true
        else
            isfileloading = false
        end
        return isfileloading
    end

    function set_loadingformat!(system)
        loadtype = request("Choose a configuration format for loading",RadioMenu([
                    "JLD",
                    "ILDG",
            ]))
        system["update_method"] = "Fileloading"

        if loadtype == 1
            system["loadU_format"] = "JLD"

        elseif loadtype == 2
            system["loadU_format"] = "ILDG"
        end

        if system["loadU_format"] ≠ nothing
            system["loadU_dir"] = String(Base.prompt("Loading directory", default="./confs"))
        end

        filelist = request("Which configurations do you use?",RadioMenu([
                    "All configurations in the directory",
                    "Configurations written in a list",
                ]))

        if filelist==1
            system["loadU_fromfile"] = false
        else
            system["loadU_fromfile"] = true

            system["loadU_filename"] = String(Base.prompt("name of the list in $(system["loadU_dir"])", default="filelist.txt"))
        end

        system["initial"] = "cold"
        system["Dirac_operator"] = nothing
        system["quench"] = true

        cg = Dict()
        wilson = Dict()
        staggered = Dict()

        return wilson,cg,staggered

    end

    function set_initialconfs!(system)
        NC = system["NC"]

        if NC == 3
            initialconf = request("Choose initial configurations",RadioMenu([
                        "cold start",
                        "hot start",
                        "start from a file",
                    ]))
        elseif NC == 2
            initialconf = request("Choose initial configurations",RadioMenu([
                    "cold start",
                    "hot start",
                    "start from a file",
                    "start from one instanton (Radius is half of Nx)",
                ]))
        end
        if initialconf == 1
            system["initial"] = "cold"
        elseif initialconf == 2
            system["initial"] = "hot"
        elseif initialconf == 3
            loadtype = request("Choose a configuration format for loading",RadioMenu([
                "JLD",
                "ILDG",
            ]))

            if loadtype == 1
                system["loadU_format"] = "JLD"
                system["initial"] = String(Base.prompt("Input the file name that you want to use",default="./confs/conf_00000001.jld"))

            elseif loadtype == 2
                system["loadU_format"] = "ILDG"
                system["initial"] = String(Base.prompt("Input the file name that you want to use",default="./confs/conf_00000001.ildg"))
            end
            system["initialtrj"] = parse(Int64,Base.prompt("Start trj number?", default="1"))

        elseif initialconf == 4
            system["initial"] = "Start from one instanton"
        end
    end

    function set_smearing!(system)
        smearing = request("Choose smearing scheme for fermions",RadioMenu([
                        "nothing",
                        "stout",
                    ]))
        if smearing == 1
            system["smearing_for_fermion"] = "nothing"
        elseif smearing == 2
            system["smearing_for_fermion"] = "stout"
            system["stout_numlayers"] = 1
            #system["stout_numlayers"] = parse(Int64,Base.prompt("How many stout layers do you consider?", default="1"))
            if system["stout_numlayers"] == 1
                kindsof_loops = ["plaquette","rectangular","chair","polyakov_x","polyakov_y","polyakov_z","polyakov_t"]
                stout_menu = MultiSelectMenu(kindsof_loops)
                choices = request("Select the kinds of loops you want to add in stout smearing:", stout_menu)
                count = 0
                ρs = Float64[]
                loops = String[]
                for  i in choices
                    count += 1
                    ρ = parse(Float64,Base.prompt("coefficient ρ for $(kindsof_loops[i]) loop?", default="0.1"))
                    push!(ρs,ρ)
                    push!(loops,kindsof_loops[i])
                end
                #println(ρs)
                system["stout_ρ"] = ρs
                system["stout_loops"] = loops
                #system["stout_ρ"] = [parse(Float64,Base.prompt("stout parameter ρ ?", default="0.1"))]
            else
                error("system[\"stout_numlayers\"] = $(system["stout_numlayers"]) is not supported yet!")
            end
        end
    end

    function set_dynamicalfermion!(system,isexpert)
        if isexpert
            ftype = request("Choose a dynamical fermion",RadioMenu([
                        "Nothing (quenched approximation)",
                        "Wilson Fermion (2-flavor)",
                        "Staggered Fermion",
                    ]))
            if ftype == 1
                cg = Dict()
                wilson = Dict()
                staggered = Dict()
                system["Dirac_operator"] = nothing
                system["quench"] = true

            elseif ftype == 2
                wilson,cg,staggered,system = wilson_wizard!(system)
                system["quench"] = false
                set_smearing!(system)
            elseif ftype == 3
                wilson,cg,staggered,system = staggered_wizard!(system)
                system["quench"] = false
                set_smearing!(system)
            end

        else
            system["Dirac_operator"] = "Wilson"

            wilson,cg,staggered,system = wilson_wizard_simple!(system)
            system["quench"] = false
        end

        return wilson,cg,staggered,system

    end

    function set_update_method!(system,isexpert)
        if isexpert
            if system["quench"] == true
                methodtype = request("Choose an update method",RadioMenu([
                    "Heatbath",
                    "Hybrid Monte Carlo",
                ]))
                if methodtype == 2
                    system["update_method"] = "HMC"
                else
                    system["update_method"] = "Heatbath"
                    or = request("Use overrelazation method?",RadioMenu([
                            "true",
                            "false",
                        ]))
                    system["useOR"] = ifelse(or==1,true,false)
                    if system["useOR"]
                        system["numOR"] = parse(Int64,Base.prompt("How many times do you want to do the OR?", default="3"))
                    end

                end
            else
                methodtype = request("Choose an update method",RadioMenu([
                    "Hybrid Monte Carlo",
                    "Integrated HMC",
                    "Self-learning Hybrid Monte Carlo (SLHMC)",
                    "Self-learning Monte Carlo (SLMC)",
                ]))
                if methodtype == 1
                    system["update_method"] = "HMC"
                elseif methodtype == 2
                    system["update_method"] = "IntegratedHMC"
                elseif methodtype == 3
                    system["update_method"] = "SLHMC"
                    system["βeff"] = parse(Float64,Base.prompt("Input initial effective β", default="$β"))
                    system["firstlearn"] = parse(Int64,Base.prompt("When do you want to start updating the effective action?", default="10"))
                    system["quench"] = true
                elseif methodtype == 4
                    system["update_method"] = "SLMC"
                    system["βeff"] = parse(Float64,Base.prompt("Input initial effective β", default="$β"))
                    system["firstlearn"] = parse(Int64,Base.prompt("When do you want to start updating the effective action?", default="10"))
                    system["quench"] = true
                end
            end
        else
            system["update_method"] = "HMC"

        end
    end

    function set_nthermalization!(system,isexpert)
        Nthermalization = 0
        if isexpert
            if system["update_method"] == "HMC" || system["update_method"] == "IntegratedHMC" || system["update_method"] == "SLHMC"|| system["update_method"] == "Heatbath" || system["update_method"] == "SLMC"
                Nthermalization = parse(Int64,Base.prompt("Input the number of thermalization steps (no mearurement)", default="0"))
                if Nthermalization<0
                    error("Invalid value for Nthermalization=$Nthermalization. This has to be positive/zero.")
                end
            end
        end
        system["Nthermalization"] = Nthermalization
    end

    function set_totaltrajectoy!(system,isexpert)
        if isexpert
            if system["update_method"] == "HMC" || system["update_method"] == "IntegratedHMC" || system["update_method"] == "SLHMC"|| system["update_method"] == "Heatbath" || system["update_method"] == "SLMC"
                Nsteps = parse(Int64,Base.prompt("Input the number of total trajectories afterthermalization", default="$(100+system["initialtrj"])"))
                if Nsteps<=0
                    error("Invalid value for Nsteps=$Nsteps. This has to be strictly positive.")
                end
            end
        else
            Nsteps = parse(Int64,Base.prompt("Input number of total trajectories", default="100"))
            if Nsteps<=0
                error("Invalid value for Nsteps=$Nsteps. This has to be strictly positive.")
            end
        end
        system["Nsteps"] = Nsteps
    end

    function set_MDparams!(system,md,isexpert)
        if isexpert
            println("Choose parameters for MD")
            MDsteps = parse(Int64,Base.prompt("Input MD steps", default="20"))
            Δτ = parse(Float64,Base.prompt("Input Δτ", default="$(1/MDsteps)"))

            #SextonWeingargten = parse(Bool,Base.prompt("Use SextonWeingargten method? true or false", default="false"))

            if system["Dirac_operator"] != nothing
                SW = request("Use SextonWeingargten method? multi-time scale",RadioMenu([
                        "false",
                        "true",
                    ]))
                SextonWeingargten = ifelse(SW==1,false,true)

                if SextonWeingargten
                    N_SextonWeingargten = parse(Int64,Base.prompt("Input number of SextonWeingargten steps", default="2"))
                else
                    N_SextonWeingargten = 2
                end
                md["SextonWeingargten"] = SextonWeingargten
                md["N_SextonWeingargten"] = N_SextonWeingargten
            end

            if MDsteps<=0
                error("Invalid value for MDsteps=$MDsteps. This has to be strictly positive.")
            end
            if Δτ<=0
                error("Invalid value for Δτ=$Δτ. This has to be strictly positive.")
            end

            md["MDsteps"] = MDsteps
            md["Δτ"] = Δτ
        else
            MDsteps = 20
            Δτ = 1/MDsteps

            SextonWeingargten = false
            N_SextonWeingargten = 2

            md["MDsteps"] = MDsteps
            md["Δτ"] = Δτ
            md["SextonWeingargten"] = SextonWeingargten
            md["N_SextonWeingargten"] = N_SextonWeingargten

        end
    end

    function set_measurementmethods!(system,measurement,staggered,wilson,options,isexpert)
        if isexpert
            L = system["L"]
            measurementmenu = MultiSelectMenu(options)
            choices = request("Select the measurement methods you want to do:", measurementmenu)
            nummeasurements  = length(choices)
            #println(choices)
            measurement_methods = Array{Dict,1}(undef,nummeasurements)
            count = 0

            for  i in choices
                count += 1
                if i == 1
                    measurement_methods[count] = plaq_wizard()
                elseif i == 2
                    measurement_methods[count] = poly_wizard()
                elseif i == 3
                    measurement_methods[count] = topo_wizard(L,system)
                elseif i == 4
                    measurement_methods[count] = chiral_wizard(staggered,system)
                elseif i == 5
                    #measurement_methods[count] = pion_wizard(wilson,system)
                    measurement_methods[count] = pion_wizard(wilson,staggered,system)
                end
            end
        else
            choices =  [1,2,5]
            nummeasurements  = length(choices)
            #println(choices)
            measurement_methods = Array{Dict,1}(undef,nummeasurements)
            count = 0

            for  i in choices
                count += 1
                if i == 1
                    measurement_methods[count] =Dict()
                    println("You measure plaquette")
                    measurement_methods[count]["methodname"] = "Plaquette"
                    measurement_methods[count]["measure_every"] = 1#parse(Int64,Base.prompt("How often measure Plaquette loops?", default="1"))
                    measurement_methods[count]["fermiontype"] = nothing

                elseif i == 2
                    measurement_methods[count] =Dict()
                    println("You measure Polyakov loop")
                    measurement_methods[count]["methodname"] = "Polyakov_loop"
                    measurement_methods[count]["measure_every"] = 1#parse(Int64,Base.prompt("How often measure Plaquette loops?", default="1"))
                    measurement_methods[count]["fermiontype"] = nothing
                elseif i == 5
                    measurement_methods[count] =Dict()
                    measurement_methods[count] = pion_wizard_simple(wilson)
                end
            end
        end

        measurement["measurement_methods"] = measurement_methods
    end

    function make_headername(system,staggered,wilson)
        L = system["L"]
        headername = system["update_method"]*"_L"*string(L[1],pad=2)*string(L[2],pad=2)*string(L[3],pad=2)*string(L[4],pad=2)*"_beta"*string(system["β"])

        if system["update_method"] == "HMC"
            if system["quench"] == true
                headername *= "_quenched"
            else
                headername *= "_"*system["Dirac_operator"]
                if system["Dirac_operator"] == "Staggered"
                    headername *= "_mass"*string(staggered["mass"])*"_Nf"*string(staggered["Nf"])
                elseif system["Dirac_operator"] == "Wilson" || system["Dirac_operator"] == "WilsonClover"
                    headername *= "_kappa"*string(wilson["hop"])
                end
            end
        elseif system["update_method"] == "Heatbath"
            headername *= "_quenched"
        else
            if system["Dirac_operator"] != nothing
                headername *= "_"*system["Dirac_operator"]
                if system["Dirac_operator"] == "Staggered"
                    headername *= "_mass"*string(staggered["mass"])*"_Nf"*string(staggered["Nf"])
                elseif system["Dirac_operator"] == "Wilson" || system["Dirac_operator"] == "WilsonClover"
                    headername *= "_kappa"*string(wilson["hop"])
                end
            else
            end
        end
        return headername
    end

    function set_measurementdir!(measurement,headername)
        nummeasurements  =length(measurement["measurement_methods"])
        if nummeasurements != 0
            measurement["measurement_basedir"] = String(Base.prompt("base directory for measurements", default="./measurements"))
            measurement["measurement_dir"] = String(Base.prompt("directory for measurements in $(measurement["measurement_basedir"])/", default=headername))
        end
    end

    function set_logdir!(system,headername)
        system["log_dir"] = String(Base.prompt("log directory", default="./logs"))
        system["logfile"] = String(Base.prompt("logfile name", default=headername*".txt"))
    end

    function set_saveU!(system,headername,isexpert)
        if isexpert
            savetype = request("Choose a configuration format for saving",RadioMenu([
                        "no save",
                        "JLD",
                        "ILDG",
                ]))
            if savetype == 2
                system["saveU_format"] = "JLD"

            elseif savetype == 1
                system["saveU_format"] = nothing
                system["saveU_dir"] = ""
            elseif savetype == 3
                system["saveU_format"] = "ILDG"
            end

            if system["saveU_format"] ≠ nothing

                system["saveU_every"] = parse(Int64,Base.prompt("How often do you save a configuration in file (Save every)?", default="10"))
                #system["saveU_basedir"] = String(Base.prompt("base directory for saving configuration", default="./confs"))
                system["saveU_dir"] = String(Base.prompt("Saving directory", default="./confs_$(headername)"))
                #system["saveU_dir"] = system["saveU_basedir"]*"/"*system["saveU_dir"]
            end
        else
            system["saveU_format"] = nothing
            system["saveU_dir"] = ""
        end
    end

    function  plaq_wizard()
        method = Dict()

        println("You measure Plaquette loops")
        method["methodname"] = "Plaquette"
        method["measure_every"] = parse(Int64,Base.prompt("How often measure Plaquette loops?", default="1"))
        method["fermiontype"] = nothing

        return method
    end

    function  poly_wizard()
        method = Dict()

        println("You measure Polyakov loops")
        method["methodname"] = "Polyakov_loop"
        method["measure_every"] = parse(Int64,Base.prompt("How often measure Polyakov loops?", default="1"))
        method["fermiontype"] = nothing

        return method
    end

    function  topo_wizard(L,system)
        method = Dict()

        if system["update_method"] == "Fileloading"
            defaultvalue = 1
        else
            defaultvalue = 10
        end

        println("You measure a topological charge")
        method["methodname"] = "Topological_charge"
        method["measure_every"] = parse(Int64,Base.prompt("How often measure a topological charge?", default="$defaultvalue"))
        method["fermiontype"] = nothing
        method["numflow"]  = parse(Int64,Base.prompt("How many times do you want to flow gauge fields to measure the topological charge?", default="10"))

        Nflowsteps = L[1]
        eps_flow = 0.01

        method["Nflowsteps"]  = parse(Int64,Base.prompt("Nflowsteps?", default="$Nflowsteps"))
        method["eps_flow"]  = parse(Float64,Base.prompt("eps_flow?", default="$eps_flow"))

        return method
    end

    function  chiral_wizard(staggered,system)
        if haskey(staggered,"mass")
            mass_default = staggered["mass"]
        else
            mass_default = 0.5
        end

        method = Dict()
        println("You measure chiral condensates with the statteggred fermion")

        method["methodname"] = "Chiral_condensate"

        if system["update_method"] == "Fileloading"
            defaultvalue = 1
        else
            defaultvalue = 10
        end

        method["measure_every"] = parse(Int64,Base.prompt("How often measure chiral condensates?", default="$defaultvalue"))
        method["fermiontype"] = "Staggered"
        method["mass"] = parse(Float64,Base.prompt("Input mass for the measurement of chiral condensates", default="$mass_default"))

        #Nfsystem = system["Nf"]
        #Nf = parse(Int64,Base.prompt("Number of flavors (tastes) for the measurement of chiral condensates", default="$Nfsystem"))
        #method["Nf"] = Nf
        method["Nf"] = 4
        println("Number of flavors (tastes) for the measurement of chiral condensates is $(method["Nf"])")

        eps = parse(Float64,Base.prompt("relative error in CG loops", default="1e-19"))
        MaxCGstep = parse(Int64,Base.prompt("Maximum iteration steps in CG loops", default="3000"))
        if eps<=0
            error("Invalid value for eps=$eps. This has to be strictly positive.")
        end
        if MaxCGstep<=0
            error("Invalid value for MaxCGstep=$MaxCGstep. This has to be strictly positive.")
        end
        method["eps"] = eps
        method["MaxCGstep"] = MaxCGstep

        set_smearing!(method)

        return method
    end

    function  pion_wizard(wilson,staggered,system)
        println("You measure Pion_correlator")
        method = Dict()
        method["methodname"] = "Pion_correlator"

        if system["update_method"] == "Fileloading"
            defaultvalue = 1
        else
            defaultvalue = 10
        end

        method["measure_every"] = parse(Int64,Base.prompt("How often measure Pion_correlator?", default="$defaultvalue"))

        wtype = request("Choose fermion type for the measurement of Pion_correlator",RadioMenu([
            "Standard Wilson fermion action",
            "Wilson+Clover fermion action",
            "Staggered fermion action",
        ]))

        if wtype == 1
            println("Standard Wilson fermion action will be used for the measurement")
            method["fermiontype"] = "Wilson"
            isWilson = true
        elseif wtype == 2
            println("Wilson+Clover fermion action will be used for the measurement")
            method["fermiontype"] = "WilsonClover"
            isWilson = true
        elseif wtype == 3
            println("Staggered fermion action will be used for the measurement")
            method["fermiontype"] = "Staggered"
            isWilson = false
        end

        if isWilson
            if haskey(wilson,"hop")
                hop_default = wilson["hop"]
            else
                hop_default = 0.141139
            end

            hop = parse(Float64,Base.prompt("Input the hopping parameter κ for the measurement", default="$hop_default"))
            if hop <= 0
                error("Invalid parameter κ=$hop")
            end
            method["hop"] = hop
            method["r"] = 1
        else
            if haskey(staggered,"mass")
                mass_default = staggered["mass"]
            else
                mass_default = 0.5
            end
            method["mass"] = parse(Float64,Base.prompt("Input mass for the measurement of Pion_correlator", default="$mass_default"))
            method["Nf"] = 4
        end

        eps = parse(Float64,Base.prompt("relative error in CG loops", default="1e-19"))
        MaxCGstep = parse(Int64,Base.prompt("Maximum iteration steps in CG loops", default="3000"))
        if eps<=0
            error("Invalid value for eps=$eps. This has to be strictly positive.")
        end
        if MaxCGstep<=0
            error("Invalid value for MaxCGstep=$MaxCGstep. This has to be strictly positive.")
        end
        method["eps"] = eps
        method["MaxCGstep"] = MaxCGstep

        set_smearing!(method)

        return method
    end

    function  pion_wizard(wilson,system)
        if haskey(wilson,"hop")
            hop_default = wilson["hop"]
        else
            hop_default = 0.141139
        end

        if system["update_method"] == "Fileloading"
            defaultvalue = 1
        else
            defaultvalue = 10
        end

        method = Dict()

        println("You measure Pion_correlator with the Wilson quark operator")

        method["methodname"] = "Pion_correlator"
        method["measure_every"] = parse(Int64,Base.prompt("How often measure Pion_correlator?", default="$defaultvalue"))
        wtype = request("Choose Wilson fermion type for the measurement of Pion_correlator",RadioMenu([
                    "Standard Wilson fermion action",
                    "Wilson+Clover fermion action",
                ]))
        if wtype == 1
            println("Standard Wilson fermion action will be used for the measurement")
            method["fermiontype"] = "Wilson"
        else
            println("Wilson+Clover fermion action will be used for the measurement")
            method["fermiontype"] = "WilsonClover"
        end

        hop = parse(Float64,Base.prompt("Input the hopping parameter κ for the measurement", default="$hop_default"))
        if hop <= 0
            error("Invalid parameter κ=$hop")
        end
        method["hop"] = hop
        method["r"] = 1

        eps = parse(Float64,Base.prompt("relative error in CG loops", default="1e-19"))
        MaxCGstep = parse(Int64,Base.prompt("Maximum iteration steps in CG loops", default="3000"))
        if eps<=0
            error("Invalid value for eps=$eps. This has to be strictly positive.")
        end
        if MaxCGstep<=0
            error("Invalid value for MaxCGstep=$MaxCGstep. This has to be strictly positive.")
        end
        method["eps"] = eps
        method["MaxCGstep"] = MaxCGstep

        set_smearing!(method)

        return method
    end

    function  pion_wizard_simple(wilson)
        if haskey(wilson,"hop")
            hop_default = wilson["hop"]
        else
            hop_default = 0.141139
        end

        method = Dict()

        println("You measure Pion_correlator with the Wilson quark operator")

        method["methodname"] = "Pion_correlator"
        method["measure_every"] = 10
        println("Standard Wilson fermion action will be used for the measurement")
        method["fermiontype"] = "Wilson"

        hop = hop_default
        if hop <= 0
            error("Invalid parameter κ=$hop")
        end
        method["hop"] = hop
        method["r"] = 1

        return method
    end

end

#using .Wizard
#Wizard.run_wizard()


text:
include("../src/Tenniskata.jl")
include("../src/Tenniskata1.jl")
include("../src/Tenniskata2.jl")
include("../src/Tenniskata3.jl")

using Test

struct TestDataSample
	player1Score::Int
	player2Score::Int
	expectedScore::String
end

testData = [
    TestDataSample(0, 0, "Love-All"),
	TestDataSample(1, 1, "Fifteen-All"),
	TestDataSample(2, 2, "Thirty-All"),
	TestDataSample(3, 3, "Deuce"),
	TestDataSample(4, 4, "Deuce"),

	TestDataSample(1, 0, "Fifteen-Love"),
	TestDataSample(0, 1, "Love-Fifteen"),
	TestDataSample(2, 0, "Thirty-Love"),
	TestDataSample(0, 2, "Love-Thirty"),
	TestDataSample(3, 0, "Forty-Love"),
	TestDataSample(0, 3, "Love-Forty"),
	TestDataSample(4, 0, "Win for player1"),
	TestDataSample(0, 4, "Win for player2"),

	TestDataSample(2, 1, "Thirty-Fifteen"),
	TestDataSample(1, 2, "Fifteen-Thirty"),
	TestDataSample(3, 1, "Forty-Fifteen"),
	TestDataSample(1, 3, "Fifteen-Forty"),
	TestDataSample(4, 1, "Win for player1"),
	TestDataSample(1, 4, "Win for player2"),

	TestDataSample(3, 2, "Forty-Thirty"),
	TestDataSample(2, 3, "Thirty-Forty"),
	TestDataSample(4, 2, "Win for player1"),
	TestDataSample(2, 4, "Win for player2"),

	TestDataSample(4, 3, "Advantage player1"),
	TestDataSample(3, 4, "Advantage player2"),
	TestDataSample(5, 4, "Advantage player1"),
	TestDataSample(4, 5, "Advantage player2"),
	TestDataSample(15, 14, "Advantage player1"),
	TestDataSample(14, 15, "Advantage player2"),

	TestDataSample(6, 4, "Win for player1"),
	TestDataSample(4, 6, "Win for player2"),
	TestDataSample(16, 14, "Win for player1"),
	TestDataSample(14, 16, "Win for player2")
]

function setScore(game, sample::TestDataSample)
    highestScore = max(sample.player1Score, sample.player2Score)

    for i = 0:highestScore
        if i < sample.player1Score
            Tenniskata.won_point(game, "player1")
        end

        if i < sample.player2Score
            Tenniskata.won_point(game, "player2")
        end
    end

    @test Tenniskata.get_score(game) == sample.expectedScore
end

@testset "Tenniskata1" begin
    @testset "$sample" for sample in testData
        setScore(TennisGame1("player1", "player2"), sample)
    end
end

@testset "Tenniskata2" begin
    @testset "$sample" for sample in testData
        setScore(TennisGame2("player1", "player2"), sample)
    end
end

@testset "Tenniskata3" begin
    @testset "$sample" for sample in testData
        setScore(TennisGame3("player1", "player2"), sample)
    end
end

ext: jl

max_stars_repo_name: jacob-alt-del/Tennis-Refactoring-Kata

max_issues_repo_name: jacob-alt-del/Tennis-Refactoring-Kata

max_forks_repo_name: jacob-alt-del/Tennis-Refactoring-Kata


text:
module ReproductionNumbers

using DataFrames, RollingFunctions, Dates, Statistics, CSV, Plots, ExcelFiles, Plots.Measures

include("getfuns.jl")
include("computations.jl")
include("compute_and_plot.jl")
include("main_nowcasting.jl")
include("main_reported.jl")

end


text:
"""
Abstract continuous filter.
"""
abstract type Filter end

"""
    IdentityFilter()

Identity filter, which does not filter.
"""
struct IdentityFilter <: Filter end

"""
    TopHatFilter(width)

Top hat filter, parameterized by a variable filter width.
"""
struct TopHatFilter <: Filter
    width::Function
end

"""
    ConvolutionalFilter(kernel)

Convolutional filter, parameterized by a filter kernel.
"""
struct ConvolutionalFilter <: Filter
    width::Function
    kernel::Function
end

"""
GaussianFilter(h, σ) -> ConvolutionalFilter
GaussianFilter(σ) -> ConvolutionalFilter

Create Gaussian ConvolutionalFilter with domain width `2h` and variance `σ^2`.
"""
GaussianFilter(h, σ) = ConvolutionalFilter(h, x -> 1 / √(2π * σ^2) * exp(-x^2 / 2σ^2))
GaussianFilter(σ) = GaussianFilter(x -> 10σ, σ)


text:
let
problem = BabyPOMDP()
policy = RandomPolicy(problem, rng=MersenneTwister(2))
steps=10
sim = HistoryRecorder(max_steps=steps, rng=MersenneTwister(3))
@show_requirements simulate(sim, problem, policy, updater(policy), initialstate_distribution(problem))
r1 = simulate(sim, problem, policy, updater(policy), initialstate_distribution(problem))
policy.rng = MersenneTwister(2)
sim.rng = MersenneTwister(3)
r2 = simulate(sim, problem, policy)

@test length(state_hist(r1)) == steps+1
@test length(action_hist(r1)) == steps
@test length(observation_hist(r1)) == steps
@test length(belief_hist(r1)) == steps+1
@test length(state_hist(r2)) == steps+1
@test length(action_hist(r2)) == steps
@test length(observation_hist(r2)) == steps
@test length(belief_hist(r2)) == steps+1
@test length(info_hist(r2)) == steps
@test length(ainfo_hist(r2)) == steps
@test length(uinfo_hist(r2)) == steps

@test exception(r1) == nothing
@test exception(r2) == nothing
@test backtrace(r1) == nothing
@test backtrace(r2) == nothing

@test n_steps(r1) == n_steps(r2)
@test undiscounted_reward(r1) == undiscounted_reward(r2)
@test discounted_reward(r1) == discounted_reward(r2)

@test length(collect(r1)) == n_steps(r1)
@test length(collect(r2)) == n_steps(r2)

for tuple in r1
    length(tuple) == 6
end

for ui in eachstep(r2, "ui")
    @test ui == nothing
end

# test that complete step is returned
step = first(eachstep(r2))
for key in POMDPSimulators.COMPLETE_POMDP_STEP
    @test haskey(step, key)
end

problem = LegacyGridWorld()
policy = RandomPolicy(problem, rng=MersenneTwister(2))
steps=10
sim = HistoryRecorder(max_steps=steps, rng=MersenneTwister(3))
@show_requirements simulate(sim, problem, policy, initialstate(problem, sim.rng))
r1 = simulate(sim, problem, policy, initialstate(problem, sim.rng))

@test length(state_hist(r1)) <= steps + 1 # less than or equal because it may reach the goal too fast
@test length(action_hist(r1)) <= steps
@test length(reward_hist(r1)) <= steps

for tuple in r1
    @test length(tuple) == 4
    @test isa(tuple[1], statetype(problem))
    @test isa(tuple[2], actiontype(problem))
    @test isa(tuple[3], Float64)
    @test isa(tuple[4], statetype(problem))
    @test isa(tuple.s, statetype(problem))
    @test isa(tuple.a, actiontype(problem))
    @test isa(tuple.r, Float64)
    @test isa(tuple.sp, statetype(problem))
end

@test length(collect(r1)) == n_steps(r1)

hv = view(r1, 2:length(r1))
@test n_steps(hv) == n_steps(r1)-1
@test undiscounted_reward(r1) == undiscounted_reward(hv) + reward_hist(r1)[1]

# iterators
rsum = 0.0
len = 0
for (s, a, r, sp, i, ai, t) in eachstep(hv, (:s,:a,:r,:sp,:i,:ai,:t))
    @test isa(s, statetype(problem))
    @test isa(a, actiontype(problem))
    @test isa(r, Float64)
    @test isa(sp, statetype(problem))
    @test isa(i, Nothing)
    @test isa(ai, Nothing)
    @test isa(t, Int)
    rsum += r
    len += 1
end
@test len == length(hv)
@test rsum == undiscounted_reward(hv)

# it = eachstep(hv, "(r,sp,s,a)")
# @test eltype(collect(it)) == Tuple{Float64, statetype(problem), statetype(problem), actiontype(problem)}
tuples = collect(eachstep(hv, "(r, sp, s, a)"))
@test sum(first(t) for t in tuples) == undiscounted_reward(hv)
@test sum(t.r for t in tuples) == undiscounted_reward(hv)
tuples = collect(eachstep(hv, "r,sp,s,a,t"))
@test sum(first(t) for t in tuples) == undiscounted_reward(hv)
@test sum(t.r for t in tuples) == undiscounted_reward(hv)

@test collect(eachstep(hv, "r")) == reward_hist(hv)

#=
function f(hv)
    rs = 0.0
    for (r,a) in HistoryIterator{typeof(hv), (:r,:a)}(hv)
        rs += r
    end
    return rs
end
@code_warntype f(hv)
hi = HistoryIterator{typeof(r1), (:r,)}(r1)
t = step_tuple(hi, 1)
@code_warntype step_tuple(hi, 1)
=#
end


text:
# This file is auto-generated by AWSMetadata.jl
using AWS
using AWS.AWSServices: comprehendmedical
using AWS.Compat
using AWS.UUIDs

"""
    DescribeEntitiesDetectionV2Job()

Gets the properties associated with a medical entities detection job. Use this operation to get the status of a detection job.

# Required Parameters
- `JobId`: The identifier that Amazon Comprehend Medical generated for the job. The StartEntitiesDetectionV2Job operation returns this identifier in its response.

"""
describe_entities_detection_v2_job(JobId; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("DescribeEntitiesDetectionV2Job", Dict{String, Any}("JobId"=>JobId); aws_config=aws_config)
describe_entities_detection_v2_job(JobId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("DescribeEntitiesDetectionV2Job", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("JobId"=>JobId), args)); aws_config=aws_config)

"""
    DescribeICD10CMInferenceJob()

Gets the properties associated with an InferICD10CM job. Use this operation to get the status of an inference job.

# Required Parameters
- `JobId`: The identifier that Amazon Comprehend Medical generated for the job. The StartICD10CMInferenceJob operation returns this identifier in its response.

"""
describe_icd10_cminference_job(JobId; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("DescribeICD10CMInferenceJob", Dict{String, Any}("JobId"=>JobId); aws_config=aws_config)
describe_icd10_cminference_job(JobId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("DescribeICD10CMInferenceJob", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("JobId"=>JobId), args)); aws_config=aws_config)

"""
    DescribePHIDetectionJob()

Gets the properties associated with a protected health information (PHI) detection job. Use this operation to get the status of a detection job.

# Required Parameters
- `JobId`: The identifier that Amazon Comprehend Medical generated for the job. The StartPHIDetectionJob operation returns this identifier in its response.

"""
describe_phidetection_job(JobId; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("DescribePHIDetectionJob", Dict{String, Any}("JobId"=>JobId); aws_config=aws_config)
describe_phidetection_job(JobId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("DescribePHIDetectionJob", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("JobId"=>JobId), args)); aws_config=aws_config)

"""
    DescribeRxNormInferenceJob()

Gets the properties associated with an InferRxNorm job. Use this operation to get the status of an inference job.

# Required Parameters
- `JobId`: The identifier that Amazon Comprehend Medical generated for the job. The StartRxNormInferenceJob operation returns this identifier in its response.

"""
describe_rx_norm_inference_job(JobId; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("DescribeRxNormInferenceJob", Dict{String, Any}("JobId"=>JobId); aws_config=aws_config)
describe_rx_norm_inference_job(JobId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("DescribeRxNormInferenceJob", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("JobId"=>JobId), args)); aws_config=aws_config)

"""
    DetectEntities()

The DetectEntities operation is deprecated. You should use the DetectEntitiesV2 operation instead.  Inspects the clinical text for a variety of medical entities and returns specific information about them such as entity category, location, and confidence score on that information .

# Required Parameters
- `Text`:  A UTF-8 text string containing the clinical content being examined for entities. Each string must contain fewer than 20,000 bytes of characters.

"""
detect_entities(Text; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("DetectEntities", Dict{String, Any}("Text"=>Text); aws_config=aws_config)
detect_entities(Text, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("DetectEntities", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Text"=>Text), args)); aws_config=aws_config)

"""
    DetectEntitiesV2()

Inspects the clinical text for a variety of medical entities and returns specific information about them such as entity category, location, and confidence score on that information. Amazon Comprehend Medical only detects medical entities in English language texts. The DetectEntitiesV2 operation replaces the DetectEntities operation. This new action uses a different model for determining the entities in your medical text and changes the way that some entities are returned in the output. You should use the DetectEntitiesV2 operation in all new applications. The DetectEntitiesV2 operation returns the Acuity and Direction entities as attributes instead of types.

# Required Parameters
- `Text`: A UTF-8 string containing the clinical content being examined for entities. Each string must contain fewer than 20,000 bytes of characters.

"""
detect_entities_v2(Text; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("DetectEntitiesV2", Dict{String, Any}("Text"=>Text); aws_config=aws_config)
detect_entities_v2(Text, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("DetectEntitiesV2", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Text"=>Text), args)); aws_config=aws_config)

"""
    DetectPHI()

 Inspects the clinical text for protected health information (PHI) entities and returns the entity category, location, and confidence score for each entity. Amazon Comprehend Medical only detects entities in English language texts.

# Required Parameters
- `Text`:  A UTF-8 text string containing the clinical content being examined for PHI entities. Each string must contain fewer than 20,000 bytes of characters.

"""
detect_phi(Text; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("DetectPHI", Dict{String, Any}("Text"=>Text); aws_config=aws_config)
detect_phi(Text, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("DetectPHI", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Text"=>Text), args)); aws_config=aws_config)

"""
    InferICD10CM()

InferICD10CM detects medical conditions as entities listed in a patient record and links those entities to normalized concept identifiers in the ICD-10-CM knowledge base from the Centers for Disease Control. Amazon Comprehend Medical only detects medical entities in English language texts.

# Required Parameters
- `Text`: The input text used for analysis. The input for InferICD10CM is a string from 1 to 10000 characters.

"""
infer_icd10_cm(Text; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("InferICD10CM", Dict{String, Any}("Text"=>Text); aws_config=aws_config)
infer_icd10_cm(Text, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("InferICD10CM", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Text"=>Text), args)); aws_config=aws_config)

"""
    InferRxNorm()

InferRxNorm detects medications as entities listed in a patient record and links to the normalized concept identifiers in the RxNorm database from the National Library of Medicine. Amazon Comprehend Medical only detects medical entities in English language texts.

# Required Parameters
- `Text`: The input text used for analysis. The input for InferRxNorm is a string from 1 to 10000 characters.

"""
infer_rx_norm(Text; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("InferRxNorm", Dict{String, Any}("Text"=>Text); aws_config=aws_config)
infer_rx_norm(Text, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("InferRxNorm", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Text"=>Text), args)); aws_config=aws_config)

"""
    ListEntitiesDetectionV2Jobs()

Gets a list of medical entity detection jobs that you have submitted.

# Optional Parameters
- `Filter`: Filters the jobs that are returned. You can filter jobs based on their names, status, or the date and time that they were submitted. You can only set one filter at a time.
- `MaxResults`: The maximum number of results to return in each page. The default is 100.
- `NextToken`: Identifies the next page of results to return.
"""
list_entities_detection_v2_jobs(; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("ListEntitiesDetectionV2Jobs"; aws_config=aws_config)
list_entities_detection_v2_jobs(args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("ListEntitiesDetectionV2Jobs", args; aws_config=aws_config)

"""
    ListICD10CMInferenceJobs()

Gets a list of InferICD10CM jobs that you have submitted.

# Optional Parameters
- `Filter`: Filters the jobs that are returned. You can filter jobs based on their names, status, or the date and time that they were submitted. You can only set one filter at a time.
- `MaxResults`: The maximum number of results to return in each page. The default is 100.
- `NextToken`: Identifies the next page of results to return.
"""
list_icd10_cminference_jobs(; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("ListICD10CMInferenceJobs"; aws_config=aws_config)
list_icd10_cminference_jobs(args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("ListICD10CMInferenceJobs", args; aws_config=aws_config)

"""
    ListPHIDetectionJobs()

Gets a list of protected health information (PHI) detection jobs that you have submitted.

# Optional Parameters
- `Filter`: Filters the jobs that are returned. You can filter jobs based on their names, status, or the date and time that they were submitted. You can only set one filter at a time.
- `MaxResults`: The maximum number of results to return in each page. The default is 100.
- `NextToken`: Identifies the next page of results to return.
"""
list_phidetection_jobs(; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("ListPHIDetectionJobs"; aws_config=aws_config)
list_phidetection_jobs(args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("ListPHIDetectionJobs", args; aws_config=aws_config)

"""
    ListRxNormInferenceJobs()

Gets a list of InferRxNorm jobs that you have submitted.

# Optional Parameters
- `Filter`: Filters the jobs that are returned. You can filter jobs based on their names, status, or the date and time that they were submitted. You can only set one filter at a time.
- `MaxResults`: Identifies the next page of results to return.
- `NextToken`: Identifies the next page of results to return.
"""
list_rx_norm_inference_jobs(; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("ListRxNormInferenceJobs"; aws_config=aws_config)
list_rx_norm_inference_jobs(args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("ListRxNormInferenceJobs", args; aws_config=aws_config)

"""
    StartEntitiesDetectionV2Job()

Starts an asynchronous medical entity detection job for a collection of documents. Use the DescribeEntitiesDetectionV2Job operation to track the status of a job.

# Required Parameters
- `DataAccessRoleArn`: The Amazon Resource Name (ARN) of the AWS Identity and Access Management (IAM) role that grants Amazon Comprehend Medical read access to your input data. For more information, see  Role-Based Permissions Required for Asynchronous Operations.
- `InputDataConfig`: Specifies the format and location of the input data for the job.
- `LanguageCode`: The language of the input documents. All documents must be in the same language.
- `OutputDataConfig`: Specifies where to send the output files.

# Optional Parameters
- `ClientRequestToken`: A unique identifier for the request. If you don't set the client request token, Amazon Comprehend Medical generates one.
- `JobName`: The identifier of the job.
- `KMSKey`: An AWS Key Management Service key to encrypt your output files. If you do not specify a key, the files are written in plain text.
"""
start_entities_detection_v2_job(DataAccessRoleArn, InputDataConfig, LanguageCode, OutputDataConfig; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("StartEntitiesDetectionV2Job", Dict{String, Any}("DataAccessRoleArn"=>DataAccessRoleArn, "InputDataConfig"=>InputDataConfig, "LanguageCode"=>LanguageCode, "OutputDataConfig"=>OutputDataConfig, "ClientRequestToken"=>string(uuid4())); aws_config=aws_config)
start_entities_detection_v2_job(DataAccessRoleArn, InputDataConfig, LanguageCode, OutputDataConfig, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("StartEntitiesDetectionV2Job", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("DataAccessRoleArn"=>DataAccessRoleArn, "InputDataConfig"=>InputDataConfig, "LanguageCode"=>LanguageCode, "OutputDataConfig"=>OutputDataConfig, "ClientRequestToken"=>string(uuid4())), args)); aws_config=aws_config)

"""
    StartICD10CMInferenceJob()

Starts an asynchronous job to detect medical conditions and link them to the ICD-10-CM ontology. Use the DescribeICD10CMInferenceJob operation to track the status of a job.

# Required Parameters
- `DataAccessRoleArn`: The Amazon Resource Name (ARN) of the AWS Identity and Access Management (IAM) role that grants Amazon Comprehend Medical read access to your input data. For more information, see  Role-Based Permissions Required for Asynchronous Operations.
- `InputDataConfig`: Specifies the format and location of the input data for the job.
- `LanguageCode`: The language of the input documents. All documents must be in the same language.
- `OutputDataConfig`: Specifies where to send the output files.

# Optional Parameters
- `ClientRequestToken`: A unique identifier for the request. If you don't set the client request token, Amazon Comprehend Medical generates one.
- `JobName`: The identifier of the job.
- `KMSKey`: An AWS Key Management Service key to encrypt your output files. If you do not specify a key, the files are written in plain text.
"""
start_icd10_cminference_job(DataAccessRoleArn, InputDataConfig, LanguageCode, OutputDataConfig; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("StartICD10CMInferenceJob", Dict{String, Any}("DataAccessRoleArn"=>DataAccessRoleArn, "InputDataConfig"=>InputDataConfig, "LanguageCode"=>LanguageCode, "OutputDataConfig"=>OutputDataConfig, "ClientRequestToken"=>string(uuid4())); aws_config=aws_config)
start_icd10_cminference_job(DataAccessRoleArn, InputDataConfig, LanguageCode, OutputDataConfig, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("StartICD10CMInferenceJob", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("DataAccessRoleArn"=>DataAccessRoleArn, "InputDataConfig"=>InputDataConfig, "LanguageCode"=>LanguageCode, "OutputDataConfig"=>OutputDataConfig, "ClientRequestToken"=>string(uuid4())), args)); aws_config=aws_config)

"""
    StartPHIDetectionJob()

Starts an asynchronous job to detect protected health information (PHI). Use the DescribePHIDetectionJob operation to track the status of a job.

# Required Parameters
- `DataAccessRoleArn`: The Amazon Resource Name (ARN) of the AWS Identity and Access Management (IAM) role that grants Amazon Comprehend Medical read access to your input data. For more information, see  Role-Based Permissions Required for Asynchronous Operations.
- `InputDataConfig`: Specifies the format and location of the input data for the job.
- `LanguageCode`: The language of the input documents. All documents must be in the same language.
- `OutputDataConfig`: Specifies where to send the output files.

# Optional Parameters
- `ClientRequestToken`: A unique identifier for the request. If you don't set the client request token, Amazon Comprehend Medical generates one.
- `JobName`: The identifier of the job.
- `KMSKey`: An AWS Key Management Service key to encrypt your output files. If you do not specify a key, the files are written in plain text.
"""
start_phidetection_job(DataAccessRoleArn, InputDataConfig, LanguageCode, OutputDataConfig; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("StartPHIDetectionJob", Dict{String, Any}("DataAccessRoleArn"=>DataAccessRoleArn, "InputDataConfig"=>InputDataConfig, "LanguageCode"=>LanguageCode, "OutputDataConfig"=>OutputDataConfig, "ClientRequestToken"=>string(uuid4())); aws_config=aws_config)
start_phidetection_job(DataAccessRoleArn, InputDataConfig, LanguageCode, OutputDataConfig, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("StartPHIDetectionJob", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("DataAccessRoleArn"=>DataAccessRoleArn, "InputDataConfig"=>InputDataConfig, "LanguageCode"=>LanguageCode, "OutputDataConfig"=>OutputDataConfig, "ClientRequestToken"=>string(uuid4())), args)); aws_config=aws_config)

"""
    StartRxNormInferenceJob()

Starts an asynchronous job to detect medication entities and link them to the RxNorm ontology. Use the DescribeRxNormInferenceJob operation to track the status of a job.

# Required Parameters
- `DataAccessRoleArn`: The Amazon Resource Name (ARN) of the AWS Identity and Access Management (IAM) role that grants Amazon Comprehend Medical read access to your input data. For more information, see  Role-Based Permissions Required for Asynchronous Operations.
- `InputDataConfig`: Specifies the format and location of the input data for the job.
- `LanguageCode`: The language of the input documents. All documents must be in the same language.
- `OutputDataConfig`: Specifies where to send the output files.

# Optional Parameters
- `ClientRequestToken`: A unique identifier for the request. If you don't set the client request token, Amazon Comprehend Medical generates one.
- `JobName`: The identifier of the job.
- `KMSKey`: An AWS Key Management Service key to encrypt your output files. If you do not specify a key, the files are written in plain text.
"""
start_rx_norm_inference_job(DataAccessRoleArn, InputDataConfig, LanguageCode, OutputDataConfig; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("StartRxNormInferenceJob", Dict{String, Any}("DataAccessRoleArn"=>DataAccessRoleArn, "InputDataConfig"=>InputDataConfig, "LanguageCode"=>LanguageCode, "OutputDataConfig"=>OutputDataConfig, "ClientRequestToken"=>string(uuid4())); aws_config=aws_config)
start_rx_norm_inference_job(DataAccessRoleArn, InputDataConfig, LanguageCode, OutputDataConfig, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("StartRxNormInferenceJob", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("DataAccessRoleArn"=>DataAccessRoleArn, "InputDataConfig"=>InputDataConfig, "LanguageCode"=>LanguageCode, "OutputDataConfig"=>OutputDataConfig, "ClientRequestToken"=>string(uuid4())), args)); aws_config=aws_config)

"""
    StopEntitiesDetectionV2Job()

Stops a medical entities detection job in progress.

# Required Parameters
- `JobId`: The identifier of the medical entities job to stop.

"""
stop_entities_detection_v2_job(JobId; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("StopEntitiesDetectionV2Job", Dict{String, Any}("JobId"=>JobId); aws_config=aws_config)
stop_entities_detection_v2_job(JobId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("StopEntitiesDetectionV2Job", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("JobId"=>JobId), args)); aws_config=aws_config)

"""
    StopICD10CMInferenceJob()

Stops an InferICD10CM inference job in progress.

# Required Parameters
- `JobId`: The identifier of the job.

"""
stop_icd10_cminference_job(JobId; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("StopICD10CMInferenceJob", Dict{String, Any}("JobId"=>JobId); aws_config=aws_config)
stop_icd10_cminference_job(JobId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("StopICD10CMInferenceJob", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("JobId"=>JobId), args)); aws_config=aws_config)

"""
    StopPHIDetectionJob()

Stops a protected health information (PHI) detection job in progress.

# Required Parameters
- `JobId`: The identifier of the PHI detection job to stop.

"""
stop_phidetection_job(JobId; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("StopPHIDetectionJob", Dict{String, Any}("JobId"=>JobId); aws_config=aws_config)
stop_phidetection_job(JobId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("StopPHIDetectionJob", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("JobId"=>JobId), args)); aws_config=aws_config)

"""
    StopRxNormInferenceJob()

Stops an InferRxNorm inference job in progress.

# Required Parameters
- `JobId`: The identifier of the job.

"""
stop_rx_norm_inference_job(JobId; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("StopRxNormInferenceJob", Dict{String, Any}("JobId"=>JobId); aws_config=aws_config)
stop_rx_norm_inference_job(JobId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = comprehendmedical("StopRxNormInferenceJob", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("JobId"=>JobId), args)); aws_config=aws_config)


text:
function idxof(list, x)
    r1, r2 = _idxof(list, x)
    return _idxof(list, x, r1, r2)
end
function _idxof(list, x)
    r = searchsorted(list, x)
    r1, r2 = first(r), last(r)
    return min(r1, r2), max(r1, r2)
end
_idxof(list, x, r1, r2) =  x - list[r1] < list[r2] - x ? r1 : r2

function idxsof(list, ti::FrameSeq)
    istart = idxof(list, ti.start)
    return OffsetArrays.IdOffsetRange(values=istart .+ ti.idx, indices=ti.idx)
end

"""
    ncells(ct::CellsTrial)

Return the number of cells stored in the `dFoF` field of `ct`.
"""
ncells(ct::CellsTrial) = size(ct.dFoF, 2)

"""
    isdeferred(fs::FrameSeq)

Return `true` if the start time in `fs` is a field name of `EventTiming`, and hence
requires concrete instantiation as `fs(et)` for a specific trial.
"""
isdeferred(fs::FrameSeq) = isa(fs.start, Symbol)

"""
    madechoice(tr::TrialResult)

Return `true` if the animal made a choice in the trial.
"""
madechoice(tr::TrialResult) = tr.choseA !== missing

"""
    isforced(tt::OfferType)
    isforced(tr::TrialResult)

Return `true` for a forced-choice trial, where either `nA` or `nB` is zero.
"""
isforced(tt::OfferType) = iszero(tt.nA) ⊻ iszero(tt.nB)
isforced(tr::TrialResult) = isforced(tr.tt)

"""
    iswrong(tr::TrialResult)

Return `true` if `tr` is a forced-choice trial and the animal chose the wrong option.
"""
iswrong(tr::TrialResult) = isforced(tr) && ((iszero(tr.nA) & (tr.choseA===true)) | (iszero(tr.nB) & (tr.choseA===false)))


text:
int main () {
  Counter c;
  c = new Counter;
  c.incr();
  c.incr();
  c.incr();
  int x = c.value();
  printInt(x);
  return 0;
}

class Counter {
  int val;

  void incr () {val++; return;}

  int value () {return val;}

}

max_stars_repo_name: carlostome/Javalette-Compiler

max_issues_repo_name: carlostome/Javalette-Compiler

max_forks_repo_name: carlostome/Javalette-Compiler


text:
using CSV, DataFrames, Statistics

#include("Inomura2020.jl");

function generate_params(PIcurve)
    ESDCell = 0.7   # Prochlorococcus ESD ~0.5-0.7 um
    RadCell = ESDCell / 2.0
    # volume of cell (um^3)
    VolCell = (4.0*3.14159/3.0)*RadCell^3.0
    # surface area of cell (um^2)
    SurfAreaCell = (4.0*3.14159)*RadCell^2.0
    # Alternatively, carbon quota for Prochlorococcus from direct measurement
    Q_C = 0.0609/12.0  # pmol C cell-1,  MED-4, P-limited, Bertilsson et al (2003)

    # Use Redfield ratio to evaluate Q_N and Q_P
    Q_N = (16.0/106.0)*Q_C           # pmol N cell-1
    Q_P = (1.0/106.0)*Q_C            # pmol P cell-1
    # Hawco et al report 1.6*10^-5 to 4.0*10^5 Fe:C ratios in Prochlorococcus
    Q_Fe = 1.6e-5*Q_C                # pmol Fe cell-1

    # set allometric scaling coeffs for Vmax_NO3 and K_NO3 (Edwards et al, 2012)
    a_V_NO3  = 10.0^(-8.1)      # umol N cell-1 day-1
    b_V_NO3 = 0.82              # power
    a_K_NO3 = 10.0^(-0.84)      # umol N L-1
    b_K_NO3 = 0.33              # power
    Vmax_NO3 = a_V_NO3 * (VolCell^b_V_NO3)    # umol N cell-1 day-1
    K_NO3 = a_K_NO3 * (VolCell^b_K_NO3)       # umol N L-1
    # evaluate N specific max N uptake
    Vmax_NO3_specific = Vmax_NO3 / (Q_N * 1.0e-6)    # day-1

    # set allometric scaling coeffs for Vmax_PO4 and K_PO4 (Edwards et al, 2012)
    a_V_PO4  = 10.0^(-9.1)      # umol N cell-1 day-1
    b_V_PO4 = 1.0               # power
    a_K_PO4 = 10.0^(-1.4)      # umol N L-1
    b_K_PO4 = 0.41              # power
    Vmax_PO4 = a_V_NO3 * (VolCell^b_V_PO4)    # umol N cell-1 day-1
    K_PO4 = a_K_PO4 * (VolCell^b_K_PO4)       # umol N L-1
    # evaluate N specific max N uptake
    Vmax_PO4_specific = Vmax_PO4 / (Q_P * 1.0e-6)    # day-1

    # set allometric scaling for Fe uptake, Shaked et al iron uptake, (Lis et al, Life, 2015; Lis et al, ISMEj 2015)
    Kin_SA_Fe = 10.0e-10                  # L day-1 um-2
    Kin_Fe = Kin_SA_Fe * SurfAreaCell    # L cell-1 day-1
    Q_Fe_molar = Q_Fe * 1.0e-12 # Q_Fe_molar - convert to pmol to mol Fe cell-1
    Kin_Fe_Specific = Kin_Fe / (Q_Fe_molar)  # L cell-1 day-1 (mol Fe cell-1)-1 = day-1 / (mol Fe L-1)

    mort = 0.8 # constant death rate
    K_R = 0.05 # respiration rate, day-1

    # Partensky et al 1993 .............................
    alpha_Chl_Partensky  = 0.041      # trying out some representative values
    # I_b and I_m are acclimated characteristics... depend on recent light
    # reported by Partensky
    I_m = 341.0             #
    I_b_Partensky = 730.0             # I_b = P_S_Chl / beta_Chl
    # Partensky don't report P_S_Chl... estimate to roughly match data
    P_S_Chl_Partensky = 15.0    # fg C (fg Chl)-1 hour-1
    beta_Chl_Partensky  = P_S_Chl_Partensky / I_b_Partensky
    # ....................................................

    # Moore and Chisholm (1999) ...........................
    # 9211 Low light strain, adapted at 9 µmol quanta m-2 s-1
    alpha_Chl_MC_9211_Lo = 0.09   # estimated directly from bar graph
    P_S_Chl_MC_9211_Lo = 3.0      # guesstimated
    beta_Chl_MC_9211_Lo = 0.010   # guesstimated
    P_S_Chl_Lo_MM = 97.47         # mol C (mol C in Chl)-1 day-1
    # 9215 High light strain, adapted at 70 µmol quanta m-2 s-1
    alpha_Chl_MC_9215_Hi = 0.05   # estimated directly from bar graph
    P_S_Chl_MC_9215_Hi = 8.0      # guesstimated
    beta_Chl_MC_9215_Hi = 0.008   # guesstimated
    P_S_Chl_Hi_MM = 259.92        # mol C (mol C in Chl)-1 day-1

     if PIcurve == "Pa"
        alpha_Chl = alpha_Chl_Partensky
        P_S_Chl = P_S_Chl_Partensky
        beta_Chl = beta_Chl_Partensky
    end
    if PIcurve == "LL"
        alpha_Chl = alpha_Chl_MC_9211_Lo
        P_S_Chl = P_S_Chl_MC_9211_Lo
        beta_Chl = beta_Chl_MC_9211_Lo
        nu_I_max = P_S_Chl_Lo_MM
    end
    if PIcurve == "HL"
        alpha_Chl = alpha_Chl_MC_9215_Hi
        P_S_Chl = P_S_Chl_MC_9215_Hi
        beta_Chl = beta_Chl_MC_9215_Hi
        nu_I_max = P_S_Chl_Hi_MM
    end
    # set I_b accordingly
    I_b = P_S_Chl / beta_Chl

    # MacroMolecule Allocation parameters from Inomura et al. 2020
    A_Pho = 1.60e1               # mol C (mol C in Chl)-1
    A_Bio = 2.71e-1              # mol C (mol C)-1 day-1
    A_RNA_P = 4.23e-3            # mol P (mol C)-1 day
    A_Pho_PChl = 2.83e-2         # mol P (mol C in Chl)-1
    Q_C_Pro_Other = 2.40e-1     # mol C (mol C)-1
    Q_C_Other0 = 1.82e-2         # mol C (mol C)-1
    Q_C_DNA = 9.41e-4            # mol C (mol C)-1
    Q_Pmin_RNA = 2.23e-4         # mol P (mol C)-1
    Y_RNA_CP = 10.7/1.0
    Y_Plip_CP = 40.0/1.0

    A_I = alpha_Chl/P_S_Chl
    E = 7.74e-1                  # synth cost dimensionless
    m = 3.93e-1 #K_R             # maintenance respiration rate, 3.93e-1 in Inomura et al.

    return (VNmax = Vmax_NO3_specific, VPmax= Vmax_PO4_specific,
        KinFe = Kin_Fe_Specific, KN = K_NO3, KP = K_PO4, KR = K_R, mort = mort,
        alphaChl = alpha_Chl, PSchl = P_S_Chl, Ib = I_b, Qc = Q_C,
        A_Pho = A_Pho, A_Bio = A_Bio, A_RNA_P = A_RNA_P, A_Pho_PChl = A_Pho_PChl,
        Q_C_Pro_Other = Q_C_Pro_Other, Q_C_Other0 = Q_C_Other0, Q_C_DNA = Q_C_DNA,
        Q_Pmin_RNA = Q_Pmin_RNA, Y_RNA_CP = Y_RNA_CP, Y_Plip_CP = Y_Plip_CP,
        A_I = A_I, nu_I_max = nu_I_max, E = E, m = m)
end

function nut_min_uptake(input, params)
    VN = params.VNmax .* input.DIN ./ (input.DIN .+ params.KN)
    VP = params.VPmax .* input.PO4 ./ (input.PO4 .+ params.KP)
    VFe= params.KinFe .* input.Fe_d .* 1.0e-9  # because [Fe_d] in nmoles L-1

    return min(VN, VFe) # per day
end

function P_Chl(input, params, ::Nothing; photo_inhib = true)
    P_Chl = params.PSchl .* (1.0 .- exp.(-params.alphaChl .* input.PARav ./ params.PSchl))
    if photo_inhib
        P_Chl .*= exp.(-1.0 .* input.PARav ./ params.Ib)
    end
    return P_Chl
end

function P_Chl(input, params, hPARfrac::Array; photo_inhib = true)
    nhour = length(hPARfrac)
    nz = size(input,1)
    I_hourly = zeros(nz, nhour)
    for k in 1:nhour
        I_hourly[:,k] = input.PARmax.*  hPARfrac[k]
    end

    P_Chl_hourly = params.PSchl .* (1.0 .- exp.(-params.alphaChl .* I_hourly ./ params.PSchl))
    if photo_inhib
        P_Chl_hourly .*= exp.(-1.0 .* I_hourly ./ params.Ib)
    end

    P_Chl = mean(P_Chl_hourly, dims=2)[:,1]
    return P_Chl # per hour
end

# nu_I(I), photosynthesis vs light. Evaluate A_Chl and B_Chl
function photosynth(I,pa)
    nu_I = pa.nu_I_max*(1.0 - exp(-pa.A_I*I))
    A_Chl = (1.0 + pa.E)/nu_I
    B_Chl = pa.m / nu_I
    return nu_I, A_Chl, B_Chl
end

# mu_max_I, max light-limited growth rate for given I (day-1)
function mu_max_I_eval(A_Chl,B_Chl,pa)
    # coefficients of quadratic
    a_M = pa.Y_RNA_CP*pa.A_RNA_P*(pa.A_Pho*A_Chl + pa.A_Bio)
    b_M = (  (1.0 + pa.A_Pho + pa.Y_Plip_CP*pa.A_Pho_PChl)*A_Chl + pa.A_Bio
                  + pa.Y_RNA_CP*pa.A_RNA_P*(pa.A_Pho*B_Chl + pa.Q_C_Pro_Other)  )
    Q_C_Other = pa.Q_C_Other0 + pa.Q_C_DNA + pa.Q_C_Pro_Other
    c_M = ( (1.0 + pa.A_Pho + pa.Y_Plip_CP*pa.A_Pho_PChl)*B_Chl
                  + Q_C_Other + pa.Y_RNA_CP*pa.Q_Pmin_RNA - 1.0     )
    # evaluate root of quadratic
    mu_max_I = (- b_M + (b_M*b_M - 4.0*a_M*c_M)^0.5 )/(2.0*a_M)
    return mu_max_I
end

# Chlorophyll to carbon ratio (moles C in Chl (mol C)-1)
function ChlC(mu,A_Chl,B_Chl)
    Q_C_Chl =  A_Chl*mu + B_Chl
    return Q_C_Chl
end

function calc_mu(input, params; hPARfrac = nothing, photo_inhib = true)
    nz = size(input, 1)

    A_Chl_out  = zeros(nz)
    B_Chl_out  = zeros(nz)
    mumaxI_out = zeros(nz)
    CN         = zeros(nz)
    CP         = zeros(nz)
    Chl_C      = zeros(nz)
    mu_C       = zeros(nz)
    mu_nut     = zeros(nz)

    # Factor to convert Chl-a:C from mol C in Chl-a (mol C)-1 [Inomura]  to  fg Chl-a (fg C)-1 [Partensky]
    Mchl=893.49  # molar mass of chlorophyll (g mol-1)
    Mc=12.0      # molar mass of carbon (g mol-1)
    C_per_Chla = 55.0   # Chlorophyll-a =  C₅₅H₇₂O₅N₄Mg
    Chl_factor = Mchl /  (Mc * C_per_Chla)

    # growth-rate INDEPENDENT photosynth params: =================
    # Use DAILY MEAN light to evaluate these...
    # ASSUMES ACCLIMATION HAPPENS ON DAILY TIMESCALE
    # otherwise acclimates Chl:C on hourly scale which leads to odd
    for i in 1:nz
        A_Chl_out[i] = photosynth(input.PARav[i],params)[2]
        B_Chl_out[i] = photosynth(input.PARav[i],params)[3]
    end

    # Iterative determination of Chl:C, growth rate, biomass
    mu_auto = (1.5 .*  exp.(-input.Depth/150.0))   # first "guess" for mu for initial Chl:C
    for j in 1:40
        for i in 1:nz
            mumaxI_out[i] = mu_max_I_eval(A_Chl_out[i], B_Chl_out[i], params)
            Chl_C[i] = ChlC(mu_auto[i],A_Chl_out[i],B_Chl_out[i]) * Chl_factor
            #CN[i] = 1.0 / NC_eval(mu_auto[i],A_Chl_out[i],B_Chl_out[i],pa)
            #CP[i] = 1.0 / PC_eval(mu_auto[i],A_Chl_out[i],B_Chl_out[i],pa)
        end

        # Eval photosynth (d-1): fg C (fg Chl)-1 h-1 * fg Chl (fg C)-1 * h d-1
        Pcalc = P_Chl(input, params, hPARfrac; photo_inhib = photo_inhib) .* Chl_C .* 24.0  # estimated photosynth growth
        mumax = max.(mumaxI_out, 0.0)  # Max possible light-lim growth rate
        #P = min.(Pcalc, Pmax)         # Photosynth "growth rate"

        # maintenance respiration rate used here and in Inomura et al are quite different, almost 10 times
        mu_C .= min.(mumax, Pcalc .- params.KR)         # net carbon growth rate
        mu_nut .= nut_min_uptake(input, params) # nutrient limited growth rate
        mu_min = min.(mu_C , mu_nut)  # minimal growth rate

        mu_auto .= max.(mu_min, 0,0)
    end

    # evaluate heterotrophic growth rate by the difference of observed growth rate and autotrophic growth rate
    mu_het = input.Pro_mu .- mu_auto
    mu_het = max.(mu_het, 0.0)

    # evaluate biomass from observed growth rate and quadratic grazing
    B_tot = input.Pro_mu ./ params.mort
    B_Chl = B_tot .* Chl_C * 12.0   # Chl concentration,  ug Chl L-1
    # estimate cell density # /10^5 cells ml-1
    CD_tot = 1.0e-5 * 1.0e3 .* B_tot ./ params.Qc   # 1000.0* micromol C L-1 / picomol C cell-1

    # evaluate biomass from simulated autotrophic growth rate and quadratic grazing
    B_auto = mu_auto ./ params.mort
    CD_auto = 1.0e-5 * 1.0e3 .* B_auto ./ params.Qc   # 1000.0* micromol C L-1 / picomol C cell-1

    return (mu_auto = mu_auto, B = B_tot, Chl = B_Chl, mu_C = mu_C, mu_nut = mu_nut, CD_tot = CD_tot, mu_het = mu_het, CD_auto = CD_auto)
end

function output_summary(input, hPARfrac)
    params_HL = generate_params("HL")
    params_LL = generate_params("LL")

    out1 = calc_mu(input, params_HL, hPARfrac = hPARfrac, photo_inhib = true)
    out2 = calc_mu(input, params_HL, hPARfrac = hPARfrac, photo_inhib = false)
    out3 = calc_mu(input, params_LL, hPARfrac = hPARfrac, photo_inhib = true)
    out4 = calc_mu(input, params_LL, hPARfrac = hPARfrac, photo_inhib = false)

    out = (out1, out2, out3, out4)

    nz = length(out1.mu_auto)

    output = zeros(nz, 4, 5)

    for i in 1:4
        output[:,i,1] = out[i].B
        output[:,i,2] = out[i].mu_auto
        output[:,i,3] = out[i].mu_het
        output[:,i,4] = out[i].CD_auto
        output[:,i,5] = out[i].CD_tot
    end

    summ = zeros(nz, 3, 5)

    for i in 1:5
        summ[:,1,i] = mean(output[:,:,i], dims = 2)
        summ[:,2,i] = minimum(output[:,:,i], dims = 2)
        summ[:,3,i] = maximum(output[:,:,i], dims = 2)
    end

    return summ, output
end

nothing


text:
using InfiniteWarpedMixtureModels
using Test

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


text:
module TestDecisionMaking
  using Test

  # target modules
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/markov_decision_process/policy_evaluator.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/markov_decision_process/dynamic_programming.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/markov_decision_process/anime_mdp.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/markov_decision_process/draw_value_heatmap.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/reinforcement_learning/state_info.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/reinforcement_learning/q_learning/anime_q_learning.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/reinforcement_learning/sarsa/sarsa_agent.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/reinforcement_learning/sarsa/anime_sarsa.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/reinforcement_learning/n_step_sarsa/n_step_sarsa_agent.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/reinforcement_learning/n_step_sarsa/anime_n_step_sarsa.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/reinforcement_learning/sarsa_lambda/sarsa_lambda_agent.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/reinforcement_learning/sarsa_lambda/anime_sarsa_lambda.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/partially_observable_mdp/q_mdp_agent.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/partially_observable_mdp/value_heatmap_amdp.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/partially_observable_mdp/pfc_agent.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/partially_observable_mdp/dp_for_pfc.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/partially_observable_mdp/belief_dynamic_programming.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/partially_observable_mdp/anime_amdp.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/partially_observable_mdp/anime_pfc.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/partially_observable_mdp/anime_dp_mcl.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/decision_making/partially_observable_mdp/amdp_policy_agent.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/model/map/map.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/model/goal/goal.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/model/puddle/puddle.jl"))
  include(joinpath(split(@__FILE__, "test")[1], "src/model/robot/warp_robot/warp_robot.jl"))

  function main()
    @testset "PolicyEvaluator" begin
      g = Goal(4.0, 4.0)
      pd = [Puddle([-2.0, 0.0], [0.0, 2.0], 0.1)]
      pe = PolicyEvaluator([0.2, 0.2, pi/18], g, pd, 0.1, 10)
      @test pe.pose_min == [-4.0, -4.0, 0.0]
      @test pe.pose_max == [4.0, 4.0, 2*pi]
      @test pe.widths == [0.2, 0.2, pi/18]
      @test pe.goal == g
      @test pe.delta_time == 0.1
      @test pe.puddle_coef == 100
      @test pe.index_nums == [40, 40, 36]
      nx, ny, nt = pe.index_nums[1], pe.index_nums[2], pe.index_nums[3]
      @test pe.indexes == vec(collect(Base.product(0:nx-1, 0:ny-1, 0:nt-1)))
      @test get_index(pe, [-4.0, -4.0, 0.0]) == [0, 0, 0]
      @test get_index(pe, [4.0, 4.0, 0.0]) == [40, 40, 0]
      @test get_index(pe, [2.9, -2.0, pi]) == [34, 10, 18]
      @test final_state(pe, (40, 40, 37)) == true
      @test final_state(pe, (1, 1, 1)) == false
      @test out_correction(pe, [1, 1, 40]) == [1, 1, 4]
    end
    @testset "DynamicProgramming" begin
      g = Goal(4.0, 4.0)
      pd = [Puddle([-2.0, 0.0], [0.0, 2.0], 0.1)]
      dp = DynamicProgramming([0.2, 0.2, pi/18], g, pd, 0.1, 10)
      @test dp.pose_min == [-4.0, -4.0, 0.0]
      @test dp.pose_max == [4.0, 4.0, 2*pi]
      @test dp.widths == [0.2, 0.2, pi/18]
      @test dp.goal == g
      @test dp.delta_time == 0.1
      @test dp.puddle_coef == 100
      @test dp.index_nums == [40, 40, 36]
      nx, ny, nt = dp.index_nums[1], dp.index_nums[2], dp.index_nums[3]
      @test dp.indexes == vec(collect(Base.product(0:nx-1, 0:ny-1, 0:nt-1)))
      @test get_index(dp, [-4.0, -4.0, 0.0]) == [0, 0, 0]
      @test get_index(dp, [4.0, 4.0, 0.0]) == [40, 40, 0]
      @test get_index(dp, [2.9, -2.0, pi]) == [34, 10, 18]
      @test final_state(dp, (40, 40, 37)) == true
      @test final_state(dp, (1, 1, 1)) == false
      @test out_correction(dp, [1, 1, 40]) == ([1, 1, 4], 0.0)
      @test out_correction(dp, [-1, 1, 40]) == ([0, 1, 4], -1e100)
      @test out_correction(dp, [40, 1, 40]) == ([39, 1, 4], -1e100)
      @test out_correction(dp, [1, -1, 40]) == ([1, 0, 4], -1e100)
      @test out_correction(dp, [1, 40, 40]) == ([1, 39, 4], -1e100)
    end
    @testset "BeliefDynamicProgramming" begin
      g = Goal(4.0, 4.0)
      s = Sensor(Map(), dist_noise_rate=0.1, dir_noise=pi/90)
      pd = [Puddle([-2.0, 0.0], [0.0, 2.0], 0.1)]
      bdp = BeliefDynamicProgramming([0.2, 0.2, pi/18], g, pd, 0.1, 10, s)
      @test bdp.pose_min == [-4.0, -4.0, 0.0]
      @test bdp.pose_max == [4.0, 4.0, 2*pi]
      @test bdp.widths == [0.2, 0.2, pi/18]
      @test bdp.goal == g
      @test bdp.delta_time == 0.1
      @test bdp.puddle_coef == 100
      @test bdp.dev_borders == [0.1, 0.2, 0.4, 0.8]
      @test bdp.dev_borders_side == [0.01, 0.1, 0.2, 0.4, 0.8, 8.0]
      @test bdp.index_nums == [40, 40, 36, 4]
      nx, ny, nt, nh = bdp.index_nums[1], bdp.index_nums[2], bdp.index_nums[3], bdp.index_nums[4]
      @test bdp.indexes == vec(collect(Base.product(0:nx-1, 0:ny-1, 0:nt-1, 0:nh-1)))
      @test get_index(bdp, [-4.0, -4.0, 0.0]) == [0, 0, 0]
      @test get_index(bdp, [4.0, 4.0, 0.0]) == [40, 40, 0]
      @test get_index(bdp, [2.9, -2.0, pi]) == [34, 10, 18]
      @test belief_final_state(bdp, (40, 40, 37)) == true
      @test belief_final_state(bdp, (1, 1, 1)) == false
      @test out_correction(bdp, [1, 1, 40]) == ([1, 1, 4], 0.0)
      @test out_correction(bdp, [-1, 1, 40]) == ([0, 1, 4], -1e100)
      @test out_correction(bdp, [40, 1, 40]) == ([39, 1, 4], -1e100)
      @test out_correction(bdp, [1, -1, 40]) == ([1, 0, 4], -1e100)
      @test out_correction(bdp, [1, 40, 40]) == ([1, 39, 4], -1e100)
    end
    @testset "AnimeMdp" begin
      @test_nowarn AnimeMdp.main(is_test=true)
    end
    @testset "DrawValueHeatmap" begin
      @test_nowarn DrawValueHeatmap.main(true)
    end
    @testset "StateInfo" begin
      si = StateInfo(5)
      @test length(si.q) == 5
      @test si.q == [0.0, 0.0, 0.0, 0.0, 0.0]
      @test si.epsilon == 0.3
      @test greedy(si) == 1
      @test max_q(si) == 0.0
    end
    @testset "AnimeQLearning" begin
      @test_nowarn AnimeQLearning.main(0.1, 10, is_test=true)
    end
    @testset "SarsaAgent" begin
      sa = SarsaAgent()
      @test sa.speed == 0.0
      @test sa.yaw_rate == 0.0
      @test sa.delta_time == 0.1
      @test sa.estimator === nothing
      @test sa.prev_spd == 0.0
      @test sa.prev_yr == 0.0
      @test sa.puddle_coef == 100
      @test sa.puddle_depth == 0.0
      @test sa.total_reward == 0.0
      @test sa.in_goal == false
      @test sa.final_value == 0.0
      @test sa.goal === nothing
      @test sa.pose_min == [-4.0, -4.0, 0.0]
      @test sa.pose_max == [4.0, 4.0, 2*pi]
      @test sa.widths == [0.2, 0.2, pi/18]
      @test sa.index_nums == round.(Int64, (sa.pose_max - sa.pose_min)./sa.widths)
      @test sa.alpha == 0.5
      @test sa.s === nothing
      @test sa.a === nothing
      @test sa.update_end == false
      @test sa.stuck_timer == 0.0
      @test sa.learning_timer == 0.0
      @test reward_per_sec(sa) == -1.0
      @test to_index(sa, [3.0, 3.0, 0.0]) == [35, 35, 0]
      @test to_index(sa, [5.0, 5.0, 0.0]) == [39, 39, 0]
      @test_nowarn draw_decision!(sa, [])
    end
    @testset "AnimeSarsa" begin
      @test_nowarn AnimeSarsa.main(0.1, 10, is_test=true)
    end
    @testset "NstepSarsaAgent" begin
      nsa = NstepSarsaAgent()
      @test nsa.speed == 0.0
      @test nsa.yaw_rate == 0.0
      @test nsa.delta_time == 0.1
      @test nsa.estimator === nothing
      @test nsa.prev_spd == 0.0
      @test nsa.prev_yr == 0.0
      @test nsa.puddle_coef == 100
      @test nsa.puddle_depth == 0.0
      @test nsa.total_reward == 0.0
      @test nsa.in_goal == false
      @test nsa.final_value == 0.0
      @test nsa.goal === nothing
      @test nsa.pose_min == [-4.0, -4.0, 0.0]
      @test nsa.pose_max == [4.0, 4.0, 2*pi]
      @test nsa.widths == [0.2, 0.2, pi/18]
      @test nsa.index_nums == round.(Int64, (nsa.pose_max - nsa.pose_min)./nsa.widths)
      @test nsa.alpha == 0.5
      @test nsa.s === nothing
      @test nsa.a === nothing
      @test nsa.update_end == false
      @test nsa.stuck_timer == 0.0
      @test nsa.learning_timer == 0.0
      @test nsa.s_trace == []
      @test nsa.a_trace == []
      @test nsa.r_trace == []
      @test nsa.n_step == 10
      @test reward_per_sec(nsa) == -1.0
      @test to_index(nsa, [3.0, 3.0, 0.0]) == [35, 35, 0]
      @test to_index(nsa, [5.0, 5.0, 0.0]) == [39, 39, 0]
      @test_nowarn draw_decision!(nsa, [])
    end
    @testset "AnimeNstepSarsa" begin
      @test_nowarn AnimeNstepSarsa.main(0.1, 10, is_test=true)
    end
    @testset "SarsaLambdaAgent" begin
      sla = SarsaLambdaAgent()
      @test sla.speed == 0.0
      @test sla.yaw_rate == 0.0
      @test sla.delta_time == 0.1
      @test sla.estimator === nothing
      @test sla.prev_spd == 0.0
      @test sla.prev_yr == 0.0
      @test sla.puddle_coef == 100
      @test sla.puddle_depth == 0.0
      @test sla.total_reward == 0.0
      @test sla.in_goal == false
      @test sla.final_value == 0.0
      @test sla.goal === nothing
      @test sla.pose_min == [-4.0, -4.0, 0.0]
      @test sla.pose_max == [4.0, 4.0, 2*pi]
      @test sla.widths == [0.2, 0.2, pi/18]
      @test sla.index_nums == round.(Int64, (sla.pose_max - sla.pose_min)./sla.widths)
      @test sla.alpha == 0.5
      @test sla.s === nothing
      @test sla.a === nothing
      @test sla.update_end == false
      @test sla.stuck_timer == 0.0
      @test sla.learning_timer == 0.0
      @test sla.s_trace == []
      @test sla.a_trace == []
      @test sla.lmd == 0.9
      @test reward_per_sec(sla) == -1.0
      @test to_index(sla, [3.0, 3.0, 0.0]) == [35, 35, 0]
      @test to_index(sla, [5.0, 5.0, 0.0]) == [39, 39, 0]
      @test_nowarn draw_decision!(sla, [])
    end
    @testset "AnimeSarsaLambda" begin
      @test_nowarn AnimeSarsaLambda.main(0.1, 10, is_test=true)
    end
    @testset "ValueHeatmapAmdp" begin
      @test_nowarn ValueHeatmapAmdp.main(true)
    end
    @testset "DpForPfc" begin
      @test_nowarn DpForPfc.main(true)
    end
    @testset "QmdpAgent" begin
      g = Goal(4.0, 4.0)
      ps = [Puddle([-2.0, 0.0], [0.0, 2.0], 0.1)]
      qma = QmdpAgent(goal=g, puddles=ps)
      @test qma.speed == 0.0
      @test qma.yaw_rate == 0.0
      @test qma.delta_time == 0.1
      @test qma.estimator === nothing
      @test qma.prev_spd == 0.0
      @test qma.prev_yr == 0.0
      @test qma.puddle_coef == 100
      @test qma.puddle_depth == 0.0
      @test qma.total_reward == 0.0
      @test qma.in_goal == false
      @test qma.final_value == 0.0
      @test qma.goal == g
      @test qma.pose_min == [-4.0, -4.0, 0.0]
      @test qma.pose_max == [4.0, 4.0, 2*pi]
      @test qma.widths == [0.2, 0.2, pi/18]
      @test qma.index_nums == round.(Int64, (qma.pose_max - qma.pose_min)./qma.widths)
      @test qma.evaluations == [0.0, 0.0, 0.0]
      @test qma.current_value == 0.0
      @test qma.stop_timer == 0.0
      @test reward_per_sec(qma) == -1.0
      @test to_index(qma, [3.0, 3.0, 0.0]) == [35, 35, 0]
      @test to_index(qma, [5.0, 5.0, 0.0]) == [39, 39, 0]
      @test_nowarn draw_decision!(qma, [])
    end
    @testset "PfcAgent" begin
      g = Goal(4.0, 4.0)
      ps = [Puddle([-2.0, 0.0], [0.0, 2.0], 0.1)]
      pfc = PfcAgent(goal=g, puddles=ps)
      @test pfc.speed == 0.0
      @test pfc.yaw_rate == 0.0
      @test pfc.delta_time == 0.1
      @test pfc.estimator === nothing
      @test pfc.prev_spd == 0.0
      @test pfc.prev_yr == 0.0
      @test pfc.puddle_coef == 100
      @test pfc.puddle_depth == 0.0
      @test pfc.total_reward == 0.0
      @test pfc.in_goal == false
      @test pfc.final_value == 0.0
      @test pfc.goal == g
      @test pfc.pose_min == [-4.0, -4.0, 0.0]
      @test pfc.pose_max == [4.0, 4.0, 2*pi]
      @test pfc.widths == [0.2, 0.2, pi/18]
      @test pfc.index_nums == round.(Int64, (pfc.pose_max - pfc.pose_min)./pfc.widths)
      @test pfc.evaluations == [0.0, 0.0, 0.0]
      @test pfc.current_value == 0.0
      @test pfc.stop_timer == 0.0
      @test pfc.magnitude == 2
      @test reward_per_sec(pfc) == -1.0
      @test to_index(pfc, [3.0, 3.0, 0.0]) == [35, 35, 0]
      @test to_index(pfc, [5.0, 5.0, 0.0]) == [39, 39, 0]
      @test_nowarn draw_decision!(pfc, [])
    end
    @testset "AmdpPolicyAgent" begin
      apa = AmdpPolicyAgent()
      @test apa.speed == 0.0
      @test apa.yaw_rate == 0.0
      @test apa.delta_time == 0.1
      @test apa.estimator === nothing
      @test apa.prev_spd == 0.0
      @test apa.prev_yr == 0.0
      @test apa.puddle_coef == 100
      @test apa.puddle_depth == 0.0
      @test apa.total_reward == 0.0
      @test apa.in_goal == false
      @test apa.final_value == 0.0
      @test apa.goal === nothing
      @test apa.pose_min == [-4.0, -4.0, 0.0]
      @test apa.pose_max == [4.0, 4.0, 2*pi]
      @test apa.widths == [0.2, 0.2, pi/18]
      @test apa.index_nums == [40, 40, 36, 4]
      @test apa.dev_borders == [0.1, 0.2, 0.4, 0.8]
      @test apa.stop_timer == 0.0
      @test reward_per_sec(apa) == -1.0
      @test to_index(apa, [3.0, 3.0, 0.0]) == [35, 35, 0]
      @test to_index(apa, [5.0, 5.0, 0.0]) == [39, 39, 0]
      @test_nowarn draw_decision!(apa, [])
    end
    @testset "AnimeAmdp" begin
      @test_nowarn AnimeAmdp.main(0.1, 10, is_test=true)
    end
    @testset "AnimeDpMcl" begin
      @test_nowarn AnimeDpMcl.main(0.1, 10, is_test=true)
    end
    @testset "AnimePfc" begin
      @test_nowarn AnimePfc.main(0.1, 10, is_test=true)
    end
  end
end

max_stars_repo_name: ShisatoYano/JuliaAutonomy

max_issues_repo_name: ShisatoYano/JuliaAutonomy

max_forks_repo_name: ShisatoYano/JuliaAutonomy