text:
using PyPlot, ParticleScattering
import Optim, JLD

output_dir = homedir()
er = 4.5
k0 = 2π
l0 = 2π/k0
a_lens = 0.2*l0
R_lens = 10*a_lens

kin = k0*sqrt(er)
N_cells = Int(round(2*R_lens/a_lens))
centers, ids_lnbrg, rs_lnbrg = luneburg_grid(R_lens, N_cells, er)
φs = zeros(Float64, length(ids_lnbrg))
pw = PlaneWave(0.0)
P = 5

fmm_options = FMMoptions(true, acc = 6, dx = 2*a_lens, method = "pre")

optim_options =  Optim.Options(x_tol = 1e-6, outer_x_tol = 1e-6,
                        iterations = 100, outer_iterations = 100,
                        store_trace = true, extended_trace = true,
                        show_trace = false, allow_f_increases = true)

points = [R_lens 0.0]
r_max = (a_lens/1.15/2)*ones(size(centers,1))
r_min = (a_lens*1e-3)*ones(size(centers,1))
rs0 = (0.25*a_lens)*ones(size(centers,1))

ids_max = collect(1:length(rs0))
test_max = optimize_radius(rs0, r_min, r_max, points, ids_max, P, pw, k0, kin, #precompile
                centers, fmm_options, optim_options, minimize = false)
optim_time = @elapsed begin
    test_max = optimize_radius(rs0, r_min, r_max, points, ids_max, P, pw, k0, kin,
                centers, fmm_options, optim_options, minimize = false)
end
rs_max = test_max.minimizer

# plot near fields
border = (R_lens + a_lens)*[-1;1;-1;1]

sp1 = ScatteringProblem([CircleParams(rs_lnbrg[i]) for i in eachindex(rs_lnbrg)],
        ids_lnbrg, centers, φs)
Ez1 = plot_near_field(k0, kin, P, sp1, pw, x_points = 300, y_points = 300,
        opt = fmm_options, border = border)

sp2 = ScatteringProblem([CircleParams(rs_max[i]) for i in eachindex(rs_max)],
        ids_max, centers, φs)
Ez2 = plot_near_field(k0, kin, P, sp2, pw, x_points = 300, y_points = 300,
            opt = fmm_options, border = border)

sp3 = ScatteringProblem([CircleParams(rs0[i]) for i in eachindex(rs0)],
        collect(1:length(rs0)), centers, φs)
Ez3 = plot_near_field(k0, kin, P, sp3, pw, x_points = 300, y_points = 300,
        opt = fmm_options, border = border)

#plot convergence
inner_iters = length(test_max.trace)
iters = [test_max.trace[i].iteration for i=1:inner_iters]
fobj = -[test_max.trace[i].value for i=1:inner_iters]
gobj = [test_max.trace[i].g_norm for i=1:inner_iters]
rng = iters .== 0

trace_of_r = [test_max.trace[i].metadata["x"] for i=1:inner_iters]
JLD.@save(joinpath(output_dir, "luneburg_optim.jld"), sp1, sp2, sp3,Ez1, Ez2, Ez3,
        inner_iters, iters, fobj, gobj, rng, optim_time, rs_max, border)

figure()
plot(0:inner_iters-1, fobj, "b", label="\$f_{\\mathrm{obj}}\$")
plot(0:inner_iters-1, log10.(gobj), "r--", label="\$\\Vert \\mathbf{g}_{\\mathrm{obj}}\\Vert_{\\infty}\$")
plot((0:inner_iters-1)[rng], fobj[rng],"bo")
plot((0:inner_iters-1)[rng], gobj[rng],"r^")
xlabel("Iterations")
legend(loc="best")

################ Testing with symmetry ######################
@assert length(ids_max)==size(centers,1)
centers_abs = centers[:,1] + 1im*abs.(centers[:,2])
ids_sym, centers_abs = ParticleScattering.uniqueind(centers_abs)
J = length(centers_abs)
r_max = (a_lens/1.15/2)*ones(J)
r_min = (a_lens*1e-3)*ones(J)
rs0 = (0.25*a_lens)*ones(J)

sym_time = @elapsed begin
    test_max_sym = optimize_radius(rs0, r_min, r_max, points, ids_sym, P, pw, k0, kin,
                centers, fmm_options, optim_options, minimize = false)
end
JLD.@save joinpath(output_dir, "luneburg_optim_sym.jld") test_max_sym sym_time

rs_sym = test_max_sym.minimizer
sp4 = ScatteringProblem([CircleParams(rs_sym[i]) for i in eachindex(rs_sym)],
        ids_sym, centers, φs)
Ez4 = plot_near_field(k0, kin, P, sp4, pw, x_points = 300, y_points = 300,
        opt = fmm_options, border = border, method = "recurrence")

u1 = calc_near_field(k0, kin, 7, sp1, points, pw; opt = fmm_options)
u2 = calc_near_field(k0, kin, 7, sp2, points, pw; opt = fmm_options)
u3 = calc_near_field(k0, kin, 7, sp3, points, pw; opt = fmm_options)
u4 = calc_near_field(k0, kin, 7, sp4, points, pw; opt = fmm_options)
abs.([u1[1];u2[1];u3[1];u4[1]])


text:
function calculate_propensity!(c::Cell, propRules::Vector{Function}, indice::Array{Int})
    for i in indice
        c.A[i] = (propRules[i](c))
    end
end

function initialize_propensities!(model::Model)
    for cell in model.cells
    # Calculate the propensity function, ak, for each reaction.
        calculate_propensity!(cell, model.propRules, collect(1:34))
        # Generate M independent, uniform (0,1) random numbers, rk, and for each k set Pk=ln1/rk.
        for i in 1:34
            cell.Pk[i] = log(1/rand())
            delT = cell.A[i] > 0 ? (cell.Pk[i]-cell.Tk[i])/cell.A[i] : Inf
            enqueue!(cell.pq, i, delT)
        end
    end
end

function min_delayed(cell::Cell, t::Float64)
    min = Inf
    sk = 0
    for i in 1:8
        if (first(cell.pq_delayed[i])-t) < min
            min = first(cell.pq_delayed[i])-t
            sk = i
        end
    end
    return (sk, min)
end

function jump(cell::Cell, t::Float64)
    sk, min = min_delayed(cell, t)
    if sk != 0
        reg = isless(peek(cell.pq)[2], min)
        dt = reg ? peek(cell.pq)[2] : min
        event = reg ? dequeue!(cell.pq) : sk + 34
        if !(reg)
            deleteat!(cell.pq_delayed[sk],1)
            cell.pos[sk] -= 1
        end
    else
        dt = peek(cell.pq)[2]
        event = dequeue!(cell.pq)
    end
    return (dt, event)
end

function update_tjump!(cell::Cell)
    for i in 1:34
        cell.pq[i] = cell.A[i] > 0 ? (cell.Pk[i]-cell.Tk[i])/cell.A[i] : Inf
    end
end

function update_tk!(cell::Cell,dt::Float64)
    for i in 1:34
        cell.Tk[i] += cell.A[i]*dt
    end
end

ext: jl

max_stars_repo_name: syedtaz/project-cait

max_issues_repo_name: syedtaz/project-cait

max_forks_repo_name: syedtaz/project-cait


text:
using MLDatasets, StatsBase, Measures, Plots; pyplot()

