text:
"""
    vgg_block(ifilters, ofilters, depth, batchnorm)

A VGG block of convolution layers
([reference](https://arxiv.org/abs/1409.1556v6)).

# Arguments
- `ifilters`: number of input feature maps
- `ofilters`: number of output feature maps
- `depth`: number of convolution/convolution + batch norm layers
- `batchnorm`: set to `true` to include batch normalization after each convolution
"""
function vgg_block(ifilters, ofilters, depth, batchnorm)
  k = (3,3)
  p = (1,1)
  layers = []
  for _ in 1:depth
    if batchnorm
      append!(layers, conv_bn(k, ifilters, ofilters; pad = p, bias = false))
    else
      push!(layers, Conv(k, ifilters => ofilters, relu, pad = p))
    end
    ifilters = ofilters
  end
  return layers
end

"""
    vgg_convolutional_layers(config, batchnorm, inchannels)

Create VGG convolution layers
([reference](https://arxiv.org/abs/1409.1556v6)).

# Arguments
- `config`: vector of tuples `(output_channels, num_convolutions)`
            for each block (see [`Metalhead.vgg_block`](#))
- `batchnorm`: set to `true` to include batch normalization after each convolution
- `inchannels`: number of input channels
"""
function vgg_convolutional_layers(config, batchnorm, inchannels)
  layers = []
  ifilters = inchannels
  for c in config
    append!(layers, vgg_block(ifilters, c..., batchnorm))
    push!(layers, MaxPool((2,2)))
    ifilters, _ = c
  end
  return layers
end

"""
    vgg_classifier_layers(imsize, nclasses, fcsize, dropout)

Create VGG classifier (fully connected) layers
([reference](https://arxiv.org/abs/1409.1556v6)).

# Arguments
- `imsize`: tuple `(width, height, channels)` indicating the size after
            the convolution layers (see [`Metalhead.vgg_convolutional_layers`](#))
- `nclasses`: number of output classes
- `fcsize`: input and output size of the intermediate fully connected layer
- `dropout`: the dropout level between each fully connected layer
"""
function vgg_classifier_layers(imsize, nclasses, fcsize, dropout)
  layers = []
  push!(layers, flatten)
  push!(layers, Dense(Int(prod(imsize)), fcsize, relu))
  push!(layers, Dropout(dropout))
  push!(layers, Dense(fcsize, fcsize, relu))
  push!(layers, Dropout(dropout))
  push!(layers, Dense(fcsize, nclasses))

  return layers
end

"""
    vgg(imsize; config, inchannels, batchnorm = false, nclasses, fcsize, dropout)

Create a VGG model
([reference](https://arxiv.org/abs/1409.1556v6)).

# Arguments
- `imsize`: input image width and height as a tuple
- `config`: the configuration for the convolution layers
            (see [`Metalhead.vgg_convolutional_layers`](#))
- `inchannels`: number of input channels
- `batchnorm`: set to `true` to use batch normalization after each convolution
- `nclasses`: number of output classes
- `fcsize`: intermediate fully connected layer size
            (see [`Metalhead.vgg_classifier_layers`](#))
- `dropout`: dropout level between fully connected layers
"""
function vgg(imsize; config, inchannels, batchnorm = false, nclasses, fcsize, dropout)
  conv = vgg_convolutional_layers(config, batchnorm, inchannels)
  imsize = outputsize(conv, (imsize..., inchannels); padbatch = true)[1:3]
  class = vgg_classifier_layers(imsize, nclasses, fcsize, dropout)
  return Chain(Chain(conv...), Chain(class...))
end

const vgg_config = Dict(:A => [(64,1), (128,1), (256,2), (512,2), (512,2)],
                        :B => [(64,2), (128,2), (256,2), (512,2), (512,2)],
                        :D => [(64,2), (128,2), (256,3), (512,3), (512,3)],
                        :E => [(64,2), (128,2), (256,4), (512,4), (512,4)])

