text:
gpuvec(x) = GPUVector(GLBuffer(x))

to_range(x, y) = to_range.((x, y))
to_range(x::ClosedInterval) = (minimum(x), maximum(x))
to_range(x::VecTypes{2}) = x
to_range(x::AbstractRange) = (minimum(x), maximum(x))
to_range(x::AbstractVector) = (minimum(x), maximum(x))
function to_range(x::AbstractArray)
    if length(x) in size(x) # assert that just one dim != 1
        to_range(vec(x))
    else
        error("Can't convert to a range. Please supply a range/vector/interval or a tuple (min, max)")
    end
end
function to_glvisualize_key(k)
    k == :rotations && return :rotation
    k == :markersize && return :scale
    k == :glowwidth && return :glow_width
    k == :glowcolor && return :glow_color
    k == :strokewidth && return :stroke_width
    k == :strokecolor && return :stroke_color
    k == :positions && return :position
    k == :linewidth && return :thickness
    k == :marker_offset && return :offset
    k == :colormap && return :color_map
    k == :colorrange && return :color_norm
    k == :transform_marker && return :scale_primitive
    k
end

make_context_current(screen::Screen) = GLFW.MakeContextCurrent(to_native(screen))

function cached_robj!(robj_func, screen, scene, x::AbstractPlot)
    # poll inside functions to make wait on compile less prominent
    GLFW.PollEvents()
    robj = get!(screen.cache, objectid(x)) do
        gl_attributes = map(filter(((k, v),)-> k != :transformation, x.attributes)) do key_value
            key, value = key_value
            gl_key = to_glvisualize_key(key)
            gl_value = lift_convert(key, value, x)
            gl_key => gl_value
        end
        robj = robj_func(Dict{Symbol, Any}(gl_attributes))
        for key in (:view, :projection, :resolution, :eyeposition, :projectionview)
            robj[key] = getfield(scene.camera, key)
        end
        screen.cache2plot[robj.id] = x
        robj
    end
    push!(screen, scene, robj)
    robj
end

function remove_automatic!(attributes)
    filter!(attributes) do (k, v)
        to_value(v) != automatic
    end
end

index1D(x::SubArray) = parentindices(x)[1]

handle_view(array::AbstractVector, attributes) = array
handle_view(array::Node, attributes) = array

function handle_view(array::SubArray, attributes)
    A = parent(array)
    indices = index1D(array)
    attributes[:indices] = indices
    A
end
function handle_view(array::Node{T}, attributes) where T <: SubArray
    A = lift(parent, array)
    indices = lift(index1D, array)
    attributes[:indices] = indices
    A
end

function lift_convert(key, value, plot)
    lift(value) do value
         convert_attribute(value, Key{key}(), Key{AbstractPlotting.plotkey(plot)}())
     end
end

pixel2world(scene, msize::Number) = pixel2world(scene, Point2f0(msize))[1]
function pixel2world(scene, msize::StaticVector{2})
    # TODO figure out why Vec(x, y) doesn't work correctly
    p0 = AbstractPlotting.to_world(scene, Point2f0(0.0))
    p1 = AbstractPlotting.to_world(scene, Point2f0(msize))
    diff = p1 - p0
    diff
end

pixel2world(scene, msize::AbstractVector) = pixel2world.(scene, msize)

function handle_intensities!(attributes)
    if haskey(attributes, :color) && attributes[:color][] isa AbstractVector{<: Number}
        c = pop!(attributes, :color)
        attributes[:intensity] = lift(x-> convert(Vector{Float32}, x), c)
    else
        delete!(attributes, :intensity)
        delete!(attributes, :color_map)
        delete!(attributes, :color_norm)
    end
end

function Base.insert!(screen::GLScreen, scene::Scene, x::Combined)
    # poll inside functions to make wait on compile less prominent
    GLFW.PollEvents()
    if isempty(x.plots) # if no plots inserted, this truely is an atomic
        draw_atomic(screen, scene, x)
    else
        foreach(x.plots) do x
            # poll inside functions to make wait on compile less prominent
            GLFW.PollEvents()
            insert!(screen, scene, x)
        end
    end
end

struct FastPixel end
AbstractPlotting.to_spritemarker(x::FastPixel) = x

function draw_atomic(screen::GLScreen, scene::Scene, x::Union{Scatter, MeshScatter})
    robj = cached_robj!(screen, scene, x) do gl_attributes
        # signals not supported for shading yet
        gl_attributes[:shading] = to_value(get(gl_attributes, :shading, true))
        marker = lift_convert(:marker, pop!(gl_attributes, :marker), x)
        if isa(x, Scatter)
            gl_attributes[:billboard] = map(rot-> isa(rot, Billboard), x.attributes[:rotations])
            gl_attributes[:distancefield][] == nothing && delete!(gl_attributes, :distancefield)
            gl_attributes[:uv_offset_width][] == Vec4f0(0) && delete!(gl_attributes, :uv_offset_width)
        end
        positions = handle_view(x[1], gl_attributes)
        if marker[] isa FastPixel
            filter!(gl_attributes) do (k, v,)
                k in (:color_map, :color, :color_norm, :scale, :fxaa, :model)
            end
            if !(gl_attributes[:color][] isa AbstractVector{<: Number})
                delete!(gl_attributes, :color_norm)
                delete!(gl_attributes, :color_map)
            end
            visualize(positions, Style(:speed), Dict{Symbol, Any}(gl_attributes)).children[]
        else
            handle_intensities!(gl_attributes)
            visualize((marker, positions), Style(:default), Dict{Symbol, Any}(gl_attributes)).children[]
        end
    end
end

function draw_atomic(screen::GLScreen, scene::Scene, x::Lines)
    robj = cached_robj!(screen, scene, x) do gl_attributes
        linestyle = pop!(gl_attributes, :linestyle)
        data = Dict{Symbol, Any}(gl_attributes)
        data[:pattern] = to_value(linestyle)
        positions = handle_view(x[1], data)
        handle_intensities!(data)
        visualize(positions, Style(:lines), data).children[]
    end
end
function draw_atomic(screen::GLScreen, scene::Scene, x::LineSegments)
    robj = cached_robj!(screen, scene, x) do gl_attributes
        linestyle = pop!(gl_attributes, :linestyle)
        data = Dict{Symbol, Any}(gl_attributes)
        data[:pattern] = to_value(linestyle)
        positions = handle_view(x.converted[1], data)
        delete!(data, :color_map)
        delete!(data, :color_norm)
        visualize(positions, Style(:linesegment), data).children[]
    end
end

using AbstractPlotting: get_texture_atlas, glyph_bearing!, glyph_uv_width!, glyph_scale!, calc_position, calc_offset

function to_gl_text(string, startpos::AbstractVector{T}, textsize, font, align, rot, model) where T <: VecTypes
    atlas = get_texture_atlas()
    N = length(T)
    positions, uv_offset_width, scale = Point{N, Float32}[], Vec4f0[], Vec2f0[]
    # toffset = calc_offset(string, textsize, font, atlas)
    char_str_idx = iterate(string)
    broadcast_foreach(1:length(string), startpos, textsize, (font,), align) do idx, pos, tsize, font, align
        char, str_idx = char_str_idx
        _font = isa(font[1], NativeFont) ? font[1] : font[1][idx]
        mpos = model * Vec4f0(to_ndim(Vec3f0, pos, 0f0)..., 1f0)
        push!(positions, to_ndim(Point{N, Float32}, mpos, 0))
        push!(uv_offset_width, glyph_uv_width!(atlas, char, _font))
        if isa(tsize, Vec2f0) # this needs better unit support
            push!(scale, tsize) # Vec2f0, we assume it's already in absolute size
        else
            push!(scale, glyph_scale!(atlas, char,_font, tsize))
        end
        char_str_idx = iterate(string, str_idx)
    end
    positions, Vec2f0(0), uv_offset_width, scale
end

function to_gl_text(string, startpos::VecTypes{N, T}, textsize, font, aoffsetvec, rot, model) where {N, T}
    atlas = get_texture_atlas()
    mpos = model * Vec4f0(to_ndim(Vec3f0, startpos, 0f0)..., 1f0)
    pos = to_ndim(Point{N, Float32}, mpos, 0f0)
    rscale = Float32(textsize)
    chars = Vector{Char}(string)
    scale = glyph_scale!.(Ref(atlas), chars, (font,), rscale)
    positions2d = calc_position(string, Point2f0(0), rscale, font, atlas)
    # font is Vector{FreeType.NativeFont} so we need to protec
    aoffset = AbstractPlotting.align_offset(Point2f0(0), positions2d[end], atlas, rscale, font, aoffsetvec)
    aoffsetn = to_ndim(Point{N, Float32}, aoffset, 0f0)
    uv_offset_width = glyph_uv_width!.(Ref(atlas), chars, (font,))
    positions = map(positions2d) do p
        pn = rot * (to_ndim(Point{N, Float32}, p, 0f0) .+ aoffsetn)
        pn .+ pos
    end
    positions, Vec2f0(0), uv_offset_width, scale
end

function draw_atomic(screen::GLScreen, scene::Scene, x::Text)
    robj = cached_robj!(screen, scene, x) do gl_attributes

        liftkeys = (:position, :textsize, :font, :align, :rotation, :model)

        gl_text = lift(to_gl_text, x[1], getindex.(Ref(gl_attributes), liftkeys)...)
        # unpack values from the one signal:
        positions, offset, uv_offset_width, scale = map((1, 2, 3, 4)) do i
            lift(getindex, gl_text, i)
        end

        atlas = get_texture_atlas()
        keys = (:color, :stroke_color, :stroke_width, :rotation)
        signals = getindex.(Ref(gl_attributes), keys)
        visualize(
            (DISTANCEFIELD, positions),
            color = signals[1],
            stroke_color = signals[2],
            stroke_width = signals[3],
            rotation = signals[4],
            scale = scale,
            offset = offset,
            uv_offset_width = uv_offset_width,
            distancefield = get_texture!(atlas),
            visible = gl_attributes[:visible]
        ).children[]
    end
end

function draw_atomic(screen::GLScreen, scene::Scene, x::Heatmap)
    robj = cached_robj!(screen, scene, x) do gl_attributes
        gl_attributes[:ranges] = lift(to_range, x[1], x[2])
        interp = to_value(pop!(gl_attributes, :interpolate))
        interp = interp ? :linear : :nearest
        tex = Texture(x[3], minfilter = interp)
        pop!(gl_attributes, :color)
        gl_attributes[:stroke_width] = pop!(gl_attributes, :thickness)
        GLVisualize.assemble_shader(GLVisualize.gl_heatmap(tex, gl_attributes)).children[]
    end
end

function vec2color(colors, cmap, crange)
    AbstractPlotting.interpolated_getindex.((to_colormap(cmap),), colors, (crange,))
end

function get_image(plot)
    if isa(plot[:color][], AbstractMatrix{<: Number})
        lift(vec2color, pop!.(Ref(plot), (:color, :color_map, :color_norm))...)
    else
        delete!(plot, :color_norm)
        delete!(plot, :color_map)
        return pop!(plot, :color)
    end
end

function draw_atomic(screen::GLScreen, scene::Scene, x::Image)
    robj = cached_robj!(screen, scene, x) do gl_attributes
        gl_attributes[:ranges] = lift(to_range, x[1], x[2])
        img = get_image(gl_attributes)
        # remove_automatic!(gl_attributes)
        visualize(img, Style(:default), gl_attributes).children[]
    end
end

convert_mesh_color(c::AbstractArray{<: Number}, cmap, crange) = vec2color(c, cmap, crange)
convert_mesh_color(c, cmap, crange) = c

function draw_atomic(screen::GLScreen, scene::Scene, x::Mesh)
    robj = cached_robj!(screen, scene, x) do gl_attributes
        # signals not supported for shading yet
        gl_attributes[:shading] = to_value(pop!(gl_attributes, :shading))
        color = pop!(gl_attributes, :color)
        cmap = get(gl_attributes, :color_map, Node(nothing)); delete!(gl_attributes, :color_map)
        crange = get(gl_attributes, :color_norm, Node(nothing)); delete!(gl_attributes, :color_norm)
        mesh = lift(x[1], color, cmap, crange) do m, c, cmap, crange
            c = convert_mesh_color(c, cmap, crange)
            if isa(m, GLNormalColorMesh) || isa(m, GLNormalAttributeMesh) || isa(m, GLNormalVertexcolorMesh)
                m
            elseif c isa Colorant
                get!(gl_attributes, :color, Node(c))[] = c
                if !(isa(m, GLPlainMesh) || isa(m, GLNormalMesh))
                    GLNormalMesh(m)
                else
                    m
                end
            elseif c isa AbstractMatrix{<: Colorant}
                get!(gl_attributes, :color, Node(c))[] = c
                m
            elseif c isa AbstractVector{<: Colorant}
                if length(c) != length(vertices(m))
                    error("Please use the same amount of colors as vertices. Found: $(length(vertices(m))) vertices, and $(length(c)) colors")
                end
                HomogenousMesh(GLNormalMesh(m), Dict{Symbol, Any}(:color => c))
            else
                error("Unsupported color type: $(typeof(c))")
            end
        end
        visualize(mesh, Style(:default), gl_attributes).children[]
    end
end

function draw_atomic(screen::GLScreen, scene::Scene, x::Surface)
    robj = cached_robj!(screen, scene, x) do gl_attributes
        color = pop!(gl_attributes, :color)
        img = nothing
        # signals not supported for shading yet
        # We automatically insert x[3] into the color channel, so if it's equal we don't need to do anything
        if isa(to_value(color), AbstractMatrix{<: Number}) && to_value(color) !== to_value(x[3])
            crange = pop!(gl_attributes, :color_norm)
            cmap = pop!(gl_attributes, :color_map)
            img = lift(color, cmap, crange) do img, cmap, norm
                AbstractPlotting.interpolated_getindex.((cmap,), img, (norm,))
            end
        elseif isa(to_value(color), AbstractMatrix{<: Colorant})
            img = color
            gl_attributes[:color_map] = nothing
            gl_attributes[:color] = nothing
            gl_attributes[:color_norm] = nothing
        end
        gl_attributes[:color] = img
        args = x[1:3]
        gl_attributes[:shading] = to_value(get(gl_attributes, :shading, true))
        if all(v-> to_value(v) isa AbstractMatrix, args)
            visualize(args, Style(:surface), gl_attributes).children[]
        else
            gl_attributes[:ranges] = to_range.(to_value.(args[1:2]))
            visualize(args[3], Style(:surface), gl_attributes).children[]
        end
    end
