text:
# SimpleTiger Problem
# POMDP, Robust POMDP, and Robust ρPOMDP formulations

struct SimpleTigerRPOMDP <: RPOMDP{Symbol, Symbol, Symbol}
    discount::Float64
    usize::Float64
end

const discount_simpletiger = 0.95
const states_simpletiger = [:tigerleft, :tigerright]
const actions_simpletiger = [:listen, :openleft, :openright]
const observations_simpletiger = [:tigerleft, :tigerright]

SimpleTigerRPOMDP(err) = SimpleTigerRPOMDP(discount_simpletiger, err)
SimpleTigerRPOMDP() = SimpleTigerRPOMDP(discount_simpletiger, 0.025)

states(::SimpleTigerRPOMDP) = states_simpletiger
actions(::SimpleTigerRPOMDP) = actions_simpletiger
observations(::SimpleTigerRPOMDP) = observations_simpletiger

n_states(::SimpleTigerRPOMDP) = 2
n_actions(::SimpleTigerRPOMDP) = 3
n_observations(::SimpleTigerRPOMDP) = 2

state_index(::SimpleTigerRPOMDP, s::Symbol) = s == :tigerleft ? 1 : 2
action_index(::SimpleTigerRPOMDP, a::Symbol) = a == :listen ? 1 : a == :openleft ? 2 : 3
observation_index(::SimpleTigerRPOMDP, z::Symbol) = z == :tigerleft ? 1 : 2
obs_index(prob::SimpleTigerRPOMDP, z::Symbol) = observation_index(prob, z)

initial_state_distribution(::SimpleTigerRPOMDP) = SparseCat([:tigerleft, :tigerright], [0.5, 0.5])
initial_belief(::SimpleTigerRPOMDP) = [0.5, 0.5]

# Nominal transition function distributions
const pϵ_simpletiger = 1e-6
const tdist_simpletiger = [SparseCat(states_simpletiger, [1.0, 0.0]) SparseCat(states_simpletiger, [0.5, 0.5]) SparseCat(states_simpletiger, [0.5, 0.5]);
                    SparseCat(states_simpletiger, [0.0, 1.0]) SparseCat(states_simpletiger, [0.5, 0.5]) SparseCat(states_simpletiger, [0.5, 0.5])]

# Nominal transition function array tarray_simpletiger[s,a,s'] = Pr(s' | s ,a)
const tarray_simpletiger = cat(3, [1.0 0.5 0.5; 0.0 0.5 0.5], [0.0 0.5 0.5; 1.0 0.5 0.5]) # P(tigerleft | s, a), P(tigerright | s, a)

# Robust transitions
# P(z,t|s,a) = P(z|s,a,t)P(t|s,a)
# PztLower = PzLower * PtLower
# PtLower = Plower(t|s,a) = t_lower[s,a,sp]
function transition(prob::SimpleTigerRPOMDP, s::Symbol, a::Symbol)
    si, ai = state_index(prob, s), action_index(prob, a)
    plower = max.(tarray_simpletiger[si,ai,:] - pϵ_simpletiger, 0.0 + pϵ_simpletiger)
    pupper = min.(tarray_simpletiger[si,ai,:] + pϵ_simpletiger, 1.0 - pϵ_simpletiger)
    plower, pupper
end
function transition(prob::SimpleTigerRPOMDP, s::Symbol, a::Symbol, sp::Symbol)
    si, ai, spi = state_index(prob, s), action_index(prob, a), state_index(prob, sp)
    plower = max.(tarray_simpletiger[si, ai, spi] - pϵ_simpletiger, 0.0 + pϵ_simpletiger)
    pupper = min.(tarray_simpletiger[si, ai, spi] + pϵ_simpletiger, 1.0 - pϵ_simpletiger)
    plower, pupper
end

# Nominal observation function distributions
const odist_simpletiger = [SparseCat(observations_simpletiger, [0.85 0.15]) SparseCat(observations_simpletiger, [0.15 0.85]);
                    SparseCat(observations_simpletiger, [0.5 0.5]) SparseCat(observations_simpletiger, [0.5 0.5]);
                    SparseCat(observations_simpletiger, [0.5 0.5]) SparseCat(observations_simpletiger, [0.5 0.5])]

# Nominal observation function array oarray_simpletiger[a,sp,z] = Pr(z|a,sp)
const oarray_simpletiger = cat(3, [0.85 0.15; 0.5 0.5; 0.5 0.5], [0.15 0.85; 0.5 0.5; 0.5 0.5]) # Pr(tigerleft|a,sp), Pr(tigerright|a,sp)

# Robust observations
# P(z,t|s,a) = P(z|s,a,t)P(t|s,a)
# PztLower = PzLower * PtLower
# PzLower = Plower(z|s,a,t) = o_lower[a,sp,z]
function observation(prob::SimpleTigerRPOMDP, a::Symbol, sp::Symbol)
    ai, spi = action_index(prob, a), state_index(prob, sp)
    plower = max.(oarray_simpletiger[ai,spi,:] - prob.usize, 0.0 + pϵ_simpletiger)
    pupper = min.(oarray_simpletiger[ai,spi,:] + prob.usize, 1.0 - pϵ_simpletiger)
    plower, pupper
end
function observation(prob::SimpleTigerRPOMDP, a::Symbol, sp::Symbol, z::Symbol)
    ai, spi, zi = action_index(prob, a), state_index(prob, sp), observation_index(prob, z)
    plower = max.(oarray_simpletiger[ai, spi, zi] - prob.usize, 0.0 + pϵ_simpletiger)
    pupper = min.(oarray_simpletiger[ai, spi, zi] + prob.usize, 1.0 - pϵ_simpletiger)
    plower, pupper
end

function dynamics(prob::SimpleTigerRPOMDP)
    ns = n_states(prob)
    nz = n_observations(prob)
    na = n_actions(prob)
    tarr = states(prob)
    sarr = states(prob)
    aarr = actions(prob)
    zarr = observations(prob)
    p = Array{Float64}(ns,nz,ns,na)
    plower = Array{Float64}(ns,nz,ns,na)
    pupper = Array{Float64}(ns,nz,ns,na)
    for tind in 1:ns, zind in 1:nz, sind in 1:ns, aind in 1:na
        ptl, ptu = transition(prob, sarr[sind], aarr[aind], tarr[tind])
        pzl, pzu = observation(prob, aarr[aind], tarr[tind], zarr[zind])
        plower[tind, zind, sind, aind] = pzl * ptl
        pupper[tind, zind, sind, aind] = pzu * ptu
    end
    plower, pupper
end

function reward(prob::SimpleTigerRPOMDP, s::Symbol, a::Symbol)
    r = 0.0
    if a == :listen
        r = -1.0
    elseif a == :openleft
        r = (s == :tigerleft) ? -100.0 : 10.0
    elseif a == :openright
        r = (s == :tigerright) ? -100.0 : 10.0
    end
    return r
end
reward(prob::SimpleTigerRPOMDP, b::Vector{Float64}, s::Symbol, a::Symbol, sp::Symbol) = reward(prob,s,a)

discount(p::SimpleTigerRPOMDP) = p.discount

# Simulation Functions
function initial_state(prob::SimpleTigerRPOMDP, rng::AbstractRNG)
    d = initial_state_distribution(prob)
    return rand(rng, d)
end

function generate_sor(prob::SimpleTigerRPOMDP, b, s, a, rng::AbstractRNG)
    tdist = SparseCat(states(prob), psample(transition(prob, s, a)...))
    sp = rand(rng, tdist)
    odist = SparseCat(observations(prob), psample(observation(prob, a, sp)...))
    o = rand(rng, odist)
    r = reward(prob, b, s, a, sp)
    sp, o, r
end


text:
module MCMC

using Celeste: Model, Transform, SensitiveFloats, MCMC
using Distributions, StatsBase, DataFrames, StaticArrays, WCS

# TODO move these to model/log_prob.jl
star_param_names = ["lnr", "cug", "cgr", "cri", "ciz", "ra", "dec"]
galaxy_param_names = [star_param_names; ["gdev", "gaxis", "gangle", "gscale"]]

# functions to create star/gal log likelihoods
include("mcmc/mcmc_functions.jl")

# slice sampling function
include("mcmc/slicesample.jl")

# misc MCMC functions
include("mcmc/mcmc_misc.jl")

end

ext: jl


text:
TOL = 0.5e-8

function fixedpointiter(fun::Function, x₀::Real;
                        ε = TOL, iₘₐₓ::int = 100)
    i = 0
    xᵢ = x₀
    x₋ = 2xᵢ + 2 # not close to xᵢ and far greater than ε
    while abs( xᵢ - x₋) / abs(xᵢ) >= ε && i < iₘₐₓ
        x₋, xᵢ = xᵢ, fun(xᵢ)
        i += 1
    end
    xᵢ, i
end


text:
# =========================================================================
#    BASIC DATA GENERATION
# =========================================================================

const template_data = Ref{Any}(nothing)
b() = template_data[] #buat manggil dt default

function extract!(path::String) #extract from excel
    xf = XLSX.readxlsx(path) #READ WORKSHEET
    data = Dict{Symbol,DataFrame}() #DATAFRAME DICT

    for sheets in XLSX.sheetnames(xf) #TURN SHEETS INTO DATAFRAME
        df = DataFrame(XLSX.gettable(xf[sheets])...) #TRANSFORM TABLE INTO DATAFRAME
        data[Symbol(sheets)] = df #DEFINE THE NAME FROM THE WORKSHEET
    end

    V = Dict{Int64,vtx}() #INITIATE VERTICES
    for v in eachrow(data[:vertices]) #ITERATE OVER DATA
        V[v.id] = vtx(
            v.name, v.type,
            v.x, v.y, v.MAX, v.MIN, v.START,
            v.h
        )
    end

    dist = JuMP.Containers.DenseAxisArray{Float64}(undef, keys(V), keys(V))
    for i in keys(V), j in keys(V)
        if i != j
            dist[i,j] = haversine([V[i].x,V[i].y],[V[j].x,V[j].y],6378.137)
        else
            dist[i,j] = 999999999
        end
    end

    K = Dict{Int64,veh}() #INITIATE VEHICLES
    for k in eachrow(data[:vehicles]) #ITERATE OVER DATA
        K[k.id] = veh(
            k.name, k.type,
            parse.(Int64,split(k.cover)), k.freq, k.Q,
            k.vx, k.vl, k.fp, k.fd
        )
    end

    T = collect( #range from starting month for duration
        range(
            last(data[:periods].start),
            length = last(data[:periods].T),
            step = 1
        )
    )

    d = JuMP.Containers.DenseAxisArray(
        Array{Float64}(data[:demands][:,string.(T)]), #dataset
        Array{Int64}(data[:demands].point), #dims 1
        T #dims 2
    )

    res = dt(V,dist,K,T,d) #WRAPPING RESULT TO TYPE dt

    return template_data[] = res
end

function stats(res = b())
    uniqueVtx = unique([res.V[i].type for i in keys(res.V)])
    uniqueVeh = unique([res.K[k].type for k in keys(res.K)])

    vtxType = Dict{String,Vector{Int64}}()
    vehType = Dict{String,Vector{Int64}}()
    for t in uniqueVtx
        vtxType[t] = sort(collect(keys(filter(p -> last(p).type == t , res.V))))
    end
    for t in uniqueVeh
        vehType[t] = sort(collect(keys(filter(p -> last(p).type == t , res.K))))
    end

    cover = Vector{Int64}()
    for k in keys(res.K)
        for c in res.K[k].cover
            push!(cover,c)
        end
        unique!(cover)
    end

    dems = [mean(res.d[:,t]) for t in res.T]

    return status(
        length(res.V),
        length(res.K),
        uniqueVtx,
        uniqueVeh,
        vtxType,
        vehType,
        cover,
        dems
    )
end

function initStab(res = b();slC::Float64,suC::Float64)
    slackCoeff = slC
    surpCoeff = suC
    slackLim = abs.(res.d)
    surpLim = abs.(res.d)

    return stabilizer(slackCoeff,surpCoeff,slackLim,surpLim)
end

function root(res = b();slC::Float64,suC::Float64)
    id = uuid1()
    root = node(
        id, id,
        Vector{bound}(),Vector{col}(),
        initStab(res,slC = slC, suC = suC),
        ["UNVISITED"]
    )

    return root
end

function origin(n::node)
    z = JuMP.Containers.DenseAxisArray{Float64}(undef,keys(b().V),keys(b().K),b().T)
    q = JuMP.Containers.DenseAxisArray{Float64}(undef,keys(b().V),keys(b().K),b().T)
    y = JuMP.Containers.DenseAxisArray{Float64}(undef,keys(b().V),keys(b().K),b().T)
    u = JuMP.Containers.DenseAxisArray{Float64}(undef,keys(b().V),keys(b().K),b().T)
    p = JuMP.Containers.DenseAxisArray{Float64}(undef,keys(b().V),keys(b().K),b().T)
    v = JuMP.Containers.DenseAxisArray{Float64}(undef,keys(b().V),keys(b().K),b().T)
    x = JuMP.Containers.DenseAxisArray{Float64}(
        undef,collect(keys(b().V)),collect(keys(b().V)),collect(keys(b().K)),b().T
    )
    l = JuMP.Containers.DenseAxisArray{Float64}(
        undef,collect(keys(b().V)),collect(keys(b().V)),collect(keys(b().K)),b().T
    )

    R = Dict(1:length(n.columns) .=> n.columns)
    mp = master(n;silent=true)
    θ = mp.obj_dict[:θ]

    for i in keys(b().V), k in keys(b().K), t in b().T
        z[i,k,t] = value(sum(R[r].z[i,k,t] * θ[r,k,t] for r in keys(R)))
        y[i,k,t] = value(sum(R[r].y[i,k,t] * θ[r,k,t] for r in keys(R)))
        p[i,k,t] = value(sum(R[r].p[i,k,t] * θ[r,k,t] for r in keys(R)))
        u[i,k,t] = value(sum(R[r].u[i,k,t] * θ[r,k,t] for r in keys(R)))
        v[i,k,t] = value(sum(R[r].v[i,k,t] * θ[r,k,t] for r in keys(R)))
        q[i,k,t] = value(sum(R[r].q[i,k,t] * θ[r,k,t] for r in keys(R)))

        for j in keys(b().V)
            x[i,j,k,t] = value(sum(R[r].x[i,j,k,t] * θ[r,k,t] for r in keys(R)))
            l[i,j,k,t] = value(sum(R[r].l[i,j,k,t] * θ[r,k,t] for r in keys(R)))
        end
    end

    return col(
        q,u,v,l,
        p,y,z,x
    )