"""
    VGG(imsize = (224, 224); config, inchannels, batchnorm = false, nclasses, fcsize, dropout)

Create a `VGG` model
([reference](https://arxiv.org/abs/1409.1556v6)).
See also [`vgg`](#).

# Arguments
- `imsize`: input image width and height as a tuple
- `config`: the configuration for the convolution layers
            (see [`Metalhead.vgg_convolutional_layers`](#))
- `inchannels`: number of input channels
- `batchnorm`: set to `true` to use batch normalization after each convolution
- `nclasses`: number of output classes
- `fcsize`: intermediate fully connected layer size
            (see [`Metalhead.vgg_classifier_layers`](#))
- `dropout`: dropout level between fully connected layers
"""
struct VGG
  layers
end

function VGG(imsize::NTuple{2, <:Integer} = (224, 224);
             config, inchannels, batchnorm = false, nclasses, fcsize, dropout)
  layers = vgg(imsize; config = config,
                        inchannels = inchannels,
                        batchnorm = batchnorm,
                        nclasses = nclasses,
                        fcsize = fcsize,
                        dropout = dropout)

  VGG(layers)
end

@functor VGG

(m::VGG)(x) = m.layers(x)

backbone(m::VGG) = m.layers[1]
classifier(m::VGG) = m.layers[2]

"""
    VGG11(; pretrain = false, batchnorm = false)

Create a VGG-11 style model
([reference](https://arxiv.org/abs/1409.1556v6)).
See also [`VGG`](#).

!!! warning
    `VGG11` does not currently support pretrained weights.

# Arguments
- `pretrain`: set to `true` to load pre-trained model weights for ImageNet
"""
function VGG11(; pretrain = false, batchnorm = false)
  model = VGG((224, 224); config = vgg_config[:A],
                          inchannels = 3,
                          batchnorm = batchnorm,
                          nclasses = 1000,
                          fcsize = 4096,
                          dropout = 0.5)

  if pretrain && !batchnorm
    loadpretrain!(model, "VGG11")
  elseif pretrain
    loadpretrain!(model, "VGG11-BN)")
  end
  return model
end

"""
    VGG13(; pretrain = false, batchnorm = false)

Create a VGG-11 style model
([reference](https://arxiv.org/abs/1409.1556v6)).
See also [`VGG`](#).

!!! warning
    `VGG13` does not currently support pretrained weights.

# Arguments
- `pretrain`: set to `true` to load pre-trained model weights for ImageNet
"""
function VGG13(; pretrain = false, batchnorm = false)
  model = VGG((224, 224); config = vgg_config[:B],
                          inchannels = 3,
                          batchnorm = batchnorm,
                          nclasses = 1000,
                          fcsize = 4096,
                          dropout = 0.5)

  if pretrain && !batchnorm
    loadpretrain!(model, "VGG13")
  elseif pretrain
    loadpretrain!(model, "VGG13-BN)")
  end
  return model
end

"""
    VGG16(; pretrain = false, batchnorm = false)

Create a VGG-11 style model
([reference](https://arxiv.org/abs/1409.1556v6)).
See also [`VGG`](#).

!!! warning
    `VGG16` does not currently support pretrained weights.

# Arguments
- `pretrain`: set to `true` to load pre-trained model weights for ImageNet
"""
function VGG16(; pretrain = false, batchnorm = false)
  model = VGG((224, 224); config = vgg_config[:D],
                          inchannels = 3,
                          batchnorm = batchnorm,
                          nclasses = 1000,
                          fcsize = 4096,
                          dropout = 0.5)

  if pretrain && !batchnorm
    loadpretrain!(model, "VGG16")
  elseif pretrain
    loadpretrain!(model, "VGG16-BN)")
  end
  return model
end

"""
    VGG19(; pretrain = false, batchnorm = false)

Create a VGG-11 style model
([reference](https://arxiv.org/abs/1409.1556v6)).
See also [`VGG`](#).

!!! warning
    `VGG19` does not currently support pretrained weights.

# Arguments
- `pretrain`: set to `true` to load pre-trained model weights for ImageNet
"""
function VGG19(; pretrain = false, batchnorm = false)
  model = VGG((224, 224); config = vgg_config[:E],
                          inchannels = 3,
                          batchnorm = batchnorm,
                          nclasses = 1000,
                          fcsize = 4096,
                          dropout = 0.5)

  if pretrain && !batchnorm
    loadpretrain!(model, "VGG19")
  elseif pretrain
    loadpretrain!(model, "VGG19-BN)")
  end
  return model