end

function to_width(x)
    mini, maxi = extrema(x)
    maxi - mini
end

function makieshader(paths...)
    view = Dict{String, String}()
    if !Sys.isapple()
        view["GLSL_EXTENSIONS"] = "#extension GL_ARB_conservative_depth: enable"
        view["SUPPORTED_EXTENSIONS"] = "#define DETPH_LAYOUT"
    end
    LazyShader(
        paths...,
        view = view,
        fragdatalocation = [(0, "fragment_color"), (1, "fragment_groupid")]
    )
end

function volume_prerender()
    glEnable(GL_DEPTH_TEST)
    glDepthMask(GL_TRUE)
    glDepthFunc(GL_LEQUAL)
    enabletransparency()
    glEnable(GL_CULL_FACE)
    glCullFace(GL_FRONT)
end

function surface_contours(volume::Volume)
    frag = joinpath(@__DIR__, "surface_contours.frag")
    paths = assetpath.("shader", ("fragment_output.frag", "util.vert", "volume.vert"))
    shader = makieshader(paths..., frag)
    model = volume[:model]
    x, y, z, vol = volume[1], volume[2], volume[3], volume[4]
    model2 = lift(x, y, z) do xyz...
        mi = minimum.(xyz)
        maxi = maximum.(xyz)
        w = maxi .- mi
        return Mat4f0(
            w[1], 0, 0, 0,
            0, w[2], 0, 0,
            0, 0, w[3], 0,
            mi[1], mi[2], mi[3], 1
        )
    end

    modelinv = lift((a,b)-> inv(b) * inv(a), model, model2)
    model2 = lift(*, model, model2)
    hull = AABB{Float32}(Vec3f0(0), Vec3f0(1))
    gl_data = Dict(
        :hull => GLUVWMesh(hull),
        :volumedata => Texture(lift(x-> convert(Array{Float32}, x), vol)),
        :model => model2,
        :modelinv => modelinv,
        :colormap => Texture(lift(to_colormap, volume[:colormap])),
        :colorrange => lift(Vec2f0, volume[:colorrange]),
        :fxaa => true
    )
    bb = lift(m-> m * hull, model)
    vp = GLVisualize.VolumePrerender(
        lift(identity, volume[:transparency]),
        lift(identity, volume[:overdraw])
    )
    robj = RenderObject(gl_data, shader, vp, bb)
    robj.postrenderfunction = GLAbstraction.StandardPostrender(robj.vertexarray, GL_TRIANGLES)
    robj
end

function draw_atomic(screen::GLScreen, scene::Scene, vol::Volume)
    robj = cached_robj!(screen, scene, vol) do gl_attributes
        if gl_attributes[:algorithm][] == 7
            surface_contours(vol)
        else
            model = vol[:model]
            x, y, z = vol[1], vol[2], vol[3]
            gl_attributes[:model] = lift(model, x, y, z) do m, xyz...
                mi = minimum.(xyz)
                maxi = maximum.(xyz)
                w = maxi .- mi
                m2 = Mat4f0(
                    w[1], 0, 0, 0,
                    0, w[2], 0, 0,
                    0, 0, w[3], 0,
                    mi[1], mi[2], mi[3], 1
                )
                convert(Mat4f0, m) * m2
            end
            visualize(vol[4], Style(:default), gl_attributes).children[]
        end
    end
end


text:
@recipe function f(es::EllipticalSurface; n_arc = 40, n_vert_lines = 2)
    seriestype --> :mesh3d
    @series begin
        label --> "Elliptical Surface"
        mesh(es, n_arc = n_arc, n_vert_lines = n_vert_lines)
    end
    if haskey(plotattributes, :show_normal) && plotattributes[:show_normal]
        @series begin
            label := nothing
            seriestype := :vector
            _plt_get_start_point_for_normal(es), normalize(Plane(es).normal) * sqrt(_plt_area(es)) / 20
        end
    end
end

_plt_area(es::CircularArea{T}) where {T} = π*es.r^2
_plt_area(es::PartialCircularArea{T}) where {T} = π*es.r^2 / ((es.φ[2]-es.φ[1])/2π)
_plt_area(es::Annulus{T}) where {T} = π*(es.r[2]^2 - es.r[1]^2)
_plt_area(es::PartialAnnulus{T}) where {T} = π*(es.r[2]^2 - es.r[1]^2) / ((es.φ[2]-es.φ[1])/2π)

_plt_get_start_point_for_normal(es::CircularArea{T}) where {T} = es.origin
function _plt_get_start_point_for_normal(es::PartialCircularArea{T}) where {T}
    cyl = CylindricalPoint{T}(es.r/2, (es.φ[2]+es.φ[1])/2, zero(T))
    _transform_into_global_coordinate_system(CartesianPoint(cyl), es)
end
function _plt_get_start_point_for_normal(es::Annulus{T}) where {T}
    cyl = CylindricalPoint{T}((es.r[2]+es.r[1])/2, zero(T), zero(T))
    _transform_into_global_coordinate_system(CartesianPoint(cyl), es)
end
function _plt_get_start_point_for_normal(es::PartialAnnulus{T}) where {T}
    cyl = CylindricalPoint{T}((es.r[2]+es.r[1])/2, (es.φ[2]+es.φ[1])/2, zero(T))
    _transform_into_global_coordinate_system(CartesianPoint(cyl), es)
end

ext: jl


text:
using Distributed
addprocs(4)

@everywhere using MendelIHT
@everywhere using SnpArrays
@everywhere using DataFrames
@everywhere using Distributions
@everywhere using Random
@everywhere using LinearAlgebra
@everywhere using GLM
@everywhere using Test

# write your own tests here
include("MendelIHT_utilities_test.jl")
include("L0_reg_test.jl")
include("cv_iht_test.jl")


text:
using SafeTestsets

@safetestset "Binning" begin include("binning/generic.jl") end
@safetestset "Uniform binning" begin include("binning/uniform.jl") end
@safetestset "Median variance binning" begin include("binning/medianvariance.jl") end
@safetestset "ECE" begin include("ece.jl") end
@safetestset "Scalar-valued kernels" begin include("kernels/scalar.jl") end
@safetestset "Matrix-valued kernels" begin include("kernels/matrix.jl") end
@safetestset "Biased SKCE" begin include("skce/biased.jl") end
@safetestset "Unbiased SKCE" begin include("skce/unbiased.jl") end


text: include("TestApp.jl")

max_stars_repo_name: tetsugps/julia

max_issues_repo_name: tetsugps/julia

max_forks_repo_name: tetsugps/julia


text:
import Pkg

const POLYHEDRA_TEST = joinpath(dirname(dirname(pathof(Polyhedra))), "test")

include(joinpath(POLYHEDRA_TEST, "utils.jl"))
include(joinpath(POLYHEDRA_TEST, "config.jl"))
include(joinpath(POLYHEDRA_TEST, "solvers.jl")) # defines lp_solver
include(joinpath(POLYHEDRA_TEST, "jump.jl"))

include(joinpath(POLYHEDRA_TEST, "basic.jl"))
include(joinpath(POLYHEDRA_TEST, "simplex.jl"))
include(joinpath(POLYHEDRA_TEST, "permutahedron.jl"))
include(joinpath(POLYHEDRA_TEST, "board.jl"))
include(joinpath(POLYHEDRA_TEST, "docexample.jl"))
include(joinpath(POLYHEDRA_TEST, "issue48.jl"))
include(joinpath(POLYHEDRA_TEST, "empty.jl"))
include(joinpath(POLYHEDRA_TEST, "sparse.jl"))
include(joinpath(POLYHEDRA_TEST, "sparserect.jl"))
include(joinpath(POLYHEDRA_TEST, "support_function.jl"))
const misctests = Dict("basic" => basictest,
                       "doc" => doctest,
                       "simplex" => simplextest,
                       "permutahedron" => permutahedrontest,
                       "board" => boardtest,
                       "issue48" => issue48test,
                       "empty" => emptytest,
                       "sparse" => sparsetest,
                       "sparserect" => sparserecttest,
                       "support_function" => support_function_test)

@polytestset misc

include(joinpath(POLYHEDRA_TEST, "decompose.jl"))

polyhedratests = Dict("jump" => jumptest,
                      "misc" => misctest,
                      "decompose" => decomposetest)

@polytestset polyhedra true

@testset "Polyhedra tests in $arith arithmetics" for arith in [:float, :exact]
    polyhedratest(ConvexHull.Library(arith, lp_solver), [
        "jumpsimplex", "nonfulldimensional", "simplex", "permutahedron",
        "board", "issue48", "empty"
    ])
end


text:
using Distributions: Uniform, sample
using LinearAlgebra
using LyceumDevTools.TestUtil
using Random
using Shapes
using SpecialArrays
using StructArrays
using Test

using LyceumBase


text:
function readPassports(lines)
    passports = Set{AbstractString}[]
    item = Set{AbstractString}()
    for line in lines
        if isempty(line)
            push!(passports, item)
            item = Set{AbstractString}()
        else
            keys = Set(map(x -> split(x, ":")[1], split(line)))
            union!(item, keys)
        end
    end
    push!(passports, item)
    passports
end

function count_valid_passports(passports)
    required_fields = Set(["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"])
    cnt = 0
    for passport in passports
        if required_fields ⊆ passport
            cnt += 1
        end
    end
    cnt
end

function main()
    lines = readlines("../resources/input_04.txt")
    passports = readPassports(lines)
    result = count_valid_passports(passports)
    println(result)
end

main()


text:
immutable SymTriangularDist <: ContinuousUnivariateDistribution
    μ::Float64
    s::Float64

    function SymTriangularDist(μ::Real, s::Real)
        s > zero(s) || error("SymTriangular: scale must be positive")
        @compat new(Float64(μ), Float64(s))
    end

    @compat SymTriangularDist(μ::Real) = new(Float64(μ), 1.0)
    SymTriangularDist() = new(0.0, 1.0)
end

@distr_support SymTriangularDist d.μ - d.s d.μ + d.s

#### Parameters

location(d::SymTriangularDist) = d.μ
scale(d::SymTriangularDist) = d.s

params(d::SymTriangularDist) = (d.μ, d.s)

#### Statistics

mean(d::SymTriangularDist) = d.μ
median(d::SymTriangularDist) = d.μ
mode(d::SymTriangularDist) = d.μ

var(d::SymTriangularDist) = d.s^2 / 6.0
skewness(d::SymTriangularDist) = 0.0
kurtosis(d::SymTriangularDist) = -0.6

entropy(d::SymTriangularDist) = 0.5 + log(d.s)

#### Evaluation

zval(d::SymTriangularDist, x::Float64) = (x - d.μ) / d.s
xval(d::SymTriangularDist, z::Float64) = d.μ + z * d.s

pdf(d::SymTriangularDist, x::Float64) = insupport(d, x) ? (1.0 - abs(zval(d, x))) / scale(d) : 0.0

logpdf(d::SymTriangularDist, x::Float64) = insupport(d, x) ? log((1.0 - abs(zval(d, x))) / scale(d)) : -Inf

function cdf(d::SymTriangularDist, x::Float64)
    (μ, s) = params(d)
    x <= μ - s ? 0.0 :
    x <= μ ? 0.5 * (1.0 + zval(d, x))^2 :
    x < μ + s ? 1.0 - 0.5 * (1.0 - zval(d, x))^2 : 1.0
end

function ccdf(d::SymTriangularDist, x::Float64)
    (μ, s) = params(d)
    x <= μ - s ? 1.0 :
    x <= μ ? 1.0 - 0.5 * (1.0 + zval(d, x))^2 :
    x < μ + s ? 0.5 * (1.0 - zval(d, x))^2 : 0.0
end

function logcdf(d::SymTriangularDist, x::Float64)
    (μ, s) = params(d)
    x <= μ - s ? -Inf :
    x <= μ ? loghalf + 2.0 * log1p(zval(d, x)) :
    x < μ + s ? log1p(-0.5 * (1.0 - zval(d, x))^2) : 0.0
end

function logccdf(d::SymTriangularDist, x::Float64)
    (μ, s) = params(d)
    x <= μ - s ? 0.0 :
    x <= μ ? log1p(-0.5 * (1.0 + zval(d, x))^2) :
    x < μ + s ? loghalf + 2.0 * log1p(-zval(d, x)) : -Inf
end

quantile(d::SymTriangularDist, p::Float64) = p < 0.5 ? xval(d, sqrt(2.0 * p) - 1.0) :
                                                       xval(d, 1.0 - sqrt(2.0 * (1.0 - p)))

cquantile(d::SymTriangularDist, p::Float64) = p > 0.5 ? xval(d, sqrt(2.0 * (1.0-p)) - 1.0) :
                                                        xval(d, 1.0 - sqrt(2.0 * p))

invlogcdf(d::SymTriangularDist, lp::Float64) = lp < loghalf ? xval(d, expm1(0.5*(lp - loghalf))) :
                                                              xval(d, 1.0 - sqrt(-2.0 * expm1(lp)))

invlogccdf(d::SymTriangularDist, lp::Float64) = lp > loghalf ? xval(d, sqrt(-2.0 * expm1(lp)) - 1.0) :
                                                               xval(d, -(expm1(0.5 * (lp - loghalf))))

function mgf(d::SymTriangularDist, t::Real)
    (μ, s) = params(d)
    a = s * t
    a == zero(a) && return one(a)
    4.0 * exp(μ * t) * (sinh(0.5 * a) / a)^2
end

function cf(d::SymTriangularDist, t::Real)
    (μ, s) = params(d)
    a = s * t
    a == zero(a) && return complex(one(a))
    4.0 * cis(μ * t) * (sin(0.5 * a) / a)^2
end

#### Sampling

rand(d::SymTriangularDist) = xval(d, rand() - rand())