end


text:
# This file is a part of Julia. License is MIT: https://julialang.org/license

@testset "string escaping & unescaping" begin
    cx = Any[
        0x00000000      '\0'        "\\0"
        0x00000001      '\x01'      "\\x01"
        0x00000006      '\x06'      "\\x06"
        0x00000007      '\a'        "\\a"
        0x00000008      '\b'        "\\b"
        0x00000009      '\t'        "\\t"
        0x0000000a      '\n'        "\\n"
        0x0000000b      '\v'        "\\v"
        0x0000000c      '\f'        "\\f"
        0x0000000d      '\r'        "\\r"
        0x0000000e      '\x0e'      "\\x0e"
        0x0000001a      '\x1a'      "\\x1a"
        0x0000001b      '\e'        "\\e"
        0x0000001c      '\x1c'      "\\x1c"
        0x0000001f      '\x1f'      "\\x1f"
        0x00000020      ' '         " "
        0x0000002f      '/'         "/"
        0x00000030      '0'         "0"
        0x00000039      '9'         "9"
        0x0000003a      ':'         ":"
        0x00000040      '@'         "@"
        0x00000041      'A'         "A"
        0x0000005a      'Z'         "Z"
        0x0000005b      '['         "["
        0x00000060      '`'         "`"
        0x00000061      'a'         "a"
        0x0000007a      'z'         "z"
        0x0000007b      '{'         "{"
        0x0000007e      '~'         "~"
        0x0000007f      '\x7f'      "\\x7f"
        0x000000bf      '\ubf'      "\\ubf"
        0x000000ff      '\uff'      "\\uff"
        0x00000100      '\u100'     "\\u100"
        0x000001ff      '\u1ff'     "\\u1ff"
        0x00000fff      '\ufff'     "\\ufff"
        0x00001000      '\u1000'    "\\u1000"
        0x00001fff      '\u1fff'    "\\u1fff"
        0x0000ffff      '\uffff'    "\\uffff"
        0x00010000      '\U10000'   "\\U10000"
        0x0001ffff      '\U1ffff'   "\\U1ffff"
        0x0002ffff      '\U2ffff'   "\\U2ffff"
        0x00030000      '\U30000'   "\\U30000"
        0x000dffff      '\Udffff'   "\\Udffff"
        0x000e0000      '\Ue0000'   "\\Ue0000"
        0x000effff      '\Ueffff'   "\\Ueffff"
        0x000f0000      '\Uf0000'   "\\Uf0000"
        0x000fffff      '\Ufffff'   "\\Ufffff"
        0x00100000      '\U100000'  "\\U100000"
        0x0010ffff      '\U10ffff'  "\\U10ffff"
    ]

    buf = IOBuffer()
    @test typeof(escape_string(buf, "test")) == Nothing
    @test String(take!(buf)) == "test"
    @test typeof(escape_string(buf, "hello", "l")) == Nothing
    @test String(take!(buf)) == "he\\l\\lo"

    @test typeof(escape_string("test", "t")) == String
    @test escape_string("test", "t") == "\\tes\\t"

    for i = 1:size(cx,1)
        cp, ch, st = cx[i,:]
        @test cp == convert(UInt32, ch)
        @test string(ch) == unescape_string(st)
        if isascii(ch) || !isprint(ch)
            @test st == escape_string(string(ch))
        end
        for j = 1:size(cx,1)
            local str = string(ch, cx[j,2])
            @test str == unescape_string(escape_string(str))
        end
        @test repr(ch) == "'$(isprint(ch) ? ch : st)'"
    end

    for i = 0:0x7f, p = ["","\0","x","xxx","\x7f","\uFF","\uFFF",
                         "\uFFFF","\U10000","\U10FFF","\U10FFFF"]
        c = Char(i)
        cp = string(c,p)
        op = string(Char(div(i,8)), string(i%8, base = 8), p)
        hp = string(Char(div(i,16)), string(i%16, base = 16), p)
        @test string(unescape_string(string("\\",string(i,base=8,pad=1),p))) == cp
        @test string(unescape_string(string("\\",string(i,base=8,pad=2),p))) == cp
        @test string(unescape_string(string("\\",string(i,base=8,pad=3),p))) == cp
        @test string(unescape_string(string("\\",string(i,base=8,pad=4),p))) == op
        @test string(unescape_string(string("\\x",string(i,base=16,pad=1),p))) == cp
        @test string(unescape_string(string("\\x",string(i,base=16,pad=2),p))) == cp
        @test string(unescape_string(string("\\x",string(i,base=16,pad=3),p))) == hp
    end

    @testset "unescape_string" begin
        @test "\0" == unescape_string("\\0")
        @test "\1" == unescape_string("\\1")
        @test "\7" == unescape_string("\\7")
        @test "\0x" == unescape_string("\\0x")
        @test "\1x" == unescape_string("\\1x")
        @test "\7x" == unescape_string("\\7x")
        @test "\00" == unescape_string("\\00")
        @test "\01" == unescape_string("\\01")
        @test "\07" == unescape_string("\\07")
        @test "\70" == unescape_string("\\70")
        @test "\71" == unescape_string("\\71")
        @test "\77" == unescape_string("\\77")
        @test "\00x" == unescape_string("\\00x")
        @test "\01x" == unescape_string("\\01x")
        @test "\07x" == unescape_string("\\07x")
        @test "\70x" == unescape_string("\\70x")
        @test "\71x" == unescape_string("\\71x")
        @test "\77x" == unescape_string("\\77x")
        @test "\000" == unescape_string("\\000")
        @test "\001" == unescape_string("\\001")
        @test "\007" == unescape_string("\\007")
        @test "\070" == unescape_string("\\070")
        @test "\071" == unescape_string("\\071")
        @test "\077" == unescape_string("\\077")
        @test "\170" == unescape_string("\\170")
        @test "\171" == unescape_string("\\171")
        @test "\177" == unescape_string("\\177")
        @test "\0001" == unescape_string("\\0001")
        @test "\0011" == unescape_string("\\0011")
        @test "\0071" == unescape_string("\\0071")
        @test "\0701" == unescape_string("\\0701")
        @test "\0711" == unescape_string("\\0711")
        @test "\0771" == unescape_string("\\0771")
        @test "\1701" == unescape_string("\\1701")
        @test "\1711" == unescape_string("\\1711")
        @test "\1771" == unescape_string("\\1771")

        @test "\x0" == unescape_string("\\x0")
        @test "\x1" == unescape_string("\\x1")
        @test "\xf" == unescape_string("\\xf")
        @test "\xF" == unescape_string("\\xF")
        @test "\x0x" == unescape_string("\\x0x")
        @test "\x1x" == unescape_string("\\x1x")
        @test "\xfx" == unescape_string("\\xfx")
        @test "\xFx" == unescape_string("\\xFx")
        @test "\x00" == unescape_string("\\x00")
        @test "\x01" == unescape_string("\\x01")
        @test "\x0f" == unescape_string("\\x0f")
        @test "\x0F" == unescape_string("\\x0F")
    end
end
@testset "join()" begin
    @test join([]) == ""
    @test join(["a"],"?") == "a"
    @test join("HELLO",'-') == "H-E-L-L-O"
    @test join(1:5, ", ", " and ") == "1, 2, 3, 4 and 5"
    @test join(["apples", "bananas", "pineapples"], ", ", " and ") == "apples, bananas and pineapples"
    @test_throws MethodError join(1, 2, 3, 4)
end

# issue #9178 `join` calls `done()` twice on the iterables
mutable struct i9178
    nnext::Int64
    ndone::Int64
end
Base.start(jt::i9178) = (jt.nnext=0 ; jt.ndone=0 ; 0)
Base.done(jt::i9178, n) = (jt.ndone += 1 ; n > 3)
Base.next(jt::i9178, n) = (jt.nnext += 1 ; ("$(jt.nnext),$(jt.ndone)", n+1))
@test join(i9178(0,0), ";") == "1,1;2,2;3,3;4,4"

# quotes + interpolation (issue #455)
@test "$("string")" == "string"
arr = ["a","b","c"]
@test "[$(join(arr, " - "))]" == "[a - b - c]"

# join with empty input
myio = IOBuffer()
join(myio, "", "", 1)
@test isempty(take!(myio))

@testset "unescape_string ArgumentErrors" begin
    @test_throws ArgumentError unescape_string(IOBuffer(), string('\\',"xZ"))
    @test_throws ArgumentError unescape_string(IOBuffer(), string('\\',"777"))
end
@testset "#11659" begin
    # The indentation code was not correctly counting tab stops
    @test Base.indentation("      \t") == (8, true)
    @test Base.indentation("  \tfoob") == (8, false)
    @test Base.indentation(" \t \t")   == (16, true)

    @test Base.unindent("\tfoo",0) == "\tfoo"
    @test Base.unindent("\tfoo",4) == "    foo"
    @test Base.unindent("    \tfoo",4) == "    foo"
    @test Base.unindent("\t\n    \tfoo",4) == "    \n    foo"
    @test Base.unindent("\tfoo\tbar",4) == "    foo     bar"
    @test Base.unindent("\n\tfoo",4) == "\n    foo"
    @test Base.unindent("\n    \tfoo",4) == "\n    foo"
    @test Base.unindent("\n\t\n    \tfoo",4) == "\n    \n    foo"
    @test Base.unindent("\n\tfoo\tbar",4) == "\n    foo     bar"
end

# issue #22021, string realloc bug with join
s22021 = String["\"\"\"
     non_max_suppression(boxes, scores, max_output_size; iou_threshold=nothing)

Greedily selects a subset of bounding boxes in descending order of score,

pruning away boxes that have high intersection-over-union (IOU) overlap
with previously selected boxes.  Bounding boxes are supplied as
[y1, x1, y2, x2], where (y1, x1) and (y2, x2) are the coordinates of any
diagonal pair of box corners and the coordinates can be provided as normalized
(i.e., lying in the interval [0, 1]) or absolute.  Note that this algorithm
is agnostic to where the origin is in the coordinate system.  Note that this
algorithm is invariant to orthogonal transformations and translations
of the coordinate system; thus translating or reflections of the coordinate
system result in the same boxes being selected by the algorithm.

The output of this operation is a set of integers indexing into the input
collection of bounding boxes representing the selected boxes.  The bounding
box coordinates corresponding to the selected indices can then be obtained
using the `tf.gather operation`.  For example:

  selected_indices = tf.image.non_max_suppression(
      boxes, scores, max_output_size, iou_threshold)
  selected_boxes = tf.gather(boxes, selected_indices)
\"\"\"",
    "    tf.@op function non_max_suppression(v13566, v13567, v13568; name=nothing, iou_threshold=nothing) ",
    "            local desc ",
    "            tf.with_op_name((()->begin  ",
    "                        desc = tf.NodeDescription(\"NonMaxSuppression\") ",
    "                        begin  ",
    "                            begin  ",
    "                                v13566 = convert(TensorFlow.Tensor{Float32}, v13566) ",
    "                                begin  ",
    "                                end",
    "                            end",
    "                            begin  ",
    "                                v13567 = convert(TensorFlow.Tensor{Float32}, v13567) ",
    "                                begin  ",
    "                                end",
    "                            end",
    "                            begin  ",
    "                                v13568 = convert(TensorFlow.Tensor{Int32}, v13568) ",
    "                                begin  ",
    "                                end",
    "                            end",
    "                        end ",
    "                        begin  ",
    "                            begin  ",
    "                                tf.add_input(desc, v13566)",
    "                            end",
    "                            begin  ",
    "                                tf.add_input(desc, v13567)",
    "                            end",
    "                            begin  ",
    "                                tf.add_input(desc, v13568)",
    "                            end",
    "                        end ",
    "                        begin  ",
    "                            begin  ",
    "                                if iou_threshold !== nothing ",
    "                                    desc[\"iou_threshold\"] = Base.identity(iou_threshold)",
    "                                end",
    "                            end",
    "                        end",
    "                    end), name, \"NonMaxSuppression\") ",
    "            tf.Tensor(tf.Operation(desc))",
    "        end"]

for i = 1:10
    buf = IOBuffer()
    print(buf, join(s22021, "\n"))
    @test isvalid(String, take!(buf))
end

max_stars_repo_name: djsegal/julia-fork

max_issues_repo_name: djsegal/julia-fork

max_forks_repo_name: djsegal/julia-fork


text:
using Documenter, SubpixelRegistration

makedocs(modules= subpixelRegistration)
deploydocs(
    julia = "nightly",
    deps   = Deps.pip("mkdocs", "python-markdown-math"),
    repo = "github.com/romainFr/SubpixelRegistration.jl.git"
)


text:
using GridapFSI

output = main(
  strategy="biharmonic",
  alpha_m=1.0e-6,
  alpha_m_weight="volume",
  model="models/elasticFlagFine.json",
  dt=0.01,
  tf=10.0,
  theta=0.6
)


text:
using PyPlot, Images
using PyCall
@pyimport numpy

function DIC_cosine_transform(img_name,lambda)

    # import image
    raw_img = PyPlot.imread(img_name);
    img = convert(Image{Images.Gray},raw_img[:,:,1:3]);
    M = convert(Array,img);
    M = float(M);

    #subtract average of each column
    mx, my = size(M)
    m1 = mean(M[:,1])
    mL = mean(M[:,end])
    for i=1:mx
        M[:,i] = M[:,i] - mean(M[:,i])
    end

    gX, gY = numpy.gradient(M);
    d1 = FFTW.r2r(gY,FFTW.REDFT00)
    nx, ny = size(d1)
    d2=zeros(ny,nx)
    d2=[(nx/pi)^2 * d1[j,i]/(lambda*j^(2.0) + i^2) for i in 1:ny, j in 1:nx];
    #d2=[(nx/pi)^2 * d1[j,i] for i in 1:ny, j in 1:nx];

    dst = convert(Array{Float64,2},d2)
    e1 = FFTW.r2r(dst,FFTW.REDFT00)
    e1 = e1 / (2*nx)^2

    maxi = maximum(e1)
    mini = minimum(e1)
    clamped = 1 +  (-e1 + maxi) * 1 / ( mini-maxi);
    out_name = split(image_name,".")[1] * "_cos_l=$(@sprintf("%.2f", lambda))" * ".png"
    imwrite(grayim(clamped),out_name)

    return 0