end


text:
#=
   This is a copy of `@forward` and `isexpr` from `Lazy.jl` (Mike Innes)
   here it is renamed `@usefield` to avoid clashing with `Lazy.jl`
   <https://github.com/MikeInnes/Lazy.jl/blob/master/src/macros.jl>
=#

"""
    @usefield T.x functions...

Define methods for `functions` on type `T`,
which call the relevant function on the field `x`.

# Example
```julia
struct Wrapper
    x
end
@usefield Wrapper.x  Base.sqrt                                  # now sqrt(Wrapper(4.0)) == 2.0
@usefield Wrapper.x  Base.length, Base.getindex, Base.iterate   # several forwarded functions are put in a tuple
@usefield Wrapper.x (Base.length, Base.getindex, Base.iterate)  # equivalent to above
```
"""
macro usefield(ex, fs)
  @capture(ex, T_.field_) || error("Syntax: @forward T.x f, g, h")
  T = esc(T)
  fs = isexpr(fs, :tuple) ? map(esc, fs.args) : [esc(fs)]
  :($([:($f(x::$T, args...; kwargs...) = (Base.@_inline_meta; $f(x.$field, args...; kwargs...)))
       for f in fs]...);
    nothing)
end

"""
    isexpr(x, ts...)

Convenient way to test the type of a Julia expression.
Expression heads and types are supported, so for example
you can call
    isexpr(expr, String, :string)
to pick up on all string-like expressions.
"""
isexpr(x::Expr) = true
isexpr(x) = false
isexpr(x::Expr, ts...) = x.head in ts
isexpr(x, ts...) = any(T->isa(T, Type) && isa(x, T), ts)

ext: jl


text:
using TcpInstruments
using Test

w = write
q = query

wg = initialize(Keysight33612A)
@info "Successfully connected $(wg.model) at $(wg.address)"

@info get_output(wg)
enable_output(wg)
@test get_output(wg) == true
disable_output(wg)
@test get_output(wg) == false

write(wg, "SOURce1:APPLy:SIN MAX")
"""
initialize() X
terminate() X
enable_output() X
disable_output() X
get_output() X
{set,get}_frequency() X
{set,get}_amplitude() X
{set,get}_burst_num_cycles() X
{set,get}_time_offset()
{set,get}_voltage_offset() X
{set,get}_burst_period() X
set_mode_burst() X
set_mode_cw() X

get_mode() X
"""

"""
FUNCtion SIN
FREQ 1e4
VOLT 1
VOLT:OFF 0.1
OUTP ON
"""

@info get_function(wg)
set_function(wg, "SIN")
@info get_function(wg)

@info get_frequency(wg)
set_frequency(wg, "1e3")
@info get_frequency(wg)

@info get_amplitude(wg)
set_amplitude(wg, 0.1)
@info get_amplitude(wg)
@info typeof(get_amplitude(wg))

@info get_voltage_offset(wg)
set_voltage_offset(wg, 0)
@info get_voltage_offset(wg)
enable_output(wg)

"""
@info get_burst_mode(wg)
@info get_mode(wg)
set_burst_mode_gated(wg)
@info get_burst_mode(wg)
@info get_mode(wg)
set_mode_burst(wg)
@info get_burst_mode(wg)
@info get_mode(wg)
set_burst_mode_gated(wg)
@info get_burst_mode(wg)
@info get_mode(wg)
"""

set_mode_cw(wg)
w(wg, "TRIGger1:SOURce TIMer")
set_mode_burst(wg)
set_mode_cw(wg)
set_function(wg, "SQU")
enable_output(wg)

@info get_function(wg; chan=2)
set_function(wg, "SIN"; chan=2)
@info get_function(wg; chan=2)

@info get_frequency(wg; chan=2)
set_frequency(wg, "1e3"; chan=2)
@info get_frequency(wg; chan=2)

@info get_amplitude(wg; chan=2)
set_amplitude(wg, 0.1)
@info get_amplitude(wg)
@info typeof(get_amplitude(wg))