xTrain, yTrain = MLDatasets.MNIST.traindata(Float32)
xTest, yTest = MLDatasets.MNIST.testdata(Float32)
nTrain, nTest = size(xTrain)[3], size(xTest)[3]
trainData = [xTrain[:,:,k]' for k in 1:nTrain]
testData = [xTest[:,:,k]' for k in 1:nTest]
positiveTrain = trainData[yTrain .== 1]
negativeTrain = trainData[yTrain .!= 1]
testLabels = yTest .== 1

function peakProp(img)
	peakSum = 0.0
	for j in 1:28
		m = argmax(img[j,:])
		(m <=2 || m >= 26) && continue
		peakSum += sum(img[j,m-2:m+2])
	end
	peakSum/sum(img)
end
predict(img,theta) = peakProp(img) <= theta ? false : true
function F1value(theta)
	predictionOnPositive = predict.(positiveTrain,theta)
	predictionOnNegative = predict.(negativeTrain,theta)
	TP = sum(predictionOnPositive)
	FN = sum(1 .- predictionOnPositive)
	FP = sum(predictionOnNegative)
	TN = sum(1 .- predictionOnNegative)
	recall, precision = TP/(TP + FN), TP/(TP + FP)
	return 2*(precision*recall)/(precision+recall)
end

psPositive, psNegative = peakProp.(positiveTrain), peakProp.(negativeTrain)
thetaRange = 0.5:0.005:1
f1Values = F1value.(thetaRange)

bestF1, bestIndex = findmax(f1Values)
bestTheta = thetaRange[bestIndex]
println("Best theta = ", bestTheta, " with F1 value of ", bestF1)

println("On test set:")
testPredictions = predict.(testData,bestTheta)
TP, FN = sum(testPredictions[testLabels]), sum(.!testPredictions[testLabels])
FP, TN = sum(testPredictions[.!testLabels]), sum(.!testPredictions[.!testLabels])
recall, precision = TP/(TP + FN), TP/(TP + FP)
F1test = harmmean([precision,recall])
@show TP, FN, FP, TN; @show recall, precision; @show F1test

p1 = stephist(psPositive, normed = true, label="1 Digit",bins=50)
stephist!(psNegative, normed = true, xlim=(0.4,1), ylim=(0,6),bins=50,
			xlabel = "Value", ylabel = "Frequency",
			label="Non 1 Digit")
plot!([bestTheta,bestTheta],[0,5], c =:black, label = :none)
p2 = plot(thetaRange,f1Values, legend = false,
	xlabel = "Threshold", ylabel = "F1 Value")
plot!([bestTheta],[bestF1], c=:black)
plot(p1,p2,size=(800,400))

max_stars_repo_name: Yoshinobu-Ishizaki/StatsWithJuliaBook

max_issues_repo_name: Yoshinobu-Ishizaki/StatsWithJuliaBook

max_forks_repo_name: Yoshinobu-Ishizaki/StatsWithJuliaBook


text:
using DrWatson
@quickactivate :FractalDimension # uses DynamicalSystems, PyPlot
include(srcdir("style.jl"))

using DelimitedFiles

name = "R1_ST_10_1.dat"

file = datadir("exp_pro", name)
M = readdlm(file)

X1 = Dataset(M) # Every single oscillator as one dimension

x2 = M[:, 1]
estimate_embedding_plot(x2)
# From the above we obtain embedding dimension of ~6 and delay time of 7

Y, τ_vals = pecuzal_embedding(x2; τs = 0:50, w = 6)
# PECUZAL method gives 4d embedding with τ = [0, 6, 3, 14]

# %%
writedlm(datadir("experimental", "roessler_all.txt"), M)
writedlm(datadir("experimental", "roessler_embed.txt"), x2)

# %% Okay, this will take tremendous amount of computation time,
# using all 28 timeseries...
# Y, τ_vals, ts_vals, = pecuzal_embedding(X1)

max_stars_repo_name: Datseris/FractalDimension

max_issues_repo_name: Datseris/FractalDimension

max_forks_repo_name: Datseris/FractalDimension


text:
"""
CTMC

Continous Time Markov Chain
"""
mutable struct CTMC
    τ::AbstractFloat
    transitiontimes::Vector{AbstractFloat}
    states::Vector{Int}
    CTMC() = new()
end

function CTMC(q::Array, τ::AbstractFloat,state1::Int)

# create empty CTMC structure
    ctmc = CTMC()
    ctmc.τ=τ

    lastchange = 0.0
    currentstate = state1

    ctmc.states = [state1]
    ctmc.transitiontimes = [lastchange]

    sidx = Vector((1:size(q, 1)))

    while lastchange < τ

# get time for state change
        k_tot = sum(q[currentstate,:])
        Δt = rand(Exponential(1 / k_tot))

# get the new state
        ps = q[currentstate,:]
        ps = ps ./ sum(ps)
        deleteat!(ps,currentstate)
        xs = sidx[:]
        deleteat!(xs,currentstate)
        newstate = rand(DiscreteNonParametric(xs, ps))

# update CTMC
        lastchange +=Δt
        push!(ctmc.states,newstate)
        push!(ctmc.transitiontimes,lastchange)
        currentstate = newstate
    end
    return ctmc
end

"""
    getstate(ctmc::CTMC,t::AbstractFloat)

 return the state at time t
"""
function getstate(ctmc::CTMC,t::AbstractFloat)
    nstates=length(ctmc.states)
    for nn=2:nstates
        if t<ctmc.transitiontimes[nn]
            return ctmc.states[nn-1]
        end
    end
end

"""
    getnext(ctmc::CTMC,t::AbstractFloat)

 return the time and state of next transision
"""
function getnext(ctmc::CTMC,t::AbstractFloat)
    nstates=length(ctmc.states)
    for nn=1:nstates
        if t<ctmc.transitiontimes[nn]
            return ctmc.states[nn],ctmc.transitiontimes[nn]
        end
    end
end

"""
    intensitytrace(f::GenericFluor, nframes::Int, framerate::AbstractFloat;state1=1)

Calculate an intensity trace.

"""
function intensitytrace(f::GenericFluor, nframes::Int, framerate::Real;state1=1)

    endtime = (nframes) / framerate

    # generate CTMC
    ctmc=SMLMSim.CTMC(f.q,endtime,state1)

    # generate integrated photons
    exptime=1/framerate
    photons=zeros(nframes)
    for nn=1:nframes
        t=(nn-1)*exptime
        frameend=(nn*exptime)
        while t<frameend
            currentstate=SMLMSim.getstate(ctmc,t)
            (~,nexttime)=SMLMSim.getnext(ctmc,t)
            tend=min(frameend,nexttime)
            if currentstate==1 # the fluorescent state
                photons[nn]+=f.γ*(tend-t)
            end
            t=tend
        end
    end
    return photons
end

# function genroistack(psf::MicroscopePSFs.PSF, xsize, ysize, nframes, framerate)
# end

"""
    function kineticmodel(smd_true::SMLMData.SMLD2D,f::Molecule,nframes::Int,framerate::AbstractFloat;ndatasets::Int=1,minphotons=50.0)

generate noise-free blinking model from smd_true
"""
function kineticmodel(smd_true::SMLMData.SMLD2D,f::Molecule,nframes::Int,framerate::Real;ndatasets::Int=1,minphotons=50.0)

    state1=2;

    smd=SMLMData.SMLD2D(0)
    smd.ndatasets=ndatasets
    smd.nframes=nframes
    smd.datasize=deepcopy(smd_true.datasize)
    for dd=1:ndatasets, ll=1:length(smd_true.x)
        photons=SMLMSim.intensitytrace(f,nframes,framerate;state1=state1);
        framenum=findall(photons.>minphotons)
        n=length(framenum)
        push!(smd.photons,photons[framenum]...)
        push!(smd.framenum,framenum...)
        for nn = 1:n
            push!(smd.x, smd_true.x[ll])
            push!(smd.y, smd_true.y[ll])
            push!(smd.connectID, smd_true.connectID[ll])
            push!(smd.datasetnum, dd)
        end
    end
    return smd
end

function noise(smd_model::SMLMData.SMLD2D,σ_psf::AbstractFloat)
    n=length(smd_model.x)
    smd=deepcopy(smd_model)
    smd.σ_x=zeros(n)
    smd.σ_y=zeros(n)

    for nn=1:n
        σ=σ_psf/sqrt(smd_model.photons[nn])
        smd.x[nn]=smd_model.x[nn]+randn()*σ
        smd.y[nn]=smd_model.y[nn]+randn()*σ
        smd.σ_x[nn]=σ
        smd.σ_y[nn]=σ
    end
    return smd
end


text:
function plotChain!(p, c::Array{Transf,1})::Plots.Plot
    points = map((t) -> (t.v.x, t.v.y, t.v.z), c)
    plot!(
        p,
        points,
        color = :black,
        label = nothing,
    )
end

function projectChain!(p, c::Array{Transf,1})::Plots.Plot
    points = map((t) -> (t.v.x, t.v.y, 0), c)
    plot!(
        p,
        points,
        color = :gray,
        label = nothing,
    )
end

function plotAxis!(p, t::Transf=Trasnf(), l::Real=1)::Plots.Plot
    zero = t.v
    x = t + Vec(l, 0, 0)
    y = t + Vec(0, l, 0)
    z = t + Vec(0, 0, l)
    plot!(p, [zero.x, x.x], [zero.y, x.y], [zero.z, x.z], color = :red, label = nothing)
    plot!(p, [zero.x, y.x], [zero.y, y.y], [zero.z, y.z], color = :green, label = nothing)
    plot!(p, [zero.x, z.x], [zero.y, z.y], [zero.z, z.z], color = :blue, label = nothing)
end

max_stars_repo_name: red-hara/K

max_issues_repo_name: red-hara/K

max_forks_repo_name: red-hara/K


text:
using Test
using Statistikk
using Distributions

@testset "UnnormalizedCategorical" begin
    idx = (7,5)
    p = zeros(10, 10)
    p[idx...] = 10.0
    d = UnnormalizedCategorical(p)
    @test d.s == 10
    @test rand(d) == idx
end

@testset "Missings" begin
    # No errors if called multiple times
    @test_nowarn Statistikk.enablemissing()
    @test_nowarn Statistikk.enablemissing()
    @test_nowarn Statistikk.disablemissing()
    @test_nowarn Statistikk.disablemissing()
end

@testset "Missings $f" for f in [pdf, logpdf, Distributions.zval]
    Statistikk.disablemissing()
    @test_throws MethodError f(Normal(), missing)

    Statistikk.enablemissing()
    @test_nowarn f(Normal(), missing)
end

@testset "Vector" begin
    d = Normal()
    X = rand(d, 1000)
    @test pdf(d, X) == pdf.(d, X)
    @test logpdf(d, X) == logpdf.(d, X)
end

max_stars_repo_name: maxmouchet/Statistikk

max_issues_repo_name: maxmouchet/Statistikk

max_forks_repo_name: maxmouchet/Statistikk


text:
module packageTrial

# export functions you want to call without qualifications
export add_exported
export my_f
#using DataFrames # or any other module

# Include functions
include("extra_file.jl")

end # module


text:
# Functions for representing graphs in GraphViz's dot format
# http://www.graphviz.org/
# http://www.graphviz.org/Documentation/dotguide.pdf
# http://www.graphviz.org/pub/scm/graphviz2/doc/info/lang.html

# Write the dot representation of a graph to a file by name.
function to_dot(graph::AbstractGraph, filename::AbstractString, attrs::AttributeDict=AttributeDict())
    open(filename,"w") do f
        to_dot(graph, f, attrs)
    end
end

# Get the dot representation of a graph as a string.
function to_dot(graph::AbstractGraph, attrs::AttributeDict=AttributeDict())
    str = IOBuffer()
    to_dot(graph, str, attrs)
    takebuf_string(str)
end

# Write the dot representation of a graph to a stream.
function to_dot{G<:AbstractGraph}(graph::G, stream::IO,attrs::AttributeDict=AttributeDict())
    has_vertex_attrs = method_exists(attributes, (vertex_type(graph), G))
    has_edge_attrs = method_exists(attributes, (edge_type(graph), G))

    write(stream, "$(graph_type_string(graph)) graphname {\n")
    write(stream, "$(to_dot_graph(attrs))")
    if implements_edge_list(graph) && implements_vertex_map(graph)
        for vtx in  vertices(graph)
            attrs = has_vertex_attrs ?  "\t$(to_dot(attributes(vtx,graph)))" : ""
            write(stream,"$(vertex_index(vtx,graph))$attrs\n")
        end
        for edge in edges(graph)
            write(stream,"$(vertex_index(source(edge), graph)) $(edge_op(graph)) $(vertex_index(target(edge), graph))\n")
        end
    elseif implements_vertex_list(graph) && (implements_incidence_list(graph) || implements_adjacency_list(graph))
        for vertex in vertices(graph)
            if has_vertex_attrs && !isempty(attributes(vertex, graph))
                write(stream, "$(vertex_index(vertex, graph)) $(to_dot(attributes(vertex, graph)))\n")
            end
            if implements_incidence_list(graph)
                for e in out_edges(vertex, graph)
                    n = target(e, graph)
                    if is_directed(graph) || vertex_index(n, graph) > vertex_index(vertex, graph)
                        write(stream,"$(vertex_index(vertex, graph)) $(edge_op(graph)) $(vertex_index(n, graph))$(has_edge_attrs ? string(" ", to_dot(attributes(e, graph))) : "")\n")
                    end
                end
            else # implements_adjacency_list
                for n in out_neighbors(vertex, graph)
                    if is_directed(graph) || vertex_index(n, graph) > vertex_index(vertex, graph)
                        write(stream,"$(vertex_index(vertex, graph)) $(edge_op(graph)) $(vertex_index(n,graph))\n")
                    end
                end
            end
        end
    else
        throw(ArgumentError("More graph Concepts needed: dot serialization requires iteration over edges or iteration over vertices and neighbors."))
    end
    write(stream, "}\n")
    stream
end
#write node attributes example: [shape=box, style=filled]
function to_dot(attrs::AttributeDict)
    if isempty(attrs)
        ""
    else
        string("[",join(map(a -> to_dot(a[1], a[2]), collect(attrs)),","),"]")
    end
end
# write a graph wide attributes example: size = "4,4";
function to_dot_graph(attrs::AttributeDict)
    if isempty(attrs)
        ""
    else
        string(join(map(a -> to_dot(a[1], a[2]), collect(attrs)),";\n"),";\n")
    end
end

to_dot(attr::AbstractString, value) = "\"$attr\"=\"$value\""

to_dot(attr_tuple::@compat Tuple{String, Any}) = "\"$(attr_tuple[1])\"=\"$(attr_tuple[2])\""

function graph_type_string(graph::AbstractGraph)
    is_directed(graph) ? "digraph" : "graph"
end

function edge_op(graph::AbstractGraph)
    is_directed(graph) ? "->" : "--"
end

function plot(g::AbstractGraph)
    stdin, proc = open(`neato -Tx11`, "w")
    to_dot(g, stdin)
    close(stdin)
end


text:
export Gateway, agent, topic, agentforservice, agentsforservice
export subscribe, unsubscribe, send, receive, request

"""
    gw = Gateway([name,] host, port)

Open a new TCP/IP gateway to communicate with fjåge agents from Julia.
"""
struct Gateway
  agentID::AgentID
  sock::Ref{TCPSocket}
  subscriptions::Set{String}
  pending::Dict{String,Channel}
  queue::Channel
  host::String
  port::Int
  reconnect::Ref{Bool}
  function Gateway(name::String, host::String, port::Int; reconnect=true)
    gw = new(
      AgentID(name, false),
      Ref(connect(host, port)),
      Set{String}(),
      Dict{String,Channel}(),
      Channel(MAX_QUEUE_LEN),
      host, port, Ref(reconnect)
    )
    @async _run(gw)
    gw
  end
end

Gateway(host::String, port::Int; reconnect=true) = Gateway("julia-gw-" * string(uuid1()), host, port; reconnect=reconnect)

Base.show(io::IO, gw::Gateway) = print(io, gw.agentID.name)

"""
    name(gw)

Get the name of the gateway.
"""
name(gw::Gateway) = gw.agentID.name

function _println(sock, s)
  @debug ">> $s"
  try
    println(sock, s)
  catch
    @warn "Connection lost..."
    close(sock)
  end
end

# respond to master container
function _respond(gw, rq::Dict, rsp::Dict)
  s = JSON.json(merge(Dict("id" => rq["id"], "inResponseTo" => rq["action"]), rsp))
  _println(gw.sock[], s)
end

# ask master container a question, and wait for reply
function _ask(gw, rq::Dict)
  id = string(uuid4())
  s = JSON.json(merge(rq, Dict("id" => id)))
  ch = Channel{Dict}(1)
  gw.pending[id] = ch
  try
    _println(gw.sock[], s)
    return take!(ch)
  finally
    delete!(gw.pending, id)
  end
end

_agents(gw::Gateway) = [gw.agentID.name]
_agents_types(gw::Gateway) = [(gw.agentID.name, "Gateway")]
_subscriptions(gw::Gateway) = gw.subscriptions
_services(gw::Gateway) = String[]
_agentsforservice(gw::Gateway, svc) = String[]
_onclose(gw::Gateway) = close(gw.sock[])
_shutdown(gw::Gateway) = close(gw)
_alive(gw::Gateway) = nothing

function _deliver(gw::Gateway, msg::Message, relay::Bool)
  while length(gw.queue.data) >= MAX_QUEUE_LEN
    take!(gw.queue)
  end
  put!(gw.queue, msg)
end

# update master container about changes to recipient watch list
function _update_watch(gw)
  watch = _agents(gw)
  append!(watch, _subscriptions(gw))
  s = JSON.json(Dict(
    "action" => "wantsMessagesFor",
    "agentIDs" => watch
  ))
  _println(gw.sock[], s)
end

# task monitoring incoming JSON messages from master container
function _run(gw)
  while true
    try
      _println(gw.sock[], "{\"alive\": true}")
      _println(gw.sock[], "{\"action\": \"auth\", \"name\": \"$(name(gw))\"}")
      _update_watch(gw)
      while isopen(gw.sock[])
        s = readline(gw.sock[])
        @debug "<< $s"
        json = JSON.parse(s)
        if haskey(json, "id") && haskey(gw.pending, json["id"])
          put!(gw.pending[json["id"]], json)
        elseif haskey(json, "action")
          if json["action"] == "agents"
            at = _agents_types(gw)
            _respond(gw, json, Dict("agentIDs" => first.(at), "agentTypes" => last.(at)))
          elseif json["action"] == "agentForService"
            alist = _agentsforservice(gw, json["service"])
            if length(alist) > 0
              _respond(gw, json, Dict("agentID" => first(alist)))
            else
              _respond(gw, json, Dict())
            end
          elseif json["action"] == "agentsForService"
            alist = _agentsforservice(gw, json["service"])
            _respond(gw, json, Dict("agentIDs" => alist))
          elseif json["action"] == "services"
            _respond(gw, json, Dict("services" => _services(gw)))
          elseif json["action"] == "containsAgent"
            ans = (json["agentID"] ∈ _agents(gw))
            _respond(gw, json, Dict("answer" => ans))
          elseif json["action"] == "send"
            rcpt = json["message"]["data"]["recipient"]
            if rcpt ∈ _agents(gw) || rcpt ∈ _subscriptions(gw)
              try
                msg = _inflate(json["message"])
                _deliver(gw, msg, json["relay"])
              catch ex
                @warn ex
              end
            end
          elseif json["action"] == "shutdown"
            _shutdown(gw)
          end
        elseif haskey(json, "alive") && json["alive"]
          _println(gw.sock[], "{\"alive\": true}")
          _alive(gw)
        end
      end
    catch ex
      if !(ex isa ErrorException && startswith(ex.msg, "Unexpected end of input"))
        @warn ex stacktrace(catch_backtrace())
      end
    end
    gw.reconnect[] || break
    while gw.reconnect[] && !isopen(gw.sock[])
      @info "Reconnecting..."
      try
        gw.sock[] = connect(gw.host, gw.port)
        @info "Reconnected"
      catch
        sleep(1.0)
      end
    end
  end
  _onclose(gw)
end

AgentID(gw::Gateway) = gw.agentID
agent(gw::Gateway, name::String) = AgentID(name, false, gw)

"Find an agent that provides a named service."
function agentforservice(gw::Gateway, svc::String)
  rq = Dict("action" => "agentForService", "service" => svc)
  rsp = _ask(gw, rq)
  haskey(rsp, "agentID") ? AgentID(rsp["agentID"], false, gw) : nothing
end

"Find all agents that provides a named service."
function agentsforservice(gw::Gateway, svc::String)
  rq = Dict("action" => "agentsForService", "service" => svc)
  rsp = _ask(gw, rq)
  [AgentID(a, false, gw) for a in rsp["agentIDs"]]
end

"Subscribe to receive all messages sent to the given topic."
function subscribe(gw::Gateway, aid::AgentID)
  push!(gw.subscriptions, string(topic(gw, aid)))
  _update_watch(gw)
  true
end

"Unsubscribe from receiving messages sent to the given topic."
function unsubscribe(gw::Gateway, aid::AgentID)
  k = string(topic(gw, aid))
  if k ∈ gw.subscriptions
    delete!(gw.subscriptions, k)
    _update_watch(gw)
    return true
  end
  false
end

"Close a gateway connection to the master container."
function Base.close(gw::Gateway)
  gw.reconnect[] = false
  _println(gw.sock[], "{\"alive\": false}")
  close(gw.sock[])
  nothing
end

# prepares a message to be sent to the server
function _prepare!(msg::Message)
  for k in keys(msg.__data__)
    v = msg.__data__[k]
    if typeof(v) <: Array && typeof(v).parameters[1] <: Complex
      btype = typeof(v).parameters[1].parameters[1]
      msg.__data__[k] = reinterpret(btype, v)
    end
  end
end

# converts Base64 encoded arrays to Julia arrays
function _b64toarray(v)
  try
    dtype = v["clazz"]
    if dtype == "[B"  # byte array
      dtype = Int8
    elseif dtype == "[S"  # short array
      dtype = Int16
    elseif dtype == "[I"  # integer array
      dtype = Int32
    elseif dtype == "[J"  # long array
      dtype = Int64
    elseif dtype == "[F"  # float array
      dtype = Float32
    elseif dtype == "[D"  # double array
      dtype = Float64
    else
      return v
    end
    return Array{dtype}(reinterpret(dtype, base64decode(v["data"])))
  catch ex
    return v
  end
end

# creates a message object from a JSON representation of the object
function _inflate(json)
  if typeof(json) == String
    json = JSON.parse(json)
  end
  clazz = json["clazz"]
  data = json["data"]
  stype = _messageclass_lookup(clazz)
  obj = @eval $stype()
  for k in keys(data)
    v = data[k]
    if endswith(k, "__isComplex")
      continue
    end
    if k == "sender" || k == "recipient"
      v = AgentID(v)
    end
    if typeof(v) <: Dict && haskey(v, "clazz") && match(r"^\[.$", v["clazz"]) != nothing
      v = _b64toarray(v)
    end
    if typeof(v) <: Array && length(v) > 0
      t = typeof(v[1])
      v = Array{t}(v)
      kcplx = k*"__isComplex"
      if haskey(data, kcplx) && data[kcplx]
        v = Array{Complex{t}}(reinterpret(Complex{t}, v))
      end
    end
    obj.__data__[k] = v
  end
  obj
end

"""
    send(gw, msg)

Send a message via the gateway to the specified agent. The `recipient` field of the message must be
populated with an agentID.
"""
function send(gw::Gateway, msg)
  msg.sender = gw.agentID
  msg.sentAt = Dates.value(now())
  _prepare!(msg)
  json = JSON.json(Dict(
    "action" => "send",
    "relay" => true,
    "message" => Dict(
      "clazz" => msg.__clazz__,
      "data" => msg.__data__
    )
  ))
  _println(gw.sock[], json)
  true
end

"""
    msg = receive(gw[, filter][, timeout])

Receive an incoming message from other agents or topics. Timeout is specified in
milliseconds. If no timeout is specified, the call is non-blocking. If a negative timeout
is specified, the call is blocking until a message is available.

If a `filter` is specified, only messages matching the filter are retrieved. A filter
may be a message type, a message or a function. If it is a message type, only messages
of that type or a subtype are retrieved. If it is a message, any message whose `inReplyTo`
field is set to the `msgID` of the specified message is retrieved. If it is a function,
it must take in a message and return `true` or `false`. A message for which it returns
`true` is retrieved.
"""
function receive(gw::Gateway, timeout::Int=0)
  isready(gw.queue) && return take!(gw.queue)
  timeout == 0 && return nothing
  waiting = true
  if timeout > 0
    @async begin
      sleep(timeout/1000.0)
      waiting && push!(gw.queue, nothing)
    end
  end
  rv = take!(gw.queue)
  waiting = false
  rv
end

function receive(gw::Gateway, filt, timeout=0)
  t1 = now() + Millisecond(timeout)
  cache = []
  while true
    msg = receive(gw, (t1-now()).value)
    if _matches(filt, msg)
      if length(cache) > 0
        while isready(gw.queue)
          push!(cache, take!(gw.queue))
        end
        for m in cache
          push!(gw.queue, m)
        end
      end
      return msg
    end
    push!(cache, msg)
  end
end

"""
    rsp = request(gw, msg[, timeout])

Send a request via the gateway to the specified agent, and wait for a response. The response is returned.
The `recipient` field of the request message (`msg`) must be populated with an agentID. The timeout
is specified in milliseconds, and defaults to 1 second if unspecified.
"""
function request(gw::Gateway, msg, timeout=1000)
  send(gw, msg)
  receive(gw, msg, timeout)
end

"Flush the incoming message queue."
function Base.flush(gw::Gateway)
  while isready(gw.queue)
    take!(gw.queue)
  end
  nothing
end


text:
using Test, SHA, SparseArrays, Downloads
using SBML
using SBML: Model, Reaction, Species
using Symbolics, Unitful

@testset "SBML test suite" begin
    include("version.jl")
    include("ecoli_flux.jl")
    include("loadmodels.jl")
    include("loaddynamicmodels.jl")
    include("symbolics.jl")
end


text:
Dict(
      "hello" => "cava FR"
)


text:
#!/usr/bin/env julia

## Tested with Julia

include("main_functions.jl")

res = simulate(runs=100, r_in = 8, r_out = 20, dt = 0.05, sleepTime = 0);

save_runs_as_video(res["all"], "all_steps_test", ".mp4")

max_stars_repo_name: Xentrics/SmoothLifeJulia

max_issues_repo_name: Xentrics/SmoothLifeJulia

max_forks_repo_name: Xentrics/SmoothLifeJulia


text:
n = 20
Z = rand(1:5, n)
ϑ = dropdims(ones(1,n) + rand(1,n), dims = 1)
μ = mean(ϑ)
kmax = 4

ω(x, α) = (x[1]+1)^(-α[x[2]]*x[2])

α = repeat([2.0], kmax)

Ω = sumOfExteriorDegreesIntensityFunction(ω, kmax)
H = sampleSBM(Z, ϑ, Ω;α=α, kmax=kmax, kmin = 1)
D = H.D
all_partitions = collect(Iterators.flatten([(partitions(i,j)) for i =1:kmax for j=1:i]))

p = [3, 1, 1]

s1 = evalSumNaive(p, Z, D)
s2 = evalSumNaive2(p, Z, D)

## d
@test s1 == s2

sumsNaive = evalSumsNaive(Z,D,kmax)
sumsPV    = evalSumsPV(Z,D,kmax)
sums      = evalSums(Z,D,kmax)[3]

@test all([sumsNaive[p] == sumsPV[p] for p in all_partitions])
@test all([sumsNaive[p] == sums[p] for p in all_partitions])

# voldiff

ℓ = maximum(Z) # number of total groups

# let's move all the nodes in group 4 to group 5
to_move = findall(==(4), Z)
t = 5
Z_ = copy(Z)

## first we'll step through, moving each node one-by-one
V, μ, M = evalSums(Z, D, kmax; constants=false, bigInt=false)

for i in to_move
    global V, μ, M
    ΔV, Δμ, ΔM = increments(V, μ, M, i, t, D, Z_)
    V, μ, M = HyperModularity.addIncrements(V, μ, M, ΔV, Δμ, ΔM)
    # carry out the change in membership
    Z_[i] = t
end
step_wise = M

# next we'll compute the complete set of increments at once
V, μ, M = evalSums(Z, D, kmax; constants=false, bigInt=false);
ΔV, Δμ, ΔM = increments(V, μ, M, to_move, t, D, Z)
V, μ, M = HyperModularity.addIncrements(V, μ, M, ΔV, Δμ, ΔM)
batch = M
#
@test all([step_wise[p] == batch[p] for p in keys(M)])

max_stars_repo_name: nveldt/TestPkg

max_issues_repo_name: nveldt/TestPkg

max_forks_repo_name: nveldt/TestPkg


text:
"""Смена направления на противоположное"""
function inverse(side::HorizonSide)
    HorizonSide(mod(Int(side)+2, 4))
end
"""Смена направления на следующее (по стороне горизонта)"""
function next(side::HorizonSide)
    HorizonSide(mod(Int(side)+3,4))
end
"""Движение и подсчёт шагов"""
function moves!(r::Robot,side::HorizonSide)
    num_steps=0
    while isborder(r,side)==false
        move!(r,side)
        num_steps=num_steps+1
    end
    return num_steps
end
"""Обход локальных преград"""
function find_decision(r::Robot, side::HorizonSide) #Обход локальных преград
    num_steps=0
    while isborder(r,side)==true&&isborder(r,next(side))==false
        move!(r,next(side))
        num_steps+=1
    end
    x=0 #Счётчик
    if isborder(r,side)==false
        move!(r,side)
        x+=1
    end
    if num_steps !=0
        while isborder(r,inverse(next(side)))==true
            move!(r,side)
            x+=1
        end
        for a ∈ 1:num_steps
            move!(r,inverse(next(side)))
        end
    end
    return x #Возвращение значения счётчика
end

max_stars_repo_name: alexgruzberg/mirea-progs

max_issues_repo_name: alexgruzberg/mirea-progs

max_forks_repo_name: alexgruzberg/mirea-progs


text:
# Raytracer.jl
# Raytracing for the generation of photorealistic images in Julia
# Copyright (c) 2021 Samuele Colombo, Paolo Galli

# Parse SceneLang constructors

"""
    parse_constructor(stream::InputStream, scene::Scene)

Return a `Tuple{Any, IdTableKey}` containing the result of the construction and its type.

If the expression from the `stream` is not a valid constructor an exception is thrown.
"""
function parse_constructor(stream::InputStream, scene::Scene)
    next_token = read_token(stream)
    unread_token(stream, next_token)
    next_val = next_token.value
    if isa(next_val, Command)
        next_val == TIME &&
            return(scene.time, LiteralNumber)
        next_val ∈ (ROTATE, TRANSLATE, SCALE) &&
            return (parse_transformation(stream, scene), TransformationType)
        next_val == LOAD &&
            return (parse_image_from_command(stream, scene), ImageType)
        next_val ∈ (UNITE, INTERSECT, DIFF, FUSE) &&
            return (parse_shape_from_command(stream, scene), ShapeType)
        throw(InvalidCommand(next_token.loc, "Command '$next_val' is not a valid construction command."))
    elseif isa(next_val, LiteralType)
        for (type, parser) ∈ (ListType           => parse_list,
                              ColorType          => parse_color,
                              PointType          => parse_point,
                              TransformationType => parse_transformation,
                              MaterialType       => parse_material,
                              BrdfType           => parse_brdf,
                              PigmentType        => parse_pigment,
                              ShapeType          => parse_shape,
                              LightType          => parse_light,
                              ImageType          => parse_image,
                              RendererType       => parse_renderer_settings,
                              CameraType         => parse_camera,
                              PcgType            => parse_pcg,
                              TracerType         => parse_tracer_settings)
            next_val == type || continue
            return (parser(stream, scene), type)
        end
        @assert false "@ $(next_token.loc): LiteralType $next_val has no named constructor."
    elseif isa(next_val, LiteralNumber) || isa(next_val, MathExpression)
        return (parse_float(stream, scene), LiteralNumber)
    elseif isa(next_val, LiteralSymbol)
        next_sym = next_val.value
        next_sym == Symbol("<") && return (parse_color(stream, scene), ColorType)
        next_sym == Symbol("{") && return (parse_point(stream, scene), PointType)
        next_sym == Symbol("[") && return (parse_list(stream, scene),  ListType)
        throw(InvalidSymbol(token.loc,
                            "Invalid symbol '$(token.value.value)'\nValid symbols:\n\t$(join((Symbol("<"), Symbol("{"), Symbol("["), Symbol("\$")), "\n\t"))",
                            token.length))
    elseif isa(next_val, LiteralString)
        return (parse_string(stream, scene), LiteralString)
    elseif isa(next_val, Identifier)
        throw(WrongTokenType("Cannot construct from identifier."))
    else
        throw(WrongTokenType("Token '$next_val' is not a valid construction token."))
    end
end

"""
    parse_string(stream::InputStream, scene::Scene)

Return a `String` value from either a [`LiteralString`](@ref) constructor or an appropriate [`Identifier`](@ref).
"""
function parse_string(stream::InputStream, scene::Scene)
table = scene.variables
    (from_id = parse_by_identifier(LiteralString, stream, table)) |> isnothing || (read_token(stream); return from_id)
    expect_string(stream).value.value
end

"""
    parse_int(stream::InputStream, scene::Scene)

Return a `Int` value from either a [`LiteralNumber`](@ref) constructor, the `TIME` command, an appropriate [`MathExpression`](@ref), or an appropriate [`Identifier`](@ref).

If the `Float32` number is not exactly representing an integer number an exception is thrown.
"""
function parse_int(stream::InputStream, scene::Scene)
    next_token = read_token(stream)
    unread_token(stream, next_token)
    n = parse_float(stream, scene)

    try
        convert(Int, n)
    catch e
        isa(e, InexactError) || rethrow(e)
        throw(WrongValueType(next_token.loc,"The given number is not convertible to an integer since it is not round",next_token.length))
    end
end

"""
    parse_float(stream::InputStream, scene::Scene)

Return a `Float32` value from either a [`LiteralNumber`](@ref) constructor, the `TIME` command, an appropriate [`MathExpression`](@ref), or an appropriate [`Identifier`](@ref).
"""
function parse_float(stream::InputStream, scene::Scene)
    table = scene.variables
    (from_id = parse_by_identifier(LiteralNumber, stream, table)) |> isnothing || (read_token(stream); return from_id)
    token = read_token(stream)
    if isa(token.value, MathExpression)
        res = evaluate_math_expression(token, scene)
        isa(res, Number) ||
        throw(InvalidExpression(token.loc, "`MathExpression` should return a `Number`: got a `$(typeof(res))`" , token.length))
        return res
    end
    token.value == TIME && return scene.time
    unread_token(stream, token)
    expect_number(stream, scene).value.value
end

"""
    parse_list(stream::InputStream, scene::Scene)

Return a `Vector{Float32}` value from either a named constructor, a symbolic constructor or an appropriate [`Identifier`](@ref).
"""
function parse_list(stream::InputStream, scene::Scene)
    table = scene.variables
    (from_id = parse_by_identifier(ListType, stream, table)) |> isnothing || (read_token(stream); return from_id)
    next_token = read_token(stream)
    unread_token(stream, next_token)
    delim = if isa(next_token.value, LiteralType)
        expect_type(stream, ListType)
        expect_symbol(stream, Symbol("("))
        Symbol(")")
    elseif isa(next_token.value, LiteralSymbol)
        expect_symbol(stream, Symbol("["))
        Symbol("]")
    else
        throw(WrongTokenType(next_token.loc,"Expected either a 'LiteralType' or a 'LiteralSymbol', got '$(typeof(next_token.value))'",next_token.length))
    end
    vec = Vector{Float32}()
    sizehint!(vec, 16) # I do not expect the users to define any list longer than 16, even if they have the ability to
    push!(vec, expect_number(stream, scene))
    while expect_symbol(stream, (Symbol(","), delim)).value.value == Symbol(",")
        push!(vec, expect_number(stream, scene))
    end
    vec
end

"""
    parse_list(stream::InputStream, scene::Scene, list_length::Int)

Return a `SVector{list_length, Float32}` value from either a named constructor, a symbolic constructor or an appropriate [`Identifier`](@ref).

If the list is not exactly `list_length` long an exception will be thrown.
"""
function parse_list(stream::InputStream, scene::Scene, list_length::Int)
    @assert list_length >= 1 "list must have size of at least 1"
    if (from_id = parse_by_identifier(ListType, stream, table)) |> !isnothing
        token = read_token(stream)
        if length(from_id) != list_length
            id_name = token.value.value
            throw(InvalidSize(token.loc, "Variable '$(id_name)' stores a list of length $(length(from_id)): expected length $list_length.\nVariable '$id_name' was declared at $(table[ListType][id_name].loc)", token.length))
        end
        return from_id
    end

    next_token = read_token(stream)
    unread_token(stream, next_token)
    delim = if isa(next_token.value, LiteralType)
        expect_type(stream, ListType)
        expect_symbol(stream, Symbol("("))
        Symbol(")")
    elseif isa(next_token.value, LiteralSymbol)
        expect_symbol(stream, Symbol("["))
        Symbol("]")
    else
        throw(WrongTokenType(next_token.loc,"Expected either a 'LiteralType' or a 'LiteralSymbol', got '$(typeof(next_token.value))'",next_token.length))
    end

    vec = SVector{list_length, Float32}([expect_number(stream, scene).value.value,
                                         ((expect_symbol(stream, Symbol(",")); expect_number(stream, scene).value.value) for _ ∈ SOneTo(list_length - 1))...
                                        ])

    expect_symbol(stream, delim)

    vec
end

"""
    parse_point(stream::InputStream, scene::Scene)

Return a [`Point`](@ref) value from either a named constructor, a symbolic constructor, an appropriate [`MathExpression`](@ref), or an appropriate [`Identifier`](@ref).

If the constructor has not exactly three arguments an exception will be thrown.
"""
function parse_point(stream::InputStream, scene::Scene)
    table = scene.variables
    (from_id = parse_by_identifier(PointType, stream, table)) |> isnothing || (read_token(stream); return from_id)
    next_token = read_token(stream)
    if isa(next_token.value, MathExpression)
        res = evaluate_math_expression(next_token, scene)
        isa(res, Point) ||
        throw(InvalidExpression(next_token.loc, "`MathExpression` should return a `Point`: got a `$(typeof(res))`" , next_token.length))
        return res
    end
    unread_token(stream, next_token)
    if isa(next_token.value, LiteralType)
        expect_type(stream, PointType)
        kw = (; X = parse_float, Y = parse_float, Z = parse_float)

        kwargs = generate_kwargs(stream, scene, kw)
        x = get(kwargs, :X, 0)
        y = get(kwargs, :Y, 0)
        z = get(kwargs, :Z, 0)
    elseif isa(next_token.value, LiteralSymbol)
        expect_symbol(stream, Symbol("{"))
        x = parse_float(stream, scene)
        expect_symbol(stream, Symbol(","))
        y = parse_float(stream, scene)
        expect_symbol(stream, Symbol(","))
        z = parse_float(stream, scene)
        expect_symbol(stream, Symbol("}"))
    else
        throw(WrongTokenType(next_token.loc,"Expected either a 'LiteralType' or a 'LiteralSymbol', got '$(typeof(next_token.value))'",next_token.length))
    end

    Point(x, y, z)
end

"""
    parse_color(stream::InputStream, scene::Scene)

Return a `RGB{Float32}` value from either a named constructor, a symbolic constructor, an appropriate [`MathExpression`](@ref), or an appropriate [`Identifier`](@ref).

If the constructor has not exactly three arguments an exception will be thrown.
"""
function parse_color(stream::InputStream, scene::Scene)
    table = scene.variables
    (from_id = parse_by_identifier(ColorType, stream, table)) |> isnothing || (read_token(stream); return from_id)
    next_token = read_token(stream)
    if isa(next_token.value, MathExpression)
        res = evaluate_math_expression(next_token, scene)
        isa(res, RGB) ||
        throw(InvalidExpression(next_token.loc, "`MathExpression` should return a `RGB`: got a `$(typeof(res))`" , next_token.length))
        return res
    end
    unread_token(stream, next_token)
    if isa(next_token.value, LiteralType)
        expect_type(stream, ColorType)
        kw = (; R = parse_float, G = parse_float, B = parse_float)

        kwargs = generate_kwargs(stream, scene, kw)
        red   = get(kwargs, :R, 0)
        green = get(kwargs, :G, 0)
        blue  = get(kwargs, :B, 0)
    elseif isa(next_token.value, LiteralSymbol)
        expect_symbol(stream, Symbol("<"))
        red = parse_float(stream, scene)
        expect_symbol(stream, Symbol(","))
        green = parse_float(stream, scene)
        expect_symbol(stream, Symbol(","))
        blue = parse_float(stream, scene)
        expect_symbol(stream, Symbol(">"))
    else
        throw(WrongTokenType(next_token.loc,"Expected either a 'LiteralType' or a 'LiteralSymbol', got '$(typeof(next_token.value))'",next_token.length))
    end
    return RGB(red, green, blue)
end

"""
    parse_pigment(stream::InputStream, scene::Scene)

Return a [`Pigment`](@ref) value from either a named constructor or an appropriate [`Identifier`](@ref).

The concrete type is determined by the first keyword after the `PigmentType` token,
which also determines the keyword arguments to be read by [`generate_kwargs`](@ref).
"""
function parse_pigment(stream::InputStream, scene::Scene)
    table = scene.variables
    (from_id = parse_by_identifier(PigmentType, stream, table)) |> isnothing || (read_token(stream); return from_id)
    expect_type(stream, PigmentType)

    type_key = expect_keyword(stream, (
        :Checkered,
        :Image,
        :Uniform
    )).value.value

    kw, res_type = if type_key == :Checkered
        ((; N = parse_int, color_on = parse_color, color_off = parse_color),
         CheckeredPigment
        )
    elseif type_key == :Uniform
        ((; color = parse_color),
         UniformPigment
        )
    elseif type_key == :Image
        ((; image = parse_image),
         ImagePigment
        )
    else
        @assert false "@ $(stream.loc): expect_keyword returned an invalid keyword"
    end

    kwargs = generate_kwargs(stream, scene, kw)

    res_type(; kwargs...)
end

"""
    parse_brdf(stream::InputStream, scene::Scene)

Return a [`BRDF`](@ref) value from either a named constructor or an appropriate [`Identifier`](@ref).

The concrete type is determined by the first keyword after the `BrdfType` token,
which also determines the keyword arguments to be read by [`generate_kwargs`](@ref).
"""
function parse_brdf(stream::InputStream, scene::Scene)
    table = scene.variables
    (from_id = parse_by_identifier(BrdfType, stream, table)) |> isnothing || (read_token(stream); return from_id)
    expect_type(stream, BrdfType)

    type_key = expect_keyword(stream, (
        :Diffuse,
        :Specular
    )).value.value

    kw, res_type = if type_key == :Diffuse
        ((; pigment = parse_pigment),
         DiffuseBRDF
        )
    elseif type_key == :Specular
        ((; pigment = parse_pigment, threshold_angle_rad = parse_float),
         SpecularBRDF
        )
    else
        @assert false "@ $(stream.loc): expect_keyword returned an invalid keyword"
    end

    kwargs = generate_kwargs(stream, scene, kw)

    res_type(; kwargs...)
end

"""
    parse_material(stream::InputStream, scene::Scene)

Return a [`Material`](@ref) value from either a named constructor or an appropriate [`Identifier`](@ref).

The concrete type is determined by the first keyword after the `MaterialType` token,
which also determines the keyword arguments to be read by [`generate_kwargs`](@ref).
"""
function parse_material(stream::InputStream, scene::Scene)
    table = scene.variables
    (from_id = parse_by_identifier(MaterialType, stream, table)) |> isnothing || (read_token(stream); return from_id)
    expect_type(stream, MaterialType)

    kw = (; brdf = parse_brdf, emitted_radiance = parse_pigment)

    kwargs = generate_kwargs(stream, scene, kw)

    Material(; kwargs...)
end

"""
    parse_transformation(stream::InputStream, scene::Scene)

Return a [`Transformation`](@ref) value from either a named constructor,
a construction command, or an appropriate [`Identifier`](@ref).

If the constructor/command/identifier is followed by an `*` operator the transformations will be
concatenated following the usual matrix multiplication rules (i.e. the rightmost transformation will
be applied first).

See also: [`parse_explicit_transformation`](@ref), [`parse_transformation_from_command`](@ref)
"""
function parse_transformation(stream::InputStream, scene::Scene)
    table = scene.variables
    transformation = if (from_id = parse_by_identifier(TransformationType, stream, table)) |> isnothing
        next_token = read_token(stream)
        unread_token(stream, next_token)
        if isa(next_token.value, LiteralType)
            parse_explicit_transformation(stream, scene)
        elseif isa(next_token.value, Command)
            parse_transformation_from_command(stream, scene)
        else
            throw(WrongTokenType(next_token.loc, "Expected either a 'LiteralType' or a 'Command', got '$(typeof(next_token.value))'" , next_token.length))
        end
    else
        read_token(stream)
        from_id
    end

    next_token = read_token(stream)
    next_token.value == LiteralSymbol(Symbol("*")) ?
        transformation * parse_transformation(stream, scene) :
        (unread_token(stream, next_token); transformation)
end

"""
    parse_explicit_transformation(stream::InputStream, scene::Scene)

Return a [`Transformation`](@ref) value from a named constructor taking a 16-long list as the only argument.

There is no way to set the inverse matrix, so it will be calculated by the `inv` algorithm upon construction.

See also: [`parse_transformation`](@ref)
"""
function parse_explicit_transformation(stream::InputStream, scene::Scene)
    table = scene.variables
    expect_type(stream, TransformationType)
    expect_symbol(stream, Symbol("("))
    mat = reshape(parse_list(stream, table, 16), 4, 4)
    expect_symbol(stream, Symbol(")"))
    Transformation(mat)
end

"""
    parse_transformation_from_command(stream::InputStream, scene::Scene)

Return a [`Transformation`](@ref) value from the `ROTATE`, `TRANSLATE`, and `SCALE` [`Command`](@ref)s.

See also: [`parse_transformation`](@ref), [`parse_rotation`](@ref), [`parse_translation`](@ref), [`parse_scaling`](@ref)
"""
function parse_transformation_from_command(stream::InputStream, scene::Scene)
    table = scene.variables
    command_token = expect_command(stream, (ROTATE, TRANSLATE, SCALE))
    unread_token(stream, command_token)
    if command_token.value == ROTATE
        parse_rotation(stream, scene)
    elseif command_token.value == TRANSLATE
        parse_translation(stream, scene)
    elseif command_token.value == SCALE
        parse_scaling(stream, scene)
    else
        @assert false "@ $(command_token.loc): command token has unknown value $(command_token.value)"
    end
end

"""
    parse_rotation(stream::InputStream, scene::Scene)

Return a [`Transformation`](@ref) value from the `ROTATE` [`Command`](@ref).

The argument of this command is a sequence of keyword arguments, with keywords representing the three axes of rotation `.X`, `.Y`, and `.Z`,
followed by a number representing the rotation angle in degrees. Each of these keyword arguments are separated by a `*` operator
which behaves as a concatenation of rotation following the usual rules of matrix multiplication (i.e. the rightmost rotation will be the first to be applied)

See also: [`parse_transformation_from_command`](@ref)
"""
function parse_rotation(stream::InputStream, scene::Scene)
    table = scene.variables
    expect_command(stream, ROTATE)
    expect_symbol(stream, Symbol("("))
    transformation = Transformation()
    while true
        key = expect_keyword(stream, (:X, :Y, :Z)).value.value
        angle_rad = deg2rad(parse_float(stream, scene))
        transformation *= if key == :X
            rotationX(angle_rad)
        elseif key == :Y
            rotationY(angle_rad)
        elseif key == :Z
            rotationZ(angle_rad)
        else
            @assert false "@ $(stream.loc): expect_keyword returned an invalid keyword '$key'"
        end
        expect_symbol(stream, (Symbol("*"), Symbol(")"))).value.value == Symbol(")") && break
    end
    transformation
end

"""
    parse_translation(stream::InputStream, scene::Scene)

Return a [`Transformation`](@ref) value from the `TRANSLATE` [`Command`](@ref).

The arguments of this command are a sequence of keyword arguments, with keywords representing the three axes of translation `.X`, `.Y`, and `.Z`,
followed by a number representing the displacement. Each of these keyword arguments are separated by a `,`.
The order of these arguments is indifferent since, in our euclidean space, translations are commutative transformations.

See also: [`parse_transformation_from_command`](@ref)
"""
function parse_translation(stream::InputStream, scene::Scene)
    expect_command(stream, TRANSLATE)

    kw = (; X = parse_float, Y = parse_float, Z = parse_float)

    kwargs = generate_kwargs(stream, scene, kw)

    translation(get(kwargs, :X, 0f0), get(kwargs, :Y, 0f0), get(kwargs, :Z, 0f0))
end

"""
    parse_scaling(stream::InputStream, scene::Scene)

Return a [`Transformation`](@ref) value from the `SCALE` [`Command`](@ref).

The arguments of this command are a sequence of keyword arguments, with keywords representing the three axes of scaling `.X`, `.Y`, and `.Z`,
followed by a number representing the scaling factor. Each of these keyword arguments are separated by a `,`.
The order of these arguments is indifferent since, in our euclidean space, scalings are commutative transformations.

An alternate form of this command sees only one numeric argument, without parenthesis, and indicates uniform scaling in all directions.

See also: [`parse_transformation_from_command`](@ref)
"""
function parse_scaling(stream::InputStream, scene::Scene)
    table = scene.variables
    expect_command(stream, SCALE)

    next_token = read_token(stream)
    unread_token(stream, next_token)
    (isa(next_token.value, LiteralNumber) || isa(next_token.value, Identifier)) &&
        return scaling(parse_float(stream, scene))

    kw = (; X = parse_float, Y = parse_float, Z = parse_float)

    kwargs = generate_kwargs(stream, scene, kw)

    scaling(get(kwargs, :X, 1f0), get(kwargs, :Y, 1f0), get(kwargs, :Z, 1f0))
end

"""
    parse_camera(stream::InputStream, scene::Scene)

Return a [`Camera`](@ref) value from either a named constructor or an appropriate [`Identifier`](@ref).

The concrete type is determined by the first keyword after the `CameraType` token,
which also determines the keyword arguments to be read by [`generate_kwargs`](@ref).
"""
function parse_camera(stream::InputStream, scene::Scene)
    table = scene.variables
    (from_id = parse_by_identifier(CameraType, stream, table)) |> isnothing || (read_token(stream); return from_id)
    expect_type(stream, CameraType)
    type_key = expect_keyword(stream, (
        :Orthogonal,
        :Perspective
    )).value.value

    kw, res_type = if type_key == :Orthogonal
        ((; aspect_ratio = parse_float, transformation = parse_transformation),
         OrthogonalCamera
        )
    elseif type_key == :Perspective
        ((; aspect_ratio = parse_float, transformation = parse_transformation, screen_distance = parse_float),
         PerspectiveCamera
        )
    else
        @assert false "@ $(stream.loc): expect_keyword returned an invalid keyword"
    end

    kwargs = generate_kwargs(stream, scene, kw)

    res_type(; kwargs...)
end

"""
    parse_pcg(stream::InputStream, scene::Scene)

Return a [`PCG`](@ref) value from either a named constructor or an appropriate [`Identifier`](@ref).
"""
function parse_pcg(stream::InputStream, scene::Scene)
    table = scene.variables
    (from_id = parse_by_identifier(ShapeType, stream, table)) |> isnothing || (read_token(stream); return from_id)
    expect_type(stream, PcgType)

    kw = (; state = parse_int, inc = parse_int)

    kwargs = generate_kwargs(stream, scene, kw)

    PCG(values(kwargs)...)
end

"""
    parse_shape(stream::InputStream, scene::Scene)

Return a [`Shape`](@ref) value from either a named constructor,
a construction command, or an appropriate [`Identifier`](@ref).

See also: [`parse_explicit_shape`](@ref), [`parse_shape_from_command`](@ref)
"""
function parse_shape(stream::InputStream, scene::Scene)
    table = scene.variables
    (from_id = parse_by_identifier(ShapeType, stream, table)) |> isnothing || (read_token(stream); return from_id)
    next_token = read_token(stream)
    unread_token(stream, next_token)
    if isa(next_token.value, LiteralType)
        parse_explicit_shape(stream, scene)
    elseif isa(next_token.value, Command)
        parse_shape_from_command(stream, scene)
    else
        throw(WrongTokenType(next_token.loc, "Expected either a 'LiteralType' or a 'Command', got '$(typeof(next_token.value))'" , next_token.length))
    end
end

"""
    parse_explicit_shape(stream::InputStream, scene::Scene)

Return a [`Shape`](@ref) value from either a named constructor or an appropriate [`Identifier`](@ref).

The concrete type is determined by the first keyword after the `ShapeType` token,
which also determines the keyword arguments to be read by [`generate_kwargs`](@ref).
"""
function parse_explicit_shape(stream::InputStream, scene::Scene)
    expect_type(stream, ShapeType)
    type_key = expect_keyword(stream, (
        :Cube,
        :Cylinder,
        :Plane,
        :Sphere
    )).value.value

    res_type = eval(type_key)
    kw = (; material = parse_material, transformation = parse_transformation)

    kwargs = generate_kwargs(stream, scene, kw)

    res_type(; kwargs...)
end

"""
    parse_shape_from_command(stream::InputStream, scene::Scene)

Return a [`Shape`](@ref) value from the `UNITE`, `INTERSECT`, `DIFF`, and `FUSE` [`Command`](@ref)s.

See also: [`parse_shape`](@ref), [`parse_union`](@ref), [`parse_intersection`](@ref), [`parse_setdiff`](@ref), [`parse_fusion`](@ref)
"""
function parse_shape_from_command(stream::InputStream, scene::Scene)
    command_token = expect_command(stream, (UNITE, INTERSECT, DIFF, FUSE))
    unread_token(stream, command_token)
    if command_token.value == UNITE
        parse_union(stream, scene)
    elseif command_token.value == INTERSECT
        parse_intersection(stream, scene)
    elseif command_token.value == DIFF
        parse_setdiff(stream, scene)
    elseif command_token.value == FUSE
        parse_fusion(stream, scene)
    else
        @assert false "@ $(command_token.loc): command token has unknown value $(command_token.value)"
    end
end

"""
    parse_union(stream::InputStream, scene::Scene)

Return a [`UnionCSG`](@ref) value from the `UNITE` [`Command`](@ref).

See also: [`parse_shape_from_command`](@ref)
"""
function parse_union(stream::InputStream, scene::Scene)
    expect_command(stream, UNITE)
    expect_symbol(stream, Symbol("("))
    shapes = Vector{Shape}()
    while true
        push!(shapes, parse_shape(stream, scene))
        expect_symbol(stream, (Symbol(","), Symbol(")"))).value.value == Symbol(")") && break
    end
    union(shapes...)
end

"""
    parse_intersection(stream::InputStream, scene::Scene)

Return a [`IntersectionCSG`](@ref) value from the `INTERSECT` [`Command`](@ref).

See also: [`parse_shape_from_command`](@ref)
"""
function parse_intersection(stream::InputStream, scene::Scene)
    expect_command(stream, INTERSECT)
    expect_symbol(stream, Symbol("("))
    shapes = Vector{Shape}()
    while true
        push!(shapes, parse_shape(stream, scene))
        expect_symbol(stream, (Symbol(","), Symbol(")"))).value.value == Symbol(")") && break
    end
    intersect(shapes...)
end

"""
    parse_setdiff(stream::InputStream, scene::Scene)

Return a [`DiffCSG`](@ref) value from the `DIFF` [`Command`](@ref).

See also: [`parse_shape_from_command`](@ref)
"""
function parse_setdiff(stream::InputStream, scene::Scene)
    expect_command(stream, DIFF)
    expect_symbol(stream, Symbol("("))
    shapes = Vector{Shape}()
    while true
        push!(shapes, parse_shape(stream, scene))
        expect_symbol(stream, (Symbol(","), Symbol(")"))).value.value == Symbol(")") && break
    end
    setdiff(shapes...)
end

"""
    parse_fusion(stream::InputStream, scene::Scene)

Return a [`FusionCSG`](@ref) value from the `FUSE` [`Command`](@ref).

See also: [`parse_shape_from_command`](@ref)
"""
function parse_fusion(stream::InputStream, scene::Scene)
    expect_command(stream, FUSE)
    expect_symbol(stream, Symbol("("))
    shapes = Vector{Shape}()
    while true
        push!(shapes, parse_shape(stream, scene))
        expect_symbol(stream, (Symbol(","), Symbol(")"))).value.value == Symbol(")") && break
    end
    fuse(shapes...)
end

"""
    parse_renderer_settings(stream::InputStream, scene::Scene)

Return a [`RendererSettings`](@ref) value from either a named constructor or an appropriate [`Identifier`](@ref).

The renderer type is determined by the first keyword after the `RendererType` token,
which also determines the keyword arguments to be read by [`generate_kwargs`](@ref) and stored in the `kwargs` field of the result.
"""
function parse_renderer_settings(stream::InputStream, scene::Scene)
    table = scene.variables
    (from_id = parse_by_identifier(RendererType, stream, table)) |> isnothing || (read_token(stream); return from_id)
    expect_type(stream, RendererType)
    type_key = expect_keyword(stream, (
        :OnOff,
        :Flat,
        :PointLight,
        :PathTracer
    )).value.value

    kw, res_type = if type_key == :OnOff
        ((; on_color = parse_color, off_color = parse_color),
         OnOffRenderer
        )
    elseif type_key == :Flat
        ((; background_color = parse_color),
         FlatRenderer
        )
    elseif type_key == :PointLight
        ((; background_color = parse_color, ambient_color = parse_color),
         PointLightRenderer
        )
    elseif type_key == :PathTracer
        ((; background_color = parse_color,
            rng              = (stream::InputStream, scene::Scene) -> PCG(convert(UInt64, parse_int(stream, scene)), convert(UInt64, parse_int(stream, scene))),
            n                = parse_int,
            max_depth        = parse_int,
            roulette_depth   = parse_int),
         PathTracer
        )
    else
        @assert false "@ $(stream.loc): expect_keyword returned an invalid keyword"
    end

    kwargs = generate_kwargs(stream, scene, kw)

    RendererSettings(res_type, NamedTuple(pairs(kwargs)))
end

"""
    parse_tracer_settings(stream::InputStream, scene::Scene)

Return a [`TracerSettings`](@ref) value from either a named constructor or an appropriate [`Identifier`](@ref).
"""
function parse_tracer_settings(stream::InputStream, scene::Scene)
    table = scene.variables
    (from_id = parse_by_identifier(RendererType, stream, table)) |> isnothing || (read_token(stream); return from_id)
    expect_type(stream, TracerType)

    kw = (; samples_per_side = parse_int, rng = parse_pcg)

    kwargs = generate_kwargs(stream, scene, kw)

    TracerSettings(NamedTuple(pairs(kwargs)))
end

"""
    parse_light(stream::InputStream, scene::Scene)

Return a [`PointLight`](@ref) value from either a named constructor or an appropriate [`Identifier`](@ref).
"""
function parse_light(stream::InputStream, scene::Scene)
    table = scene.variables
    (from_id = parse_by_identifier(RendererType, stream, table)) |> isnothing || (read_token(stream); return from_id)
    expect_type(stream, LightType)

    kw =  (; position = parse_point,
             color = parse_color,
             linear_radius = parse_float)

    kwargs = generate_kwargs(stream, scene, kw)

    PointLight(; kwargs...)
end

"""
    parse_image(stream::InputStream, scene::Scene)

Return an [`HdrImage`](@ref) value from either a named constructor,
a construction command, or an appropriate [`Identifier`](@ref).

See also: [`parse_explicit_image`](@ref), [`parse_image_from_command`](@ref)
"""
function parse_image(stream::InputStream, scene::Scene)
    table = scene.variables
    (from_id = parse_by_identifier(ImageType, stream, table)) |> isnothing || (read_token(stream); return from_id)
    next_token = read_token(stream)
    unread_token(stream, next_token)
    if isa(next_token.value, LiteralType)
        parse_explicit_image(stream, scene)
    elseif isa(next_token.value, Command)
        parse_image_from_command(stream, scene)
    else
        throw(WrongTokenType(next_token.loc, "Expected either a 'LiteralType' or a 'Command', got '$(typeof(next_token.value))'" , next_token.length))
    end
end

"""
    parse_explicit_image(stream::InputStream, scene::Scene)

Return an [`HdrImage`](@ref) value from a named constructor.

There are two versions of the constructor:
- one taking a valid file path [`LiteralString`](@ref) as the only argument and loading the image stored in that file
- the other taking two integer [`LiteralNumber`](@ref)s as width and height and constructing an empty image.

See also: [`parse_image`](@ref)
"""
function parse_explicit_image(stream::InputStream, scene::Scene)
    table = scene.variables
    expect_type(stream, ImageType)
    expect_symbol(stream, Symbol("("))
    next_token = read_token(stream)
    unread_token(stream, next_token)
    type = isa(next_token.value, Identifier) ?
        findfirst(d -> haskey(d, next_token.value.value), table) :
        next_token.value

    image = if isa(type, LiteralString)
        file_path = parse_string(stream, scene)
        isfile(file_path) || throw(InvalidFilePath(next_token.loc,"The file path\n$file_path\ndoes not lead to a file" ,next_token.length))
        try
            load(file_path) |> HdrImage
        catch e
            isa(e, ErrorException) || rethrow(e)
            throw(InvalidFilePath(next_token.loc,"The file path\n$file_path\nleads to a file of invalid format",next_token.length))
        end
    elseif isa(type, LiteralNumber)
        width = parse_int(stream, scene)
        expect_symbol(stream, Symbol(","))
        height = parse_int(stream, scene)
        HdrImage(width, height)
    else
        throw(WrongTokenType(next_token.loc, "Expected a 'LiteralString' file path, a 'LiteralNumber', or an 'Identifier': got a $type", next_token.length))
    end
    expect_symbol(stream, Symbol(")"))
    image
end

"""
    parse_image_from_command(stream::InputStream, scene::Scene)

Return an [`HdrImage`](@ref) value from the `LOAD` [`Command`](@ref).

The `LOAD` [`Command`](@ref) takes only one [`LiteralString`](@ref) representing a valid file path to an image file as an argument.

See also: [`parse_image`](@ref)
"""
function parse_image_from_command(stream::InputStream, scene::Scene)
    table = scene.variables
    expect_command(stream, LOAD)
    next_token = read_token(stream)
    unread_token(stream, next_token)
    file_path = parse_string(stream, scene)
    isfile(file_path) || throw(InvalidFilePath(next_token.loc,"The file path\n$file_path\ndoes not lead to a file" ,next_token.length))
    try
        load(file_path) |> HdrImage
    catch e
        isa(e, ErrorException) || rethrow(e)
        throw(InvalidFilePath(next_token.loc,"The file path\n$file_path\nleads to a file of invalid format",next_token.length))
    end
end


text:
"""
    get_branchlength_vector(post_order::Vector{Node})::Vector{Float64}

Return a vector of branch lengths.

* `post_order` : Vector of Nodes of a tree.
"""
function get_branchlength_vector(post_order::Vector{T})::Vector{Float64}  where T<:GeneralNode
    #println("You called a legacy function.")
    @warn "You called a legacy function"
    out = zeros(length(post_order)-1)
    @views @simd for i in eachindex(post_order)
        if !post_order[i].root
            out[post_order[i].num]= post_order[i].inc_length
        end
    end
    return out
end # function get_branchlength_vector