end

max_stars_repo_name: bcollyer/DICkit

max_issues_repo_name: bcollyer/DICkit

max_forks_repo_name: bcollyer/DICkit


text:
using Gtk.ShortNames, Graphics
using DataFrames
using SQLite

include("game_init.jl")
include("move.jl")
include("game_init.jl")
include("validate_alone.jl")
include("types.jl")
include("win.jl")
include("move_helpers.jl")

function readMove()
    global moveNum
    global currentMove
    global server
    move=chomp(readline(server))
    move=split(move,":")
    println(move)
    sx=parse(Int64,String(move[5]))
    sy=parse(Int64,String(move[6]))
    tx=parse(Int64,String(move[7]))
    ty=parse(Int64,String(move[8]))
    currentMove+=1
    println(move)
    push!(userMove,(sx,sy))
    push!(userMove,(tx,ty))
    moveCheck()
end

function sendMove(sx,sy,tx,ty)
    global server
    global authString
    global currentMove
    move="2:$authString:$currentMove:1:$sx:$sy:$tx:$ty:0:0:0:0:0:0"
    println(server,move)
    currentMove+=1
end

function getPiece(xCoord,yCoord)
    for piece in pieceArr
        if piece.x==xCoord && piece.y==yCoord
            return piece
        end
    end
end

function getImage(p::piece)
    path=pwd()
    path=joinpath(path,"images")
    if gameType=="standard"
        path=joinpath(path,"standard")
    elseif gameType=="minishogi"
        path=joinpath(path,"mini")
    elseif  gameType=="chu"
        path=joinpath(path,"chu")
    else
        path=joinpath(path,"tenjiku")
    end
    path=joinpath(path,color)
    side = p.side == 0? "left":"right"
    path=joinpath(path,side)
    if p.promoted
        path=joinpath(path,string(lowercase(p.original),"p"))
    else
        path=joinpath(path,string(p.name))
    end
    path=path*".jpg"
end

function checkWin(typeMove, istimed, sentetime, gotetime, boards)

    global window
    global grid
    frame=@Frame()
    button=@Button()
    setproperty!(button,:label,"Click to exit.")
    id=signal_connect(button,"clicked") do widget
        destroy(window)
    end
    if win(typeMove, istimed, sentetime, gotetime, boards)=="W"
        setproperty!(button,:label,"Gote wins! Click to exit.")
        destroy(grid)
        push!(frame,button)
        push!(window,frame)
        showall(window)
        return true
    elseif win(typeMove, istimed, sentetime, gotetime, boards)=="B"
        setproperty!(button,:label,"Sente wins! Click to exit.")
        destroy(grid)
        push!(frame,button)
        push!(window,frame)
        showall(window)
        return true
    else
        return false
    end
end

function checkPromote(p,number,tx)
    global gameType
    global gote_promo_range
    global sente_promo_range
    if number%2==1
        if tx in sente_promo_range
            p=promote(p,gameType)
            return p
        end
    else
        if tx in gote_promo_range
            p=promote(p,gameType)
            return p
        end
    end
    return p
end

function movePieceGUI(sx,sy,tx,ty)
    global board
    global moveNum
    p=getPiece(sx,sy)
    if p!=nothing
        t=getPiece(tx,ty)
        if t!=nothing
            t.x=-1
            t.y=-1
        end
        a=checkPromote(p,moveNum,tx)
        p.name=a.name
        p.promoted=a.promoted
        p.x=tx
        p.y=ty
        eImage=@Image()
        setproperty!(eImage,:file,emptyPath)
        setproperty!(grid[sx,sy],:image,eImage)
        i=@Image()
        setproperty!(i,:file,getImage(p))
        setproperty!(grid[tx,ty],:image,i)
    end
end

function reset()
    for y in 1: N
        for x in 1:N
            image = @Image()
            setproperty!(image, :file, emptyPath)
            b=@Button()
            setproperty!(b,:image,image)
            grid[x,y]=b
        end
    end
end

function setBoardGUI()
    for p in pieceArr
        if p.x!=-1
            image = @Image()
            setproperty!(image, :file, getImage(p))
            destroy(grid[p.x,p.y])
            b=@Button()
            setproperty!(b,:image,image)
            grid[p.x,p.y]=b
        end
    end
end

function moveCheck()
    global board
    global userTurn
    global prevtx
    global prevty
    global prevsx
    global prevsy
    global DF
    global userMove
    global moveNum
    sx=userMove[1][1]
    sy=userMove[1][2]
    tx=userMove[2][1]
    ty=userMove[2][2]
    tx2=-1
    ty2=-1
    tx3=-1
    ty3=-1
    if DF==1
        if tx==sx && ty==sy #Doesnt want second move
            thisMove=move(moveNum,"move",prevsx,prevsy,sx,sy,"",false,tx2,ty2,tx3,ty3)
            userMove=[]
        else #wants second move
            thisMove=move(moveNum,"move",prevsx,prevsy,prevtx,prevty,"",false,tx,ty,tx3,ty3)
            @async begin
            sendMove(sx,sy,tx,ty)
        end
            movePieceGUI(sx,sy,tx,ty)
            userMakingMove=readline(server)
            userMove=[]
        end
        if moveNum%2==1
            if !(sx in sente_promo_range) && ((tx in sente_promo_range) || (tx2 in sente_promo_range) || (tx3 in sente_promo_range))
                thisMove.option="!"
            end
        else
            if !(sx in gote_promo_range) && ((tx in gote_promo_range) || (tx2 in gote_promo_range) || (tx3 in gote_promo_range))
                thisMove.option="!"
            end
        end
        board[ty][tx]=board[sy][sx]
        board[ty][tx]=checkPromote(board[ty][tx],moveNum,tx)
        board[sy][sx]=empty
        push!(allBoards,duplicateBoard(board))
        if checkWin(thisMove.move_type,isTimed,sente_time,gote_time,allBoards)
            return
        end
        DF=0
    else
        if getPiece(sx,sy)!= nothing && getPiece(sx,sy).name in double && DF==0
            DF=1
            moveNum-=1
            @async begin
            sendMove(sx,sy,tx,ty)
        end
            movePieceGUI(sx,sy,tx,ty)
            userMakingMove=readline(server)
            userMove=[]
        else
            thisMove=move(moveNum,"move",sx,sy,tx,ty,"",false,tx2,ty2,tx3,ty3)
            if moveNum%2==1
                if !(sx in sente_promo_range) && ((tx in sente_promo_range) || (tx2 in sente_promo_range) || (tx3 in sente_promo_range))
                    thisMove.option="!"
                end
            else
                if !(sx in gote_promo_range) && ((tx in gote_promo_range) || (tx2 in gote_promo_range) || (tx3 in gote_promo_range))
                    thisMove.option="!"
                end
            end
            @async begin
            sendMove(sx,sy,tx,ty)
        end
            movePieceGUI(sx,sy,tx,ty)
            userMakingMove=readline(server)
            userMove=[]
            board[ty][tx]=board[sy][sx]
            board[ty][tx]=checkPromote(board[ty][tx],moveNum,tx)
            board[sy][sx]=empty
            push!(allBoards,duplicateBoard(board))
            if checkWin(thisMove.move_type,isTimed,sente_time,gote_time,allBoards)
                return
            end
        end
    end
    prevsx=sx
    prevsy=sy
    prevtx=tx
    prevty=ty
    moveNum+=1
    if moveNum%2==userTurn
        if userTurn==1
            init_buttons("sente")
        else
            init_buttons("gote")
        end
    else
        readMove()
    end
end

function clear_buttons()
    for a in 1:length(id2Arr)
        if id2Arr[a][1]!=0
            try
                signal_handler_block(grid[id2Arr[a][2],id2Arr[a][3]],(id2Arr[a][1]))
            catch e
                signal_handler_block(grid[id2Arr[a][2],id2Arr[a][3]],Int64(id2Arr[a][1]))
            end
        end
    end
    for b in 1:length(idArr)
        if idArr[b][1]!=0
            try
                signal_handler_block(grid[idArr[b][2],idArr[b][3]],(idArr[b][1]))
            catch e
                signal_handler_block(grid[idArr[b][2],idArr[b][3]],Int64(idArr[b][1]))
            end
        end
    end
end

function init_target_buttons(sx,sy)
    global sente_time
    global gote_time
    clear_buttons()
    global id
    for y in 1:N
        for x in 1:N
            tempMove=move(moveNum,"move",sx,sy,x,y,"",false,-1,-1,-1,-1)
            id2=0
            if inRange(board,tempMove)
                id2=signal_connect(grid[x,y],"clicked") do widget
                    push!(userMove,(x,y))
                    if moveNum%2==1
                        sente_time-=toc()
                        sente_time+=timeAdd
                        println(sente_time)
                    else
                        gote_time-=toc()
                        gote_time+=timeAdd
                        println(gote_time)
                    end
                    for a in 1:N
                        for b in 1:N
                            setproperty!(grid[b,a],:sensitive,true)
                        end
                    end
                    moveCheck()
                end
            else
                setproperty!(grid[x,y],:sensitive,false)
            end
            push!(id2Arr,(id2,x,y))
        end
    end
end

function init_buttons(side::String)
    global DF
    clear_buttons()
    if DF==1
        id=signal_connect(grid[prevtx,prevty],"clicked") do widget
                tic()
                push!(userMove,(prevtx,prevty))
                init_target_buttons(prevtx,prevty)
            end
        push!(idArr,(id,prevtx,prevty))
    elseif side=="sente"
        for p in sente
            if p.x!=-1
            id=signal_connect(grid[p.x,p.y],"clicked") do widget
                tic()
                push!(userMove,(p.x,p.y))
                init_target_buttons(p.x,p.y)
            end
            push!(idArr,(id,p.x,p.y))
        end
        end
    else
        for p in gote
            if p.x!=-1
            id=signal_connect(grid[p.x,p.y],"clicked") do widget
                tic()
                push!(userMove,(p.x,p.y))
                init_target_buttons(p.x,p.y)
            end
            push!(idArr,(id,p.x,p.y))
        end
    end
    end
end

#$port $gameType $timeLimit $timeIncrement $japaneseRoulette $cheatingAllowed

function client_join(portNum,ipAddr,colorBoard)
global ip=ipAddr
global port=portNum
global gameType="standard"
global timeLimit=0
global timeAdd=0
global japaneseRoulette=false
global cheatingAllowed="F"
global color=colorBoard

if cheatingAllowed=="T"
    global noCheating=0
else
    global noCheating=1
end

global currentMove=1
global gote_time=timeLimit
global sente_time=timeLimit

global requestGame=string("0:",uppercase(gameType[1]),":$noCheating:$timeLimit:$timeAdd")

global server=connect(port)
println(server, requestGame)

global settings=split(chomp(readline(server)),":")
println(settings)

global authString=settings[2]

if settings[1]=="0"
    global goFirst=true
else
    global goFirst=false
end

if settings[3]=="S"
    gameType="standard"
    global N=9
elseif settings[3]=="M"
    gameType="mini"
    global N=5
elseif  settings[3]=="C"
    gameType="chu"
    global N=12
else
    gameType="tenjiku"
    global N=16
end

global empty=piece("", "", 0, 0, -1, false)

global board = [ [ empty for i = 1:N ] for j = 1:N ]
global allBoards=[]
global pieceArr=[]

global sente_promo_range
global gote_promo_range