@info get_voltage_offset(wg)
set_voltage_offset(wg, 0)
@info get_voltage_offset(wg)
enable_output(wg)

#@info q(wg, "CHAN?"), "SOURCE"
terminate(wg)
@info "Thanks"


text:
using Revise #src
Pkg.activate(".") #src
##
import Literate
##
path=pwd()
outputdir=path*"/docs/src"

exmpls=[("00_NLEVP",false),
        ("01_rijke_tube",false),
        ("02_global_eigenvalue_solver",false),
        ("03_local_eigenvalue_solver",false),
        ("04_perturbation_theory",true),
        ("05_mesh_refinement",false),
        ("06_second_order_elements",false)]

cd("./examples/tutorials")
for (exmp,exec) in exmpls
    Literate.markdown("./tutorial_$exmp.jl",outputdir,execute=true)
    #Literate.notebook("./tutorial_$exmp.jl",outputdir)
    #Literate.script("./tutorial_$exmp.jl",outputdir,keep_comments=true)
end

cd(path)


text:
function get_indiv(paramset::Int)::Vector{Float64}
    best_generation::Int64 = readdlm(
        "./fitparam/$paramset/generation.dat"
    )[1,1]
    best_indiv::Vector{Float64} = readdlm(
        @sprintf(
            "./fitparam/%d/fit_param%d.dat",
            paramset, best_generation
        )
    )[:,1]

    return best_indiv
end

function load_param(paramset::Int)::Tuple{Array{Float64,1},Array{Float64,1}}
    best_indiv::Vector{Float64} = get_indiv(paramset)
    (p,u0) = update_param(best_indiv)

    return p, u0
end

function get_executable()
    n_file::Vector{Int} = []
    fitparam_files::Vector{String} = readdir("./fitparam")
    for file in fitparam_files
        if occursin(r"\d",file)
            push!(n_file, parse(Int64,file))
        end
    end
    empty_folder::Vector{Int} = []
    for (i,nth_param_set) in enumerate(n_file)
        if !isfile("./fitparam/$nth_param_set/generation.dat")
            push!(empty_folder,i)
        end
    end
    for i in sort(empty_folder,rev=true)
        deleteat!(n_file,i)
    end

    return n_file
end

function validate(nth_param_set::Int64)

    (p,u0) = load_param(nth_param_set)

    if Sim.simulate!(p,u0) isa Nothing
        return Sim, true
    else
        print(
            "Simulation failed. #$nth_param_set\n"
        )
        return Sim, false
    end

    return Sim
end

function write_best_fit_param(best_param_set::Int)
    (p,u0) = load_param(best_param_set)

    open("best_fit_param.txt","w") do f
        write(
            f,@sprintf(
                "# param set: %d\n",best_param_set
            )
        )
        write(
            f,"\n### Param const\n"
        )
        for (i,param) in enumerate(C.NAMES)
            write(
                f,@sprintf(
                    "p[C.%s] = %e\n", param, p[i]
                )
            )
        end
        write(
            f,"\n### Non-zero initial conditions\n"
        )
        for (i,specie) in enumerate(V.NAMES)
            if u0[i] != 0.0
                write(
                    f,@sprintf(
                        "u0[V.%s] = %e\n", specie, u0[i]
                    )
                )
            end
        end
    end
end

function save_param_range(n_file::Vector{Int})
    search_idx::Tuple{Array{Int64,1},Array{Int64,1}} = get_search_index()
    popt::Matrix{Float64} = zeros(length(n_file),length(search_idx[1]))
    for (i,nth_param_set) in enumerate(n_file)
        best_indiv = get_indiv(nth_param_set)
        popt[i,:] = best_indiv[1:length(search_idx[1])]
    end
    # --------------------------------------------------------------------------
    # Seaborn.boxplot

    fig = figure(figsize=(8,length(search_idx[1])/2.5))
    # rcParams
    rc("font",family = "Arial")
    rc("font",size = 12)
    rc("axes",linewidth = 1)
    # sns.despine
    gca().spines["right"].set_visible(false)
    gca().spines["top"].set_visible(false)
    gca().yaxis.set_ticks_position("left")
    gca().xaxis.set_ticks_position("bottom")

    ax = Seaborn.boxplot(
        data=popt,
        orient="h",
        linewidth=1,
        palette="Set2"
    )

    ax.set_xlabel("Parameter value")
    ax.set_ylabel("")
    ax.set_yticklabels([C.NAMES[i] for i in search_idx[1]])
    ax.set_xscale("log")

    savefig("./figure/param_range.pdf",bbox_inches="tight")
    close(fig)
