text:
#########################################################################
# Printers for various data types. They are all overloading Base.show() #
#########################################################################

# Function that returns an alias to be printed for any data cell
_show_celltype_(c::CellData) = !isempty(c.tinfo) ? "" : "DataCell"
_show_celltype_(c::T where T<:DataCell{U,Void,Void} where U<:SubArray) = !isempty(c.tinfo) ? "[*]"*c.tinfo : "[*]DataCell"
_show_celltype_(c::T where T<:DataCell{U,V,Void} where U<:SubArray where V<:SubArray) = !isempty(c.tinfo) ? "[*]"*c.tinfo : "[*]DataCell"
_show_celltype_(c::CellFun) = !isempty(c.tinfo) ? "" : "FunctionCell"
_show_celltype_(c::PipeGeneric) = !isempty(c.tinfo) ? "" : "Generic Pipe"
_show_celltype_(c::PipeStacked) = !isempty(c.tinfo) ? "" : "Stacked Pipe"
_show_celltype_(c::PipeParallel) = !isempty(c.tinfo) ? "" : "Parallel Pipe"
_show_celltype_(c::PipeSerial) = !isempty(c.tinfo) ? "" : "Serial Pipe"
_show_celltype_(c::T where T<:AbstractCell) = !isempty(c.tinfo) ? "" : "AbstractCell"

# Function that prints a status based on a defined alias
_show_status_(::AbstractCell) = "<no status>"
_show_status_(::CellDataU) = ""
_show_status_(::CellDataLL) = ""
_show_status_(::CellDataL) = ""
_show_status_(::CellFunF) = "fixed"
_show_status_(::CellFunU) = "untrained"
_show_status_(::CellFunT) = "trained"
_show_status_(::PipeGeneric) = "generic"
_show_status_(::PipeStackedF) = "fixed"
_show_status_(::PipeParallelF) = "fixed"
_show_status_(::PipeSerialF) = "fixed"
_show_status_(::PipeStackedU) = "untrained"
_show_status_(::PipeParallelU) = "untrained"
_show_status_(::PipeSerialU) = "untrained"
_show_status_(::PipeStackedT) = "trained"
_show_status_(::PipeParallelT) = "trained"
_show_status_(::PipeSerialT) = "trained"

# Title printer
_show_title_(c::T where T<:AbstractCell) = isempty(c.tinfo) ? "" : c.tinfo

# Dimension printers
_show_dims_(c::T where T<:CellFunF) = "varying I/O dimensions"
_show_dims_(c::T where T<:CellFun) = begin

	# Read input and output dimensions
	_getdims_(c::CellFunU) = (gety!(c).idim, gety!(c).odim)
	_getdims_(c::CellFunT) = (getx!(c).properties.idim, getx!(c).properties.odim)
	idim, odim = _getdims_(c)

	# Build dimension string
	dimstr = ""
	if idim !=0
		if odim != 0
			dimstr = string(idim) * "->" * string(odim)
		else
			dimstr = string(idim) * "->" * "unknown"
		end
	else
		if odim != 0
			dimstr = "unknown" * "->" * string(odim)
		else
			dimstr="varying I/O dimensions"
		end
	end
	return dimstr
end
_show_dims_(c::T where T<:CellDataU) = string(nobs(c))*" obs, "*string(nvars(c))*" vars, "*"0 target(s)/obs"
_show_dims_(c::T where T<:CellDataL) = string(nobs(c))*" obs, "*string(nvars(c))*" vars, 1 target(s)/obs, "*string(length(classnames(c)))*" distinct values"
_show_dims_(c::T where T<:CellDataLL) = string(nobs(c))*" obs, "*string(nvars(c))*" vars, "*string(length(classnames(c)))*" target(s)/obs"
_show_dims_(c::T where T<:AbstractCell) = "<no dimensions>"

# Printer for unlabeled data blocks
Base.show(io::IO, c::CellDataU) = print(io, _show_celltype_(c), _show_title_(c), ", ", _show_dims_(c))

# Printer for labeled data blocks
Base.show(io::IO, c::CellDataL) = begin
	cm = countmap(gety!(c))
    	cstr = ": "
	nlab = length(keys(cm))
	if nlab > 8
        	cstr ="";
	else
        	for key in keys(cm)
			cstr = cstr * string("\"", key, "\"", "(", Int(cm[key]),"),")
        	end
		cstr=chop(cstr)
    	end

	print(io, _show_celltype_(c), _show_title_(c), ", ", _show_dims_(c), cstr)

end

# Printer for data blocks with multiple labels
Base.show(io::IO, c::CellDataLL) = print(io, _show_celltype_(c), _show_title_(c), ", ", _show_dims_(c))

# Printer for fixed/untrained function cells
Base.show(io::IO, c::CellFun) = print(io, _show_celltype_(c), _show_title_(c), ", ", _show_dims_(c), ", ", _show_status_(c))