text:
# structs
export mjContact, mjWarningStat, mjTimerStat, mjSolverStat, mjData, mjLROpt, mjVFS, mjOption, mjVisual, mjStatistic, mjModel, mjrRect, mjrContext, mjuiState, mjuiThemeSpacing, mjuiThemeColor, mjuiItem, mjuiSection, mjUI, mjuiDef, mjvPerturb, mjvCamera, mjvGLCamera, mjvGeom, mjvLight, mjvOption, mjvScene, mjvFigure
#names,
#_global,
#quality,
#headlight,
#map,
#scale,
#rgba,

export mj_activate, mj_deactivate, mj_certQuestion, mj_certAnswer, mj_certCheck, mj_defaultVFS, mj_addFileVFS, mj_makeEmptyFileVFS, mj_findFileVFS, mj_deleteFileVFS, mj_deleteVFS, mj_loadXML, mj_saveLastXML, mj_freeLastXML, mj_printSchema, mj_step, mj_step1, mj_step2, mj_forward, mj_inverse, mj_forwardSkip, mj_inverseSkip, mj_defaultLROpt, mj_defaultSolRefImp, mj_defaultOption, mj_defaultVisual, mj_copyModel, mj_saveModel, mj_loadModel, mj_deleteModel, mj_sizeModel, mj_makeData, mj_copyData, mj_resetData, mj_resetDataDebug, mj_resetDataKeyframe, mj_stackAlloc, mj_deleteData, mj_resetCallbacks, mj_setConst, mj_setLengthRange, mj_printModel, mj_printData, mj_fwdPosition, mj_fwdVelocity, mj_fwdActuation, mj_fwdAcceleration, mj_fwdConstraint, mj_Euler, mj_RungeKutta, mj_invPosition, mj_invVelocity, mj_invConstraint, mj_compareFwdInv, mj_sensorPos, mj_sensorVel, mj_sensorAcc, mj_energyPos, mj_energyVel, mj_checkPos, mj_checkVel, mj_checkAcc, mj_kinematics, mj_comPos, mj_camlight, mj_tendon, mj_transmission, mj_crb, mj_factorM, mj_solveM, mj_solveM2, mj_comVel, mj_passive, mj_subtreeVel, mj_rne, mj_rnePostConstraint, mj_collision, mj_makeConstraint, mj_projectConstraint, mj_referenceConstraint, mj_constraintUpdate, mj_addContact, mj_isPyramidal, mj_isSparse, mj_isDual, mj_mulJacVec, mj_mulJacTVec, mj_jac, mj_jacBody, mj_jacBodyCom, mj_jacGeom, mj_jacSite, mj_jacPointAxis, mj_name2id, mj_id2name, mj_fullM, mj_mulM, mj_mulM2, mj_addM, mj_applyFT, mj_objectVelocity, mj_objectAcceleration, mj_contactForce, mj_differentiatePos, mj_integratePos, mj_normalizeQuat, mj_local2Global, mj_getTotalmass, mj_setTotalmass, mj_version, mj_ray, mj_rayHfield, mj_rayMesh, mjv_defaultCamera, mjv_defaultPerturb, mjv_room2model, mjv_model2room, mjv_cameraInModel, mjv_cameraInRoom, mjv_frustumHeight, mjv_alignToCamera, mjv_moveCamera, mjv_movePerturb, mjv_moveModel, mjv_initPerturb, mjv_applyPerturbPose, mjv_applyPerturbForce, mjv_averageCamera, mjv_select, mjv_defaultOption, mjv_defaultFigure, mjv_initGeom, mjv_makeConnector, mjv_defaultScene, mjv_makeScene, mjv_freeScene, mjv_updateScene, mjv_addGeoms, mjv_makeLights, mjv_updateCamera, mjv_updateSkin, mjr_defaultContext, mjr_makeContext, mjr_changeFont, mjr_addAux, mjr_freeContext, mjr_uploadTexture, mjr_uploadMesh, mjr_uploadHField, mjr_restoreBuffer, mjr_setBuffer, mjr_readPixels, mjr_drawPixels, mjr_blitBuffer, mjr_setAux, mjr_blitAux, mjr_text, mjr_overlay, mjr_maxViewport, mjr_rectangle, mjr_figure, mjr_render, mjr_finish, mjr_getError, mjr_findRect, mju_printMat, mju_printMatSparse, mju_rayGeom, mju_raySkin, mju_error, mju_error_i, mju_error_s, mju_warning, mju_warning_i, mju_warning_s, mju_clearHandlers, mju_malloc, mju_free, mj_warning, mju_writeLog, mju_zero3, mju_copy3, mju_scl3, mju_add3, mju_sub3, mju_addTo3, mju_subFrom3, mju_addToScl3, mju_addScl3, mju_normalize3, mju_norm3, mju_dot3, mju_dist3, mju_rotVecMat, mju_rotVecMatT, mju_cross, mju_zero4, mju_unit4, mju_copy4, mju_normalize4, mju_zero, mju_copy, mju_sum, mju_L1, mju_scl, mju_add, mju_sub, mju_addTo, mju_subFrom, mju_addToScl, mju_addScl, mju_normalize, mju_norm, mju_dot, mju_mulMatVec, mju_mulMatTVec, mju_transpose, mju_mulMatMat, mju_mulMatMatT, mju_mulMatTMat, mju_sqrMatTD, mju_transformSpatial, mju_dotSparse, mju_dotSparse2, mju_dense2sparse, mju_sparse2dense, mju_mulMatVecSparse, mju_compressSparse, mju_combineSparse, mju_sqrMatTDSparse, mju_transposeSparse, mju_rotVecQuat, mju_negQuat, mju_mulQuat, mju_mulQuatAxis, mju_axisAngle2Quat, mju_quat2Vel, mju_subQuat, mju_quat2Mat, mju_mat2Quat, mju_derivQuat, mju_quatIntegrate, mju_quatZ2Vec, mju_mulPose, mju_negPose, mju_trnVecPose, mju_cholFactor, mju_cholBacksub, mju_cholSolve, mju_cholUpdate, mju_cholFactorSparse, mju_cholSolveSparse, mju_cholUpdateSparse, mju_eig3, mju_muscleFVL, mju_musclePassive, mju_pneumatic, mju_muscleGain, mju_muscleBias, mju_muscleDynamics, mju_encodePyramid, mju_decodePyramid, mju_springDamper, mju_min, mju_max, mju_sign, mju_round, mju_type2Str, mju_str2Type, mju_warningText, mju_isBad, mju_isZero, mju_standardNormal, mju_f2n, mju_n2f, mju_d2n, mju_n2d, mju_insertionSort, mju_Halton, mju_strncpy, mjui_themeSpacing, mjui_themeColor, mjui_add, mjui_resize, mjui_update, mjui_event, mjui_render


text:
module CGPrism3D
using LinearAlgebra
#using StatsBase

# Define chop function
export numchop
numchop(num::Real)=(abs(num) >= 1000*eps() ? num : zero(Real))

function numchop(num::Complex)
    numchop(imag(num)) == 0 ? numchop(real(num)) : Complex(numchop(real(num)), numchop(imag(num)))
end

# Define k-level of SU(2)_k
const K = 3 # K-level
const x = K+1 #number of spins
const y = K/2 # maximum spin

#Define all functions needed for G-symbol
# Define delta{ijk} -> coupling rules
function delta(i::Float64,j::Float64,k::Float64)
    sol = 0
    if i <=(j+k) && j<=(i+k) && k<=(i+j) && i+j+k <= K && 2*(i+j+k)%2 ==0
        sol = 1
    end
    return sol
end

#Define quantum numbers qn (this is real)
function qn(n::Float64)
    sol = (exp(pi*n*im/(K+2)) - exp(-pi*n*im/(K+2))) / (exp(pi*im/(K+2)) - exp(-pi*im/(K+2)))
    return real(sol)
end

#Define qn factorial
function qnfact(n::Float64)
    sol = 1
    for i in 1:n
        sol *= qn(i)
    end
    return sol
end

#Define square root of quantum dimension
function visqrt(i::Float64)
    sol = ((-1+0im)^i )*sqrt(qn(2*i+1))
    return sol
end

#Define triangle equality
function trian(i::Float64,j::Float64,k::Float64)
    sol = 0
    if delta(i,j,k) == 1
        sol = delta(i,j,k)*sqrt(qnfact(i+j-k)*qnfact(i-j+k)*qnfact(-i+j+k)/qnfact(i+j+k+1))
    end
    return sol
end

# Define Racah-Wigner six-j symbol
function RacWig6j(i::Float64,j::Float64,m::Float64,k::Float64,l::Float64,n::Float64)
    a = i+j+m; b = i+l+n; c = k+j+n; d = k+l+m;  e = i+j+k+l; f = i+k+m+n; g = j+l+m+n
    sol = 0
    if delta(i,j,m) != 0 && delta(i,l,n) != 0 && delta(k,j,n) != 0 && delta(k,l,m) != 0
        sumz = 0
        for z in max(a,b,c,d):min(e,f,g)
            sumz += (-1)^z *qnfact(z+1)/
                ((qnfact(e-z)*qnfact(f-z)*qnfact(g-z))* (qnfact(z-a)*qnfact(z-b)*qnfact(z-c)*qnfact(z-d)))
        end
        sol = trian(i,j,m)*trian(i,l,n)*trian(k,j,n)*trian(k,l,m)*sumz
    end
    return sol
end

#Define F-symbol
function Fsymb(i::Float64,j::Float64,m::Float64,k::Float64,l::Float64,n::Float64)
    sol = 0
    if delta(i,j,m) != 0 && delta(i,l,n) != 0 && delta(k,j,n) != 0 && delta(k,l,m) != 0
        sol = (-1+0im)^(i+j+k+l)*sqrt(qn(2*m+1)*qn(2*n+1)) * RacWig6j(i,j,m,k,l,n)
    end
    return sol
end

#Define G-symbol
function Gsymb(i::Float64,j::Float64,m::Float64,k::Float64,l::Float64,n::Float64)
    sol = 0
    if delta(i,j,m) != 0 && delta(i,l,n) != 0 && delta(k,j,n) != 0 && delta(k,l,m) != 0
        sol = Fsymb(i,j,m,k,l,n) /(visqrt(m)*visqrt(n))
    end
    return sol
end

export Tetra6j, delta, visqrt
#Define G-symbol times dimensions
function Tetra6j(i::Float64,j::Float64,m::Float64,k::Float64,l::Float64,n::Float64)
    sol = 0
    if delta(i,j,m) != 0 && delta(i,l,n) != 0 && delta(k,j,n) != 0 && delta(k,l,m) != 0
        dims = prod(visqrt.([i,j,m,k,l,n]))
        sol =  numchop(dims*Gsymb(i,j,m,k,l,n))
    end
    return sol
end

#Define G-symbol 2
function Gsymb2(i::Float64,j::Float64,m::Float64,k::Float64,l::Float64,n::Float64)
    sol = 0
    if delta(i,j,m) != 0 && delta(i,l,n) != 0 && delta(k,j,n) != 0 && delta(k,l,m) != 0
        sol = (-1+0im)^(i+j+k+l+m+n)*RacWig6j(i,j,m,k,l,n)
    end
    return sol
end

## Define Prisms
#Prism A as gluing together three tetrahedra ;  Prism B changing diagonals using F-symbol
function prismA(jd1::Float64,jd2::Float64,je1::Float64,jb1::Float64,jg::Float64,ja1::Float64,jc::Float64,
                jb2::Float64,jf1::Float64,ja2::Float64,jf2::Float64,je2::Float64)
    sol = 0
    if delta(jd1,jd2,je1) != 0 && delta(jd1,jb1,jg) != 0 && delta(ja1,jd2,jg) != 0 && delta(ja1,jb1,je1) != 0 && delta(jd1,jc,jb2) != 0 && delta(jf1,jd2,jb2) != 0 && delta(jf1,jc,je1) != 0 && delta(jd1,ja2,jf2) != 0 && delta(jc,je2,jf2) != 0 && delta(jb2,je2,ja2) != 0
        dims = visqrt(ja1)*visqrt(jb1)*visqrt(jg)*visqrt(jf1)*visqrt(jc)*visqrt(jb2)*visqrt(je2)*visqrt(ja2)*visqrt(jf2)*visqrt(jd1)*visqrt(jd2)*visqrt(je1)
        sol =  dims*Gsymb(jd1,jd2,je1,ja1,jb1,jg) * Gsymb(jd1,jd2,je1,jf1,jc,jb2) * Gsymb(jd1,jc,jb2,je2,ja2,jf2)
    end
    return sol
end

function prismB(jd2p::Float64,jd1p::Float64,je2::Float64,jb2::Float64,jg::Float64,ja2::Float64,jc::Float64,
                jb1::Float64,jf2::Float64,ja1::Float64,jf1::Float64,je1::Float64)
    sol = 0
    if delta(jd1p,jd2p,je2) != 0 && delta(jd2p,jb2,jg) != 0 && delta(ja2,jd1p,jg) != 0 && delta(ja2,jb2,je2) != 0 && delta(jd2p,jc,jb1) != 0 && delta(jf2,jd1p,jb1) != 0 && delta(jf2,jc,je2) != 0 && delta(jd2p,ja1,jf1) != 0 && delta(jc,je1,jf1) != 0 && delta(jb1,je1,ja1) != 0
        for jd1 in 0.:0.5:y
            if delta(jb1,jg,jd1) != 0 && delta(ja2,jf2,jd1) != 0
                for jd2 in 0.:0.5:y
                    if delta(ja1,jg,jd2) != 0 && delta(jb2,jf1,jd2) != 0
                        sol += numchop(Fsymb(ja1,jg,jd2,jb2,jf1,jd2p)*Fsymb(jb1,jg,jd1,ja2,jf2,jd1p)*prismA(jd1,jd2,je1,jb1,jg,ja1,jc,jb2,jf1,ja2,jf2,je2))
                    end
                end
            end
        end
    end
    return sol
end

# This is the relabelling vertices. Does it work in general after one step in algorithm?
function prismB2(jd2::Float64,jd1::Float64,je2::Float64,jb2::Float64,jg::Float64,ja2::Float64,jc::Float64,
                jb1::Float64,jf2::Float64,ja1::Float64,jf1::Float64,je1::Float64)
    return prismA(jd1,jd2,je1,jb1,jg,ja1,jc,jb2,jf1,ja2,jf2,je2)
end