if gameType == "tenjiku"
        sente_promo_range=1:5
        gote_promo_range=12:16
        # sente/black/odd pieces
        board[1][16] = piece("lance", "lance", 16, 1, 1, false)
        board[16][16] = piece("lance", "lance", 16, 16, 1, false)
        board[2][16] = piece("knight", "knight", 16, 2, 1, false)
        board[15][16] = piece("knight", "knight", 16, 15, 1, false)
        board[3][16] = piece("leopard", "leopard", 16, 3, 1, false) # ferocious leopard
        board[14][16] = piece("leopard", "leopard", 16, 14, 1, false) # ferocious leopard
        board[4][16] = piece("iron", "iron", 16, 4, 1, false) # iron general
        board[13][16] = piece("iron", "iron", 16, 13, 1, false) # iron general
        board[5][16] = piece("copper", "copper", 16, 5, 1, false) # copper general
        board[12][16] = piece("copper", "copper", 16, 12, 1, false) # copper general
        board[6][16] = piece("silver", "silver", 16, 6, 1, false) # silver general
        board[11][16] = piece("silver", "silver", 16, 11, 1, false) # silver general
        board[7][16] = piece("gold", "gold", 16, 7, 1, false) # gold general
        board[10][16] = piece("gold", "gold", 16, 10, 1, false) # gold general
        board[8][16] = piece("elephant", "elephant", 16, 8, 1, false) # drunk elephant
        board[9][16] = piece("king", "king", 16, 9, 1, false)
        board[1][15] = piece("chariot", "chariot", 15, 1, 1, false) # reverse chariot
        board[16][15] = piece("chariot", "chariot", 15, 16, 1, false) # reverse chariot
        board[3][15] = piece("csoldier", "csoldier", 15, 3, 1, false) # chariot soldier
        board[4][15] = piece("csoldier", "csoldier", 15, 4, 1, false) # chariot soldier
        board[13][15] = piece("csoldier", "csoldier", 15, 13, 1, false) # chariot soldier
        board[14][15] = piece("csoldier", "csoldier", 15, 14, 1, false) # chariot soldier
        board[6][15] = piece("tiger", "tiger", 15, 6, 1, false) # blind tiger
        board[11][15] = piece("tiger", "tiger", 15, 11, 1, false) # blind tiger
        board[7][15] = piece("phoenix", "phoenix", 15, 7, 1, false)
        board[8][15] = piece("queen", "queen", 15, 8, 1, false)
        board[9][15] = piece("lion", "lion", 15, 9, 1, false)
        board[10][15] = piece("kirin", "kirin", 15, 10, 1, false)
        board[1][14] = piece("ssoldier", "ssoldier", 14, 1, 1, false) # side soldier
        board[16][14] = piece("ssoldier", "ssoldier", 14, 16, 1, false) # side soldier
        board[2][14] = piece("vsoldier", "vsoldier", 14, 2, 1, false) # vertical soldier
        board[15][14] = piece("vsoldier", "vsoldier", 14, 15, 1, false) # vertical soldier
        board[3][14] = piece("bishop", "bishop", 14, 3, 1, false)
        board[14][14] = piece("bishop", "bishop", 14, 14, 1, false)
        board[4][14] = piece("horse", "horse", 14, 4, 1, false) # dragon horse
        board[13][14] = piece("horse", "horse", 14, 13, 1, false) # dragon horse
        board[5][14] = piece("dragon", "dragon", 14, 5, 1, false) # dragon king
        board[12][14] = piece("dragon", "dragon", 14, 12, 1, false) # dragon king
        board[6][14] = piece("buffalo", "buffalo", 14, 6, 1, false) # water buffalo
        board[11][14] = piece("buffalo", "buffalo", 14, 11, 1, false) # water buffalo
        board[7][14] = piece("demon", "demon", 14, 7, 1, false) # fire demon
        board[10][14] = piece("demon", "demon", 14, 10, 1, false) # fire demon
        board[8][14] = piece("eagle", "eagle", 14, 8, 1, false) # free eagle
        board[9][14] = piece("hawk", "hawk", 14, 9, 1, false) # lion hawk
        board[1][13] = piece("smover", "smover", 13, 1, 1, false) # side mover
        board[16][13] = piece("smover", "smover", 13, 16, 1, false) # side mover
        board[2][13] = piece("vmover", "vmover", 13, 2, 1, false) # vertical mover
        board[15][13] = piece("vmover", "vmover", 13, 15, 1, false) # vertical mover
        board[3][13] = piece("rook", "rook", 13, 3, 1, false)
        board[14][13] = piece("rook", "rook", 13, 14, 1, false)
        board[4][13] = piece("falcon", "falcon", 13, 4, 1, false) # horned falcon
        board[13][13] = piece("falcon", "falcon", 13, 13, 1, false) # horned falcon
        board[5][13] = piece("soaring", "soaring", 13, 5, 1, false) # soaring eagle
        board[12][13] = piece("soaring", "soaring", 13, 12, 1, false) # soaring eagle
        board[6][13] = piece("bgeneral", "bgeneral", 13, 6, 1, false) # bishop general
        board[11][13] = piece("bgeneral", "bgeneral", 13, 11, 1, false) # bishop general
        board[7][13] = piece("rgeneral", "rgeneral", 13, 7, 1, false) # rook general
        board[10][13] = piece("rgeneral", "rgeneral", 13, 10, 1, false) # rook general
        board[8][13] = piece("vice", "vice", 13, 8, 1, false) # vice general
        board[9][13] = piece("great", "great", 13, 9, 1, false) # great general
        board[1][12] = piece("pawn", "pawn", 12, 1, 1, false)
        board[2][12] = piece("pawn", "pawn", 12, 2, 1, false)
        board[3][12] = piece("pawn", "pawn", 12, 3, 1, false)
        board[4][12] = piece("pawn", "pawn", 12, 4, 1, false)
        board[5][12] = piece("pawn", "pawn", 12, 5, 1, false)
        board[6][12] = piece("pawn", "pawn", 12, 6, 1, false)
        board[7][12] = piece("pawn", "pawn", 12, 7, 1, false)
        board[8][12] = piece("pawn", "pawn", 12, 8, 1, false)
        board[9][12] = piece("pawn", "pawn", 12, 9, 1, false)
        board[10][12] = piece("pawn", "pawn", 12, 10, 1, false)
        board[11][12] = piece("pawn", "pawn", 12, 11, 1, false)
        board[12][12] = piece("pawn", "pawn", 12, 12, 1, false)
        board[13][12] = piece("pawn", "pawn", 12, 13, 1, false)
        board[14][12] = piece("pawn", "pawn", 12, 14, 1, false)
        board[15][12] = piece("pawn", "pawn", 12, 15, 1, false)
        board[16][12] = piece("pawn", "pawn", 12, 16, 1, false)
        board[5][11] = piece("dog", "dog", 11, 5, 1, false)
        board[12][11] = piece("dog", "dog", 11, 12, 1, false)

        # gote/white/even pieces
        board[1][1] = piece("lance", "lance", 1, 1, 0, false)
        board[16][1] = piece("lance", "lance", 1, 16, 0, false)
        board[2][1] = piece("knight", "knight", 1, 2, 0, false)
        board[15][1] = piece("knight", "knight", 1, 15, 0, false)
        board[3][1] = piece("leopard", "leopard", 1, 3, 0, false) # ferocious leopard
        board[14][1] = piece("leopard", "leopard", 1, 14, 0, false) # ferocious leopard
        board[4][1] = piece("iron", "iron", 1, 4, 0, false) # iron general
        board[13][1] = piece("iron", "iron", 1, 13, 0, false) # iron general
        board[5][1] = piece("copper", "copper", 1, 5, 0, false) # copper general
        board[12][1] = piece("copper", "copper", 1, 12, 0, false) # copper general
        board[6][1] = piece("silver", "silver", 1, 6, 0, false) # silver general
        board[11][1] = piece("silver", "silver", 1, 11, 0, false) # silver general
        board[7][1] = piece("gold", "gold", 1, 7, 0, false) # gold general
        board[10][1] = piece("gold", "gold", 1, 10, 0, false) # gold general
        board[8][1] = piece("king", "king", 1, 8, 0, false) # king
        board[9][1] = piece("elephant", "elephant", 1, 9, 0, false) # drunk elephant
        board[1][2] = piece("chariot", "chariot", 2, 1, 0, false) # reverse chariot
        board[16][2] = piece("chariot", "chariot", 2, 16, 0, false) # reverse chariot
        board[3][2] = piece("csoldier", "csoldier", 2, 3, 0, false) # chariot soldier
        board[4][2] = piece("csoldier", "csoldier", 2, 4, 0, false) # chariot soldier
        board[13][2] = piece("csoldier", "csoldier", 2, 13, 0, false) # chariot soldier
        board[14][2] = piece("csoldier", "csoldier", 2, 14, 0, false) # chariot soldier
        board[6][2] = piece("tiger", "tiger", 2, 6, 0, false) # blind tiger
        board[11][2] = piece("tiger", "tiger", 2, 11, 0, false) # blind tiger
        board[7][2] = piece("kirin", "kirin", 2, 7, 0, false)
        board[8][2] = piece("lion", "lion", 2, 8, 0, false)
        board[9][2] = piece("queen", "queen", 2, 9, 0, false)
        board[10][2] = piece("phoenix", "phoenix", 2, 10, 0, false)
        board[1][3] = piece("ssoldier", "ssoldier", 3, 1, 0, false) # side soldier
        board[16][3] = piece("ssoldier", "ssoldier", 3, 16, 0, false) # side soldier
        board[2][3] = piece("vsoldier", "vsoldier", 3, 2, 0, false) # vertical soldier
        board[15][3] = piece("vsoldier", "vsoldier", 3, 15, 0, false) # vertical soldier
        board[3][3] = piece("bishop", "bishop", 3, 3, 0, false)
        board[14][3] = piece("bishop", "bishop", 3, 14, 0, false)
        board[4][3] = piece("horse", "horse", 3, 4, 0, false) # dragon horse
        board[13][3] = piece("horse", "horse", 3, 13, 0, false) # dragon horse
        board[5][3] = piece("dragon", "dragon", 3, 5, 0, false) # dragon king
        board[12][3] = piece("dragon", "dragon", 3, 12, 0, false) # dragon king
        board[6][3] = piece("buffalo", "buffalo", 3, 6, 0, false) # water buffalo
        board[11][3] = piece("buffalo", "buffalo", 3, 11, 0, false) # water buffalo
        board[7][3] = piece("demon", "demon", 3, 7, 0, false) # fire demon
        board[10][3] = piece("demon", "demon", 3, 10, 0, false) # fire demon
        board[8][3] = piece("hawk", "hawk", 3, 8, 0, false) # lion hawk
        board[9][3] = piece("eagle", "eagle", 3, 9, 0, false) # free eagle
        board[1][4] = piece("smover", "smover", 4, 1, 0, false) # side mover
        board[16][4] = piece("smover", "smover", 4, 16, 0, false) # side mover
        board[2][4] = piece("vmover", "vmover", 4, 2, 0, false) # vertical mover
        board[15][4] = piece("vmover", "vmover", 4, 15, 0, false) # vertical mover
        board[3][4] = piece("rook", "rook", 4, 3, 0, false)
        board[14][4] = piece("rook", "rook", 4, 14, 0, false)
        board[4][4] = piece("falcon", "falcon", 4, 4, 0, false) # horned falcon
        board[13][4] = piece("falcon", "falcon", 4, 13, 0, false) # horned falcon
        board[5][4] = piece("soaring", "soaring", 4, 5, 0, false) # soaring eagle
        board[12][4] = piece("soaring", "soaring", 4, 12, 0, false) # soaring eagle
        board[6][4] = piece("bgeneral", "bgeneral", 4, 6, 0, false) # bishop general
        board[11][4] = piece("bgeneral", "bgeneral", 4, 11, 0, false) # bishop general
        board[7][4] = piece("rgeneral", "rgeneral", 4, 7, 0, false) # rook general
        board[10][4] = piece("rgeneral", "rgeneral", 4, 10, 0, false) # rook general
        board[8][4] = piece("great", "great", 4, 8, 0, false) # great general
        board[9][4] = piece("vice", "vice", 4, 9, 0, false) # vice general
        board[1][5] = piece("pawn", "pawn", 5, 1, 0, false)
        board[2][5] = piece("pawn", "pawn", 5, 2, 0, false)
        board[3][5] = piece("pawn", "pawn", 5, 3, 0, false)
        board[4][5] = piece("pawn", "pawn", 5, 4, 0, false)
        board[5][5] = piece("pawn", "pawn", 5, 5, 0, false)
        board[6][5] = piece("pawn", "pawn", 5, 6, 0, false)
        board[7][5] = piece("pawn", "pawn", 5, 7, 0, false)
        board[8][5] = piece("pawn", "pawn", 5, 8, 0, false)
        board[9][5] = piece("pawn", "pawn", 5, 9, 0, false)
        board[10][5] = piece("pawn", "pawn", 5, 10, 0, false)
        board[11][5] = piece("pawn", "pawn", 5, 11, 0, false)
        board[12][5] = piece("pawn", "pawn", 5, 12, 0, false)
        board[13][5] = piece("pawn", "pawn", 5, 13, 0, false)
        board[14][5] = piece("pawn", "pawn", 5, 14, 0, false)
        board[15][5] = piece("pawn", "pawn", 5, 15, 0, false)
        board[16][5] = piece("pawn", "pawn", 5, 16, 0, false)
        board[5][6] = piece("dog", "dog", 6, 5, 0, false)
        board[12][6] = piece("dog", "dog", 6, 12, 0, false)

    elseif gameType == "chu" # game setup for chu shogi
        sente_promo_range=1:4
        gote_promo_range=9:12
        # sente/black/odd pieces
        board[4][8] = piece("cobra", "cobra", 8, 4, 1, false) # AKA go-between
        board[9][8] = piece("cobra", "cobra", 8, 9, 1, false) # AKA go-between
        board[1][9] = piece("pawn", "pawn", 9, 1, 1, false)
        board[2][9] = piece("pawn", "pawn", 9, 2, 1, false)
        board[3][9] = piece("pawn", "pawn", 9, 3, 1, false)
        board[4][9] = piece("pawn", "pawn", 9, 4, 1, false)
        board[5][9] = piece("pawn", "pawn", 9, 5, 1, false)
        board[6][9] = piece("pawn", "pawn", 9, 6, 1, false)
        board[7][9] = piece("pawn", "pawn", 9, 7, 1, false)
        board[8][9] = piece("pawn", "pawn", 9, 8, 1, false)
        board[9][9] = piece("pawn", "pawn", 9, 9, 1, false)
        board[10][9] = piece("pawn", "pawn", 9, 10, 1, false)
        board[11][9] = piece("pawn", "pawn", 9, 11, 1, false)
        board[12][9] = piece("pawn", "pawn", 9, 12, 1, false)
        board[1][10] = piece("smover", "smover", 10, 1, 1, false)
        board[2][10] = piece("vmover", "vmover", 10, 2, 1, false)
        board[3][10] = piece("rook", "rook", 10, 3, 1, false)
        board[4][10] = piece("horse", "horse", 10, 4, 1, false) # dragon horse
        board[5][10] = piece("dragon", "dragon", 10, 5, 1, false) # dragon king
        board[6][10] = piece("queen", "queen", 10, 6, 1, false)
        board[7][10] = piece("lion", "lion", 10, 7, 1, false)
        board[8][10] = piece("dragon", "dragon", 10, 8, 1, false) # dragon king
        board[9][10] = piece("horse", "horse", 10, 9, 1, false) # dragon horse
        board[10][10] = piece("rook", "rook", 10, 10, 1, false)
        board[11][10] = piece("vmover", "vmover", 10, 11, 1, false) # vertical mover
        board[12][10] = piece("smover", "smover", 10, 12, 1, false) # side mover
        board[1][11] = piece("chariot", "chariot", 11, 1, 1, false) # reverse chariot
        board[3][11] = piece("bishop", "bishop", 11, 3, 1, false)
        board[5][11] = piece("tiger", "tiger", 11, 5, 1, false) # blind tiger
        board[6][11] = piece("phoenix", "phoenix", 11, 6, 1, false)
        board[7][11] = piece("kirin", "kirin", 11, 7, 1, false)
        board[8][11] = piece("tiger", "tiger", 11, 8, 1, false) # blind tiger
        board[10][11] = piece("bishop", "bishop", 11, 10, 1, false)
        board[12][11] = piece("chariot", "chariot", 11, 12, 1, false) # reverse chariot
        board[1][12] = piece("lance", "lance", 12, 1, 1, false)
        board[2][12] = piece("leopard", "leopard", 12, 2, 1, false) # ferocious leopard
        board[3][12] = piece("copper", "copper", 12, 3, 1, false) # copper general
        board[4][12] = piece("silver", "silver", 12, 4, 1, false) # silver general
        board[5][12] = piece("gold", "gold", 12, 5, 1, false) # gold general
        board[6][12] = piece("elephant", "elephant", 12, 6, 1, false) # drunk elephant
        board[7][12] = piece("king", "king", 12, 7, 1, false)
        board[8][12] = piece("gold", "gold", 12, 8, 1, false) # gold general
        board[9][12] = piece("silver", "silver", 12, 9, 1, false) # silver general
        board[10][12] = piece("copper", "copper", 12, 10, 1, false) # copper general
        board[11][12] = piece("leopard", "leopard", 12, 11, 1, false) # ferocious leopard
        board[12][12] = piece("lance", "lance", 12, 12, 1, false)

        # gote/white/even pieces
        board[4][5] = piece("cobra", "cobra", 5, 4, 0, false) # AKA go-between
        board[9][5] = piece("cobra", "cobra", 5, 9, 0, false) # AKA go-between
        board[1][4] = piece("pawn", "pawn", 4, 1, 0, false)
        board[2][4] = piece("pawn", "pawn", 4, 2, 0, false)
        board[3][4] = piece("pawn", "pawn", 4, 3, 0, false)
        board[4][4] = piece("pawn", "pawn", 4, 4, 0, false)
        board[5][4] = piece("pawn", "pawn", 4, 5, 0, false)
        board[6][4] = piece("pawn", "pawn", 4, 6, 0, false)
        board[7][4] = piece("pawn", "pawn", 4, 7, 0, false)
        board[8][4] = piece("pawn", "pawn", 4, 8, 0, false)
        board[9][4] = piece("pawn", "pawn", 4, 9, 0, false)
        board[10][4] = piece("pawn", "pawn", 4, 10, 0, false)
        board[11][4] = piece("pawn", "pawn", 4, 11, 0, false)
        board[12][4] = piece("pawn", "pawn", 4, 12, 0, false)
        board[1][3] = piece("smover", "smover", 3, 1, 0, false) # side mover
        board[2][3] = piece("vmover", "vmover", 3, 2, 0, false) # vertical mover
        board[3][3] = piece("rook", "rook", 3, 3, 0, false)
        board[4][3] = piece("horse", "horse", 3, 4, 0, false) # dragon horse
        board[5][3] = piece("dragon", "dragon", 3, 5, 0, false) # dragon king
        board[6][3] = piece("lion", "lion", 3, 6, 0, false)
        board[7][3] = piece("queen", "queen", 3, 7, 0, false)
        board[8][3] = piece("dragon", "dragon", 3, 8, 0, false) # dragon king
        board[9][3] = piece("horse", "horse", 3, 9, 0, false) # dragon horse
        board[10][3] = piece("rook", "rook", 3, 10, 0, false)
        board[11][3] = piece("vmover", "vmover", 3, 11, 0, false) # vertical mover
        board[12][3] = piece("smover", "smover", 3, 12, 0, false) # side mover
        board[1][2] = piece("chariot", "chariot", 2, 1, 0, false) # reverse chariot
        board[3][2] = piece("bishop", "bishop", 2, 3, 0, false)
        board[5][2] = piece("tiger", "tiger", 2, 5, 0, false) # blind tiger
        board[6][2] = piece("kirin", "kirin", 2, 6, 0, false)
        board[7][2] = piece("phoenix", "phoenix", 2, 7, 0, false)
        board[8][2] = piece("tiger", "tiger", 2, 8, 0, false) # blind tiger
        board[10][2] = piece("bishop", "bishop", 2, 10, 0, false)
        board[12][2] = piece("chariot", "chariot", 2, 12, 0, false) # reverse chariot
        board[1][1] = piece("lance", "lance", 1, 1, 0, false)
        board[2][1] = piece("leopard", "leopard", 1, 2, 0, false) # ferocious leopard
        board[3][1] = piece("copper", "copper", 1, 3, 0, false) # copper general
        board[4][1] = piece("silver", "silver", 1, 4, 0, false) # silver general
        board[5][1] = piece("gold", "gold", 1, 5, 0, false) # gold general
        board[6][1] = piece("king", "king", 1, 6, 0, false)
        board[7][1] = piece("elephant", "elephant", 1, 7, 0, false) # drunk elephant
        board[8][1] = piece("gold", "gold", 1, 8, 0, false) # gold general
        board[9][1] = piece("silver", "silver", 1, 9, 0, false) # silver general
        board[10][1] = piece("copper", "copper", 1, 10, 0, false) # copper general
        board[11][1] = piece("leopard", "leopard", 1, 11, 0, false) #ferocious leopard
        board[12][1] = piece("lance", "lance", 1, 12, 0, false)

    elseif gameType == "standard" # game setup for standard shogi
        sente_promo_range=1:3
        gote_promo_range=7:9
        # sente/black/odd player
        board[1][7] = piece("pawn", "pawn", 7, 1, 1, false)
        board[2][7] = piece("pawn", "pawn", 7, 2, 1, false)
        board[3][7] = piece("pawn", "pawn", 7, 3, 1, false)
        board[4][7] = piece("pawn", "pawn", 7, 4, 1, false)
        board[5][7] = piece("pawn", "pawn", 7, 5, 1, false)
        board[6][7] = piece("pawn", "pawn", 7, 6, 1, false)
        board[7][7] = piece("pawn", "pawn", 7, 7, 1, false)
        board[8][7] = piece("pawn", "pawn", 7, 8, 1, false)
        board[9][7] = piece("pawn", "pawn", 7, 9, 1, false)
        board[2][8] = piece("rook", "rook", 8, 2, 1, false)
        board[8][8] = piece("bishop", "bishop", 8, 8, 1, false)
        board[1][9] = piece("lance", "lance", 9, 1, 1, false)
        board[2][9] = piece("knight", "knight", 9, 2, 1, false)
        board[3][9] = piece("silver", "silver", 9, 3, 1, false) # silver general
        board[4][9] = piece("gold", "gold", 9, 4, 1, false) # gold general
        board[5][9] = piece("king", "king", 9, 5, 1, false)
        board[6][9] = piece("gold", "gold", 9, 6, 1, false) # gold general
        board[7][9] = piece("silver", "silver", 9, 7, 1, false) # silver general
        board[8][9] = piece("knight", "knight", 9, 8, 1, false)
        board[9][9] = piece("lance", "lance", 9, 9, 1, false)

        # gote/white/even player
        board[1][3] = piece("pawn", "pawn", 3, 1, 0, false)
        board[2][3] = piece("pawn", "pawn", 3, 2, 0, false)
        board[3][3] = piece("pawn", "pawn", 3, 3, 0, false)
        board[4][3] = piece("pawn", "pawn", 3, 4, 0, false)
        board[5][3] = piece("pawn", "pawn", 3, 5, 0, false)
        board[6][3] = piece("pawn", "pawn", 3, 6, 0, false)
        board[7][3] = piece("pawn", "pawn", 3, 7, 0, false)
        board[8][3] = piece("pawn", "pawn", 3, 8, 0, false)
        board[9][3] = piece("pawn", "pawn", 3, 9, 0, false)
        board[2][2] = piece("bishop", "bishop", 2, 2, 0, false)
        board[8][2] = piece("rook", "rook", 2, 8, 0, false)
        board[1][1] = piece("lance", "lance", 1, 1, 0, false)
        board[2][1] = piece("knight", "knight", 1, 2, 0, false)
        board[3][1] = piece("silver", "silver", 1, 3, 0, false) # silver general
        board[4][1] = piece("gold", "gold", 1, 4, 0, false) # gold general
        board[5][1] = piece("king", "king", 1, 5, 0, false)
        board[6][1] = piece("gold", "gold", 1, 6, 0, false) # gold general
        board[7][1] = piece("silver", "silver", 1, 7, 0, false) # silver general
        board[8][1] = piece("knight", "knight", 1, 8, 0, false)
        board[9][1] = piece("lance", "lance", 1, 9, 0, false)

    else # game setup for minishogi
        sente_promo_range=1:1
        gote_promo_range=5:5
        # sente/black/odd player
        board[5][4] = piece("pawn", "pawn", 4, 5, 1, false)
        board[1][5] = piece("rook", "rook", 5, 1, 1, false)
        board[2][5] = piece("bishop", "bishop", 5, 2, 1, false)
        board[3][5] = piece("silver", "silver", 5, 3, 1, false) # silver general
        board[4][5] = piece("gold", "gold", 5, 4, 1, false) # gold general
        board[5][5] = piece("king", "king", 5, 5, 1, false)

        # gote/white/even player
        board[1][2] = piece("pawn", "pawn", 2, 1, 0, false)
        board[1][1] = piece("king", "king", 1, 1, 0, false)
        board[2][1] = piece("gold", "gold", 1, 2, 0, false) # gold general
        board[3][1] = piece("silver", "silver", 1, 3, 0, false) # silver general
        board[4][1] = piece("bishop", "bishop", 1, 4, 0, false)
        board[5][1] = piece("rook", "rook", 1, 5, 0, false)

    end

    push!(allBoards,duplicateBoard(board))
    global pieceArr=[]

    for y in 1:N
        for x in 1:N
            if board[y][x]!=empty
                push!(pieceArr,board[y][x])
            end
        end
    end