# Printer for pipes
Base.show(io::IO, p::PipeGeneric) = print(io, _show_celltype_(p), _show_title_(p), ", ", length(getx!(p)), " element(s)", ", ",p.layer," layer(s)",", ", _show_status_(p))

# Printer for AbstractCells (e.g. everything generic)
Base.show(io::IO, ac::T where T<:AbstractCell) = print(io, _show_celltype_(ac), _show_title_(ac), " [", typeof(getx!(ac)), "]", ", ",ac.layer," layer(s)")

# Low-level printer for tuples containing AbstractCells
Base.show(io::IO, x::T where T<:PTuple{AbstractCell}) = begin
	println("$(length(x))-element Tuple{$(eltype(x))}:")
	for i in x
		print(io,"`- "); println(io, i)
	end
end

Base.show(io::IO, x::Tuple{}) = "()"


text:
# Tests based on the Raster API tutorial found at http://gdal.org/gdal_tutorial.html

using GDAL

utmsmall = joinpath(@__DIR__, "data/utmsmall.tif")
utmsmall_copy = joinpath(@__DIR__, "tmp/utmsmall.tif")

# needed to actually load tifs
GDAL.gdalallregister()

# Opening the File
dataset = GDAL.gdalopen(utmsmall, GDAL.GA_ReadOnly) # file from GDAL SVN

# Getting Dataset Information
driver = GDAL.gdalgetdriverbyname("GTiff")
@test GDAL.gdalgetdrivershortname(driver) == "GTiff"
@test GDAL.gdalgetdriverlongname(driver) == "GeoTIFF"

@test GDAL.gdalgetrasterxsize(dataset) == 100
@test GDAL.gdalgetrasterysize(dataset) == 100
@test GDAL.gdalgetrastercount(dataset) == 1
nad27_prefix = "PROJCS[\"NAD27 / UTM zone 11N\",GEOGCS[\"NAD27\",DATUM[\"North_American_Datum_1927\","
@test startswith(GDAL.gdalgetprojectionref(dataset), nad27_prefix)

geotransform = fill(0.0, 6)
GDAL.gdalgetgeotransform(dataset, geotransform)
@test geotransform == [440720.0,60.0,0.0,3.75132e6,0.0,-60.0]

# Fetching a Raster Band
band = GDAL.gdalgetrasterband(dataset, 1)

blockxsize, blockysize = Ref(Cint(-1)), Ref(Cint(-1))
GDAL.gdalgetblocksize(band, blockxsize, blockysize)
@test blockxsize[] == 100
@test blockysize[] == 81

@test GDAL.gdalgetdatatypename(GDAL.gdalgetrasterdatatype(band)) == "Byte"
@test GDAL.gdalgetcolorinterpretationname(GDAL.gdalgetrastercolorinterpretation(band)) == "Gray"

gotmin, gotmax = Ref(Cint(-1)), Ref(Cint(-1))
@test GDAL.gdalgetrasterminimum(band, gotmin) == 0.0
@test GDAL.gdalgetrastermaximum(band, gotmax) == 255.0
@test gotmin[] == gotmax[] == 0

@test GDAL.gdalgetoverviewcount(band) == 0
# note that if there is no raster color table, no error (C_None) is set by GDAL
# so there is no GDALError thrown here
@test GDAL.gdalgetrastercolortable(band) == C_NULL

# Reading Raster Data
xsize = GDAL.gdalgetrasterbandxsize(band)
@test xsize == 100
scanline = fill(0.0f0, xsize)
GDAL.gdalrasterio(band, GDAL.GF_Read, 0, 0, xsize, 1,
              scanline, xsize, 1, GDAL.GDT_Float32, 0, 0)
@test scanline == Float32[107.0f0,123.0f0,132.0f0,115.0f0,132.0f0,132.0f0,140.0f0,132.0f0,132.0f0,132.0f0,107.0f0,132.0f0,107.0f0,132.0f0,132.0f0,107.0f0,123.0f0,115.0f0,156.0f0,148.0f0,107.0f0,132.0f0,107.0f0,115.0f0,99.0f0,123.0f0,99.0f0,74.0f0,115.0f0,82.0f0,115.0f0,115.0f0,107.0f0,123.0f0,123.0f0,99.0f0,123.0f0,123.0f0,115.0f0,115.0f0,107.0f0,90.0f0,99.0f0,107.0f0,107.0f0,99.0f0,123.0f0,107.0f0,140.0f0,123.0f0,123.0f0,115.0f0,99.0f0,132.0f0,123.0f0,115.0f0,115.0f0,123.0f0,132.0f0,115.0f0,123.0f0,132.0f0,214.0f0,156.0f0,165.0f0,148.0f0,115.0f0,148.0f0,156.0f0,148.0f0,140.0f0,165.0f0,156.0f0,197.0f0,156.0f0,197.0f0,140.0f0,173.0f0,156.0f0,165.0f0,148.0f0,156.0f0,206.0f0,214.0f0,181.0f0,206.0f0,173.0f0,222.0f0,206.0f0,255.0f0,214.0f0,173.0f0,214.0f0,255.0f0,214.0f0,247.0f0,255.0f0,230.0f0,206.0f0,197.0f0]