export dataPrsmA, dataPrsmB, dataPrsmB2, dataTet, dataTetF

# get all non-zero amplitudes and spins
function dataPrsmA()
    ampsInfo = Array{Float64,1}[]
    amps = Float64[]
    for jd1 in 0.:0.5:y, jd2 in 0.:0.5:y, je1 in 0.:0.5:y
        if delta(jd1,jd2,je1) != 0
            for jb1 in 0.:0.5:y, jg in 0.:0.5:y
                if delta(jd1,jb1,jg) != 0
                    for ja1 in 0.:0.5:y
                        if delta(ja1,jd2,jg) != 0 && delta(ja1,jb1,je1) != 0
                            for jc in 0.:0.5:y, jb2 in 0.:0.5:y
                                if delta(jd1,jc,jb2) != 0
                                    for jf1 in 0.:0.5:y
                                        if delta(jf1,jd2,jb2) != 0 && delta(jf1,jc,je1) != 0
                                            for ja2 in 0.:0.5:y, jf2 in 0.:0.5:y
                                                if delta(jd1,ja2,jf2) != 0
                                                    for je2 in 0.:0.5:y
                                                        if delta(jc,je2,jf2) != 0 && delta(jb2,je2,ja2) != 0 #
                                                            sol = numchop(prismA(jd1,jd2,je1,jb1,jg,ja1,jc,jb2,jf1,ja2,jf2,je2))
                                                            if sol != 0
                                                                indx = [jb1,jg,ja1,jd1,jd2,je1,jc,jb2,jf1,ja2,jf2,je2]
                                                                push!(ampsInfo,indx)
                                                                push!(amps,sol)
                                                            end
                                                        end
                                                    end
                                                end
                                            end
                                        end
                                    end
                                end
                            end
                        end
                    end
                end
            end
        end
    end
    return ampsInfo, amps
end

function dataPrsmB()
    ampsInfo = Array{Float64,1}[]
    amps = Float64[]
    for jd2 in 0.:0.5:y, jd1 in 0.:0.5:y, je2 in 0.:0.5:y
        if delta(jd1,jd2,je2) != 0
            for jb2 in 0.:0.5:y, jg in 0.:0.5:y
                if delta(jd2,jb2,jg) != 0
                    for ja2 in 0.:0.5:y
                        if delta(ja2,jd1,jg) != 0 && delta(ja2,jb2,je2) != 0
                            for jc in 0.:0.5:y, jb1 in 0.:0.5:y
                                if delta(jd2,jc,jb1) != 0
                                    for jf2 in 0.:0.5:y
                                        if delta(jf2,jd1,jb1) != 0 && delta(jf2,jc,je2) != 0
                                            for ja1 in 0.:0.5:y, jf1 in 0.:0.5:y
                                                if delta(jd2,ja1,jf1) != 0
                                                    for je1 in 0.:0.5:y
                                                        if delta(jc,je1,jf1) != 0 && delta(jb1,je1,ja1) != 0 #
                                                            sol = numchop(prismB(jd2,jd1,je2,jb2,jg,ja2,jc,jb1,jf2,ja1,jf1,je1))
                                                            if sol != 0
                                                                indx = [jb2,jg,ja2,jd2,jd1,je2,jc,jb1,jf2,ja1,jf1,je1]
                                                                push!(ampsInfo,indx)
                                                                push!(amps,sol)
                                                            end
                                                        end
                                                    end
                                                end
                                            end
                                        end
                                    end
                                end
                            end
                        end
                    end
                end
            end
        end
    end
    return ampsInfo, amps
end

function dataPrsmB2()
    ampsInfo = Array{Float64,1}[]
    amps = Float64[]
    for jd2 in 0.:0.5:y, jd1 in 0.:0.5:y, je2 in 0.:0.5:y
        if delta(jd2,jd1,je2) != 0
            for jb2 in 0.:0.5:y, jg in 0.:0.5:y
                if delta(jd2,jb2,jg) != 0
                    for ja2 in 0.:0.5:y
                        if delta(ja2,jd1,jg) != 0 && delta(ja2,jb2,je2) != 0
                            for jc in 0.:0.5:y, jb1 in 0.:0.5:y
                                if delta(jd2,jc,jb1) != 0
                                    for jf2 in 0.:0.5:y
                                        if delta(jf2,jd1,jb1) != 0 && delta(jf2,jc,je2) != 0
                                            for ja1 in 0.:0.5:y, jf1 in 0.:0.5:y
                                                if delta(jd2,ja1,jf1) != 0
                                                    for je1 in 0.:0.5:y
                                                        if delta(jc,je1,jf1) != 0 && delta(jb1,je1,ja1) != 0 #
                                                            sol = numchop(prismB2(jd2,jd1,je2,jb2,jg,ja2,jc,jb1,jf2,ja1,jf1,je1))
                                                            if sol != 0
                                                                indx = [jb2,jg,ja2,jd2,jd1,je2,jc,jb1,jf2,ja1,jf1,je1]
                                                                push!(ampsInfo,indx)
                                                                push!(amps,sol)
                                                            end
                                                        end
                                                    end
                                                end
                                            end
                                        end
                                    end
                                end
                            end
                        end
                    end
                end
            end
        end
    end
    Indxspins = sort(ampsInfo)
    ampvals = amps[sortperm(ampsInfo)]
    return Indxspins, ampvals
end

function dataTet()
    t6j = []
    t6s = []
    for ja in 0.:0.5:y, jb in 0.:0.5:y, jc in 0.:0.5:y
        if delta(ja,jb,jc) != 0
            for jd in 0.:0.5:y, je in 0.:0.5:y
                if delta(jc,jd,je) != 0
                    for jf in 0.:0.5:y
                        if delta(ja,je,jf) != 0 && delta(jb,jd,jf) != 0
            #dims = prod(visqrt.([ja,jb,jc,jd,je,jf]))
                            sol = numchop(Tetra6j(ja,jb,jc,jd,je,jf) )
                            if sol != 0
                                push!(t6s,sol)
                                push!(t6j,[ja,jb,jc,jd,je,jf])
                            end
                        end
                    end
                end
            end
        end
    end
    return t6j,t6s
end

function dataTetF()
    t6j = []
    t6s = []
    for ja in 0.:0.5:y, jb in 0.:0.5:y, jc in 0.:0.5:y
        if delta(ja,jb,jc) != 0
            for jd in 0.:0.5:y, je in 0.:0.5:y
                if delta(jc,jd,je) != 0
                    for jf in 0.:0.5:y
                        if delta(ja,je,jf) != 0 && delta(jb,jd,jf) != 0
            #dims = prod(visqrt.([ja,jb,jc,jd,je,jf]))
                            sol = numchop(Fsymb(ja,jb,jc,jd,je,jf) )
                            if sol != 0
                                push!(t6s,sol)
                                push!(t6j,[ja,jb,jc,jd,je,jf])
                            end
                        end
                    end
                end
            end
        end
    end
    return t6j,t6s
end

export tensorSplitSVD, fullSplitPrism3D, tensorGlue, tensorSum, tensorGluePrism3D, tensor22move, tensor31move

# a general function to split a tensor M^C_{AB} to U^C_{Ai} and  V^C_{iB} with C the shared face.. for particular values of C
# first reduce to matrix form and then perform svd to get U, s, and V
#This returns the svd of tensorM,i.e., U^C_{Ai}, s_i, and V^C_{iB}.
function tensorSplitSVD(tensorM,posnA,posnB,posnC,spinC)
    indx = tensorM[1]
    ampvals = tensorM[2]
    fc = findall(x-> x[posnC] == spinC, indx) #find spinsC in all spins length(posnC) = length(spinC)
    ampInfo = indx[fc] # this contains all spin configuration containing ampsC
    amps = ampvals[fc] # this contains the corresponding spin amplitude values for ampsC
    Ucol = unique(getindex.(ampInfo, [posnA]))
    Vrow = unique(getindex.(ampInfo, [posnB]))
    matM = zeros(length(Ucol),length(Vrow))
    if length(matM) != 0
        for i in 1:length(ampInfo)
            qu = findall(x-> x == ampInfo[i][posnA], Ucol)[1]# [1] since it returns an array [1]
            qv = findall(x-> x == ampInfo[i][posnB], Vrow)[1]
            matM[qu,qv] = amps[i]
        end
        U, s, V = svd(matM)
        return U,s,V
    else
        return 0,0,0
    end
end

#A general function to splits fully the tensor M^C_{AB} to tensors U^C_{Ai} and V^C_{iB}.
# It uses tensorSplitSVD,'fixes' the sign problem from svd, and normalize
#This is designed specifically for the prisms we are working with. It keeps only the first singular value (assuming a gemetric split)
# splits prism into tetrahedron and a  pyramid
function fullSplitPrism3D(dataM,posnA,posnB,posnC) # posnA,B,C must be vectors @assert length(dataM) = vcat(A,B,C)
    indx = dataM[1]
    ampvals = dataM[2]
    posAC = vcat(posnA,posnC) # assert posnA,posnC must be both vectors
    posCB = vcat(posnC,posnB) # assert posnB,posnC must be both vectors
    indxU = unique(getindex.(indx, [posAC]))
    indxV = unique(getindex.(indx, [posCB]))
    ampsC = unique(getindex.(indx, [posnC])) # get all unique spins C (jd1,jd2,je1)
    ampsU = [] # this will store all amplitudes for U^C_{A}
    ampsV = [] # this will store all amplitudes for V^C_{B}
    #indxUV = [] # if we want this will store all spins in the right order
    for i in 1:length(ampsC) # loop over the unique spins
        jd1 = ampsC[i][1]; jd2 = ampsC[i][2]; je1 = ampsC[i][3]  #jd1,jd2,je1 in spin C form a triangle
        if delta(jd1,jd2,je1) != 0
            spinC = [jd1,jd2,je1]
            U, s, V = tensorSplitSVD(dataM,posnA,posnB,posnC,spinC)
            #truncate and use only first singular value
            U1 = U[:,1]
            V1 = V[:,1]
            s1 = s[1]
            valU = U1*sqrt(s1)*sqrt(prod(visqrt.(ampsC[i]))) # multiply by leftover dimension factors
            valV = V1*sqrt(s1)*sqrt(prod(visqrt.(ampsC[i])))
            # valU,valV are all either real or purely imaginary
            valU = real(valU) - imag(valU) # take -ve of imaginary part if it gives only imag
            valV = real(valV) + imag(valV)
            ja1 = indxU[1][1]; jb1 = indxU[1][2]; jg = indxU[1][3] # pick the first spins in U
            #Fixing sign problem -- keep the same sign for U and Tetra6j symbol
            if sign(valU[1]) == sign(Tetra6j(jd1,jd2,je1,jb1,jg,ja1) )
                push!(ampsU, valU)#/valU[1])
                push!(ampsV, valV)#/valV[1])
            else
                push!(ampsU, -valU)#/valU[1])
                push!(ampsV, -valV)#/valV[1])
            end
        end
    end
    solU = collect(Iterators.flatten(ampsU))
    solV = collect(Iterators.flatten(ampsV))
    ansU = solU/solU[1] # normalization condition
    ansV = solV/solV[1]
    return (indxU,ansU),(indxV,ansV) #,indxUV
end

#its better if TA the 'smallest' tensor, posnA and posnB should be of the same length
function tensorGlue(tensorB,tensorA,posnB,posnA)# glue two tensors TA,TB along posnA from TA and posnB from TB
    indxA = tensorA[1] # spins of TA
    indxB = tensorB[1] # spins of TB
    ampsA = tensorA[2] # amplitudes of TA
    ampsB = tensorB[2] # amplitudes of TB
    lena = collect(1:length(indxA[1]))
    deleteat!(lena,sort(posnA)) # assert needs posnA to be a vector
    #if length(posnA) > 1 deleteat!(lena,sort(posnA,dims=2) else  deleteat!(lena,sort(posnA)) end
    amps = []
    qq = []
    for i in 1:length(indxA)
        fc = findall(x-> x[posnB] == indxA[i][posnA], indxB) # needs length(posnA) = length(posnB)
        ans = @. ampsA[i]*ampsB[fc]
        push!(amps,ans)
        indxa = repeat([indxA[i][lena]],length(indxB[fc]))
        #for j in indxA[i][lena]
        indxa1 = vcat.(indxB[fc],indxa)
        push!(qq,indxa1)
        #push!(qq,[collect(Iterators.flatten([indxB[fc][j],indxA[i][lena]])) for j in 1:length(indxB[fc])])
    end
    sol = collect(Iterators.flatten(amps))
    indxsol = collect(Iterators.flatten(qq))
    return indxsol, sol
end
export tensorGlueN

function tensorGlueN(tensorB,tensorA,posnB,posnA)# glue two tensors TA,TB along posnA from TA and posnB from TB
    indxA = tensorA[1] # spins of TA
    indxB = tensorB[1] # spins of TB
    ampsA = tensorA[2] # amplitudes of TA
    ampsB = tensorB[2] # amplitudes of TB
    shrdA = getindex.(indxA,[posnA])
    shrdB = getindex.(indxB,[posnB])
    lena = collect(1:length(indxA[1]))
    deleteat!(lena,sort(posnA)) # assert needs posnA to be a vector
    #if length(posnA) > 1 deleteat!(lena,sort(posnA,dims=2) else  deleteat!(lena,sort(posnA)) end
    shrdAB = []
    qq = []
    amps = []
    sa = sortperm(shrdA)
    sb = sortperm(shrdB)
    shrdA = shrdA[sa]
    shrdB = shrdB[sb]
    sindxA = indxA[sa]
    sindxB = indxB[sb]
    sampsA = ampsA[sa]
    sampsB = ampsB[sb]
    shrdAu = unique(shrdA)
    shrdBu = unique(shrdB)
    shrd = shrdAu
    if shrdAu == shrdBu
        shrd = shrdAu
    else
        for i in shrdBu
            shrd = shrdAu
            if !(i in shrdAu)
                push!(shrd,i)
            end
        end
    end
    cshrdA = countmap(shrdA)
    cshrdB = countmap(shrdB)
    for i in shrd
        ca = count(x->x==i,shrdA)
        cb = count(x->x==i,shrdB)
        push!(shrdAB, (i, ca,cb ))
    end
    cnt = 1
    cntb = 1
    for i in shrdAB
        # Put condition for when one of a or b is zero
        for j in 1:i[2]
            ans = @. sampsA[j]*sampsB[1:i[3]]
            push!(amps,ans)
            indxa = repeat([sindxA[j][lena]],i[3])
            #for j in indxA[i][lena]
            indxa1 = vcat.(sindxB[1:i[3]],indxa)
            push!(qq,indxa1)
        end
        deleteat!(sindxA,1:i[2])
        deleteat!(sindxB,1:i[3])
        deleteat!(sampsA,1:i[2])
        deleteat!(sampsB,1:i[3])
        #cntb = cnt
    end
    indxsol = collect(Iterators.flatten(qq))
    sol = collect(Iterators.flatten(amps))
    return indxsol,sol