global grid = @Grid()
global window = @Window("Shogi by null_ptr")
#println(gameType)
global emptyPath=joinpath(pwd(),"images",gameType,color,"left","empty.jpg")
global moveNum=1
global double=["lion","falcon","soaring"]
global triple=["demon","vice","great","tetrarch"]
global sente=[]
global gote=[]
global idArr=[]
global id2Arr=[]
global prevsx=0
global prevsy=0
global prevtx=0
global prevty=0
global userMove=[]
global DF=0

for p in pieceArr
    if p.side==0
        push!(gote,p)
    else
        push!(sente,p)
    end
end

reset()
setBoardGUI()
if goFirst
    global userTurn=1
    init_buttons("sente")
else
    global userTurn=0
    global userMakingMove=readline(server)
    readMove()
end
push!(window,grid)
showall(window)

if !isinteractive()
    c = Condition()
    signal_connect(window, :destroy) do widget
        notify(c)
    end
    wait(c)
end
end

max_stars_repo_name: DarienFlamont/Shogi

max_issues_repo_name: DarienFlamont/Shogi

max_forks_repo_name: DarienFlamont/Shogi


text:
# wrapper for value
struct PQValue{OID}
    jl_result::Result

    # 0-indexed
    row::Cint
    col::Cint

    function PQValue{OID}(jl_result::Result, row::Integer, col::Integer) where OID
        return new{OID}(jl_result, row - 1, col - 1)
    end
end

function PQValue(jl_result::Result, row::Integer, col::Integer)
    oid = libpq_c.PQftype(jl_result.result, col - 1)

    return PQValue{oid}(jl_result, row, col)
end

# strlen
num_bytes(pqv::PQValue) = libpq_c.PQgetlength(pqv.jl_result.result, pqv.row, pqv.col)

data_pointer(pqv::PQValue) = libpq_c.PQgetvalue(pqv.jl_result.result, pqv.row, pqv.col)

function Base.unsafe_string(pqv::PQValue)
    return unsafe_string(data_pointer(pqv), num_bytes(pqv))
end

function string_view(pqv::PQValue)
    return String(unsafe_wrap(Vector{UInt8}, data_pointer(pqv), num_bytes(pqv)))
end

# includes null
bytes_view(pqv::PQValue) = unsafe_wrap(Vector{UInt8}, data_pointer(pqv), num_bytes(pqv) + 1)

Base.String(pqv::PQValue) = unsafe_string(pqv)
Base.parse(::Type{String}, pqv::PQValue) = unsafe_string(pqv)
Base.convert(::Type{String}, pqv::PQValue) = String(pqv)
Base.length(pqv::PQValue) = length(string_view(pqv))
Base.endof(pqv::PQValue) = endof(string_view(pqv))

# fallback, because Base is bad with string iteration
Base.parse(::Type{T}, pqv::PQValue) where {T} = parse(T, string_view(pqv))

# allow parsing as a Symbol anything which works as a String
Base.parse(::Type{Symbol}, pqv::PQValue) = Symbol(string_view(pqv))

function Base.start(pqv::PQValue)
    sv = string_view(pqv)
    return (sv, start(sv))
end

function Base.next(pqv::PQValue, state)
    sv, sv_state = state
    c, new_sv_state = next(sv, sv_state)
    return c, (sv, new_sv_state)
end

function Base.done(pqv::PQValue, state)
    sv, sv_state = state
    return done(sv, sv_state)
end

## integers
_DEFAULT_TYPE_MAP[:int2] = Int16
_DEFAULT_TYPE_MAP[:int4] = Int32
_DEFAULT_TYPE_MAP[:int8] = Int64

## floating point
_DEFAULT_TYPE_MAP[:float4] = Float32
_DEFAULT_TYPE_MAP[:float8] = Float64

## oid
_DEFAULT_TYPE_MAP[:oid] = Oid

## numeric
_DEFAULT_TYPE_MAP[:numeric] = Decimal

# no default for monetary; needs lconv and lc_monetary from result/connection

## character
# bpchar is char(n)
Base.parse(::Type{String}, pqv::PQValue{PQ_SYSTEM_TYPES[:bpchar]}) = rstrip(pqv, ' ')
# char is "char"
_DEFAULT_TYPE_MAP[:char] = PQChar
Base.parse(::Type{PQChar}, pqv::PQValue{PQ_SYSTEM_TYPES[:char]}) = PQChar(first(pqv))
Base.parse(::Type{Char}, pqv::PQValue{PQ_SYSTEM_TYPES[:char]}) = Char(parse(PQChar, pqv))
# varchar, text, and name are all String

## binary data