# Closing the Dataset
GDAL.gdalclose(dataset)

# Techniques for Creating Files
@test GDAL.gdalgetmetadataitem(driver, "DCAP_CREATE", "") == "YES"
@test GDAL.gdalgetmetadataitem(driver, "DCAP_CREATECOPY", "") == "YES"

# Using CreateCopy()
ds_src = GDAL.gdalopen(utmsmall, GDAL.GA_ReadOnly)

progressfunc = convert(Ptr{GDAL.GDALProgressFunc}, C_NULL)

ds_dst = GDAL.gdalcreatecopy(driver, utmsmall_copy, ds_src, 0,
                         C_NULL, progressfunc, C_NULL)
GDAL.gdalclose(ds_dst)
GDAL.gdalclose(ds_src)

rm(utmsmall_copy)
# rest of the tutorial is skipped, perhaps we should wrap "cpl_string.h"
# to be able to build papszOptions, or write it in julia
# #include "cpl_string.h"
# ...
#     char **papszOptions = NULL;
#
#     papszOptions = CSLSetNameValue( papszOptions, "TILED", "YES" );
#     papszOptions = CSLSetNameValue( papszOptions, "COMPRESS", "PACKBITS" );
#     hDstDS = GDALCreateCopy( hDriver, pszDstFilename, hSrcDS, FALSE,
#                              papszOptions, GDALTermProgres, NULL );
#     /* Once we're done, close properly the dataset */
#     if( hDstDS != NULL )
#         GDALClose( hDstDS );
#     CSLDestroy( papszOptions );

ext: jl


text:
using Clang

function cursor_wrapped(decl)
    header = filename(decl)
    (header |> splitdir |> last) == "api.h" || return false
    true
end

ctx = init(
    headers = [joinpath(dirname(@__DIR__), "deps", "include", "api.h")],
    output_file = joinpath(dirname(@__DIR__), "api.jl"),
    common_file = "common.jl",
    header_wrapped = (root, current) -> root == current,
    header_library = (x...) -> "libtreesitter",
    clang_args = ["-std=gnu99"],
    clang_includes = [CLANG_INCLUDE],
)

run(ctx, false)


text:
# IPO EA Test
# ===========
# EA works on pre-inlining IR

include(normpath(@__DIR__, "setup.jl"))

# callsites
# ---------

noescape(a) = nothing
noescape(a, b) = nothing
function global_escape!(x)
    GR[] = x
    return nothing
end
union_escape!(x) = global_escape!(x)
union_escape!(x::SafeRef) = nothing
union_escape!(x::SafeRefs) = nothing
Base.@constprop :aggressive function conditional_escape!(cnd, x)
    cnd && global_escape!(x)
    return nothing
end

# MethodMatchInfo -- global cache
let result = code_escapes((SafeRef{String},); optimize=false) do x
        return noescape(x)
    end
    @test has_no_escape(ignore_argescape(result.state[Argument(2)]))
end
let result = code_escapes((SafeRef{String},); optimize=false) do x
        identity(x)
        return nothing
    end
    @test has_no_escape(ignore_argescape(result.state[Argument(2)]))
end
let result = code_escapes((SafeRef{String},); optimize=false) do x
        return identity(x)
    end
    r = only(findall(isreturn, result.ir.stmts.inst))
    @test has_return_escape(result.state[Argument(2)], r)
end
let result = code_escapes((SafeRef{String},); optimize=false) do x
        return Ref(x)
    end
    r = only(findall(isreturn, result.ir.stmts.inst))
    @test has_return_escape(result.state[Argument(2)], r)
end
let result = code_escapes((SafeRef{String},); optimize=false) do x
        r = Ref{SafeRef{String}}()
        r[] = x
        return r
    end
    r = only(findall(isreturn, result.ir.stmts.inst))
    @test has_return_escape(result.state[Argument(2)], r)
end
let result = code_escapes((SafeRef{String},); optimize=false) do x
        global_escape!(x)
    end
    @test has_all_escape(result.state[Argument(2)])
end
# UnionSplitInfo
let result = code_escapes((Bool,Vector{Any}); optimize=false) do c, s
        x = c ? s : SafeRef(s)
        union_escape!(x)
    end
    @test has_all_escape(result.state[Argument(3)]) # s