end

export visqrt, tensorGluePrism3D2, tensorGluePrism3DN

function tensorGluePrism3D(tensorB,tensorA,posnB,posnA)
    indx, amps = tensorGlue(tensorB,tensorA,posnB,posnA)
    face = getindex.(indx, [posnB])
    ans = complex(zeros(length(face)))
    for i in 1:length(face)
        ans[i] = prod(visqrt.(face[i]))
    end
    ampsN = @. amps / ans
    ampsN = real(ampsN)+imag(ampsN)
    return indx, ampsN
end

function tensorGluePrism3DN(tensorB,tensorA,posnB,posnA)
    indx, amps = tensorGlueN(tensorB,tensorA,posnB,posnA)
    face = getindex.(indx, [posnB])
    ans = complex(zeros(length(face)))
    for i in 1:length(face)
        ans[i] = prod(visqrt.(face[i]))
    end
    ampsN = @. amps / ans
    ampsN = real(ampsN)+imag(ampsN)
    return indx, ampsN
end

## This is to try to take care of bulk spins
function tensorGluePrism3D2(tensorB,tensorA,posnB,posnA)
    indx, amps = tensorGlue(tensorB,tensorA,posnB,posnA)
    face = getindex.(indx, [posnB])
    ans = complex(ones(length(face)))
    for i in 2:length(face)
        ans[i] = prod(visqrt.(face[i]))
    end
    ampsN = @. amps / ans
    ampsN = real(ampsN)+imag(ampsN)
    return indx, ampsN
end

function tensorSum(ampJ,posnN)
    indx = ampJ[1]
    amps = ampJ[2]
    lenS = collect(1:length(indx[1]))
    deleteat!(lenS,sort(posnN))
    #if length(posnN) > 1   deleteat!(lenS,sort(posnN,dims=2)) else  deleteat!(lenS,sort(posnN)) end
    indxef = getindex.(indx,[lenS]) # get all spins without N
    indxefu = unique(indxef)
    tt = sortperm(indxef) # sort them spins
    indxef = indxef[tt] # apply sort on spins
    amps = amps[tt]  # apply sort on amps
    #fc = findall(x-> x[lenS]==ans ,indx)
    qq = []
    indq = []
    fc = sortperm(indxef)
    indxN = indxef[fc]
    ampsN = amps[fc]

    for i in 2:length(indxN)
        if indxN[i] == indxN[i-1]
            ampsN[i] += ampsN[i-1]
        elseif numchop(ampsN[i-1]) != 0
            push!(indq,indxN[i-1])
            push!(qq,ampsN[i-1])
        end
    end
    push!(indq,indxN[end])
    push!(qq,ampsN[end])
    return indq, qq
end

function tensor22move(tensor,face)# place middle edge at last position # first 2 position form a triangle
    # assert face contains 5 elements
    indx = tensor[1] # spins of TB
    amps = tensor[2]
    flast = face[end]
    ff1 = collect(1:length(indx[1]))
    deleteat!(ff1,flast)
    indxf1 = getindex.(indx, [ff1])
    indxf1u = unique(indxf1)
    #indxf1uMod = unique(indxf1)
    indxlast = getindex.(indx, [flast])
    for i in 1:4
        if face[i]>flast
            face[i] = face[i]-1
        end
    end
    sol = []
    findx = []
    for i in 1:length(indxf1u)
        iMod = copy(indxf1u[i])
        j1 = iMod[face[1]]; j2 = iMod[face[2]]; j3 = iMod[face[3]]; j4 = iMod[face[4]]; #j5 = ampsN[i][face[5]]
    #    #ans = 0#amps[i]
    #    ind = zeros(length(indx[1]))
        for j in 0.:0.5:y
            #iMod = deepcopy(indxf1u)
            if delta(j1,j3,j) != 0 && delta(j2,j4,j) != 0
                fc = findall(x-> x == iMod,indxf1 )
                ans = 0
                for t in fc
                    ju = indxlast[t]
                    ans += numchop(amps[t] * Fsymb(j1,j3,j,j4,j2,ju)) #* ampls[t]
                end
                if numchop(ans) !=0
                    push!(sol,ans)
                    iMods = copy(indxf1u[i])
                    push!(findx,insert!(iMods,flast,j))
                end
    #            end
            end
        end
    end
    return findx,sol#indx,amps
end

function tensor31move(tensor,tet)
    # assert tet contains 6 elements
    indx = tensor[1] # spins of TB
    amps = tensor[2] # amps
    indxout = getindex.(indx, [tet[4:6]])
    ff1 = collect(1:length(indx[1]))
    deleteat!(ff1,sort(tet[4:6]))
    indxkeep = getindex.(indx, [ff1])
    indxkeepu = unique(getindex.(indx, [ff1]))
    sol = []
    indxn = []
    for i in 1:length(indxkeepu)
        ff = findfirst(x-> x == indxkeepu[i], indxkeep)
        j1 = indx[ff][tet[1]]; j2 = indx[ff][tet[2]]; j3 = indx[ff][tet[3]]
        j4 = indx[ff][tet[4]]; j5 = indx[ff][tet[5]]; j6 = indx[ff][tet[6]]
        dim = visqrt(j4)*visqrt(j5)/visqrt(j3)
        fac = numchop(dim*Fsymb(j1,j2,j3,j4,j5,j6))
        ans = numchop(amps[ff]/fac )
        push!(sol,ans)
        push!(indxn,indxkeepu[i])
        #global cou = 0
        #if sign(fac) == sign(amps[i] )
        #    ans = numchop(amps[i] / fac)
        #    push!(sol,ans)
        #else
        #    ans = numchop(amps[i] / fac)
        #    push!(sol,-ans)
        #    #cou += 1
        #end
    end
    return indxn,sol#indx,sol#,couff1
end

end # module


text:
########################################################################
# Synchronous Vertical Federated Logistic Regression for Adult dataset
########################################################################
using VerFedLogistic
using Printf
using SparseArrays

# load data
filename = "adult"
Xtrain, Ytrain, Xtest, Ytest = load_data(filename)

# config
config = Dict{String, Union{Int64, Float64, String}}()
config["num_classes"] = 2
config["num_clients"] = 3
config["num_epoches"] = 40
config["batch_size"] = 2837
config["learning_rate"] = 0.5
config["local_model"] = "mlp"

# vertically split data
Xtrain_split, Xtest_split = split_data(Xtrain, Xtest, config["num_clients"])

# initialize server
server = Server(Ytrain, Ytest, config)

# initialize clients
clients = Vector{Client}(undef, config["num_clients"])
for id = 1:config["num_clients"]
    c = Client(id, Xtrain_split[id], Xtest_split[id], config)
    clients[id] = c
    # connect with server
    connect(server, c)
end

# training
startT = time()
vertical_lr_train(server, clients)
endT = time()
@printf "training time: %.2f secs \n" endT - startT

# evaluation
evaluation(server, clients)


text:
#!/usr/bin/env julia
using DelimitedFiles, Random
base = ARGS[1]

# Determine groups
id = readdlm("17k.id", String)[:, 1]
allid = Set{String}(id)
ngrp = 60        # n-groups

# Set group size
group = repeat([length(id) ÷ ngrp], ngrp)
for  i in 1:length(id)-group[ngrp]*ngrp
    group[i] += 1
end

shuffle!(id)
beg = 1
for i in 1:ngrp
    global beg
    msk = Set{String}(id[beg:beg+group[i]-1])
    beg = beg + group[i]
    ref = setdiff(allid, msk)
    writedlm("msk.id", msk)
    writedlm("ref.id", ref)
    run(pipeline(`zcat imp.vcf.gz`,
                 `$base/bin/vcf-by-id ref.id`,
                 `gzip -c >ref.vcf.gz`))
    run(pipeline(`zcat imp.vcf.gz`,
                 `$base/bin/vcf-by-id msk.id`,
                 `gzip -c >cmp.vcf.gz`))
    msk = i - 1
    run(pipeline(`zcat pre.vcf.gz`,
                 `$base/bin/vcf-by-id msk.id`,
                 `$base/bin/msk-eth $msk $ngrp`,
                 `gzip -c >msk.vcf.gz`))
    run(`java -jar $base/bin/beagle.jar ref=ref.vcf.gz gt=msk.vcf.gz ne=100 out=tst`)
    # ToDo
    # extract relevant loci of cmp and imp, and compare
end

max_stars_repo_name: xijiang/Refactered-NSG

max_issues_repo_name: xijiang/Refactered-NSG

max_forks_repo_name: xijiang/Refactered-NSG


text:
module MuZero

include("Constructors.jl")

include("SelfPlay.jl")

include("ReplayBuffer.jl")

include("Learning.jl")

# # Workers. But how many cpus to each?
# self_play_workers = nothing
# test_worker = nothing
# training_worker = nothing
# reanalyse_worker = nothing
# replay_buffer_worker = nothing  # these are storages so what part uses CPU?
# shared_storage_worker = nothing  # these are storages so what part uses CPU?

# # run reanalyse on reanalyse_worker #TODO

# # check how to use reserources like multiple cpus and gpus

# function Muzero()
	# # Load the game and the config from the module with the game name
	# # fix the random seed
	# # initialize Checkpoints and replay buffer
	# # run self_play() on self_play_workers
	# # run continuous_update_weight() on training_worker

    #     # Launch the test worker to get performance metrics
    #     # Write everything in TensorBoard
    #         # Persist replay buffer to disk ?
# end

# #Search for hyperparameters by launching parallel experiments.
# function hyperparameter_search() end

end


text:
using Jrill

println("hello world")

drill_conn = Jrill.drill_connection(ARGS[1], 8047)
#println(drill_conn)

println(Jrill.make_url(drill_conn))

options = Jrill.drill_options(drill_conn)
#println(typeof(options))

#println(Jrill.drill_threads(drill_conn))
#println(Jrill.drill_metrics(drill_conn))

query = "SELECT * FROM sys.version"
#ret = Jrill.drill_query(drill_conn, query)
#println(ret)

ret = Jrill.drill_query(drill_conn, query, to_df=true)
#println(ret)


text:
@testset "DenseMatrix" begin
    tol = 1e-8

    Random.seed!(0)
    for k=1:10
        n = 10
        A = ExaTron.TronDenseMatrix{Array{Float64, 2}}(n)
        B = zeros(n,n)
        for j=1:n, i=j:n
            v = rand(1)[1]
            A.vals[i,j] = v
            B[i,j] = v
            B[j,i] = v
        end

        # Test A == B.
        @test (A.vals == tril(B))

        # Test dssyax().
        x = rand(n)
        y = zeros(n)
        ExaTron.dssyax(n, A, x, y)
        @test norm(y .- (B*x)) <= tol

        # Test nrm2!().
        wa = zeros(n)
        wb = [norm(B[:,i]) for i=1:n]
        ExaTron.nrm2!(wa, A, n)
        @test norm(wa .- wb) <= tol

        # Test reorder!().
        iwa = zeros(Int, n)
        nfree = rand(1:n)[1]
        indfree = sort(StatsBase.sample(1:n, nfree, replace=false))
        for j=1:nfree
            iwa[indfree[j]] = j
        end
        C = ExaTron.TronDenseMatrix{Array{Float64, 2}}(n)
        ExaTron.reorder!(C, A, indfree, nfree, iwa)
        @test C.vals[1:nfree,1:nfree] == A.vals[indfree,indfree]

        # Test copy constructor.
        L = ExaTron.TronDenseMatrix(A)
        @test L.vals == A.vals

        # Test dnsol() and dtsol().
        fill!(x, 1.0)
        fill!(y, 1.0)
        ExaTron.dnsol(n, L, y)
        @test norm(y .- (A.vals\x)) <= tol
        fill!(x, 1.0)
        fill!(y, 1.0)
        ExaTron.dtsol(n, L, y)
        @test norm(y .- (transpose(A.vals)\x)) <= tol

        # Test dicf().
        A.vals .= tril(L.vals * transpose(L.vals))
        info = ExaTron.dicf(n, 1, A, 1, [], [], [], [])
        @test info == 0
        @test norm(A.vals .- L.vals) <= tol

        # Test Tron.
        A.vals = (L.vals * transpose(L.vals))
        g = ones(n)
        x = zeros(n)
        xc = zeros(n)
        xl = -Inf*ones(n)
        xu = Inf*ones(n)
        eval_f_cb(x) = 0.5*(transpose(x)*A.vals*x) + transpose(g)*x
        function eval_grad_f_cb(x, grad_f)
            grad_f .= A.vals*x .+ g
        end
        function eval_h_cb(x, mode, rows, cols, scale, lambda, values)
            if mode == :Structure
                nz = 1
                for j=1:n,i=j:n
                    rows[nz] = i
                    cols[nz] = j
                    nz += 1
                end
            else
                nz = 1
                for j=1:n,i=j:n
                    values[nz] = A.vals[i,j]
                    nz += 1
                end
            end
        end
        prob = ExaTron.createProblem(n, xl, xu, Int(floor((n*(n+1))/2)),
                                     eval_f_cb, eval_grad_f_cb, eval_h_cb; :matrix_type=>:Dense)
        status = ExaTron.solveProblem(prob)
        @test status == :Solve_Succeeded
        # Default termination tolerance of Tron is 1e-6.
        @test norm(A.vals*prob.x .+ g) <= 1e-6
    end
end


text:
using HTTP, DataFrames, Dates, MLBStatsAPI