_DEFAULT_TYPE_MAP[:bytea] = Vector{UInt8}
function Base.parse(::Type{Vector{UInt8}}, pqv::PQValue{PQ_SYSTEM_TYPES[:bytea]})
    byte_length = Ref{Csize_t}(0)
    bytes = bytes_view(pqv)

    unescaped_ptr = libpq_c.PQunescapeBytea(bytes, byte_length)

    if unescaped_ptr == C_NULL
        error("Could not unescape byte sequence $(String(bytes))")
    end

    unescaped_vec = copy(unsafe_wrap(Vector{UInt8}, unescaped_ptr, byte_length[]))

    libpq_c.PQfreemem(unescaped_ptr)

    return unescaped_vec
end

## bool
# TODO: check whether we ever need this or if PostgreSQL always gives t or f
_DEFAULT_TYPE_MAP[:bool] = Bool
const BOOL_TRUE = r"^\s*(t|true|y|yes|on|1)\s*$"i
const BOOL_FALSE = r"^\s*(f|false|n|no|off|0)\s*$"i
function Base.parse(::Type{Bool}, pqv::PQValue{PQ_SYSTEM_TYPES[:bool]})
    str = string_view(pqv)

    if ismatch(BOOL_TRUE, str)
        return true
    elseif ismatch(BOOL_FALSE, str)
        return false
    else
        error("\"$str\" is not a valid boolean")
    end
end

## dates and times
# ISO, YMD
_DEFAULT_TYPE_MAP[:timestamp] = DateTime
const TIMESTAMP_FORMAT = dateformat"y-m-d HH:MM:SS.s"  # .s is optional here
function Base.parse(::Type{DateTime}, pqv::PQValue{PQ_SYSTEM_TYPES[:timestamp]})
    str = string_view(pqv)

    if str == "infinity"
        return typemax(DateTime)
    elseif str == "-infinity"
        return typemin(DateTime)
    end

    return parse(DateTime, str, TIMESTAMP_FORMAT)
end

# ISO, YMD
_DEFAULT_TYPE_MAP[:timestamptz] = ZonedDateTime
const TIMESTAMPTZ_FORMATS = (
    dateformat"y-m-d HH:MM:SSz",
    dateformat"y-m-d HH:MM:SS.sz",
    dateformat"y-m-d HH:MM:SS.ssz",
    dateformat"y-m-d HH:MM:SS.sssz",
    dateformat"y-m-d HH:MM:SS.ssssz",
    dateformat"y-m-d HH:MM:SS.sssssz",
    dateformat"y-m-d HH:MM:SS.ssssssz",
)
function Base.parse(::Type{ZonedDateTime}, pqv::PQValue{PQ_SYSTEM_TYPES[:timestamptz]})
    str = string_view(pqv)

    if str == "infinity"
        return ZonedDateTime(typemax(DateTime), tz"UTC")
    elseif str == "-infinity"
        return ZonedDateTime(typemin(DateTime), tz"UTC")
    end

    for fmt in TIMESTAMPTZ_FORMATS[1:end-1]
        try
            return parse(ZonedDateTime, str, fmt)
        catch
            continue
        end
    end

    return parse(ZonedDateTime, str, TIMESTAMPTZ_FORMATS[end])
end

# UNIX timestamps
function Base.parse(::Type{DateTime}, pqv::PQValue{PQ_SYSTEM_TYPES[:int8]})
    unix2datetime(parse(Int64, pqv))
end

function Base.parse(::Type{ZonedDateTime}, pqv::PQValue{PQ_SYSTEM_TYPES[:int8]})
    TimeZones.unix2zdt(parse(Int64, pqv))
end

## arrays
# numeric arrays never have double quotes and always use ',' as a separator
function parse_numeric_array(eltype::Type{T}, str::AbstractString) where T
    eq_ind = searchindex(str, '=')

    if eq_ind > 0
        offset_str = str[1:eq_ind-1]
        range_strs = split(str[1:eq_ind-1], ['[',']']; keep=false)

        ranges = map(range_strs) do range_str
            lower, upper = split(range_str, ':'; limit=2)
            return parse(Int, lower):parse(Int, upper)
        end

        arr = OffsetArray(T, ranges...)
    else
        arr = Array{T}(array_size(str)...)
    end

    idx_iter = imap(reverse, product(reverse(indices(arr))...))
    el_iter = eachmatch(r"[^\}\{,]+", str[eq_ind+1:end])
    for (idx, num_match) in zip(idx_iter, el_iter)
        arr[idx...] = parse(T, num_match.match)
    end

    return arr
end

function array_size(str)
    ndims = findfirst(c -> c != '{', str) - 1
    dims = zeros(Int, ndims)

    curr_dim = ndims
    curr_pos = ndims
    open_braces = ndims
    last_ind = endof(str)
    el_count = 0
    while curr_dim > 0 && curr_pos < last_ind
        curr_pos = nextind(str, curr_pos)

        if str[curr_pos] == '}'
            open_braces -= 1

            if open_braces < curr_dim
                dims[curr_dim] = el_count
                curr_dim -= 1
                el_count = 1
            end
        elseif str[curr_pos] == '{'
            open_braces += 1
        elseif str[curr_pos] == ','
            if open_braces == curr_dim
                el_count += 1
            end
        else
            if open_braces == curr_dim && el_count == 0
                el_count = 1
            end
        end
    end

    return dims
end

for pq_eltype in ("int2", "int4", "int8", "float4", "float8", "oid", "numeric")
    array_oid = PQ_SYSTEM_TYPES[Symbol("_$pq_eltype")]
    jl_eltype = _DEFAULT_TYPE_MAP[Symbol(pq_eltype)]

    # could be an OffsetArray or Array of any dimensionality
    _DEFAULT_TYPE_MAP[array_oid] = AbstractArray{jl_eltype}

    @eval function Base.parse(::Type{AbstractArray{$jl_eltype}}, pqv::PQValue{$array_oid})
        parse_numeric_array($jl_eltype, string_view(pqv))
    end
end

struct FallbackConversion <: AbstractDict{Tuple{Oid, Type}, Base.Callable}
end

function Base.getindex(cmap::FallbackConversion, oid_typ::Tuple{Integer, Type})
    _, typ = oid_typ

    return function parse_type(pqv::PQValue)
        parse(typ, pqv)
    end
end

Base.haskey(cmap::FallbackConversion, oid_typ::Tuple{Integer, Type}) = true

const _FALLBACK_CONVERSION = FallbackConversion()


text:
module SharedVertexMesh

import DataStructures: OrderedDict

struct Vertex
    x::Float32
    y::Float32
    z::Float32
end

struct Triangle
    v1::UInt
    v2::UInt
    v3::UInt
end

struct Mesh
    vertices::Array{Vertex, 1}
    triangles::Array{Triangle, 1}
end

function readvertex!(stl, vertices)
    vertex = Vertex(read(stl, Float32), read(stl, Float32), read(stl, Float32))
    haskey(vertices, vertex) ? vertices[vertex] : vertices[vertex] = length(vertices) + 1
end

function from(path::AbstractString)
    vertices = OrderedDict{Vertex, UInt}()
    triangles = Array{Triangle, 1}()

    open(path) do stl
        skip(stl, 80)  # skip header

        trianglecount = read(stl, UInt32)

        for _ in 1:trianglecount
            skip(stl, 12)  # skip normal vector

            triangle = Triangle(readvertex!(stl, vertices),
                                readvertex!(stl, vertices),
                                readvertex!(stl, vertices))
            push!(triangles, triangle)

            skip(stl, 2)  # skip attribute byte count
        end

        @assert eof(stl)
    end

    Mesh(collect(keys(vertices)), triangles)
end

end # module


text:
# Simulations for figures f1, f2, f3
#NOTE: run `include("scripts/script1.jl")` from top level module directory `PrimordialB`

#= NOTE: to reset a git build on a server do this:
git fetch origin master
git reset --hard FETCH_HEAD
git clean -df
=#

#= NOTE: for server runs I've had to use the following commands in bash to get the libs linked correctly
unset LD_LIBRARY_PATH
LD_PRELOAD='/usr/local/julia-0.5/lib/julia/libgfortran.so.3 /usr/local/julia-0.5/lib/julia/libfftw3_threads.so.3.4.4' julia
=#

tic()
addprocs(30) # addprocs(3) #
println("nproces = $(nprocs())")
@everywhere push!(LOAD_PATH, homedir())
using JLD, ProgressMeter
import PrimordialB
const seedstart = 0x3f77869c073f2346 # 0xfad38326fbba9e09 #0xe467d3a81ca391be   #rand(UInt64)
srand(seedstart)

#####################################################################################
###### different parameters of each simulation run ############

# # ------- figure 2 --------
# savepath = joinpath("scripts/", "out_figure2a.jld") # on Phall 7/8/2017
# μKarcminT          = 10.0
# lense_unitr_sc(ek, bk, len, g, order) = PrimordialB.lense_unitr_sc_allorder(ek, bk, len, g, order)

# savepath = joinpath("scripts/", "out_figure2b.jld") # on Poisson 7/7/2017
# μKarcminT          = 1.0
# lense_unitr_sc(ek, bk, len, g, order) = PrimordialB.lense_unitr_sc_allorder(ek, bk, len, g, order)
# trying 5 blocks...

# savepath = joinpath("scripts/", "out_figure2c.jld") # on Poisson 7/8/2017
# μKarcminT          = 0.5
# lense_unitr_sc(ek, bk, len, g, order) = PrimordialB.lense_unitr_sc_allorder(ek, bk, len, g, order)

# ------- figure 3 --------
# savepath = joinpath("scripts/", "out_figure3a.jld") # on Phall 7/9/2017
# μKarcminT          = 1.0
# lense_unitr_sc(ek, bk, len, g, order) = PrimordialB.lense_unitr_sc_null(ek, bk, len, g, order)

# savepath = joinpath("scripts/", "out_figure3b.jld") # on Poisson 7/9/2017
# μKarcminT          = 1.0
# lense_unitr_sc(ek, bk, len, g, order) = PrimordialB.lense_unitr_sc_allEfromE(ek, bk, len, g, order)

savepath = joinpath("scripts/", "out_figure3c.jld") # on Phall 7/10/2017
μKarcminT          = 1.0
lense_unitr_sc(ek, bk, len, g, order) = PrimordialB.lense_unitr_sc_allBfromE(ek, bk, len, g, order)

#####################################################################################
###### fixed parameters of the simulation run  ############

nside              = 200
n_sims             = 500
nblks              = 4
sblks_approx       = 1000

pixel_side_length  = 10
phiest_pixel_side_length = 2
period                = pixel_side_length*nside*π/(180*60) # 5, nside*π/(180*60) corresponds to 1 arcmin pixels
phiest_nside          = ceil(Int64, pixel_side_length*nside/phiest_pixel_side_length) #nside * 5
phiest_μKarcminT      = μKarcminT
beamFWHM              = deg2rad(pixel_side_length/60)
phiest_beamFWHM       = deg2rad(phiest_pixel_side_length/60)
g                     = PrimordialB.FFTgrid(PrimordialB.Pix{period, nside}())
fsky_percent          = 100 * (period)^2 / (4π)
fsky_percent_forphi   = 100 * (phiest_pixel_side_length*phiest_nside*π/(180*60))^2 / (4π)
@everywhere rng_true  = [logspace(-3,-2, 20);linspace(0.0125,0.1, 20)] #[1:2:end] # 0.0005:.0025:.1
@everywhere rng       = 0:.0001:.2
order                 = 7 # lensing order
rand_us               = rand(30) # these will determine the location of the noise modulations
σmod                  = ones(size(g.x[1])) # noise modulation
pix                   = PrimordialB.Pix{period, nside}()

lmin = 2.0
lmax = Inf #0.9*g.nyq
hermitianhalf = (g.k[1] .> 0) | ((g.k[1] .== 0.0) & (g.k[2] .> 0.0))
lrestriction  = (lmin .<= g.r .<= lmax) & hermitianhalf

####################################################################
############# get the cls and simulate phi #######################
cls, mCls, cls_no_B    = PrimordialB.get_spectra(μKarcminT, beamFWHM, period, nside) # for B survey
N0ℓ, Aℓ, mCls_cnϕk, cnϕk_mask = PrimordialB.get_N0ℓAℓ(cls_no_B, phiest_pixel_side_length, phiest_nside, phiest_μKarcminT, phiest_beamFWHM, period, nside)

ϕx, ϕk   = PrimordialB.sim_xk(mCls.cϕϕk, g)
len      = PrimordialB.LenseDecomp(ϕk, zeros(ϕk), g)
nϕx, nϕk = PrimordialB.sim_xk(mCls_cnϕk, g)
ϕestk    = ϕk + nϕk; ϕestk[cnϕk_mask] = 0.0
ρl       = PrimordialB.squash(mCls.cϕϕk ./ √(mCls.cϕϕk) ./ √(mCls_cnϕk + mCls.cϕϕk)); ρl[cnϕk_mask] = 0.0
μϕk      = PrimordialB.squash(mCls.cϕϕk./(mCls_cnϕk + mCls.cϕϕk)) .* ϕestk; μϕk[cnϕk_mask] = 0.0
varϕk    = PrimordialB.squash(mCls_cnϕk .* mCls.cϕϕk ./ (mCls_cnϕk + mCls.cϕϕk)); varϕk[cnϕk_mask] = mCls.cϕϕk[cnϕk_mask]
μlen     = PrimordialB.LenseDecomp(copy(μϕk), zeros(ϕk), g)

# @everywhere function noise_cov_col(pix_index, beamCovk, g)
#     exsy_forbeam = exp.( - complex.(0., g.k[1].*g.x[1][pix_index]) - complex.(0., g.k[2].*g.x[2][pix_index]) )
#     Σbeam        = real.(g.FFT \ (exsy_forbeam.*beamCovk))
#     #Σbeam[pix_index] += σmod[pix_index] # not sure how to do this one...
#     return Σbeam
# end