end
let result = code_escapes((Bool,Vector{Any}); optimize=false) do c, s
        x = c ? SafeRef(s) : SafeRefs(s, s)
        union_escape!(x)
    end
    @test has_no_escape(ignore_argescape(result.state[Argument(2)]))
end
# ConstCallInfo -- local cache
let result = code_escapes((SafeRef{String},); optimize=false) do x
        return conditional_escape!(false, x)
    end
    @test has_no_escape(ignore_argescape(result.state[Argument(2)]))
end
# InvokeCallInfo
let result = code_escapes((SafeRef{String},); optimize=false) do x
        return Base.@invoke noescape(x::Any)
    end
    @test has_no_escape(ignore_argescape(result.state[Argument(2)]))
end
let result = code_escapes((SafeRef{String},); optimize=false) do x
        return Base.@invoke conditional_escape!(false::Any, x::Any)
    end
    @test has_no_escape(ignore_argescape(result.state[Argument(2)]))
end

# MethodError
# -----------
# accounts for ThrownEscape via potential MethodError

# no method error
identity_if_string(x::SafeRef) = nothing
let result = code_escapes((SafeRef{String},); optimize=false) do x
        identity_if_string(x)
    end
    i = only(findall(iscall((result.ir, identity_if_string)), result.ir.stmts.inst))
    r = only(findall(isreturn, result.ir.stmts.inst))
    @test !has_thrown_escape(result.state[Argument(2)], i)
    @test !has_return_escape(result.state[Argument(2)], r)
end
let result = code_escapes((Union{SafeRef{String},Vector{String}},); optimize=false) do x
        identity_if_string(x)
    end
    i = only(findall(iscall((result.ir, identity_if_string)), result.ir.stmts.inst))
    r = only(findall(isreturn, result.ir.stmts.inst))
    @test has_thrown_escape(result.state[Argument(2)], i)
    @test !has_return_escape(result.state[Argument(2)], r)
end
let result = code_escapes((SafeRef{String},); optimize=false) do x
        try
            identity_if_string(x)
        catch err
            global GV = err
        end
        return nothing
    end
    @test !has_all_escape(result.state[Argument(2)])
end
let result = code_escapes((Union{SafeRef{String},Vector{String}},); optimize=false) do x
        try
            identity_if_string(x)
        catch err
            global GV = err
        end
        return nothing
    end
    @test has_all_escape(result.state[Argument(2)])
end
# method ambiguity error
ambig_error_test(a::SafeRef, b) = nothing
ambig_error_test(a, b::SafeRef) = nothing
ambig_error_test(a, b) = nothing
let result = code_escapes((SafeRef{String},Any); optimize=false) do x, y
        ambig_error_test(x, y)
    end
    i = only(findall(iscall((result.ir, ambig_error_test)), result.ir.stmts.inst))
    r = only(findall(isreturn, result.ir.stmts.inst))
    @test has_thrown_escape(result.state[Argument(2)], i)  # x
    @test has_thrown_escape(result.state[Argument(3)], i)  # y
    @test !has_return_escape(result.state[Argument(2)], r)  # x
    @test !has_return_escape(result.state[Argument(3)], r)  # y
end
let result = code_escapes((SafeRef{String},Any); optimize=false) do x, y
        try
            ambig_error_test(x, y)
        catch err
            global GV = err
        end
    end
    @test has_all_escape(result.state[Argument(2)])  # x
    @test has_all_escape(result.state[Argument(3)])  # y
end

# Local EA integration
# --------------------

# propagate escapes imposed on call arguments

# FIXME handle _apply_iterate
# FIXME currently we can't prove the effect-freeness of `getfield(RefValue{String}, :x)`
# because of this check https://github.com/JuliaLang/julia/blob/94b9d66b10e8e3ebdb268e4be5f7e1f43079ad4e/base/compiler/tfuncs.jl#L745
# and thus it leads to the following two broken tests

@noinline broadcast_noescape1(a) = (broadcast(identity, a); nothing)
let result = code_escapes() do
        broadcast_noescape1(Ref("Hi"))
    end
    i = only(findall(isnew, result.ir.stmts.inst))
    @test_broken !has_return_escape(result.state[SSAValue(i)])
    @test_broken !has_thrown_escape(result.state[SSAValue(i)])
end
@noinline broadcast_noescape2(b) = broadcast(identity, b)
let result = code_escapes() do
        broadcast_noescape2(Ref("Hi"))
    end
    i = only(findall(isnew, result.ir.stmts.inst))
    @test_broken !has_return_escape(result.state[SSAValue(i)])
    @test_broken !has_thrown_escape(result.state[SSAValue(i)])
end
@noinline allescape_argument(a) = (global GV = a) # obvious escape
let result = code_escapes() do
        allescape_argument(Ref("Hi"))
    end
    i = only(findall(isnew, result.ir.stmts.inst))
    @test has_all_escape(result.state[SSAValue(i)])