function extract(params)
    result = DataFrame(
        date = String[],
        pitcherid = Int64[],
        pitcher_teamid = Int64[],
        pitcher_firstname = String[],
        pitcher_lastname = String[],
        pitcher_teamname = String[],
        pitcherthrow = String[],
        batterid = Int64[],
        batter_teamid = Int64[],
        batter_firstname = String[],
        batter_lastname = String[],
        batter_teamname = String[],
        batterstand = String[],
        eventdesc = String[],
        pitchresult = String[],
        x = Float64[],
        y = Float64[],
        px = Float64[],
        pz = Float64[],
        pfxx = Float64[],
        pfxz = Float64[],
        zone = Int64[],
        sztop = Float64[],
        szbottom = Float64[],
        pitchtype = String[],
        startspeed = Float64[],
        endspeed = Float64[],
        spindir = Float64[],
        spinrate = Float64[],
        nasty = Float64[]
    )
    schedule = schedulemlb(params)
    for date in schedule["dates"]
        games = date["games"]
        for g in games
            gameparams = Dict(
                "gamePk" => g["gamePk"]
            )
            feed = game(gameparams)
            gamedate = split(feed["metaData"]["timeStamp"], "_")[1]
            roster = feed["gameData"]["players"]
            plays = feed["liveData"]["plays"]["allPlays"]
            for play in plays
                pitcherid = play["matchup"]["pitcher"]["id"]
                pitcherteamid = play["about"]["halfInning"] == "top" ? feed["gameData"]["teams"]["home"]["id"] : feed["gameData"]["teams"]["away"]["id"]
                pitcherteamname = play["about"]["halfInning"] == "top" ? feed["gameData"]["teams"]["home"]["name"] : feed["gameData"]["teams"]["away"]["name"]
                pitcherfn = roster["ID" * string(pitcherid)]["firstName"]
                pitcherln = roster["ID" * string(pitcherid)]["lastName"]
                pitcherthrow = play["matchup"]["pitchHand"]["code"]
                batterid = play["matchup"]["batter"]["id"]
                batterteamid = play["about"]["halfInning"] == "top" ? feed["gameData"]["teams"]["away"]["id"] : feed["gameData"]["teams"]["home"]["id"]
                batterteamname = play["about"]["halfInning"] == "top" ? feed["gameData"]["teams"]["away"]["name"] : feed["gameData"]["teams"]["home"]["name"]
                batterfn = roster["ID" * string(batterid)]["firstName"]
                batterln = roster["ID" * string(batterid)]["lastName"]
                batterstand = play["matchup"]["batSide"]["code"]
                eventdesc = play["result"]["description"]
                events = play["playEvents"]
                for event in events
                    ispitch = event["isPitch"]
                    if !ispitch
                        @warn "This row will be skipped from result dataframe due to non-pitch record."
                        continue
                    end
                    pitchresult = event["details"]["description"]
                    if haskey(event, "pitchData")
                        try
                            x = event["pitchData"]["coordinates"]["x"]
                            y = event["pitchData"]["coordinates"]["y"]
                            px = event["pitchData"]["coordinates"]["pX"]
                            pz = event["pitchData"]["coordinates"]["pZ"]
                            pfxx = event["pitchData"]["coordinates"]["pfxX"]
                            pfxz = event["pitchData"]["coordinates"]["pfxZ"]
                            zone = event["pitchData"]["zone"]
                            sztop = event["pitchData"]["strikeZoneTop"]
                            szbottom = event["pitchData"]["strikeZoneBottom"]
                            pitchtype = event["details"]["type"]["code"]
                            startspeed = event["pitchData"]["startSpeed"]
                            endspeed = event["pitchData"]["endSpeed"]
                            spinrate = event["pitchData"]["breaks"]["spinRate"]
                            spindir = event["pitchData"]["breaks"]["spinDirection"]
                            nasty = 0
                            push!(result, [
                                gamedate,
                                pitcherid,
                                pitcherteamid,
                                pitcherfn,
                                pitcherln,
                                pitcherteamname,
                                pitcherthrow,
                                batterid,
                                batterteamid,
                                batterfn,
                                batterln,
                                batterteamname,
                                batterstand,
                                eventdesc,
                                pitchresult,
                                x,
                                y,
                                px,
                                pz,
                                pfxx,
                                pfxz,
                                zone,
                                sztop,
                                szbottom,
                                pitchtype,
                                startspeed,
                                endspeed,
                                spinrate,
                                spindir,
                                nasty
                            ])
                        catch
                            @warn "At least one column data cannot be extracted. This row will be skipped from result dataframe."
                            continue
                        end
                    end
                end
            end
        end
    end
    return result
end


text:
# Julia wrapper for header: nidmm.h
# Automatically generated using Clang.jl

function niDMM_init(resourceName, IDQuery, rst, newVi)
    ccall((:niDMM_init, libnidmm), ViStatus, (ViRsrc, ViBoolean, ViBoolean, Ptr{ViSession}), resourceName, IDQuery, rst, newVi)
end

function niDMM_InitWithOptions(resourceName, IDQuery, resetDevice, optionsString, newVi)
    ccall((:niDMM_InitWithOptions, libnidmm), ViStatus, (ViRsrc, ViBoolean, ViBoolean, ViString, Ptr{ViSession}), resourceName, IDQuery, resetDevice, optionsString, newVi)
end

function niDMM_close(vi)
    ccall((:niDMM_close, libnidmm), ViStatus, (ViSession,), vi)
end

function niDMM_GetError(vi, errorCode, bufferSize, description)
    ccall((:niDMM_GetError, libnidmm), ViStatus, (ViSession, Ptr{ViStatus}, ViInt32, Ptr{ViChar}), vi, errorCode, bufferSize, description)
end

function niDMM_GetErrorMessage(vi, errorCode, bufferSize, errMessage)
    ccall((:niDMM_GetErrorMessage, libnidmm), ViStatus, (ViSession, ViStatus, ViInt32, Ptr{ViChar}), vi, errorCode, bufferSize, errMessage)
end

function niDMM_ClearError(vi)
    ccall((:niDMM_ClearError, libnidmm), ViStatus, (ViSession,), vi)
end

function niDMM_reset(vi)
    ccall((:niDMM_reset, libnidmm), ViStatus, (ViSession,), vi)
end

function niDMM_self_test(vi, selfTestResult, selfTestMessage)
    ccall((:niDMM_self_test, libnidmm), ViStatus, (ViSession, Ptr{ViInt16}, Ptr{ViChar}), vi, selfTestResult, selfTestMessage)
end

function niDMM_SelfCal(vi)
    ccall((:niDMM_SelfCal, libnidmm), ViStatus, (ViSession,), vi)
end

function niDMM_revision_query(vi, driverRev, instrRev)
    ccall((:niDMM_revision_query, libnidmm), ViStatus, (ViSession, Ptr{ViChar}, Ptr{ViChar}), vi, driverRev, instrRev)
end

function niDMM_InvalidateAllAttributes(vi)
    ccall((:niDMM_InvalidateAllAttributes, libnidmm), ViStatus, (ViSession,), vi)
end

function niDMM_ResetWithDefaults(vi)
    ccall((:niDMM_ResetWithDefaults, libnidmm), ViStatus, (ViSession,), vi)
end

function niDMM_Disable(vi)
    ccall((:niDMM_Disable, libnidmm), ViStatus, (ViSession,), vi)
end

function niDMM_GetMeasurementPeriod(vi, period)
    ccall((:niDMM_GetMeasurementPeriod, libnidmm), ViStatus, (ViSession, Ptr{ViReal64}), vi, period)
end

function niDMM_ConfigureTrigger(vi, trigSource, triggerDelay)
    ccall((:niDMM_ConfigureTrigger, libnidmm), ViStatus, (ViSession, ViInt32, ViReal64), vi, trigSource, triggerDelay)
end

function niDMM_Read(vi, maxTime, reading)
    ccall((:niDMM_Read, libnidmm), ViStatus, (ViSession, ViInt32, Ptr{ViReal64}), vi, maxTime, reading)
end

function niDMM_Fetch(vi, maxTime, reading)
    ccall((:niDMM_Fetch, libnidmm), ViStatus, (ViSession, ViInt32, Ptr{ViReal64}), vi, maxTime, reading)
end

function niDMM_Abort(vi)
    ccall((:niDMM_Abort, libnidmm), ViStatus, (ViSession,), vi)
end

function niDMM_Initiate(vi)
    ccall((:niDMM_Initiate, libnidmm), ViStatus, (ViSession,), vi)
end

function niDMM_IsOverRange(vi, measurementValue, isOverRange)
    ccall((:niDMM_IsOverRange, libnidmm), ViStatus, (ViSession, ViReal64, Ptr{ViBoolean}), vi, measurementValue, isOverRange)
end

function niDMM_IsUnderRange(vi, measurementValue, isUnderRange)
    ccall((:niDMM_IsUnderRange, libnidmm), ViStatus, (ViSession, ViReal64, Ptr{ViBoolean}), vi, measurementValue, isUnderRange)
end

function niDMM_ConfigureACBandwidth(vi, minFreq, maxFreq)
    ccall((:niDMM_ConfigureACBandwidth, libnidmm), ViStatus, (ViSession, ViReal64, ViReal64), vi, minFreq, maxFreq)
end

function niDMM_ConfigureFrequencyVoltageRange(vi, frequencyVoltageRange)
    ccall((:niDMM_ConfigureFrequencyVoltageRange, libnidmm), ViStatus, (ViSession, ViReal64), vi, frequencyVoltageRange)
end

function niDMM_ConfigureMeasCompleteDest(vi, destination)
    ccall((:niDMM_ConfigureMeasCompleteDest, libnidmm), ViStatus, (ViSession, ViInt32), vi, destination)
end

function niDMM_ConfigureMultiPoint(vi, triggerCount, sampleCount, sampleTrigger, sampleInterval)
    ccall((:niDMM_ConfigureMultiPoint, libnidmm), ViStatus, (ViSession, ViInt32, ViInt32, ViInt32, ViReal64), vi, triggerCount, sampleCount, sampleTrigger, sampleInterval)
end

function niDMM_ReadMultiPoint(vi, maxTime, arraySize, readingArray, actualPts)
    ccall((:niDMM_ReadMultiPoint, libnidmm), ViStatus, (ViSession, ViInt32, ViInt32, Ptr{ViReal64}, Ptr{ViInt32}), vi, maxTime, arraySize, readingArray, actualPts)
end

function niDMM_FetchMultiPoint(vi, maxTime, arraySize, readingArray, actualPts)
    ccall((:niDMM_FetchMultiPoint, libnidmm), ViStatus, (ViSession, ViInt32, ViInt32, Ptr{ViReal64}, Ptr{ViInt32}), vi, maxTime, arraySize, readingArray, actualPts)
end

function niDMM_ConfigureTriggerSlope(vi, polarity)
    ccall((:niDMM_ConfigureTriggerSlope, libnidmm), ViStatus, (ViSession, ViInt32), vi, polarity)
end

function niDMM_SendSoftwareTrigger(vi)
    ccall((:niDMM_SendSoftwareTrigger, libnidmm), ViStatus, (ViSession,), vi)
end

function niDMM_GetApertureTimeInfo(vi, apertureTime, apertureTimeUnits)
    ccall((:niDMM_GetApertureTimeInfo, libnidmm), ViStatus, (ViSession, Ptr{ViReal64}, Ptr{ViInt32}), vi, apertureTime, apertureTimeUnits)
end

function niDMM_GetAutoRangeValue(vi, autoRangeValue)
    ccall((:niDMM_GetAutoRangeValue, libnidmm), ViStatus, (ViSession, Ptr{ViReal64}), vi, autoRangeValue)
end

function niDMM_ConfigureAutoZeroMode(vi, autoZeroMode)
    ccall((:niDMM_ConfigureAutoZeroMode, libnidmm), ViStatus, (ViSession, ViInt32), vi, autoZeroMode)
end

function niDMM_ConfigurePowerLineFrequency(vi, frequency)
    ccall((:niDMM_ConfigurePowerLineFrequency, libnidmm), ViStatus, (ViSession, ViReal64), vi, frequency)
end

function niDMM_ConfigureMeasurementDigits(vi, measFunction, vrange, resolutionDigits)
    ccall((:niDMM_ConfigureMeasurementDigits, libnidmm), ViStatus, (ViSession, ViInt32, ViReal64, ViReal64), vi, measFunction, vrange, resolutionDigits)
end

function niDMM_ConfigureMeasurementAbsolute(vi, measFunction, vrange, resolutionAbsolute)
    ccall((:niDMM_ConfigureMeasurementAbsolute, libnidmm), ViStatus, (ViSession, ViInt32, ViReal64, ViReal64), vi, measFunction, vrange, resolutionAbsolute)
end

function niDMM_ConfigureMeasCompleteSlope(vi, polarity)
    ccall((:niDMM_ConfigureMeasCompleteSlope, libnidmm), ViStatus, (ViSession, ViInt32), vi, polarity)
end

function niDMM_ConfigureSampleTriggerSlope(vi, polarity)
    ccall((:niDMM_ConfigureSampleTriggerSlope, libnidmm), ViStatus, (ViSession, ViInt32), vi, polarity)
end

function niDMM_ReadStatus(vi, acqBacklog, acqDone)
    ccall((:niDMM_ReadStatus, libnidmm), ViStatus, (ViSession, Ptr{ViInt32}, Ptr{ViInt16}), vi, acqBacklog, acqDone)
end

function niDMM_Control(vi, action)
    ccall((:niDMM_Control, libnidmm), ViStatus, (ViSession, ViInt32), vi, action)
end

function niDMM_ConfigureADCCalibration(vi, adcGainComp)
    ccall((:niDMM_ConfigureADCCalibration, libnidmm), ViStatus, (ViSession, ViInt32), vi, adcGainComp)
end

function niDMM_ConfigureOffsetCompOhms(vi, offsetCompOhms)
    ccall((:niDMM_ConfigureOffsetCompOhms, libnidmm), ViStatus, (ViSession, ViInt32), vi, offsetCompOhms)
end

function niDMM_ConfigureCurrentSource(vi, diodeCurrentSrc)
    ccall((:niDMM_ConfigureCurrentSource, libnidmm), ViStatus, (ViSession, ViReal64), vi, diodeCurrentSrc)
end