let varϕk=varϕk, μlen=μlen, mCls=mCls, order=order, pix=pix, ϕestk=ϕestk, ρl=ρl, lrestriction=lrestriction, μKarcminT=μKarcminT
    @everywhere const gl = PrimordialB.FFTgrid($pix)
    @everywhere const φ2_l     = 2angle.(gl.k[1] + im * gl.k[2])
    @everywhere const cos²φ    = abs2.(cos.(φ2_l))
    @everywhere const sin²φ    = abs2.(sin.(φ2_l))
    @everywhere const sincosφ  = cos.(φ2_l).*sin.(φ2_l)
    @everywhere const beamCovk =  $(mCls.cBBnoisek) ./ (2π)
    @everywhere const covϕk     = $varϕk ./ (2π)
    @everywhere const covCEk    = cos²φ .* $(mCls.cEEk) ./ (2π)
    @everywhere const covSEk    = sin²φ .* $(mCls.cEEk) ./ (2π)
    @everywhere const covSCEk   = sincosφ .* $(mCls.cEEk) ./ (2π)
    @everywhere const covCB0k   = cos²φ .* $(mCls.cBB0k) ./ (2π)
    @everywhere const covSB0k   = sin²φ .* $(mCls.cBB0k) ./ (2π)
    @everywhere const covSCB0k  = - sincosφ .* $(mCls.cBB0k) ./ (2π)
    @everywhere const local_order = $order
    @everywhere const local_μlen = $μlen
    @everywhere const local_lrestriction = $lrestriction
    @everywhere const local_ϕestk = $ϕestk
    @everywhere const local_ρl = $ρl
    @everywhere const local_mCls = $mCls
    @everywhere const local_pix = $pix
    @everywhere const local_μKarcminT = $μKarcminT

    @everywhere function cov_col(pix_index)
        exsy = exp.(- im .* gl.k[1] .* (gl.x[1][pix_index] + local_μlen.displx[pix_index]) - im .* gl.k[2] .* (gl.x[2][pix_index] + local_μlen.disply[pix_index]))::Array{Complex{Float64},2}
        exsy_nolen = exp.(- im .* gl.k[1] .* gl.x[1][pix_index] - im .* gl.k[2] .* gl.x[2][pix_index])::Array{Complex{Float64},2}

        ΣCE, ΣCB          = PrimordialB.lense(real.(gl.FFT \ (exsy.*covCEk)),  real.(gl.FFT \ (exsy.*covCB0k)),  local_μlen, gl, local_order)
        ΣSE, ΣSB          = PrimordialB.lense(real.(gl.FFT \ (exsy.*covSEk)),  real.(gl.FFT \ (exsy.*covSB0k)),  local_μlen, gl, local_order)
        ΣSCE, ΣSCB        = PrimordialB.lense(real.(gl.FFT \ (exsy.*covSCEk)), real.(gl.FFT \ (exsy.*covSCB0k)), local_μlen, gl, local_order)
        Σ∂11CE,  Σ∂11CB   = PrimordialB.lense(real.(gl.FFT \ (exsy.*gl.k[1].*gl.k[1].*covCEk)),  real.(gl.FFT \ (exsy.*gl.k[1].*gl.k[1].*covCB0k)),  local_μlen, gl, local_order)
        Σ∂11SE,  Σ∂11SB   = PrimordialB.lense(real.(gl.FFT \ (exsy.*gl.k[1].*gl.k[1].*covSEk)),  real.(gl.FFT \ (exsy.*gl.k[1].*gl.k[1].*covSB0k)),  local_μlen, gl, local_order)
        Σ∂11SCE, Σ∂11SCB  = PrimordialB.lense(real.(gl.FFT \ (exsy.*gl.k[1].*gl.k[1].*covSCEk)), real.(gl.FFT \ (exsy.*gl.k[1].*gl.k[1].*covSCB0k)), local_μlen, gl, local_order)
        Σ∂12CE,  Σ∂12CB   = PrimordialB.lense(real.(gl.FFT \ (exsy.*gl.k[1].*gl.k[2].*covCEk)),  real.(gl.FFT \ (exsy.*gl.k[1].*gl.k[2].*covCB0k)),  local_μlen, gl, local_order)
        Σ∂12SE,  Σ∂12SB   = PrimordialB.lense(real.(gl.FFT \ (exsy.*gl.k[1].*gl.k[2].*covSEk)),  real.(gl.FFT \ (exsy.*gl.k[1].*gl.k[2].*covSB0k)),  local_μlen, gl, local_order)
        Σ∂12SCE, Σ∂12SCB  = PrimordialB.lense(real.(gl.FFT \ (exsy.*gl.k[1].*gl.k[2].*covSCEk)), real.(gl.FFT \ (exsy.*gl.k[1].*gl.k[2].*covSCB0k)), local_μlen, gl, local_order)
        Σ∂22CE,  Σ∂22CB   = PrimordialB.lense(real.(gl.FFT \ (exsy.*gl.k[2].*gl.k[2].*covCEk)),  real.(gl.FFT \ (exsy.*gl.k[2].*gl.k[2].*covCB0k)),  local_μlen, gl, local_order)
        Σ∂22SE,  Σ∂22SB   = PrimordialB.lense(real.(gl.FFT \ (exsy.*gl.k[2].*gl.k[2].*covSEk)),  real.(gl.FFT \ (exsy.*gl.k[2].*gl.k[2].*covSB0k)),  local_μlen, gl, local_order)
        Σ∂22SCE, Σ∂22SCB  = PrimordialB.lense(real.(gl.FFT \ (exsy.*gl.k[2].*gl.k[2].*covSCEk)), real.(gl.FFT \ (exsy.*gl.k[2].*gl.k[2].*covSCB0k)), local_μlen, gl, local_order)

        ∂12Σϕ   = real.(gl.FFT \ (exsy_nolen.*gl.k[1].*gl.k[2].*covϕk))
        ∂11Σϕ   = real.(gl.FFT \ (exsy_nolen.*gl.k[1].*gl.k[1].*covϕk))
        ∂22Σϕ   = real.(gl.FFT \ (exsy_nolen.*gl.k[2].*gl.k[2].*covϕk))

        v11Σϕ = ∂11Σϕ[pix_index] .- ∂11Σϕ
        v22Σϕ = ∂22Σϕ[pix_index] .- ∂22Σϕ
        v12Σϕ = ∂12Σϕ[pix_index] .- ∂12Σϕ

        Σce   = ΣCE  - v11Σϕ .* Σ∂11CE - v22Σϕ .* Σ∂22CE - 2v12Σϕ .* Σ∂12CE
        Σcb   = ΣCB  - v11Σϕ .* Σ∂11CB - v22Σϕ .* Σ∂22CB - 2v12Σϕ .* Σ∂12CB
        Σse   = ΣSE  - v11Σϕ .* Σ∂11SE - v22Σϕ .* Σ∂22SE - 2v12Σϕ .* Σ∂12SE
        Σsb   = ΣSB  - v11Σϕ .* Σ∂11SB - v22Σϕ .* Σ∂22SB - 2v12Σϕ .* Σ∂12SB
        Σsce  = ΣSCE - v11Σϕ .* Σ∂11SCE - v22Σϕ .* Σ∂22SCE - 2v12Σϕ .* Σ∂12SCE
        Σscb  = ΣSCB - v11Σϕ .* Σ∂11SCB - v22Σϕ .* Σ∂22SCB - 2v12Σϕ .* Σ∂12SCB

        ##Σbeam = noise_cov_col(pix_index, beamCovk, gl)
        Σbeam =  real.(gl.FFT \ (exsy_nolen.*beamCovk))
        Σce += Σbeam
        Σse += Σbeam

        #σEEarcmin = √2 * local_μKarcminT
        #σEErad    = σEEarcmin * (π / 180 / 60)
        #Σce[pix_index] += abs2(σEErad / gl.deltx)
        #Σse[pix_index] += abs2(σEErad / gl.deltx)
        # check that the origin isn't presenting problems...

        return Σce, Σcb, Σse, Σsb, Σsce, Σscb # vectorize these to get the column
    end
    @everywhere function VQcolQB(pix_index)
        qx = zeros(gl.nside, gl.nside)
        ux = zeros(gl.nside, gl.nside)
        qx[pix_index] = 1.0
        qk = gl.FFT * qx
        uk = gl.FFT * ux
        ek, bk,   = PrimordialB.qu2eb(qk, uk, gl)
        δ1residk  = bk - PrimordialB.estδ1BfromEk(ek,local_ϕestk, local_ρl, local_mCls, gl)
        return δ1residk[local_lrestriction]
    end
    @everywhere function VUcolQB(pix_index)
        qx = zeros(gl.nside, gl.nside)
        ux = zeros(gl.nside, gl.nside)
        ux[pix_index] = 1.0
        qk = gl.FFT * qx
        uk = gl.FFT * ux
        ek, bk,   = PrimordialB.qu2eb(qk, uk, gl)
        δ1residk  = bk - PrimordialB.estδ1BfromEk(ek, local_ϕestk, local_ρl, local_mCls, gl)
        return δ1residk[local_lrestriction]
    end

    @everywhere function VQcolE(pix_index)
        qx = zeros(gl.nside, gl.nside)
        ux = zeros(gl.nside, gl.nside)
        qx[pix_index] = 1.0
        qk = gl.FFT * qx
        uk = gl.FFT * ux
        ek, bk,   = PrimordialB.qu2eb(qk, uk, gl)
        return ek[local_lrestriction]
    end
    @everywhere function VUcolE(pix_index)
        qx = zeros(gl.nside, gl.nside)
        ux = zeros(gl.nside, gl.nside)
        ux[pix_index] = 1.0
        qk = gl.FFT * qx
        uk = gl.FFT * ux
        ek, bk,   = PrimordialB.qu2eb(qk, uk, gl)
        return ek[local_lrestriction]
    end
    @everywhere function VQcolB(pix_index)
        qx = zeros(gl.nside, gl.nside)
        ux = zeros(gl.nside, gl.nside)
        qx[pix_index] = 1.0
        qk = gl.FFT * qx
        uk = gl.FFT * ux
        ek, bk,   = PrimordialB.qu2eb(qk, uk, gl)
        return bk[local_lrestriction]
    end
    @everywhere function VUcolB(pix_index)
        qx = zeros(gl.nside, gl.nside)
        ux = zeros(gl.nside, gl.nside)
        ux[pix_index] = 1.0
        qk = gl.FFT * qx
        uk = gl.FFT * ux
        ek, bk,   = PrimordialB.qu2eb(qk, uk, gl)
        return bk[local_lrestriction]
    end
    @everywhere function block_VqVu(vqcol::Function, vucol::Function, indrng, nside)
        nb  = length(indrng)
        npx = nside^2
        vq = zeros(Complex{Float64}, nb, npx)
        vu = zeros(Complex{Float64}, nb, npx)
        ProgressMeter.@showprogress 4 "constructing Vq, Vu..." for i in 1:npx
            vq[:,i] = vqcol(i)[indrng]
            vu[:,i] = vucol(i)[indrng]
        end
        Vq = vcat(real.(vq), imag.(vq))
        Vu = vcat(real.(vu), imag.(vu))
        return Vq, Vu
    end
end

########## get projection matrices for local blocks ############
sblks = floor(Int64, min(sum(lrestriction)/nblks, sblks_approx))
# ------------ order the modes into signal to noise ---------
mat_clnbk  = PrimordialB.ResB_matpwr(mCls, ρl, g)
signal_to_noiseQB = mCls.cBB0k ./ (mCls.cBBnoisek + mat_clnbk)
signal_to_noiseE  = mCls.cEEk  ./ mCls.cEEnoisek
VqVu_SN_weightsQB = signal_to_noiseQB[lrestriction]
VqVu_SN_weightsE  = signal_to_noiseE[lrestriction]
permQB = sortperm(VqVu_SN_weightsQB, rev=true) # these are the modes that the quadratic estimate produces
permE  = sortperm(VqVu_SN_weightsE, rev=true)
indxQB = (1:length(VqVu_SN_weightsQB))[permQB]
indxE  = (1:length(VqVu_SN_weightsE))[permE]
# ------------ find the projection matrices ------------
VqVu = @sync @parallel (vcat) for i in 1:nblks
    VqQB, VuQB = block_VqVu(VQcolQB,  VUcolQB, indxQB[(i-1)*sblks+(1:sblks)], nside)
    VqE, VuE   = block_VqVu(VQcolE,    VUcolE, indxE[(i-1)*sblks+(1:sblks)], nside)
    Vq = vcat(VqQB, VqE)
    Vu = vcat(VuQB, VuE)
    (i, Vq, Vu)
end
Vq = Dict(VqVu[i][1] => VqVu[i][2] for i in 1:nblks)
Vu = Dict(VqVu[i][1] => VqVu[i][3] for i in 1:nblks)
#clear memory
VqVu = 0.0
@everywhere gc()

# #TODO: try a Vecchia approach and have these blocks overlap.
for i = 1:nblks
    v = hcat(Vq[i], Vu[i]) # ------- now reduce vq, vu by finding an ortho basis of the range
    newv = transpose(PrimordialB.orth(transpose(v); cut = 1e-15))
    Vq[i] = newv[:,1:size(Vq[i],2)]
    Vu[i] = newv[:,size(Vu[i],2)+1:end]
    @everywhere gc()
end

# ------------ compute the covariance of the projections ------------
npx = nside^2
max_blk_size = 2*nprocs()
mypartition(x, max_blk_size) = [x[i:min(i+max_blk_size-1,length(x))] for i in 1:max_blk_size:length(x)]
pixl_partition = mypartition(1:npx, max_blk_size)
vΣev = Dict(i=>zeros(size(Vq[i],1), size(Vq[i],1)) for i=1:nblks)
vΣbv = Dict(i=>zeros(size(Vq[i],1), size(Vq[i],1)) for i=1:nblks)
@showprogress 4 "constructing vΣev, vΣbv..." for pixel_rnge in pixl_partition
    vecΣeb = @sync @parallel (hcat) for i in pixel_rnge
        Σce, Σcb, Σse, Σsb, Σsce, Σscb = cov_col(i)
        vcat(vec(Σce), vec(Σcb), vec(Σse), vec(Σsb), vec(Σsce), vec(Σscb))
    end
    tΣce, tΣcb, tΣse, tΣsb, tΣsce, tΣscb = vecΣeb[1:npx,:], vecΣeb[npx+1:2npx,:], vecΣeb[2npx+1:3npx,:], vecΣeb[3npx+1:4npx,:], vecΣeb[4npx+1:5npx,:], vecΣeb[5npx+1:6npx,:]
    for i in 1:nblks
        vΣev[i]  += (Vq[i] * tΣce  + Vu[i] * tΣsce) * transpose(Vq[i][:,pixel_rnge])
        vΣev[i]  += (Vq[i] * tΣsce + Vu[i] * tΣse)  * transpose(Vu[i][:,pixel_rnge])
        vΣbv[i]  += (Vq[i] * tΣsb  + Vu[i] * tΣscb) * transpose(Vq[i][:,pixel_rnge])
        vΣbv[i]  += (Vq[i] * tΣscb + Vu[i] * tΣcb)  * transpose(Vu[i][:,pixel_rnge])
    end
    @everywhere gc()