end
# if we can't determine the matching method statically, we should be conservative
let result = code_escapes((Ref{Any},)) do a
        may_exist(a)
    end
    @test has_all_escape(result.state[Argument(2)])
end
let result = code_escapes((Ref{Any},)) do a
        Base.@invokelatest broadcast_noescape1(a)
    end
    @test has_all_escape(result.state[Argument(2)])
end

# handling of simple union-split (just exploit the inliner's effort)
@noinline unionsplit_noescape(a)      = string(nothing)
@noinline unionsplit_noescape(a::Int) = a + 10
let result = code_escapes((Union{Int,Nothing},)) do x
        s = SafeRef{Union{Int,Nothing}}(x)
        unionsplit_noescape(s[])
        return nothing
    end
    inds = findall(isnew, result.ir.stmts.inst) # find allocation statement
    @assert !isempty(inds)
    for i in inds
        @test has_no_escape(result.state[SSAValue(i)])
    end
end

@noinline function unused_argument(a)
    println("prevent inlining")
    return Base.inferencebarrier(nothing)
end
let result = code_escapes() do
        a = Ref("foo") # shouldn't be "return escape"
        b = unused_argument(a)
        nothing
    end
    i = only(findall(isnew, result.ir.stmts.inst))
    r = only(findall(isreturn, result.ir.stmts.inst))
    @test !has_return_escape(result.state[SSAValue(i)], r)

    result = code_escapes() do
        a = Ref("foo") # still should be "return escape"
        b = unused_argument(a)
        return a
    end
    i = only(findall(isnew, result.ir.stmts.inst))
    r = only(findall(isreturn, result.ir.stmts.inst))
    @test has_return_escape(result.state[SSAValue(i)], r)
end

# should propagate escape information imposed on return value to the aliased call argument
@noinline returnescape_argument(a) = (println("prevent inlining"); a)
let result = code_escapes() do
        obj = Ref("foo")           # should be "return escape"
        ret = returnescape_argument(obj)
        return ret                 # alias of `obj`
    end
    i = only(findall(isnew, result.ir.stmts.inst))
    r = only(findall(isreturn, result.ir.stmts.inst))
    @test has_return_escape(result.state[SSAValue(i)], r)
end
@noinline noreturnescape_argument(a) = (println("prevent inlining"); identity("hi"))
let result = code_escapes() do
        obj = Ref("foo")              # better to not be "return escape"
        ret = noreturnescape_argument(obj)
        return ret                    # must not alias to `obj`
    end
    i = only(findall(isnew, result.ir.stmts.inst))
    r = only(findall(isreturn, result.ir.stmts.inst))
    @test !has_return_escape(result.state[SSAValue(i)], r)
end

max_stars_repo_name: JuliaLabs/julia

max_issues_repo_name: JuliaLabs/julia

max_forks_repo_name: JuliaLabs/julia


text:
using SumProductNetworks
using Test

testcases = Dict(
        "utilities"  => ["utilityFunctionTest"],
        "nodes"     => ["nodeFunctionTests"]
)

# Run tests
path = dirname(@__FILE__)
cd(path)

@testset "Sum-product network tests" begin
    for (target, list) in testcases
        @testset "$target" begin
            for t in list
                filename = string(t, ".jl")
                include( joinpath(target, filename) );
            end
        end
    end
end


text:
# TODO: add to documentation page and do tests

#######################################################################################################################################################################################################
#
# Changes to this struct
# General
#     2021-Oct-22: refactor the structure with renamed fields
#     2021-Oct-22: add a constructor to define the structure from wavelength sets and prescribed wave shape
#
#######################################################################################################################################################################################################
"""
$(TYPEDEF)

Structure that stores hyperspectral radiation information

# Fields
$(TYPEDFIELDS)
"""
mutable struct HyperspectralRadiation{FT<:AbstractFloat}
    # prognostic variables that change with time
    "Direct radiation `[mW m⁻² nm⁻¹]`"
    e_direct::Vector{FT}
    "Diffuse radiation `[mW m⁻² nm⁻¹]`"
    e_diffuse::Vector{FT}
end