function niDMM_ConfigureCableCompType(vi, typeOfCompensation)
    ccall((:niDMM_ConfigureCableCompType, libnidmm), ViStatus, (ViSession, ViInt32), vi, typeOfCompensation)
end

function niDMM_PerformOpenCableComp(vi, conductance, susceptance)
    ccall((:niDMM_PerformOpenCableComp, libnidmm), ViStatus, (ViSession, Ptr{ViReal64}, Ptr{ViReal64}), vi, conductance, susceptance)
end

function niDMM_PerformShortCableComp(vi, resistance, reactance)
    ccall((:niDMM_PerformShortCableComp, libnidmm), ViStatus, (ViSession, Ptr{ViReal64}, Ptr{ViReal64}), vi, resistance, reactance)
end

function niDMM_ConfigureOpenCableCompValues(vi, conductance, susceptance)
    ccall((:niDMM_ConfigureOpenCableCompValues, libnidmm), ViStatus, (ViSession, ViReal64, ViReal64), vi, conductance, susceptance)
end

function niDMM_ConfigureShortCableCompValues(vi, resistance, reactance)
    ccall((:niDMM_ConfigureShortCableCompValues, libnidmm), ViStatus, (ViSession, ViReal64, ViReal64), vi, resistance, reactance)
end

function niDMM_LockSession(vi, callerHasLock)
    ccall((:niDMM_LockSession, libnidmm), ViStatus, (ViSession, Ptr{ViBoolean}), vi, callerHasLock)
end

function niDMM_UnlockSession(vi, callerHasLock)
    ccall((:niDMM_UnlockSession, libnidmm), ViStatus, (ViSession, Ptr{ViBoolean}), vi, callerHasLock)
end

function niDMM_ConfigureWaveformAcquisition(vi, _function, vrange, rate, waveformPoints)
    ccall((:niDMM_ConfigureWaveformAcquisition, libnidmm), ViStatus, (ViSession, ViInt32, ViReal64, ViReal64, ViInt32), vi, _function, vrange, rate, waveformPoints)
end

function niDMM_ConfigureWaveformCoupling(vi, coupling)
    ccall((:niDMM_ConfigureWaveformCoupling, libnidmm), ViStatus, (ViSession, ViInt32), vi, coupling)
end

function niDMM_FetchWaveform(vi, maxTime, arraySize, waveformArray, actualPoints)
    ccall((:niDMM_FetchWaveform, libnidmm), ViStatus, (ViSession, ViInt32, ViInt32, Ptr{ViReal64}, Ptr{ViInt32}), vi, maxTime, arraySize, waveformArray, actualPoints)
end

function niDMM_ReadWaveform(vi, maxTime, arraySize, waveformArray, actualPoints)
    ccall((:niDMM_ReadWaveform, libnidmm), ViStatus, (ViSession, ViInt32, ViInt32, Ptr{ViReal64}, Ptr{ViInt32}), vi, maxTime, arraySize, waveformArray, actualPoints)
end

function niDMM_GetAttributeViInt32(vi, channelName, attributeId, value)
    ccall((:niDMM_GetAttributeViInt32, libnidmm), ViStatus, (ViSession, ViConstString, ViAttr, Ptr{ViInt32}), vi, channelName, attributeId, value)
end

function niDMM_SetAttributeViInt32(vi, channelName, attributeId, value)
    ccall((:niDMM_SetAttributeViInt32, libnidmm), ViStatus, (ViSession, ViConstString, ViAttr, ViInt32), vi, channelName, attributeId, value)
end

function niDMM_CheckAttributeViInt32(vi, channelName, attributeId, value)
    ccall((:niDMM_CheckAttributeViInt32, libnidmm), ViStatus, (ViSession, ViConstString, ViAttr, ViInt32), vi, channelName, attributeId, value)
end

function niDMM_GetAttributeViReal64(vi, channelName, attributeId, value)
    ccall((:niDMM_GetAttributeViReal64, libnidmm), ViStatus, (ViSession, ViConstString, ViAttr, Ptr{ViReal64}), vi, channelName, attributeId, value)
end

function niDMM_SetAttributeViReal64(vi, channelName, attributeId, value)
    ccall((:niDMM_SetAttributeViReal64, libnidmm), ViStatus, (ViSession, ViConstString, ViAttr, ViReal64), vi, channelName, attributeId, value)
end

function niDMM_CheckAttributeViReal64(vi, channelName, attributeId, value)
    ccall((:niDMM_CheckAttributeViReal64, libnidmm), ViStatus, (ViSession, ViConstString, ViAttr, ViReal64), vi, channelName, attributeId, value)
end

function niDMM_GetAttributeViString(vi, channelName, attributeId, bufSize, value)
    ccall((:niDMM_GetAttributeViString, libnidmm), ViStatus, (ViSession, ViConstString, ViAttr, ViInt32, Ptr{ViChar}), vi, channelName, attributeId, bufSize, value)
end

function niDMM_SetAttributeViString(vi, channelName, attributeId, value)
    ccall((:niDMM_SetAttributeViString, libnidmm), ViStatus, (ViSession, ViConstString, ViAttr, Ptr{ViChar}), vi, channelName, attributeId, value)
end

function niDMM_CheckAttributeViString(vi, channelName, attributeId, value)
    ccall((:niDMM_CheckAttributeViString, libnidmm), ViStatus, (ViSession, ViConstString, ViAttr, Ptr{ViChar}), vi, channelName, attributeId, value)
end

function niDMM_GetAttributeViSession(vi, channelName, attributeId, value)
    ccall((:niDMM_GetAttributeViSession, libnidmm), ViStatus, (ViSession, ViConstString, ViAttr, Ptr{ViSession}), vi, channelName, attributeId, value)
end

function niDMM_SetAttributeViSession(vi, channelName, attributeId, value)
    ccall((:niDMM_SetAttributeViSession, libnidmm), ViStatus, (ViSession, ViConstString, ViAttr, ViSession), vi, channelName, attributeId, value)
end

function niDMM_CheckAttributeViSession(vi, channelName, attributeId, value)
    ccall((:niDMM_CheckAttributeViSession, libnidmm), ViStatus, (ViSession, ViConstString, ViAttr, ViSession), vi, channelName, attributeId, value)
end

function niDMM_GetAttributeViBoolean(vi, channelName, attributeId, value)
    ccall((:niDMM_GetAttributeViBoolean, libnidmm), ViStatus, (ViSession, ViConstString, ViAttr, Ptr{ViBoolean}), vi, channelName, attributeId, value)
end

function niDMM_SetAttributeViBoolean(vi, channelName, attributeId, value)
    ccall((:niDMM_SetAttributeViBoolean, libnidmm), ViStatus, (ViSession, ViConstString, ViAttr, ViBoolean), vi, channelName, attributeId, value)
end

function niDMM_CheckAttributeViBoolean(vi, channelName, attributeId, value)
    ccall((:niDMM_CheckAttributeViBoolean, libnidmm), ViStatus, (ViSession, ViConstString, ViAttr, ViBoolean), vi, channelName, attributeId, value)
end

function niDMM_ImportAttributeConfigurationFile(vi, filePath)
    ccall((:niDMM_ImportAttributeConfigurationFile, libnidmm), ViStatus, (ViSession, ViConstString), vi, filePath)
end

function niDMM_ExportAttributeConfigurationFile(vi, filePath)
    ccall((:niDMM_ExportAttributeConfigurationFile, libnidmm), ViStatus, (ViSession, ViConstString), vi, filePath)
end

function niDMM_ImportAttributeConfigurationBuffer(vi, sz, configuration)
    ccall((:niDMM_ImportAttributeConfigurationBuffer, libnidmm), ViStatus, (ViSession, ViInt32, ViAddr), vi, sz, configuration)
end

function niDMM_ExportAttributeConfigurationBuffer(vi, sz, configuration)
    ccall((:niDMM_ExportAttributeConfigurationBuffer, libnidmm), ViStatus, (ViSession, ViInt32, ViAddr), vi, sz, configuration)
end

function niDMM_GetNextCoercionRecord(vi, bufferSize, record)
    ccall((:niDMM_GetNextCoercionRecord, libnidmm), ViStatus, (ViSession, ViInt32, Ptr{ViChar}), vi, bufferSize, record)
end

function niDMM_GetNextInterchangeWarning(vi, bufferSize, warnString)
    ccall((:niDMM_GetNextInterchangeWarning, libnidmm), ViStatus, (ViSession, ViInt32, Ptr{ViChar}), vi, bufferSize, warnString)
end

function niDMM_ResetInterchangeCheck(vi)
    ccall((:niDMM_ResetInterchangeCheck, libnidmm), ViStatus, (ViSession,), vi)
end

function niDMM_ClearInterchangeWarnings(vi)
    ccall((:niDMM_ClearInterchangeWarnings, libnidmm), ViStatus, (ViSession,), vi)
end

function niDMM_4022Control(resourceName, configuration)
    ccall((:niDMM_4022Control, libnidmm), ViStatus, (ViRsrc, ViInt32), resourceName, configuration)
end

function niDMM_GetChannelName(vi, index, bufferSize, name)
    ccall((:niDMM_GetChannelName, libnidmm), ViStatus, (ViSession, ViInt32, ViInt32, Ptr{ViChar}), vi, index, bufferSize, name)
end

function niDMM_InitExtCal(resourceName, password, newVi)
    ccall((:niDMM_InitExtCal, libnidmm), ViStatus, (ViRsrc, Ptr{ViChar}, Ptr{ViSession}), resourceName, password, newVi)
end

function niDMM_CloseExtCal(vi, action)
    ccall((:niDMM_CloseExtCal, libnidmm), ViStatus, (ViSession, ViInt32), vi, action)
end

function niDMM_CalAdjustLinearization(vi, mode, vrange, inputR, expectedValue)
    ccall((:niDMM_CalAdjustLinearization, libnidmm), ViStatus, (ViSession, ViInt32, ViReal64, ViReal64, ViReal64), vi, mode, vrange, inputR, expectedValue)
end

function niDMM_CalAdjustGain(vi, mode, vrange, inputR, expectedValue)
    ccall((:niDMM_CalAdjustGain, libnidmm), ViStatus, (ViSession, ViInt32, ViReal64, ViReal64, ViReal64), vi, mode, vrange, inputR, expectedValue)
end

function niDMM_CalAdjustOffset(vi, mode, vrange, inputR)
    ccall((:niDMM_CalAdjustOffset, libnidmm), ViStatus, (ViSession, ViInt32, ViReal64, ViReal64), vi, mode, vrange, inputR)
end

function niDMM_CalAdjustMisc(vi, typ)
    ccall((:niDMM_CalAdjustMisc, libnidmm), ViStatus, (ViSession, ViInt32), vi, typ)
end

function niDMM_CalAdjustLC(vi, typ)
    ccall((:niDMM_CalAdjustLC, libnidmm), ViStatus, (ViSession, ViInt32), vi, typ)
end

function niDMM_CalAdjustACFilter(vi, mode, vrange, frequency, expectedValue)
    ccall((:niDMM_CalAdjustACFilter, libnidmm), ViStatus, (ViSession, ViInt32, ViReal64, ViReal64, ViReal64), vi, mode, vrange, frequency, expectedValue)
end

function niDMM_RestoreLastExtCalConstants(vi)
    ccall((:niDMM_RestoreLastExtCalConstants, libnidmm), ViStatus, (ViSession,), vi)
end

function niDMM_SetCalPassword(vi, oldPassword, newPassword)
    ccall((:niDMM_SetCalPassword, libnidmm), ViStatus, (ViSession, Ptr{ViChar}, Ptr{ViChar}), vi, oldPassword, newPassword)
end

function niDMM_GetExtCalRecommendedInterval(vi, months)
    ccall((:niDMM_GetExtCalRecommendedInterval, libnidmm), ViStatus, (ViSession, Ptr{ViInt32}), vi, months)
end

function niDMM_SetCalUserDefinedInfo(vi, info)
    ccall((:niDMM_SetCalUserDefinedInfo, libnidmm), ViStatus, (ViSession, Ptr{ViChar}), vi, info)
end

function niDMM_GetCalUserDefinedInfoMaxSize(vi, infoSize)
    ccall((:niDMM_GetCalUserDefinedInfoMaxSize, libnidmm), ViStatus, (ViSession, Ptr{ViInt32}), vi, infoSize)
end

function niDMM_GetCalUserDefinedInfo(vi, bufferSize, info)
    ccall((:niDMM_GetCalUserDefinedInfo, libnidmm), ViStatus, (ViSession, ViInt32, Ptr{ViChar}), vi, bufferSize, info)
end

function niDMM_GetSelfCalSupported(vi, selfCalSupported)
    ccall((:niDMM_GetSelfCalSupported, libnidmm), ViStatus, (ViSession, Ptr{ViBoolean}), vi, selfCalSupported)
end

function niDMM_GetCalDateAndTime(vi, calType, month, day, year, hour, minute)
    ccall((:niDMM_GetCalDateAndTime, libnidmm), ViStatus, (ViSession, ViInt32, Ptr{ViInt32}, Ptr{ViInt32}, Ptr{ViInt32}, Ptr{ViInt32}, Ptr{ViInt32}), vi, calType, month, day, year, hour, minute)
end

function niDMM_GetCalCount(vi, calType, cnt)
    ccall((:niDMM_GetCalCount, libnidmm), ViStatus, (ViSession, ViInt32, Ptr{ViInt32}), vi, calType, cnt)
end

function niDMM_GetLastCalTemp(vi, calType, temperature)
    ccall((:niDMM_GetLastCalTemp, libnidmm), ViStatus, (ViSession, ViInt32, Ptr{ViReal64}), vi, calType, temperature)
end

function niDMM_GetDevTemp(vi, reserved, temperature)
    ccall((:niDMM_GetDevTemp, libnidmm), ViStatus, (ViSession, ViString, Ptr{ViReal64}), vi, reserved, temperature)
end

function niDMM_ConfigureTransducerType(vi, transducerType)
    ccall((:niDMM_ConfigureTransducerType, libnidmm), ViStatus, (ViSession, ViInt32), vi, transducerType)
end

function niDMM_ConfigureThermocouple(vi, thermocoupleType, refJunctionType)
    ccall((:niDMM_ConfigureThermocouple, libnidmm), ViStatus, (ViSession, ViInt32, ViInt32), vi, thermocoupleType, refJunctionType)