end

# ------------ get the eigen decomp of covariance of the projections ------------
@time vec_DVDbVb = @sync @parallel (vcat) for i = 1:nblks
    local_vΣev = remotecall_fetch(()->vΣev[i], 1)
    local_vΣbv = remotecall_fetch(()->vΣbv[i], 1)
    vDv, vVv, vDbv, vVbv = PrimordialB.get_D_V_Db_Vb(local_vΣev, local_vΣbv)
    i => (vDv, vVv, vDbv, vVbv)
end
dic_DVDbVb =  Dict(vec_DVDbVb)
# clear memory
vec_DVDbVb = 0
@everywhere gc()

# since the simulations below are done on the master node, we can release the workers
rmprocs(workers())

# ----------- simulate
rest_B      = zeros(length(rng_true), n_sims)
rest_modes  = zeros(length(rng_true), n_sims)
@showprogress 4 "simulations..." for ctr = 1:n_sims
    # simulate data of the form the form
    # dqx   = dncex + √(r) .* dsbx # <--- the data
    # dux   = dnsex + √(r) .* dcbx # <--- the data
    nex, nek                   = PrimordialB.sim_xk(mCls.cEEnoisek, g)
    nbx, nbk                   = PrimordialB.sim_xk(mCls.cBBnoisek, g)
    nqk, nuk, nqx, nux         = PrimordialB.eb2qu(nek, nbk, g)
    ex, ek                     = PrimordialB.sim_xk(mCls.cEEk, g)
    #bx, bk                     = sim_xk(mCls.cBBk, g)
    bx, bk                     = PrimordialB.sim_xk(mCls.cBB0k, g)
    ln_cex, ln_sex, ln_cbx, ln_sbx  = lense_unitr_sc(ek, bk, len, g, order)
    dncex = ln_cex + nqx
    dnsex = ln_sex + nux
    dcbx  = ln_cbx
    dsbx  = ln_sbx

    # ---- blakes method all ell
    rll_B  = PrimordialB.full_quadratic_B_delenser_qxux(lmin, lmax, dncex, dnsex, dsbx, dcbx, mCls, rng, rng_true, ρl, ϕestk, period, nside)
    rll_B_maxind = mapslices(x->findmax(x)[2], rll_B, 2)[:]
    rest_B[:,ctr] = rng[rll_B_maxind]

    rll_modes = sum(1:nblks) do i
        vDv, vVv, vDbv, vVbv = dic_DVDbVb[i]
        qudata_en = Vq[i] * dncex[:] + Vu[i] * dnsex[:]
        qudata_b  = Vq[i] * dsbx[:]  + Vu[i] * dcbx[:]
        PrimordialB.loglike_r_rtrue(rng, rng_true, qudata_en, qudata_b, vDv, vVv, vDbv, vVbv)
    end
    rll_modes_maxind = mapslices(x->findmax(x)[2], rll_modes, 2)[:]
    rest_modes[:,ctr] = rng[rll_modes_maxind]
end

#= PLOTS for local debugging

bias_B_1  = mean((rest_B .- rng_true),2)
bias_L_1  = mean((rest_modes .- rng_true),2)
standard_error_B_1 = sqrt.(mean((rest_B .- rng_true).^2, 2))
standard_error_L_1 = sqrt.(mean((rest_modes .- rng_true).^2, 2))

fig, ax = plt[:subplots](1,1, figsize=(10,3.7), sharex=true,  sharey=true)
fontsize = 10

ax[:plot](rng_true, rng_true./standard_error_B_1, label = "quadratic delenser")
ax[:plot](rng_true, rng_true./standard_error_L_1, label = "likelihood approx")
ax[:set_ylabel](L"$\frac{r}{\sigma(r)}$       ", fontsize=fontsize+4,  rotation="horizontal")
ax[:set_xlabel](L"$r$", fontsize=fontsize)
ax[:set_xticks]([.01, .03, .05, .07, .09])
ax[:tick_params](axis="y", labelsize = fontsize-2)
ax[:tick_params](axis="x", labelsize = fontsize-2)
ax[:legend](loc="best", fontsize=fontsize)
ax[:grid](true)

=#

runtime = toc()

@save "$savepath" rest_B rest_modes rng rng_true n_sims len μKarcminT beamFWHM nside period seedstart N0ℓ Aℓ varϕk σmod pixel_side_length

message = """
script1.jl job completed in $(round(Int64, runtime/60)) minutes.
fsky is at $(round(fsky_percent,1)) %
μKarcminT = $(μKarcminT)
"""
run(pipeline(`echo $message`, `mail 7733153613@mms.att.net`))
println(message)


text:
"""
return rfs_vec, where the vector is the rfs indexed by receptive field
"""
function get_rfs_vec(real_objects::Vector{Detection2D},
                    params::Video_Params, v::Matrix{Real})
    #just one rf
    rec_field = Receptive_Field(p1 = (0, 0), p2 = (params.image_dim_x, params.image_dim_y)) #should make it from params
    real_rf = filter(p -> within(p, rec_field), real_objects)
    rfs_vec = get_rfs(rec_field, real_rf, params, v)
    #println("rfs_vec ", rfs_vec)
end

"""
returns rfs elements for a particular receptive field
"""
function get_rfs(rec_field::Receptive_Field, real::Vector{Detection2D}, params::Video_Params, v::Matrix{Real})

    #########################################################################
    #for imaginary objects
    lambda_fas = v[:,1]
    #fases = fill(fas, length(imaginary))
    #imagined_objects_2D = map(to_element, imaginary, fases)
    #imaginary = hallucination_distribution(params) #do I want to trace this? probably
    imagined_objects_2D = PoissonElement{Detection2D}(sum(v[:,1]), hallucination_distribution, (params, v, rec_field))

    #for real objects
    misses = v[:,2]
    #hitses = fill(hits, length(real))
    real_objects_2D = to_elements_real(real, misses)

    #println("imagined_objects_2D ", imagined_objects_2D)
    #println("real_objects_2D ", real_objects_2D)
    rfs = [imagined_objects_2D; real_objects_2D]

    rfs = RFSElements{Detection2D}(rfs)
    return rfs
end

"""
objects is a list of Detection2Ds. ps is a vector of probabilities indexed by object category
"""
function to_elements_real(objects::Vector{Detection2D}, miss_rates::Vector{Real})
    #will probably need to redo this stuff
    sd_x = 40. #might work????
    sd_y = 40.
    cov = [sd_x 0.; 0. sd_y;]

    n = length(objects)
    objects_2D = Vector{GeometricElement{Detection2D}}(undef, n) #no idea if that will work
    for i = 1:n
        x = objects[i][1]#trying to get x from Detection2D Tuple
        y = objects[i][2]
        cat = objects[i][3]
        miss_rate = miss_rates[cat] #get the detection rate for this category
        objects_2D[i] = GeometricElement{Detection2D}(miss_rate, object_distribution_image, ([x, y], cov, cat))
    end
    return objects_2D
end

"""
returns true if the object position is within rf
"""
function within(point::Detection2D, rf::Receptive_Field)
    x = point[1]
    y = point[2]
    x >= rf.p1[1] && x <= rf.p2[1] && y >= rf.p1[2] && y <= rf.p2[2] #top and right size will not be represented in rfs. nead it to be this way so intersections in receptive fields have reasonable explanations
end

function within(point::Tuple{Float64, Float64}, rf::Receptive_Field)
    x = point[1]
    y = point[2]
    x >= rf.p1[1] && x <= rf.p2[1] && y >= rf.p1[2] && y <= rf.p2[2] #top and right size will not be represented in rfs. nead it to be this way so intersections in receptive fields have reasonable explanations
end

export within

################################################################################
"""
set up receptive_fields
"""
function make_receptive_fields(params::Video_Params)

    # #square receptive fields. hardcoded for the 240 x 320 image
    # pixels = 80
    #
	# #layer 1 of receptive fields. 3x4, inside the image
    # n_horizontal = 4
    # n_vertical = 3
    # n = n_horizontal*n_vertical
    # receptive_fields_layer_1 = Vector{Receptive_Field}(undef, n) #of length n
    # for h = 1:n_horizontal
    #     for v = 1:n_vertical
    #         receptive_fields_layer_1[n_vertical*(h-1)+v] = Receptive_Field(p1 = ((h-1)*pixels, (v-1)*pixels), p2 = (h*pixels, v*pixels))
    #     end
    # end
    #
	# #layer 2 of receptive fields. 4x5 overlay
	# n_horizontal = 5
    # n_vertical = 4
    # n = n_horizontal*n_vertical
    # receptive_fields_layer_2 = Vector{Receptive_Field}(undef, n) #of length n
    # for h = 1:n_horizontal
    #     for v = 1:n_vertical
    #         receptive_fields_layer_2[n_vertical*(h-1)+v] = Receptive_Field(p1 = ((h-1.5)*pixels, (v-1.5)*pixels), p2 = ((h-0.5)*pixels, (v-0.5)*pixels))
    #     end
    # end
    #
	# #layer 3 of receptive fields. 3x5 overlay, tiled horizontally
	# n_horizontal = 5
    # n_vertical = 3
    # n = n_horizontal*n_vertical
    # receptive_fields_layer_3 = Vector{Receptive_Field}(undef, n) #of length n
    # for h = 1:n_horizontal
    #     for v = 1:n_vertical
    #         receptive_fields_layer_3[n_vertical*(h-1)+v] = Receptive_Field(p1 = ((h-1.5)*pixels, (v-1)*pixels), p2 = ((h-0.5)*pixels, v*pixels))
    #     end
    # end
    #
	# #layer 4 of receptive fields. 4x4 overlay, tiled vertically
	# n_horizontal = 4
    # n_vertical = 4
    # n = n_horizontal*n_vertical
    # receptive_fields_layer_4 = Vector{Receptive_Field}(undef, n) #of length n
    # for h = 1:n_horizontal
    #     for v = 1:n_vertical
    #         receptive_fields_layer_4[n_vertical*(h-1)+v] = Receptive_Field(p1 = ((h-1)*pixels, (v-1.5)*pixels), p2 = (h*pixels, (v-0.5)*pixels))
    #     end
    # end
    #
	# receptive_fields = vcat(receptive_fields_layer_1, receptive_fields_layer_2, receptive_fields_layer_3, receptive_fields_layer_4)

    receptive_fields = Vector{Receptive_Field}(undef, 1)
    receptive_fields[1] = Receptive_Field(p1 = (0, 0), p2 = (params.image_dim_x, params.image_dim_y))

    return receptive_fields
end

export make_receptive_fields

max_stars_repo_name: zhangir-azerbayev/MetaGen

max_issues_repo_name: zhangir-azerbayev/MetaGen

max_forks_repo_name: zhangir-azerbayev/MetaGen


text:
function exponential_decay(;λ=-50, u0=1., tspan=(0.0, 1.0))
    f(u, p, t) = λ .* u
    exp_decay = ODEProblem(f, u0, tspan)
    return exp_decay
end

function logistic_equation(; u0=[1e-1], tspan=(0.0, 2.5), p=[3.0])
    function logistic!(du, u, p, t)
        r = p[1]
        du[1] = r * u[1] .* (1 .- u[1])
    end
    function analytic(u0, p, t)
        r = p[1]
        return [exp(r*t) / (1/u0[1] - 1 + exp(r*t))]
    end
    log_reg = ODEProblem(
        ODEFunction(logistic!, analytic=analytic),
        u0, tspan, p)
    return log_reg
end

function brusselator(; u0=[1.5; 3], tspan=(0., 10.))
    function f(du, u, p, t)
        du[1] = 1 + u[1]^2*u[2] - 4 * u[1]
        du[2] = 3 * u[1] - u[1]^2 * u[2]
    end
    brusselator = ODEProblem(f, u0, tspan)
    return brusselator
end

function fitzhugh_nagumo(; u0=[-1.0; 1.0], tspan=(0., 20.), p=[0.2,0.2,3.0])
    function fitz(u,p,t)
        V,R = u
        a,b,c = p
        return [
            c*(V - V^3/3 + R)
            -(1/c)*(V -  a - b*R)
        ]
    end
    return ODEProblem(fitz,u0,tspan,p)
end

function fitzhugh_nagumo_iip(; u0=[-1.0; 1.0], tspan=(0., 20.), p=[0.2,0.2,3.0])
    function fitz!(du,u,p,t)
        V,R = u
        a,b,c = p
        du[1] = c*(V - V^3/3 + R)
        du[2] = -(1/c)*(V -  a - b*R)
    end
    return ODEProblem(fitz!,u0,tspan,p)
end

function lotka_volterra(;
                        u0=[1.0;1.0],
                        tspan=(0.0,10.0),
                        p=[1.5,1.0,3.0,1.0])
    function f(du, u, p, t)
        a, b, c, d = p
        du[1] = a*u[1] - b*u[1]*u[2]
        du[2] = -c*u[2] + d*u[1]*u[2]
    end
    return ODEProblem(f, u0, tspan, p)
end

function van_der_pol(; u0=[0;2.], tspan=(0.0,6.3), p=[1e6])
    function f(du, u, p, t)
        μ = p[1]
        du[1] = μ*((1-u[2]^2)*u[1] - u[2])
        du[2] = 1*u[1]
    end
    return ODEProblem(f, u0, tspan, p)
end

max_stars_repo_name: nathanaelbosch/capos

max_issues_repo_name: nathanaelbosch/capos

max_forks_repo_name: nathanaelbosch/capos