"""
    HyperspectralRadiation{FT}(wls::WaveLengthSet = WaveLengthSet{FT}(), file::String = FILE_SUN)

Constructor for [`HyperspectralRadiation`](@ref), given
- `wls` [`WaveLengthSet`](@ref) type struct that defines wavelength settings
- `file` File path to solar radiation setting, default is `ClimaCache.FILE_SUN`

---
# Examples
```julia
rad = HyperspectralRadiation{FT}();
rad = HyperspectralRadiation{FT}(WaveLengthSet{FT}(collect(400:50:2400)));
rad = HyperspectralRadiation{FT}(WaveLengthSet{FT}(collect(400:50:2400)); file = "");
rad = HyperspectralRadiation{FT}(WaveLengthSet{FT}(collect(400:50:2400)); file = ClimaCache.FILE_SUN);
```
"""
HyperspectralRadiation{FT}(wls::WaveLengthSet = WaveLengthSet{FT}(); file::String = FILE_SUN) where {FT<:AbstractFloat} = (
    @unpack SΛ, NΛ = wls;

    # create arrays
    _e_direct  = zeros(FT, NΛ);
    _e_diffuse = zeros(FT, NΛ);

    # Read data from SCOPE MAT file if file is given, if not use 0
    if isfile(file)
        _suni    = matread(file)["sun"];
        _wl      = _suni["wl"      ];
        __e_dir  = _suni["Edirect" ];
        __e_diff = _suni["Ediffuse"];

        # fill in the arrays
        for _i in 1:NΛ
            _wi = findall( SΛ[_i] .<= _wl .< SΛ[_i+1] );
            if length(_wi)==0 @warn "Some wavelengths out of bounds $(string(SΛ[_i]))" end;
            _e_direct[_i]  = mean( __e_dir[_wi]);
            _e_diffuse[_i] = mean(__e_diff[_wi]);
        end;
    end;

    return HyperspectralRadiation{FT}(_e_direct, _e_diffuse)
);


text:
__precompile__()
module FuzzySearch
    include("FuzzySearch_.jl")
    export brute_force_search, brute_force_search_bestfuzzy, bestof2searches, brute_force_search_wildcard
end

max_stars_repo_name: straightlab/chartools-dev

max_issues_repo_name: straightlab/chartools-dev

max_forks_repo_name: straightlab/chartools-dev


text:
using ContextTracking
using Logging
using LoggingFacilities

# Top level function
@ctx function foo()
    @memo x = 1
    @memo y = 2
    bar()
end

# Lower level function that inherits parent context
@ctx function bar()
    z = 3
    @info "inside bar" z
end

# =============================================================================
# Example 1: just include context data as kwargs
# =============================================================================

context_logger = build(current_logger(), inject(KwargsLocation(), () -> context().data));

with_logger(context_logger) do
    foo()
end
#=
julia> with_logger(context_logger) do
           foo()
       end
┌ Info: inside bar
│   y = 2
│   x = 1
└   z = 3
=#

# =============================================================================
# Example 2: logging context data as JSON
# =============================================================================

using JSON

# use MessageOnlyLogger here to avoid unwanted garbage e.g. level prefix.
json_logger = build(MessageOnlyLogger(),
                    # inject context data into kwargs location
                    inject(KwargsLocation(), (:Context => context().data,)),
                    # migrate level to kwargs location
                    migrate(LevelProperty(), KwargsProperty(); label = :Level, transform = string),
                    # migrate message to kwargs location
                    migrate(MessageProperty(), KwargsProperty(); label = :Message),
                    # migrate kwargs data to message location as JSON format
                    migrate(KwargsProperty(), MessageProperty(); transform = x -> json(x, 2))
                    );

with_logger(json_logger) do
    foo()
end

#=
julia> with_logger(json_logger) do
           foo()
       end
{
  "Message": "inside bar",
  "Level": "Info",
  "Context": {
    "y": 2,
    "x": 1
  },
  "z": 3
}
=#


text:
function findMatching(viznodes, neuron)
  for viznode in viznodes
    if viznode.neuron === neuron
      return viznode
    end
  end
  error("Couldn't find matching viznode for $neuron")
end

# ---------------------------------------------------------------------------

type LiquidVisualizationNode
  neuron::SpikingNeuron
  circle::SceneItem
  isinput::Bool
end

function LiquidVisualizationNode(neuron::SpikingNeuron, pos::P3, isinput::Bool)
  # shift x/y coords based on zvalue to give a 3d-ish look
  z = pos[3]
  pos = pos + P3(z/5, z/5, 0)

  # create a new circle in the scene
  radius = 20
  circle = circle!(radius, pos)
  brush!(pen!(circle, 0), :lightGray)
  if !neuron.excitatory
    pen!(circle, 3, :yellow)
  end

  LiquidVisualizationNode(neuron, circle, isinput)
end

  # draw lines for synapses
function addSynapticConnections(viznodes::Vector{LiquidVisualizationNode})
  for viznode in viznodes
    for synapse in viznode.neuron.synapses
      connectedViznode = findMatching(viznodes, synapse.postsynapticNeuron)
      l = line!(viznode.circle, connectedViznode.circle)
      # pen!(l, 1 + 2 * abs(synapse.weight), 0, 0, 0, 0.3)
      pen!(l, 1 + 2 * abs(synapse.weight), :lightGray)
    end
  end
end

# ---------------------------------------------------------------------------