end

function niDMM_ConfigureFixedRefJunction(vi, fixedRefJunction)
    ccall((:niDMM_ConfigureFixedRefJunction, libnidmm), ViStatus, (ViSession, ViReal64), vi, fixedRefJunction)
end

function niDMM_ConfigureRTDType(vi, rtdType, resistance)
    ccall((:niDMM_ConfigureRTDType, libnidmm), ViStatus, (ViSession, ViInt32, ViReal64), vi, rtdType, resistance)
end

function niDMM_ConfigureRTDCustom(vi, a, b, c)
    ccall((:niDMM_ConfigureRTDCustom, libnidmm), ViStatus, (ViSession, ViReal64, ViReal64, ViReal64), vi, a, b, c)
end

function niDMM_ConfigureThermistorType(vi, thermistorType)
    ccall((:niDMM_ConfigureThermistorType, libnidmm), ViStatus, (ViSession, ViInt32), vi, thermistorType)
end

function niDMM_ConfigureThermistorCustom(vi, a, b, c)
    ccall((:niDMM_ConfigureThermistorCustom, libnidmm), ViStatus, (ViSession, ViReal64, ViReal64, ViReal64), vi, a, b, c)
end


text:
function job_function(cols, rows)
    println("Doing my job($cols,$rows)...")
    sleep(10)
    rand(rows, cols)
end


text:
function molecule(::Molecule"glycine")
  return """
C	0.0000000	0.5506150	0.0000000
O	1.1776070	0.8118730	0.0000000
O	-0.9694240	1.4927290	0.0000000
C	-0.5847620	-0.8563810	0.0000000
N	0.4006580	-1.9277700	0.0000000
H	-0.5071000	2.3458330	0.0000000
H	-1.2456590	-0.9456040	0.8813150
H	-1.2456590	-0.9456040	-0.8813150
H	1.0184570	-1.7812290	0.8032340
H	1.0184570	-1.7812290	-0.8032340
  """
end


text:
module LoopVectorization

# if (!isnothing(get(ENV, "TRAVIS_BRANCH", nothing)) || !isnothing(get(ENV, "APPVEYOR", nothing))) && isdefined(Base, :Experimental) && isdefined(Base.Experimental, Symbol("@optlevel"))
    # @eval Base.Experimental.@optlevel 1
# end

using VectorizationBase, SLEEFPirates, UnPack, OffsetArrays
using VectorizationBase: REGISTER_SIZE, REGISTER_COUNT, data,
    mask, pick_vector_width_val, MM,
    maybestaticlength, maybestaticsize, staticm1, staticp1, staticmul, vzero,
    Zero, maybestaticrange, offsetprecalc, lazymul,
    maybestaticfirst, maybestaticlast, scalar_less, scalar_greaterequal, gep, gesp, pointerforcomparison, NativeTypes,
    vfmadd, vfmsub, vfnmadd, vfnmsub, vfmadd231, vfmsub231, vfnmadd231, vfnmsub231, vadd, vsub, vmul,
    relu, stridedpointer, StridedPointer, StridedBitPointer, AbstractStridedPointer,
    reduced_add, reduced_prod, reduce_to_add, reduce_to_prod, reduced_max, reduced_min, reduce_to_max, reduce_to_min,
    vsum, vprod, vmaximum, vminimum, vstorent!

using IfElse: ifelse

# missing: stridedpointer_for_broadcast, noalias!, gepbyte,
# using SIMDPirates: VECTOR_SYMBOLS, evadd, evsub, evmul, evfdiv, vrange,
#     reduced_add, reduced_prod, reduce_to_add, reduced_max, reduced_min, vsum, vprod, vmaximum, vminimum,
#     sizeequivalentfloat, sizeequivalentint, vadd!, vsub!, vmul!, vfdiv!, vfmadd!, vfnmadd!, vfmsub!, vfnmsub!,
#     vfmadd231, vfmsub231, vfnmadd231, vfnmsub231, sizeequivalentfloat, sizeequivalentint, #prefetch,
#     vmullog2, vmullog10, vdivlog2, vdivlog10, vmullog2add!, vmullog10add!, vdivlog2add!, vdivlog10add!, vfmaddaddone, vadd1, relu
using SLEEFPirates: pow
using Base.Broadcast: Broadcasted, DefaultArrayStyle
using LinearAlgebra: Adjoint, Transpose
using Base.Meta: isexpr
using DocStringExtensions
import LinearAlgebra # for check_args

using Base.FastMath: add_fast, sub_fast, mul_fast, div_fast

using ArrayInterface
using ArrayInterface: OptionallyStaticUnitRange, Zero, One
const Static = ArrayInterface.StaticInt

export LowDimArray, stridedpointer,
    @avx, @_avx, *ˡ, _avx_!,
    vmap, vmap!, vmapt, vmapt!, vmapnt, vmapnt!, vmapntt, vmapntt!,
    vfilter, vfilter!, vmapreduce, vreduce

@inline unwrap(::Val{N}) where {N} = N
@inline unwrap(::Static{N}) where {N} = N
@inline unwrap(x) = x

const VECTORWIDTHSYMBOL, ELTYPESYMBOL = Symbol("##Wvecwidth##"), Symbol("##Tloopeltype##")

include("vectorizationbase_compat/contract_pass.jl")
include("vectorizationbase_compat/subsetview.jl")
include("getconstindexes.jl")
include("predicates.jl")
include("map.jl")
include("filter.jl")
include("costs.jl")
include("operations.jl")
include("graphs.jl")
include("operation_evaluation_order.jl")
include("memory_ops_common.jl")
include("add_loads.jl")
include("add_stores.jl")
include("add_compute.jl")
include("add_constants.jl")
include("add_ifelse.jl")
include("determinestrategy.jl")
include("loopstartstopmanager.jl")
include("lower_compute.jl")
include("lower_constant.jl")
include("lower_memory_common.jl")
include("lower_load.jl")
include("lower_store.jl")
include("lowering.jl")
include("split_loops.jl")
include("condense_loopset.jl")
include("reconstruct_loopset.jl")
include("constructors.jl")
include("user_api_conveniences.jl")
include("mapreduce.jl")
include("broadcast.jl")

"""
LoopVectorization provides macros and functions that combine SIMD vectorization and
loop-reordering so as to improve performance:

- [`@avx`](@ref): transform `for`-loops and broadcasting
- [`@_avx`](@ref): similar to `@avx` but does not use type information
- [`vmap`](@ref) and `vmap!`: vectorized version of `map` and `map!`
- [`vmapnt`](@ref) and `vmapnt!`: non-temporal variants of `vmap` and `vmap!`
- [`vmapntt`](@ref) and `vmapntt!`: threaded variants of `vmapnt` and `vmapnt!`
- [`vfilter`](@ref) and `vfilter!`: vectorized versions of `filter` and `filter!`
"""
LoopVectorization

include("precompile.jl")
_precompile_()

end # module


text:
# @author:      0.382
# @description: ini文件读取
#

"A `key = value` item."
mutable struct IniItem
    key::String
    value::Union{Bool,Int64,Float64,String,Nothing}
end

"A ini file section."
mutable struct IniSection
    name::String
    items::Vector{IniItem}
end

"""
    IniFile(fname::AbstractString)
IniFile struct, with several sections, including `default` section. Construct it with a file name.
"""
struct IniFile
    sections::Vector{IniSection}
    good::Bool
    err_msg::String
    IniFile(secs::Vector{IniSection}, good::Bool, msg::AbstractString) = new(secs, good, msg)
end

"""
    isgood(ini::IniFile)
Determine if the ini file is opened successful.
"""
isgood(ini::IniFile) = ini.good

"""
    error_msg(ini::IniFile)
Get error message of IniFile.
"""
error_msg(ini::IniFile) = ini.err_msg

IniFile(secs::Vector{IniSection}) = IniFile(secs, true, "")

IniFile(fname::AbstractString) = begin
    try
        secs = open(read_inifile, fname, "r")
        return IniFile(secs, true, "")
    catch err
        msg = ""
        if err isa SystemError
            msg = "cannot " * err.prefix
        else
            msg = string(err)
        end
        return IniFile(Vector{IniSection}(), false, msg)
    end
end

function read_inifile(fp::IO)::Vector{IniSection}
    inisections = Vector{IniSection}()
    inisec = IniSection("", Vector{IniItem}())
    iniitem = IniItem("", "")
    for line in eachline(fp)
        line = strip(remove_comment(line))
        line == "" && continue
        if line[1] == '[' && line[end] == ']'
            push!(inisections, deepcopy(inisec))
            inisec = IniSection(strip(line, ('[', ']', ' ')), Vector{IniItem}())
        elseif build_item!(line, iniitem)
            push!(inisec.items, deepcopy(iniitem))
        else
            throw("invalid ini line: " * line)
        end
    end
    push!(inisections, inisec)
end

"""
    getValue(ini::IniFile, section::AbstractString, key::AbstractString)
    getValue(ini::IniFile, key::AbstractString)
Get a value with a key in one section. The version without section name searches the `default` section.
"""
function getValue(ini::IniFile, section::AbstractString, key::AbstractString)::Union{Bool,Int64,Float64,String}
    try
        err_secname = section == "" ? "(default)" : section
        pos = findfirst(x -> x.name == section, ini.sections)
        pos === nothing && throw(KeyError("no section '$err_secname'"))
        sec::IniSection = ini.sections[pos]
        pos = findfirst(x -> x.key == key, sec.items)
        pos === nothing && throw(KeyError("no key '$key' in section '$err_secname'"))
        return sec.items[pos].value
    catch err
        println("get failed: ", err)
        exit(-1)
    end
end

"""
    getString(ini::IniFile, section::AbstractString, key::AbstractString)
    getString(ini::IniFile, key::AbstractString)
Get a string value with a key in one section. The version without section name searches the `default` section.
"""
getString(ini::IniFile, section::AbstractString, key::AbstractString) = getValue(ini, section, key)::AbstractString

"""
    getBool(ini::IniFile, section::AbstractString, key::AbstractString)
    getBool(ini::IniFile, key::AbstractString)
Get a boolean value with a key in one section. The version without section name searches the `default` section.
"""
getBool(ini::IniFile, section::AbstractString, key::AbstractString) = getValue(ini, section, key)::Bool

"""
    getInt(ini::IniFile, section::AbstractString, key::AbstractString)
    getInt(ini::IniFile, key::AbstractString)
Get a integer value with a key in one section. The version without section name searches the `default` section.
"""
getInt(ini::IniFile, section::AbstractString, key::AbstractString) = getValue(ini, section, key)::Int64

"""
    getFloat(ini::IniFile, section::AbstractString, key::AbstractString)
    getFloat(ini::IniFile, key::AbstractString)
Get a floating point value with a key in one section. The version without section name searches the `default` section.
"""
getFloat(ini::IniFile, section::AbstractString, key::AbstractString) = getValue(ini, section, key)::Float64

getValue(ini::IniFile, key::AbstractString) = getValue(ini, "", key)
getString(ini::IniFile, key::AbstractString) = getString(ini, "", key)
getBool(ini::IniFile, key::AbstractString) = getBool(ini, "", key)
getInt(ini::IniFile, key::AbstractString) = getInt(ini, "", key)
getFloat(ini::IniFile, key::AbstractString) = getFloat(ini, "", key)

"""
    Base.show(io::IO, ini::IniFile)
Import `Base.show` to print a `IniFile`.
"""
Base.show(io::IO, ini::IniFile) = begin
    for sec in ini.sections
        sec.name == "" || println(io, "[$(sec.name)]")
        for it in sec.items
            println(io, "$(it.key) = $(it.value)")
        end
    end
end

"""
    saveAs(ini::IniFile, fname::AbstractString)
Save the ini file to file.
"""
function saveAs(ini::IniFile, fname::AbstractString)
    open(fname, "w") do io
        print(io, ini)
    end
end

# 去掉尾部的注释
function remove_comment(line::AbstractString)::String
    rl = line[:]
    for c in ["#", ";", "//"]
        pos = findfirst(c, rl)
        pos === nothing || (rl = rl[1:pos.start - 1])
    end
    return rl
end

# 利用一行字符串创建 IniItem
function build_item!(line::AbstractString, it::IniItem)
    pos = findfirst('=', line)
    pos === nothing && return false
    it.key = strip(line[1:pos - 1], [' ', '\'', '\"'])
    temp::String = strip(line[pos + 1:end], [' ', '\'', '\"'])
    it.value = tryparse(Bool, temp)
    it.value === nothing || return true
    it.value = tryparse(Int64, temp)
    it.value === nothing || return true
    it.value = tryparse(Float64, temp)
    it.value === nothing || return true
    it.value = temp
    it.value == "" || return true
    return false
end


text:
import MLJModelInterface
import Soss

function predict_particles(predictor::SossMLJPredictor, Xnew)
    args = predictor.args
    pars = Soss.particles(predictor.post)
    pred = predictor.pred
    transform = predictor.model.transform
    dist = pred(merge(args, transform(Xnew), pars))
    return Soss.particles(dist)
end

function predict_particles(sm::SossMLJModel,
                           fitresult,
                           Xnew;
                           response = sm.response)
    predictor_joint = MLJModelInterface.predict_joint(sm, fitresult, Xnew)
    return getproperty(predict_particles(predictor_joint, Xnew), response)
end


text:
using SimpleGraphs, DrawSimpleGraphs

"""
    dodec_with_ham_cycle()
Create a drawing of the dodecahedron graph with black vertices, a red Hamiltonian
cycle, and a blue perfect matching.
"""
function dodec_with_ham_cycle()
    G = Dodecahedron()
    n = NV(G)

    # Create a 2nd graph that is a Hamiltonian cycle of G
    hc = hamiltonian_cycle(G)
    H = IntGraph()
    for i = 1:n-1
        add!(H, hc[i], hc[i+1])
    end
    add!(H, hc[1], hc[end])

    xy = getxy(G)
    embed(H, xy)

    set_line_color(G,:blue)
    set_line_color(H,:red)

    newdraw()       # ensure a blank canvas
    draw_edges(G)
    draw_edges(H)
    set_line_color(H,:black)
    set_vertex_color(H,:black)
    draw_nodes(H)
end