end

function simulate_all(
        Sim::Module=Sim;
        viz_type::String,
        show_all::Bool,
        stdev::Bool)
    if !isdir("./figure")
        mkdir("./figure")
    end

    if !(viz_type in ["best","average","original","experiment"])
        try
            parse(Int64,viz_type)
        catch
            error(
                "Avairable viz_type are: 'best','average','original','experiment','n(=1,2,...)'"
            )
        end
    end

    n_file::Vector{Int} = viz_type in ["original", "experiment"] ? [] : get_executable()

    simulaitons_all::Array{Float64,4} = fill(
        NaN,(length(observables),length(n_file),length(Sim.t),length(Sim.conditions))
    )
    if viz_type != "experiment"
        if length(n_file) > 0
            if length(n_file) == 1 && viz_type == "average"
                error("viz_type should be best, not $viz_type")
                # viz_type = "best"
            end
            for (i,nth_param_set) in enumerate(n_file)
                (Sim,is_successful) = validate(nth_param_set)
                if is_successful
                    for j in eachindex(observables)
                        @inbounds simulaitons_all[j,i,:,:] = Sim.simulations[j,:,:]
                    end
                end
            end

            best_fitness_all::Vector{Float64} = fill(Inf,length(n_file))
            for (i,nth_param_set) in enumerate(n_file)
                if isfile("./fitparam/$nth_param_set/best_fitness.dat")
                    best_fitness_all[i] = readdlm(
                        "./fitparam/$nth_param_set/best_fitness.dat"
                    )[1,1]
                end
            end
            best_param_set::Int = n_file[argmin(best_fitness_all)]
            write_best_fit_param(best_param_set)

            if viz_type == "best"
                Sim,_ = validate(best_param_set)
            elseif viz_type != "average" && parse(Int64,viz_type) <= length(n_file)
                Sim,_ = validate(parse(Int64,viz_type))
            elseif viz_type != "average" && parse(Int64,viz_type) > length(n_file)
                error(
                    @sprintf(
                        "n (%d) must be smaller than n_fitparam (%d)",
                        parse(Int64,viz_type), length(n_file)
                    )
                )
            end

            if length(n_file) > 1
                save_param_range(n_file)
            end
        else
            p::Vector{Float64} = param_values()
            u0::Vector{Float64} = initial_values()
            if Sim.simulate!(p,u0) !== nothing
                error(
                    "Simulation failed."
                )
            end
        end
    end
    plotFunc_timecourse(
        Sim,n_file,viz_type,show_all,stdev,simulaitons_all
    )
end


text:
"""
    Base.copy(m::StandardModel)

Shallow copy of a [`StandardModel`](@ref)
"""
Base.copy(m::StandardModel) = StandardModel(
    m.id,
    reactions = m.reactions,
    metabolites = m.metabolites,
    genes = m.genes,
)

"""
    Base.copy(r::Reaction)

Shallow copy of a [`Reaction`](@ref)
"""
Base.copy(r::Reaction) = Reaction(
    r.id;
    metabolites = r.metabolites,
    lb = r.lb,
    ub = r.ub,
    grr = r.grr,
    subsystem = r.subsystem,
    notes = r.notes,
    annotations = r.annotations,
    objective_coefficient = r.objective_coefficient,
)

"""
    Base.copy(m::Metabolite)

Shallow copy of a [`Metabolite`](@ref)
"""
Base.copy(m::Metabolite) = Metabolite(
    m.id;
    formula = m.formula,
    charge = m.charge,
    compartment = m.compartment,
    notes = m.notes,
    annotations = m.annotations,
)

"""
    Base.copy(g::Gene)

Shallow copy of a [`Gene`](@ref)
"""
Base.copy(g::Gene) = Gene(g.id; notes = g.notes, annotations = g.annotations)