function visualize(input::GRFInput, pos::P2, viznodes)
  ys = getLinspace(length(input.neurons), 100)
  pt = P3(pos - P2(70, 0), -10000)
  for (i,neuron) in enumerate(input.neurons)
    viznode = LiquidVisualizationNode(neuron, P3(pos + P2(0,ys[i])), true)
    push!(viznodes, viznode)
    pen!(line!(viznode.circle, pt), 2, :cyan)  # connect line to pt
  end
  pen!(line!(pt, pt - P3(70,0,0)), 2, :cyan)
end

# ---------------------------------------------------------------------------

type LiquidVisualization
  lsm::LiquidStateMachine
  window::Widget
  scene::Scene
  pltEstVsAct::PlotWidget
  pltScatter::PlotWidget
  pltMembranePotential::PlotWidget
  pltSpikeTrains::PlotWidget
  viznodes::Vector{LiquidVisualizationNode}
  t::Int
end

function visualize(lsm::LiquidStateMachine)

  nin = lsm.nin
  nout = lsm.nout
  liquid = lsm.liquid

  # set up the liquid scene
  scene = Scene(show=false)
  background!(:gray)
  viznodes = LiquidVisualizationNode[]

  # input
  nin = length(lsm.inputs.inputs)
  x = -400
  ys = getLinspace(nin, 400)
  for (i,input) in enumerate(lsm.inputs.inputs)
    pos = P2(x, ys[i])
    visualize(input, pos, viznodes)
  end

  # liquid
  xs = getLinspace(liquid.params.l, 140)
  ys = getLinspace(liquid.params.w, 200)
  zs = getLinspace(liquid.params.h, 120)
  for neuron in liquid.neurons
    i, j, k = neuron.position
    pos = P3(xs[i], ys[j], zs[k])
    push!(viznodes, LiquidVisualizationNode(neuron, pos, false))
  end

  addSynapticConnections(viznodes)

  # set up the estimate vs actual plot
  pltEstVsAct = plot(zeros(0,nout*2),
                     title="predicted vs actual",
                     labels = map(i->string(i<=nout ? "Act" : "Est", i), 1:nout*2),
                     show=false)

  # set up the scatter plot of estimate vs actual
  pltScatter = scatter(zeros(0,nout),
                       zeros(0,nout),
                       xlabel = "predicted",
                       ylabel = "actual",
                       show=false)

  # set up the plot of membrane potential
  pltMembranePotential = plot(zeros(0, 4), #length(liquid.neurons)),
                              title = "Membrane Potential",
                              show = false)

  pltSpikeTrains = scatter(zeros(0, 2),
                           title = "Spike Trains",
                           labels = ["Inputs", "Liquid"],
                           show = false)

  # put all 3 together into a widget container, resize, then show
  window = vsplitter(hsplitter(scene, vsplitter(pltScatter, pltSpikeTrains)), hsplitter(pltEstVsAct, pltMembranePotential))
  moveToLastScreen(window)
  resizewidget(window, screenSize(screenCount()) - P2(20,20))
  showwidget(window)

  LiquidVisualization(lsm, window, scene, pltEstVsAct, pltScatter, pltMembranePotential, pltSpikeTrains, viznodes, 0)
end

#update visualization
function OnlineStats.fit!(viz::LiquidVisualization, y::VecF)
  viz.t += 1

  for viznode in viz.viznodes
    neuron = viznode.neuron
    local args
    if neuron.fired
      args = (:red,)
    else
      upct = 1.0 - max(0., min(neuron.u / neuron.ϑ, 1.))
      args = (upct,upct,upct)
    end
    brush!(viznode.circle, args...)
  end

  # neuron-specific plotting
  for (i,neuron) in enumerate(viz.lsm.liquid.neurons[1:length(viz.pltMembranePotential.lines)])
    if neuron.fired
      push!(viz.pltMembranePotential, i, viz.t, neuron.ϑ)
      push!(viz.pltMembranePotential, i, viz.t, neuron.ϑ + 0.25)
    end
    push!(viz.pltMembranePotential, i, viz.t, neuron.u)
  end

  # readout plotting
  ####################################################
  # TODO the prediction should really be the prediction from 100 periods ago... not the current prediction!!
  ####################################################
  est = predict(viz.lsm)
  for (i,e) in enumerate(est)
    push!(viz.pltEstVsAct, i, viz.t, y[i])
    push!(viz.pltEstVsAct, i+viz.lsm.nout, viz.t, e)
    push!(viz.pltScatter, i, e, y[i])
  end

  # spike train plotting
  for (i,viznode) in enumerate(viz.viznodes)
    if viznode.neuron.fired
      # line = viz.pltSpikeTrains.lines[viznode.isinput ? 1 : 2]
      push!(viz.pltSpikeTrains, viznode.isinput ? 1 : 2, viz.t, Float64(i))
    end
  end

  # refresh the plots
  refresh(viz.pltEstVsAct)
  refresh(viz.pltScatter)
  refresh(viz.pltMembranePotential)
  refresh(viz.pltSpikeTrains)

  sleep(0.0001)