text:
# ## BioModel9d

# ## Model

module biomodel9d   #jl

using ReachabilityAnalysis

@taylorize function biomodel9d!(dx, x, p, t)
    dx[1] = 3.0*x[3] - x[1]*x[6]
    dx[2] = x[4] - x[2]*x[6]
    dx[3] = x[1]*x[6] - 3.0*x[3]
    dx[4] = x[2]*x[6] - x[4]
    dx[5] = 3.0*x[3] + 5.0*x[1] - x[5]
    dx[6] = 5.0*x[5] + 3.0*x[3] + x[4] - x[6]*(x[1]+x[2]+2.0*x[8]+1.0)
    dx[7] = 5.0*x[4] + x[2] - 0.5*x[7]
    dx[8] = 5.0*x[7] - 2.0*x[6]*x[8] + x[9] - 0.2*x[8]
    dx[9] = 2.0*x[6]*x[8] - x[9]
    return dx
end

function model(X0)
    S = @system(x' = biomodel9d!(x), dim:9)
    return IVP(S, X0)
end

end #jl

# ## References

max_stars_repo_name: mforets/ReachabilityLibrary

max_issues_repo_name: mforets/ReachabilityLibrary

max_forks_repo_name: mforets/ReachabilityLibrary


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

mutable struct IoK8sApiAutoscalingV2beta1PodsMetricSource <: SwaggerModel
    metricName::Any # spec type: Union{ Nothing, String } # spec name: metricName
    selector::Any # spec type: Union{ Nothing, IoK8sApimachineryPkgApisMetaV1LabelSelector } # spec name: selector
    targetAverageValue::Any # spec type: Union{ Nothing, IoK8sApimachineryPkgApiResourceQuantity } # spec name: targetAverageValue

    function IoK8sApiAutoscalingV2beta1PodsMetricSource(;metricName=nothing, selector=nothing, targetAverageValue=nothing)
        o = new()
        validate_property(IoK8sApiAutoscalingV2beta1PodsMetricSource, Symbol("metricName"), metricName)
        setfield!(o, Symbol("metricName"), metricName)
        validate_property(IoK8sApiAutoscalingV2beta1PodsMetricSource, Symbol("selector"), selector)
        setfield!(o, Symbol("selector"), selector)
        validate_property(IoK8sApiAutoscalingV2beta1PodsMetricSource, Symbol("targetAverageValue"), targetAverageValue)
        setfield!(o, Symbol("targetAverageValue"), targetAverageValue)
        o
    end
end # type IoK8sApiAutoscalingV2beta1PodsMetricSource

const _property_map_IoK8sApiAutoscalingV2beta1PodsMetricSource = Dict{Symbol,Symbol}(Symbol("metricName")=>Symbol("metricName"), Symbol("selector")=>Symbol("selector"), Symbol("targetAverageValue")=>Symbol("targetAverageValue"))
const _property_types_IoK8sApiAutoscalingV2beta1PodsMetricSource = Dict{Symbol,String}(Symbol("metricName")=>"String", Symbol("selector")=>"IoK8sApimachineryPkgApisMetaV1LabelSelector", Symbol("targetAverageValue")=>"IoK8sApimachineryPkgApiResourceQuantity")
Base.propertynames(::Type{ IoK8sApiAutoscalingV2beta1PodsMetricSource }) = collect(keys(_property_map_IoK8sApiAutoscalingV2beta1PodsMetricSource))
Swagger.property_type(::Type{ IoK8sApiAutoscalingV2beta1PodsMetricSource }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_IoK8sApiAutoscalingV2beta1PodsMetricSource[name]))}
Swagger.field_name(::Type{ IoK8sApiAutoscalingV2beta1PodsMetricSource }, property_name::Symbol) =  _property_map_IoK8sApiAutoscalingV2beta1PodsMetricSource[property_name]

function check_required(o::IoK8sApiAutoscalingV2beta1PodsMetricSource)
    (getproperty(o, Symbol("metricName")) === nothing) && (return false)
    (getproperty(o, Symbol("targetAverageValue")) === nothing) && (return false)
    true
end

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