end


text:
using Revise
using Test
using MAT
using NNFEM
using PyCall
using PyPlot
using JLD2
using ADCME
using LinearAlgebra

include("nnutil.jl")
testtype = "NeuralNetwork1D"
include("NNTrussPull_Domain.jl")
tid = 3

#nntype = "ae_scaled"
#nntype = "piecewise"
ite_id = 10
#nnname = "Data/$(nntype)/trained_nn$(idx)_from3_ite$(ite_id).mat"
#nnname = "Data/$(nntype)/NNPreLSfit_nn$(idx)_ite$(start_id).mat"
nnname = "Data/$(nntype)/learned_nn$(idx)_ite$(ite_id)_$(nn_init_id).mat"
@show nnname
s = ae_to_code(nnname, nntype)
eval(Meta.parse(s))

nodes, EBC, g, gt, FBC, fext, ft, npoints, node_to_point = BoundaryCondition(tid)
prop = Dict("name"=> testtype, "rho"=> 8000.0, "E"=> 200e3, "nu"=> 0.45,
           "sigmaY"=>0.3e3, "K"=>1/9*200e3, "B"=> 0.0, "A0"=> 0.005, "nn"=>post_nn)

elements = []
for i = 1:nx
    elnodes = [i, i+1]; coords = nodes[elnodes,:];
    push!(elements, FiniteStrainTruss(coords,elnodes, prop, ngp))
end
domain = Domain(nodes, elements, ndofs, EBC, g, FBC, fext)
state = zeros(domain.neqs)
∂u = zeros(domain.neqs)
globdat = GlobalData(state,zeros(domain.neqs), zeros(domain.neqs),∂u, domain.neqs, gt, ft)
assembleMassMatrix!(globdat, domain)
# need to update state in domain from globdat
updateStates!(domain, globdat)

adaptive_solver_args = Dict("Newmark_rho"=> 0.0,
                          "Newton_maxiter"=>10,
                          "Newton_Abs_Err"=>1e-4,
                          "Newton_Rel_Err"=>1e-6,
                          "damped_Newton_eta" => 1.0)
globdat, domain, ts = AdaptiveSolver("NewmarkSolver", globdat, domain, T, NT, adaptive_solver_args)

# for i = 1:NT
#     @info i, "/" , NT
#     solver = NewmarkSolver(Δt, globdat, domain, -1.0, 0.0, 1e-8, 1e-8, 10) # ok
# end

domain_te = domain
@info tid
@save "Data/$(nntype)/nn$(idx)_domain_te$(tid).jld2" domain_te

############################## Plot stress

close("all")
strain = hcat(domain_te.history["strain"]...)
stress = hcat(domain_te.history["stress"]...)
i = 8
plot(strain[i,:], stress[i,:], ".", label="Estimated")

@load "Data/domain$tid.jld2" domain
strain = hcat(domain.history["strain"]...)
stress = hcat(domain.history["stress"]...)
i = 8
plot(strain[i,:], stress[i,:], "--", label="Reference")

xlabel("Strain")
ylabel("Stress")
legend()
#mpl.save("truss1d_stress$tid.tex")
savefig("nntest$(idx)_$(nntype)_truss1d_stress$tid.png")


text:
function readinput(filename)
    map(value -> parse(Int, value), readlines(filename))
end

function getjoltdifferences(jolts)
    basejolt = 0
    joltdifferences = Dict(1 => 0, 2 => 0, 3 => 0)
    joltdifferences[3] += 1
    while length(jolts) > 0
        jolt = popfirst!(jolts)
        joltdifferences[jolt - basejolt] += 1
        basejolt = jolt
    end
    return joltdifferences
end

function getjoltcombinations(jolts)
    pushfirst!(jolts, 0)
    n = length(jolts)
    joltcombinations = zeros(Int, n)
    joltcombinations[1] = 1
    for i in 1:n-1
        for k in i+1:n
            if jolts[k] - jolts[i] <= 3
                joltcombinations[k] += joltcombinations[i]
            end
        end
    end
    return joltcombinations
end

jolts = sort!(readinput("d10.in"))
joltdifferences = getjoltdifferences(deepcopy(jolts))
joltcombinations = getjoltcombinations(deepcopy(jolts))
println("P1: ", joltdifferences[1] * joltdifferences[3])
println("P2: ", joltcombinations[end])

max_stars_repo_name: eduellery/adventofcode

max_issues_repo_name: eduellery/adventofcode

max_forks_repo_name: eduellery/adventofcode