text:
using NLsolve
using LinearAlgebra

include("utils.jl")

Random.seed!(10)

@testset "approximate inverse retractions" begin
    @testset "NLSolveInverseRetraction" begin
        @testset "constructor" begin
            X = randn(3)

            @test NLSolveInverseRetraction <: ApproximateInverseRetraction
            m1 = NLSolveInverseRetraction(ExponentialRetraction())
            @test m1.retraction === ExponentialRetraction()
            @test m1.X0 === nothing
            @test !m1.project_tangent
            @test !m1.project_point
            @test isempty(m1.nlsolve_kwargs)

            m2 = NLSolveInverseRetraction(
                PolarRetraction(),
                [1.0, 2.0, 3.0];
                project_tangent=true,
                project_point=true,
                autodiff=:forward,
            )
            @test m2.retraction === PolarRetraction()
            @test m2.X0 == [1.0, 2.0, 3.0]
            @test m2.project_tangent
            @test m2.project_point
            @test (; m2.nlsolve_kwargs...) == (; autodiff=:forward)
        end
        @testset "Euclidean" begin
            M = Euclidean(3)
            p = [1.0, 2.0, 3.0]
            q = [4.0, 5.0, 6.0]
            retr_method = ExponentialRetraction()
            inv_retr_method = NLSolveInverseRetraction(retr_method)
            X = inverse_retract(M, p, q, inv_retr_method)
            @test is_vector(M, p, X)
            @test X isa Vector{Float64}
            @test X ≈ q - p
        end
        @testset "Power" begin
            M = PowerManifold(Euclidean(2), NestedPowerRepresentation(), 2)
            p = [[1.0, 2.0], [3.0, 4.0]]
            q = [[5.0, 6.0], [7.0, 8.0]]
            retr_method = ExponentialRetraction()
            inv_retr_method = NLSolveInverseRetraction(retr_method)
            X = inverse_retract(M, p, q, inv_retr_method)
            @test is_vector(M, p, X)
            @test X isa Vector{Vector{Float64}}
            @test X ≈ q - p
        end
        @testset "Sphere" begin
            M = Sphere(2)
            p = [1.0, 0.0, 0.0]
            q = [1 / sqrt(2), 1 / sqrt(2), 0.0]
            X_exp = inverse_retract(M, p, q, ProjectionInverseRetraction())
            # vector must be nonzero to converge
            X0 = randn(3) .* eps()
            inv_retr_method =
                NLSolveInverseRetraction(ProjectionRetraction(), X0; project_point=true)
            X = inverse_retract(M, p, q, inv_retr_method)
            @test is_vector(M, p, X; atol=1e-9)
            @test X ≈ X_exp atol = 1e-8
            @test_throws OutOfInjectivityRadiusError inverse_retract(
                M,
                p,
                -p,
                inv_retr_method,
            )
        end

        # Requires https://github.com/JuliaNLSolvers/NLSolversBase.jl/pull/141
        # @testset "Circle(ℂ)" begin
        #     M = Circle(ℂ)
        #     p = fill(1.0 * im)
        #     X = fill(p[1] * im * (π / 4))
        #     q = exp(M, p, X)
        #     X_exp = log(M, p, q)
        #     inv_retr_method =
        #         NLSolveInverseRetraction(ExponentialRetraction(); project_point=true)
        #     X = inverse_retract(M, p, q, inv_retr_method)
        #     @test is_vector(M, p, X; atol=1e-8)
        #     @test X ≈ X_exp
        # end
    end
end


text:
module TestExamples2DPart2

using Test
using Trixi

include("test_trixi.jl")

# pathof(Trixi) returns /path/to/Trixi/src/Trixi.jl, dirname gives the parent directory
EXAMPLES_DIR = joinpath(pathof(Trixi) |> dirname |> dirname, "examples", "tree_2d_dgsem")

# Start with a clean environment: remove Trixi output directory if it exists
outdir = "out"
isdir(outdir) && rm(outdir, recursive=true)

@testset "2D-Part2" begin

# Run basic tests
@testset "Examples 2D" begin
  # Compressible Euler Multicomponent
  include("test_examples_2d_eulermulti.jl")

  # MHD
  include("test_examples_2d_mhd.jl")

  # MHD Multicomponent
  include("test_examples_2d_mhdmulti.jl")

  # Lattice-Boltzmann
  include("test_examples_2d_lbm.jl")
end

# Clean up afterwards: delete Trixi output directory
@test_nowarn rm(outdir, recursive=true)

end # 2D-Part2

end #module

ext: jl


text:
### A Pluto.jl notebook ###
# v0.15.1

using Markdown
using InteractiveUtils

# ╔═╡ 82da667e-11e6-474f-b388-5325baf83cac
using MPIFiles, MPIReco, DataFrames, CSV, Plots, LsqFit, LazyArtifacts

# ╔═╡ 3dc2447c-9bac-11eb-2c55-a356da25ed08
md"""
# Spatial orientation estimation of immobilized magnetic nanoparticles with parallel aligned easy axes

This Pluto notebook contains the whole evaluation pipeline related to the project. Note that running this notebook for the first time can take serval minutes, as Julia packages have to be installed and a large number of data sets are processed.

Here, the package environment required to run this notebook is set up.
"""

# ╔═╡ b3a4b435-d8a4-4d40-9a18-c294d4d8f942
md"""
## Data

### Calibration measurements

12 calibration measurements are available. Their easy axis orientation (°) and file path are documented here.
"""

# ╔═╡ 5dd4e6c3-eb71-4df6-9f90-bc392384f5f8
md"""
### Measurements

756 measurements are available. Each with one of 36 easy axis orientations (°) and at one of 21 spatial positions (m). A complete list is given below.
"""

# ╔═╡ fabfcd41-563e-45e1-b657-d36ae57735a9
md"""
## Reconstruction

Here, the [multi-contrast reconstruction method](https://iopscience.iop.org/article/10.1088/0031-9155/60/5/1775) by Rahmer et al. is used to obtain a 12-channel MPI tomogram from the 12 system matrices available.
"""

# ╔═╡ a6a61f0f-f34e-4e64-a40c-84f32d349615
md"""
### Set up MDF data set store

All measurements are stored in the Magnetic Particle Imaging Data Format ([MDF](https://arxiv.org/pdf/1602.06072.pdf)) and collected in an MDF dataset store.
"""

# ╔═╡ ca5764d5-5719-4d7c-bde4-6308ef12a872
begin
	pathToMDFStore = artifact"MDFStore"
	MDFStoreEasyAxis = MDFDatasetStore(pathToMDFStore)
	study = getStudy(MDFStoreEasyAxis,"20210423_230806_magnetic easy axis orientation")
end;

# ╔═╡ 6545ea1c-c5f1-474c-93be-b86a9a85e021
dfSF = DataFrame(CSV.File(joinpath(pathToMDFStore,"calibrations.csv")))

# ╔═╡ 36917ded-0b60-44e0-be11-784692a96b97
dfMeas = DataFrame(CSV.File(joinpath(pathToMDFStore,"measurements.csv")))

# ╔═╡ eeed6fe4-2a6f-477c-ab5f-971dbad7e5ef
md"""
### Set up reconstruction parameters

Note, any change to one of these parameters triggers a reconstruction of all 756 data sets. This can take up to several hours and the duration is mainly impacted by the number of `:iterations`.
"""

# ╔═╡ bce35624-154a-46c4-8f7e-15109d0f473d
begin
	recoparams = defaultRecoParams()
	recoparams[:SFPath] = dfSF[:,:path] # system matrices used for multi-contrast reconstruction
	recoparams[:lambd] = 1e-2 # relative Tikhonov regularization parameter λ
	recoparams[:iterations] = 5000 # number of iterations for iterative  Kaczmarz  solver
	recoparams[:minFreq] = 80e3 # use signal frequencies above 80kHz only
	recoparams[:SNRThresh] = 5.0 # use signal frequencies with SNR >= 5
end;

# ╔═╡ 48cfa5b0-5c86-4afc-be82-6c9017675c8d
md"""
### Load exemplary tomogram

To illustrate the reconstruction pipeline, a measurement is chosen randomly from the data frame `dfMeas` and reconstructed.
"""

# ╔═╡ 902b5f9d-5320-4ffa-8e1f-1778fc415c75
begin
	# choose random data set
	n = rand(1:nrow(dfMeas))
	experimentNumber = dfMeas[n,:experimentNumber]
	experiment = getExperiment(study,experimentNumber)
	tomogram = reconstruction(experiment,recoparams)
end;

# ╔═╡ 2ad4d959-a7c0-498f-8101-168718b56768
md"""
### Get meta data from data frame

The sample position and axis alignment can be obtained from the data frame `dfMeas`.
"""

# ╔═╡ 037ff94d-3e90-4596-baed-694263200b1c
begin
	x = dfMeas[n,:x]
	y = dfMeas[n,:y]
	β = dfMeas[n,:easyAxisOrientation]
end;

# ╔═╡ fd8bd61a-940e-4799-a46e-08e04ccec5b3
md"""
### Visualize tomogram

Here, the reconstructed 12-channel tomogram is visualized by going through all channels individually.
"""

# ╔═╡ 8572bc03-380b-460e-b3ce-f46d7a6dd86b
begin
    xs = -13.636363636363637:2.727272727272727:13.636363636363637
	ys = -13.636363636363637:2.727272727272727:13.636363636363637
	anim1 = @animate for channel=1:12
	    heatmap(xs,ys,tomogram[channel,:,:,1,1]',
		color = :viridis,
		clim = (0,maximum(tomogram)),
		aspect_ratio = 1,
		title = "$(experiment.name), $(Int(dfSF[:,:easyAxisOrientation][channel]))°-channel",
		xlabel = "x / mm",
		ylabel = "y / mm")
	end
	gif(anim1, "images/eval1.gif", fps = 2)
end

# ╔═╡ ea314390-64ee-4597-83d4-941c6e5de64a
md"""
## Calculate weights

Here, the signal weight of the sample is calculated for each individual channel.
"""

# ╔═╡ 517bcca3-2e03-459e-b656-7410bc23108e
md"""
### Calibration angles α
"""

# ╔═╡ 9a644b3e-7195-4389-b666-91722e95fa15
calibrationEasyAxisOrientations = Float64.(dfSF[:,:easyAxisOrientation])

# ╔═╡ da7cefff-fe8c-418d-b161-e59500af1bff
md"""
### Obtain geometric properties of tomograms
"""

# ╔═╡ b38c0c68-6830-48e3-8c6d-59a02f472fe3
begin
	sf = MPIFile(joinpath(pathToMDFStore,"calibrations/1.mdf"))
	fovWidth = calibFov(sf)[1] # width of the fov in m
	fovHeight = calibFov(sf)[2] # height of the fov in m
	imageWidth = calibSize(sf)[1] # image height in px
	imageHeight = calibSize(sf)[2] # image width in px
end;

# ╔═╡ fc498516-a743-4b85-8af3-1052a763637a
md"""
### Create circular mask around the sample position
"""

# ╔═╡ a08fbfdc-d3c0-4e64-8e5b-770893906f5b
# creates discrete circular mask with radius 2 pixels around position x, y
function mask(x,y,imageWidth=imageWidth,imageHeight=imageHeight,radius=2.0)
    mask = zeros(Float64,1,imageWidth,imageHeight,1,1)
    for i in CartesianIndices(mask)
        if (i[2]-x)^2 + (i[3]-y)^2 < radius^2
            mask[i]=1
        end
    end
    return mask
end

# ╔═╡ 325f4196-f0aa-4781-bd6e-923025923d0f
md"""
### Visualize masked tomogram
"""

# ╔═╡ 0849ef36-003b-4376-a2d9-64b5fa5ba041
md"""
### Obtain weights
"""

# ╔═╡ bcc103eb-ed60-4bf9-986f-92dd8f3db7e1
begin
	# calculate sample position in pixel coordinates
	xImagePos = (x .+ fovWidth./2)./(fovWidth./imageWidth)
	yImagePos = (y .+ fovHeight./2)./(fovHeight./imageHeight)

	# create discrete circular mask
	sumMask = mask(xImagePos,yImagePos)
	rawData = arraydata(arraydata(tomogram))
	maskData = rawData.*sumMask
	weights = vec(sum(maskData, dims=(2,3,4)))
end

# ╔═╡ 16447270-a584-4d50-96c1-fd5340542c56
begin
	anim2 = @animate for channel=1:12
	    heatmap(xs,ys,(sumMask.*tomogram)[channel,:,:,1,1]',
		color = :viridis,
		clim = (0,maximum(tomogram)),
		aspect_ratio = 1,
		title = "β=$(β)° @($(Float16(x*1000)),$(Float16(y*1000))) mm, masked, $(calibrationEasyAxisOrientations[channel])°-channel",
		xlabel = "x / mm",
		ylabel = "y / mm")
	end
	gif(anim2, "images/eval2.gif", fps = 2)
end

# ╔═╡ 38cb9e6a-0781-4047-a6c3-6da451d82605
md"""
### Visualize masked tomogram

Note that the weights are large at and around the alignment of the magnetic easy axis β.
"""

# ╔═╡ 9c1cff7e-3daa-45a1-87ae-41b268b01826
plt1 = scatter(calibrationEasyAxisOrientations,weights,
	title = "β=$(β)° @($(Float16(x*1000)),$(Float16(y*1000))) mm, weights",
	label = "w_α",
	xlabel = "α / °",
	ylabel = "weights / a.u.",
	xticks = 0:15:165)

# ╔═╡ 362beeab-1fc0-4386-b92e-a18f7d98ef95
savefig(plt1,"images/weights.svg")

# ╔═╡ 64bcdd37-d208-480e-a8ab-f1dbed80b782
md"""
### Let's do this for all tomograms

Here, the weights for all measurements are calculated and saved in a data frame.
"""

# ╔═╡ 70edbec3-82ff-4980-aa2a-c7866a739488
function getWeights(experimentNumber,x,y)
	# calculate sample position in pixel coordinates
	xImagePos = (x .+ fovWidth./2)./(fovWidth./imageWidth)
	yImagePos = (y .+ fovHeight./2)./(fovHeight./imageHeight)

	# load tomogram
	experiment = getExperiment(study,experimentNumber)
	tomogram = reconstruction(experiment,recoparams)

	# create circular mask around sample position
	sumMask = mask(xImagePos,yImagePos)

	# obtain numerical raw data from image object
	rawData = arraydata(arraydata(tomogram))

	# mask data
	maskData = rawData.*sumMask

	# calculate weights by summing each channel
	weights = vec(sum(maskData, dims=(2,3,4)))
	return weights
end

# ╔═╡ ad4f7a3d-98e1-408c-a9a6-d35a35f0a905
dfWeights = transform(dfMeas, [:experimentNumber,:x,:y] => ((easyAxisOrientation,x,y) -> getWeights.(easyAxisOrientation,x,y)) => :weights)

# ╔═╡ da4073b7-abe9-441b-9af1-425b341a2c06
md"""
## Estimate easy axis alignment

In this section of the notebook, the easy axis alignment is estimated.
"""

# ╔═╡ 67b4daed-bf84-45ad-b809-c234a477efea
md"""
### Define estimator function

First, a family of continuous estimator functions for the weights is defined. Here, the vector $p$ hols the three parameters `p[1]`, `p[2]` and `p[3]`. Each function is 180°-periodic and has a single peak of height `p[1]` at `p[2]`.
"""

# ╔═╡ 8be12329-c063-4008-9e97-0b4ba3b0ec8b
@. model(x, p) = p[1]*(cos(π*(x-p[2])/180)^2)^p[3]

# ╔═╡ 5c4414b8-6fd3-4ff5-949c-87450b0ec46f
md"""
### Least squares fit estimator function to data

Second, this function is fitted to the weights. The model parameter `p[2]` (peak location) is extracted as the estimator for the easy axis alignment.
"""

# ╔═╡ 52b7f31e-c9fa-4feb-8490-533accef9f10
function estimateAlignment(initialGuess, weights)
	# the easy axis orientation is used as as initial guess
	# this choice results in a reliable optimization
	# other choices independent on the orientation we aim to estimate are possible
	p0 = [0.0, initialGuess, 1.0]
	# least squares fit
	fit = curve_fit(model, calibrationEasyAxisOrientations, weights, p0, lower=[0.0,0.0,1.0], upper=[Inf,180.0,Inf])
	# optimal parameters
	p = coef(fit)
	# return easy axis alignment estimator
	return p[2]
end

# ╔═╡ 4d3cf4cb-5f5b-476b-a6b1-a1f93aa96a0e
βest = estimateAlignment(β, weights)

# ╔═╡ 4ffb5972-0c52-4be1-aa7b-9dc94ed7c4bb
begin
	# for plotting we need all parameters
	p0 = [0.0, β, 1.0]
	fit = curve_fit(model, calibrationEasyAxisOrientations, weights, p0, lower=[0.0,0.0,1.0], upper=[Inf,180.0,Inf])
	p = coef(fit)

	plt2 = scatter(calibrationEasyAxisOrientations,weights,
		title = "β=$(β)° @($(Float16(x*1000)),$(Float16(y*1000))) mm, β_est=$(Float16(βest))°",
		label = "w_α",
		xlabel = "α / °",
		ylabel = "weights / a.u.",
		xticks = 0:15:165)

	xmodel = 0:0.5:180
	ymodel = map(x->model(x,coef(fit)),xmodel)
	plot!(plt2,xmodel,ymodel, linewidth=2, label="estimator fit")
end

# ╔═╡ 6f32f17d-4ed2-4929-bc37-04cf06c8994c
savefig(plt2,"images/weightsandfit.svg")

# ╔═╡ 0ad5d465-841d-4364-81de-c476f281e928
md"""
### Obtain estimate from all measurements

Here, the axis alignment is estimated for all measurements.
"""

# ╔═╡ 02243e99-fb29-40bb-89c7-3ceeed44c0a6
dfEst = transform(dfWeights, [:easyAxisOrientation, :weights] => ((easyAxisOrientation, weights) -> estimateAlignment.(easyAxisOrientation, weights)) => :orientationEstimate)

# ╔═╡ 1705d7c4-c9bb-41e3-8d15-49fc6fc93e62
md"""
## Calculate estimation errors

The estimation error is calculated for each measurement and its distribution over all measurements visualized.
"""

# ╔═╡ 25bdc400-6681-48e4-97b3-fc614c3ea48c
function calcError(easyAxisOrientation, orientationEstimate)
    err = orientationEstimate-easyAxisOrientation
    # Correction periodic orientations at 180 to 0 degree
    if err > 90
        err = (orientationEstimate-180.0)-easyAxisOrientation
    elseif err < -90
        err = (orientationEstimate+180.0)-easyAxisOrientation
    end
    return err
end

# ╔═╡ 0c1115f6-2524-421c-8be6-492d39eed618
dfErr = transform(dfEst, [:easyAxisOrientation, :orientationEstimate] => ((easyAxisOrientation, orientationEstimate) -> calcError.(easyAxisOrientation, orientationEstimate)) => :estimationError)

# ╔═╡ e2db427b-2e3f-4ebc-907a-3af082ca5350
plt3 = histogram(dfErr[:,:estimationError],
	title = "error distribution, mean=$(Float16(mean(dfErr[:,:estimationError])))°, std=$(Float16(std(dfErr[:,:estimationError])))°",
	xlabel = "alignment estimation error / °",
	ylabel = "absolute frequency",
	label=nothing)

# ╔═╡ 3e80dbe6-e8e8-4492-b565-5731a62b095f
savefig(plt3,"images/errordistribution.svg")

# ╔═╡ 24973fd9-9e62-4769-838c-2a7fa2bdff33
md"""
### Save the results

Finally, we save the results to a `csv`-file.
"""

# ╔═╡ 6f5ef619-f8da-49cc-92f5-b8de0e72599d
begin
	dfResults = select(dfErr, [:experimentNumber,:easyAxisOrientation,:x,:y,:orientationEstimate,:estimationError])
	CSV.write("results.csv", dfResults)
end

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
LazyArtifacts = "4af54fe1-eca0-43a8-85a7-787d91b784e3"
LsqFit = "2fda8390-95c7-5789-9bda-21331edee243"
MPIFiles = "371237a9-e6c1-5201-9adb-3d8cfa78fa9f"
MPIReco = "e4246700-6248-511e-8146-a1d1f47669d2"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"

[compat]
CSV = "~0.8.5"
DataFrames = "~1.2.2"
LsqFit = "~0.12.1"
MPIFiles = "~0.11.14"
MPIReco = "~0.3.7"
Plots = "~1.21.1"
"""

# ╔═╡ 00000000-0000-0000-0000-000000000002
PLUTO_MANIFEST_TOML_CONTENTS = """
# This file is machine-generated - editing it directly is not advised

[[AbstractFFTs]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "485ee0867925449198280d4af84bdb46a2a404d0"
uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c"
version = "1.0.1"

[[Adapt]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "84918055d15b3114ede17ac6a7182f68870c16f7"
uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
version = "3.3.1"

[[ArgTools]]
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"

[[ArrayInterface]]
deps = ["IfElse", "LinearAlgebra", "Requires", "SparseArrays", "Static"]
git-tree-sha1 = "045ff5e1bc8c6fb1ecb28694abba0a0d55b5f4f5"
uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
version = "3.1.17"

[[Artifacts]]
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"

[[AxisAlgorithms]]
deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"]
git-tree-sha1 = "a4d07a1c313392a77042855df46c5f534076fab9"
uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950"
version = "1.0.0"

[[AxisArrays]]
deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"]
git-tree-sha1 = "d127d5e4d86c7680b20c35d40b503c74b9a39b5e"
uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9"
version = "0.4.4"

[[BFloat16s]]
deps = ["LinearAlgebra", "Test"]
git-tree-sha1 = "4af69e205efc343068dc8722b8dfec1ade89254a"
uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b"
version = "0.1.0"

[[Base64]]
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"

[[Blosc]]
deps = ["Blosc_jll"]
git-tree-sha1 = "84cf7d0f8fd46ca6f1b3e0305b4b4a37afe50fd6"
uuid = "a74b3585-a348-5f62-a45c-50e91977d574"
version = "0.7.0"

[[Blosc_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Lz4_jll", "Pkg", "Zlib_jll", "Zstd_jll"]
git-tree-sha1 = "e747dac84f39c62aff6956651ec359686490134e"
uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9"
version = "1.21.0+0"

[[Bzip2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "c3598e525718abcc440f69cc6d5f60dda0a1b61e"
uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0"
version = "1.0.6+5"

[[CEnum]]
git-tree-sha1 = "215a9aa4a1f23fbd05b92769fdd62559488d70e9"
uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82"
version = "0.4.1"

[[CSV]]
deps = ["Dates", "Mmap", "Parsers", "PooledArrays", "SentinelArrays", "Tables", "Unicode"]
git-tree-sha1 = "b83aa3f513be680454437a0eee21001607e5d983"
uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
version = "0.8.5"

[[CUDA]]
deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CompilerSupportLibraries_jll", "DataStructures", "ExprTools", "GPUArrays", "GPUCompiler", "LLVM", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "MacroTools", "Memoize", "NNlib", "Printf", "Random", "Reexport", "Requires", "SparseArrays", "Statistics", "TimerOutputs"]
git-tree-sha1 = "6893a46f357eabd44ce0fc1f9a264120a1a3a732"
uuid = "052768ef-5323-5732-b1bb-66c8b64840ba"
version = "2.6.3"

[[Cairo_jll]]
deps = ["Artifacts", "Bzip2_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "e2f47f6d8337369411569fd45ae5753ca10394c6"
uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a"
version = "1.16.0+6"

[[CatIndices]]
deps = ["CustomUnitRanges", "OffsetArrays"]
git-tree-sha1 = "a0f80a09780eed9b1d106a1bf62041c2efc995bc"
uuid = "aafaddc9-749c-510e-ac4f-586e18779b91"
version = "0.2.2"

[[ChainRulesCore]]
deps = ["Compat", "LinearAlgebra", "SparseArrays"]
git-tree-sha1 = "bdc0937269321858ab2a4f288486cb258b9a0af7"
uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
version = "1.3.0"

[[CodecZlib]]
deps = ["TranscodingStreams", "Zlib_jll"]
git-tree-sha1 = "ded953804d019afa9a3f98981d99b33e3db7b6da"
uuid = "944b1d66-785c-5afd-91f1-9de20f533193"
version = "0.7.0"

[[ColorSchemes]]
deps = ["ColorTypes", "Colors", "FixedPointNumbers", "Random"]
git-tree-sha1 = "9995eb3977fbf67b86d0a0a0508e83017ded03f2"
uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
version = "3.14.0"

[[ColorTypes]]
deps = ["FixedPointNumbers", "Random"]
git-tree-sha1 = "32a2b8af383f11cbb65803883837a149d10dfe8a"
uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
version = "0.10.12"

[[ColorVectorSpace]]
deps = ["ColorTypes", "Colors", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "StatsBase"]
git-tree-sha1 = "4d17724e99f357bfd32afa0a9e2dda2af31a9aea"
uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4"
version = "0.8.7"

[[Colors]]
deps = ["ColorTypes", "FixedPointNumbers", "Reexport"]
git-tree-sha1 = "417b0ed7b8b838aa6ca0a87aadf1bb9eb111ce40"
uuid = "5ae59095-9a9b-59fe-a467-6f913c188581"
version = "0.12.8"

[[CommonSolve]]
git-tree-sha1 = "68a0743f578349ada8bc911a5cbd5a2ef6ed6d1f"
uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2"
version = "0.2.0"

[[CommonSubexpressions]]
deps = ["MacroTools", "Test"]
git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7"
uuid = "bbf7d656-a473-5ed7-a52c-81e309532950"
version = "0.3.0"

[[Compat]]
deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "SHA", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"]
git-tree-sha1 = "727e463cfebd0c7b999bbf3e9e7e16f254b94193"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "3.34.0"

[[CompilerSupportLibraries_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"

[[ComputationalResources]]
git-tree-sha1 = "52cb3ec90e8a8bea0e62e275ba577ad0f74821f7"
uuid = "ed09eef8-17a6-5b46-8889-db040fac31e3"
version = "0.3.2"

[[ConstructionBase]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "f74e9d5388b8620b4cee35d4c5a618dd4dc547f4"
uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
version = "1.3.0"

[[Contour]]
deps = ["StaticArrays"]
git-tree-sha1 = "9f02045d934dc030edad45944ea80dbd1f0ebea7"
uuid = "d38c429a-6771-53c6-b99e-75d170b6e991"
version = "0.5.7"

[[CoordinateTransformations]]
deps = ["LinearAlgebra", "StaticArrays"]
git-tree-sha1 = "6d1c23e740a586955645500bbec662476204a52c"
uuid = "150eb455-5306-5404-9cee-2592286d6298"
version = "0.6.1"

[[Crayons]]
git-tree-sha1 = "3f71217b538d7aaee0b69ab47d9b7724ca8afa0d"
uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
version = "4.0.4"

[[CustomUnitRanges]]
git-tree-sha1 = "1a3f97f907e6dd8983b744d2642651bb162a3f7a"
uuid = "dc8bdbbb-1ca9-579f-8c36-e416f6a65cce"
version = "1.0.2"

[[DSP]]
deps = ["FFTW", "IterTools", "LinearAlgebra", "Polynomials", "Random", "Reexport", "SpecialFunctions", "Statistics"]
git-tree-sha1 = "2a63cb5fc0e8c1f0f139475ef94228c7441dc7d0"
uuid = "717857b8-e6f2-59f4-9121-6e50c889abd2"
version = "0.6.10"

[[DataAPI]]
git-tree-sha1 = "ee400abb2298bd13bfc3df1c412ed228061a2385"
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
version = "1.7.0"

[[DataFrames]]
deps = ["Compat", "DataAPI", "Future", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrettyTables", "Printf", "REPL", "Reexport", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"]
git-tree-sha1 = "d785f42445b63fc86caa08bb9a9351008be9b765"
uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
version = "1.2.2"

[[DataStructures]]
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
git-tree-sha1 = "7d9d316f04214f7efdbb6398d545446e246eff02"
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
version = "0.18.10"

[[DataValueInterfaces]]
git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6"
uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464"
version = "1.0.0"

[[Dates]]
deps = ["Printf"]
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"

[[DelimitedFiles]]
deps = ["Mmap"]
uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab"

[[DiffResults]]
deps = ["StaticArrays"]
git-tree-sha1 = "c18e98cba888c6c25d1c3b048e4b3380ca956805"
uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5"
version = "1.0.3"

[[DiffRules]]
deps = ["NaNMath", "Random", "SpecialFunctions"]
git-tree-sha1 = "3ed8fa7178a10d1cd0f1ca524f249ba6937490c0"
uuid = "b552c78f-8df3-52c6-915a-8e097449b14b"
version = "1.3.0"

[[Distances]]
deps = ["LinearAlgebra", "Statistics", "StatsAPI"]
git-tree-sha1 = "abe4ad222b26af3337262b8afb28fab8d215e9f8"
uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
version = "0.10.3"

[[Distributed]]
deps = ["Random", "Serialization", "Sockets"]
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"

[[DistributedArrays]]
deps = ["Distributed", "LinearAlgebra", "Primes", "Random", "Serialization", "SparseArrays", "Statistics"]
git-tree-sha1 = "8b73f8289d73306e3fc04e8622a2db562e01cd07"
uuid = "aaf54ef3-cdf8-58ed-94cc-d582ad619b94"
version = "0.6.6"

[[Distributions]]
deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SparseArrays", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns"]
git-tree-sha1 = "f389cb8974e02d7eaa6ae2ccedbbfb43174cd8e8"
uuid = "31c24e10-a181-5473-b8eb-7969acd0382f"
version = "0.25.14"

[[DocStringExtensions]]
deps = ["LibGit2"]
git-tree-sha1 = "a32185f5428d3986f47c2ab78b1f216d5e6cc96f"
uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
version = "0.8.5"

[[Downloads]]
deps = ["ArgTools", "LibCURL", "NetworkOptions"]
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"

[[EarCut_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "92d8f9f208637e8d2d28c664051a00569c01493d"
uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5"
version = "2.1.5+1"

[[EllipsisNotation]]
deps = ["ArrayInterface"]
git-tree-sha1 = "8041575f021cba5a099a456b4163c9a08b566a02"
uuid = "da5c29d0-fa7d-589e-88eb-ea29b0a81949"
version = "1.1.0"

[[Expat_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "b3bfd02e98aedfa5cf885665493c5598c350cd2f"
uuid = "2e619515-83b5-522b-bb60-26c02a35a201"
version = "2.2.10+0"

[[ExprTools]]
git-tree-sha1 = "b7e3d17636b348f005f11040025ae8c6f645fe92"
uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04"
version = "0.1.6"

[[FFMPEG]]
deps = ["FFMPEG_jll"]
git-tree-sha1 = "b57e3acbe22f8484b4b5ff66a7499717fe1a9cc8"
uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a"
version = "0.4.1"

[[FFMPEG_jll]]
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "LibVPX_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "Pkg", "Zlib_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"]
git-tree-sha1 = "3cc57ad0a213808473eafef4845a74766242e05f"
uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5"
version = "4.3.1+4"

[[FFTViews]]
deps = ["CustomUnitRanges", "FFTW"]
git-tree-sha1 = "70a0cfd9b1c86b0209e38fbfe6d8231fd606eeaf"
uuid = "4f61f5a4-77b1-5117-aa51-3ab5ef4ef0cd"
version = "0.3.1"

[[FFTW]]
deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"]
git-tree-sha1 = "f985af3b9f4e278b1d24434cbb546d6092fca661"
uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
version = "1.4.3"

[[FFTW_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "3676abafff7e4ff07bbd2c42b3d8201f31653dcc"
uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a"
version = "3.3.9+8"

[[FastClosures]]
git-tree-sha1 = "acebe244d53ee1b461970f8910c235b259e772ef"
uuid = "9aa1b823-49e4-5ca5-8b0f-3971ec8bab6a"
version = "0.3.2"

[[FileIO]]
deps = ["Pkg", "Requires", "UUIDs"]
git-tree-sha1 = "937c29268e405b6808d958a9ac41bfe1a31b08e7"
uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
version = "1.11.0"

[[FillArrays]]
deps = ["LinearAlgebra", "Random", "SparseArrays", "Statistics"]
git-tree-sha1 = "7c365bdef6380b29cfc5caaf99688cd7489f9b87"
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
version = "0.12.2"

[[FiniteDiff]]
deps = ["ArrayInterface", "LinearAlgebra", "Requires", "SparseArrays", "StaticArrays"]
git-tree-sha1 = "8b3c09b56acaf3c0e581c66638b85c8650ee9dca"
uuid = "6a86dc24-6348-571c-b903-95158fe2bd41"
version = "2.8.1"

[[FixedPointNumbers]]
deps = ["Statistics"]
git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc"
uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
version = "0.8.4"

[[Fontconfig_jll]]
deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "35895cf184ceaab11fd778b4590144034a167a2f"
uuid = "a3f928ae-7b40-5064-980b-68af3947d34b"
version = "2.13.1+14"

[[Formatting]]
deps = ["Printf"]
git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8"
uuid = "59287772-0a20-5a39-b81b-1366585eb4c0"
version = "0.4.2"

[[ForwardDiff]]
deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "NaNMath", "Printf", "Random", "SpecialFunctions", "StaticArrays"]
git-tree-sha1 = "b5e930ac60b613ef3406da6d4f42c35d8dc51419"
uuid = "f6369f11-7733-5829-9624-2563aa707210"
version = "0.10.19"

[[FreeType2_jll]]
deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "cbd58c9deb1d304f5a245a0b7eb841a2560cfec6"
uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7"
version = "2.10.1+5"

[[FriBidi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91"
uuid = "559328eb-81f9-559d-9380-de523a88c83c"
version = "1.0.10+0"

[[Future]]
deps = ["Random"]
uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820"

[[GLFW_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"]
git-tree-sha1 = "dba1e8614e98949abfa60480b13653813d8f0157"
uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89"
version = "3.3.5+0"

[[GPUArrays]]
deps = ["AbstractFFTs", "Adapt", "LinearAlgebra", "Printf", "Random", "Serialization", "Statistics"]
git-tree-sha1 = "df5b8569904c5c10e84c640984cfff054b18c086"
uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7"
version = "6.4.1"

[[GPUCompiler]]
deps = ["DataStructures", "ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "Serialization", "TimerOutputs", "UUIDs"]
git-tree-sha1 = "ef2839b063e158672583b9c09d2cf4876a8d3d55"
uuid = "61eb1bfa-7361-4325-ad38-22787b887f55"
version = "0.10.0"

[[GR]]
deps = ["Base64", "DelimitedFiles", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Pkg", "Printf", "Random", "Serialization", "Sockets", "Test", "UUIDs"]
git-tree-sha1 = "182da592436e287758ded5be6e32c406de3a2e47"
uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
version = "0.58.1"

[[GR_jll]]
deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Pkg", "Qt5Base_jll", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "d59e8320c2747553788e4fc42231489cc602fa50"
uuid = "d2c73de3-f751-5644-a686-071e5b155ba9"
version = "0.58.1+0"

[[GeometryBasics]]
deps = ["EarCut_jll", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"]
git-tree-sha1 = "58bcdf5ebc057b085e58d95c138725628dd7453c"
uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
version = "0.4.1"

[[Gettext_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046"
uuid = "78b55507-aeef-58d4-861c-77aaff3498b1"
version = "0.21.0+0"

[[Glib_jll]]
deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "7bf67e9a481712b3dbe9cb3dac852dc4b1162e02"
uuid = "7746bdde-850d-59dc-9ae8-88ece973131d"
version = "2.68.3+0"

[[Graphics]]
deps = ["Colors", "LinearAlgebra", "NaNMath"]
git-tree-sha1 = "2c1cf4df419938ece72de17f368a021ee162762e"
uuid = "a2bd30eb-e257-5431-a919-1863eab51364"
version = "1.1.0"

[[Grisu]]
git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2"
uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe"
version = "1.0.2"

[[HDF5]]
deps = ["Blosc", "Compat", "HDF5_jll", "Libdl", "Mmap", "Random", "Requires"]
git-tree-sha1 = "83173193dc242ce4b037f0263a7cc45afb5a0b85"
uuid = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f"
version = "0.15.6"

[[HDF5_jll]]
deps = ["Artifacts", "JLLWrappers", "LibCURL_jll", "Libdl", "OpenSSL_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "fd83fa0bde42e01952757f01149dd968c06c4dba"
uuid = "0234f1f7-429e-5d53-9886-15a909be8d59"
version = "1.12.0+1"

[[HTTP]]
deps = ["Base64", "Dates", "IniFile", "MbedTLS", "Sockets"]
git-tree-sha1 = "c7ec02c4c6a039a98a15f955462cd7aea5df4508"
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
version = "0.8.19"

[[Hwloc]]
deps = ["Hwloc_jll"]
git-tree-sha1 = "92d99146066c5c6888d5a3abc871e6a214388b91"
uuid = "0e44f5e4-bd66-52a0-8798-143a42290a1d"
version = "2.0.0"

[[Hwloc_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "3395d4d4aeb3c9d31f5929d32760d8baeee88aaf"
uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8"
version = "2.5.0+0"

[[IdentityRanges]]
deps = ["OffsetArrays"]
git-tree-sha1 = "be8fcd695c4da16a1d6d0cd213cb88090a150e3b"
uuid = "bbac6d45-d8f3-5730-bfe4-7a449cd117ca"
version = "0.3.1"

[[IfElse]]
git-tree-sha1 = "28e837ff3e7a6c3cdb252ce49fb412c8eb3caeef"
uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173"
version = "0.1.0"

[[ImageAxes]]
deps = ["AxisArrays", "ImageCore", "Reexport", "SimpleTraits"]
git-tree-sha1 = "794ad1d922c432082bc1aaa9fa8ffbd1fe74e621"
uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac"
version = "0.6.9"

[[ImageContrastAdjustment]]
deps = ["ColorVectorSpace", "ImageCore", "ImageTransformations", "Parameters"]
git-tree-sha1 = "2e6084db6cccab11fe0bc3e4130bd3d117092ed9"
uuid = "f332f351-ec65-5f6a-b3d1-319c6670881a"
version = "0.3.7"

[[ImageCore]]
deps = ["AbstractFFTs", "Colors", "FixedPointNumbers", "Graphics", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "Reexport"]
git-tree-sha1 = "db645f20b59f060d8cfae696bc9538d13fd86416"
uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534"
version = "0.8.22"

[[ImageDistances]]
deps = ["ColorVectorSpace", "Distances", "ImageCore", "ImageMorphology", "LinearAlgebra", "Statistics"]
git-tree-sha1 = "6378c34a3c3a216235210d19b9f495ecfff2f85f"
uuid = "51556ac3-7006-55f5-8cb3-34580c88182d"
version = "0.2.13"

[[ImageFiltering]]
deps = ["CatIndices", "ColorVectorSpace", "ComputationalResources", "DataStructures", "FFTViews", "FFTW", "ImageCore", "LinearAlgebra", "OffsetArrays", "Requires", "SparseArrays", "StaticArrays", "Statistics", "TiledIteration"]
git-tree-sha1 = "bf96839133212d3eff4a1c3a80c57abc7cfbf0ce"
uuid = "6a3955dd-da59-5b1f-98d4-e7296123deb5"
version = "0.6.21"

[[ImageMagick]]
deps = ["FileIO", "ImageCore", "ImageMagick_jll", "InteractiveUtils", "Libdl", "Pkg", "Random"]
git-tree-sha1 = "5bc1cb62e0c5f1005868358db0692c994c3a13c6"
uuid = "6218d12a-5da1-5696-b52f-db25d2ecc6d1"
version = "1.2.1"

[[ImageMagick_jll]]
deps = ["JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pkg", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "1c0a2295cca535fabaf2029062912591e9b61987"
uuid = "c73af94c-d91f-53ed-93a7-00f77d67a9d7"
version = "6.9.10-12+3"

[[ImageMetadata]]
deps = ["AxisArrays", "ColorVectorSpace", "ImageAxes", "ImageCore", "IndirectArrays"]
git-tree-sha1 = "ae76038347dc4edcdb06b541595268fca65b6a42"
uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49"
version = "0.9.5"

[[ImageMorphology]]
deps = ["ColorVectorSpace", "ImageCore", "LinearAlgebra", "TiledIteration"]
git-tree-sha1 = "68e7cbcd7dfaa3c2f74b0a8ab3066f5de8f2b71d"
uuid = "787d08f9-d448-5407-9aad-5290dd7ab264"
version = "0.2.11"

[[ImageQualityIndexes]]
deps = ["ColorVectorSpace", "ImageCore", "ImageDistances", "ImageFiltering", "OffsetArrays", "Statistics"]
git-tree-sha1 = "1198f85fa2481a3bb94bf937495ba1916f12b533"
uuid = "2996bd0c-7a13-11e9-2da2-2f5ce47296a9"
version = "0.2.2"

[[ImageShow]]
deps = ["Base64", "FileIO", "ImageCore", "Requires"]
git-tree-sha1 = "c9df184bc7c2e665f971079174aabb7d18f1845f"
uuid = "4e3cecfd-b093-5904-9786-8bbb286a6a31"
version = "0.2.3"

[[ImageTransformations]]
deps = ["AxisAlgorithms", "ColorVectorSpace", "CoordinateTransformations", "IdentityRanges", "ImageCore", "Interpolations", "OffsetArrays", "Rotations", "StaticArrays"]
git-tree-sha1 = "e4cc551e4295a5c96545bb3083058c24b78d4cf0"
uuid = "02fcd773-0e25-5acc-982a-7f6622650795"
version = "0.8.13"

[[ImageUtils]]
deps = ["AxisArrays", "ColorSchemes", "ColorVectorSpace", "Colors", "FFTW", "FixedPointNumbers", "ImageMagick", "Images", "Interpolations", "LinearAlgebra", "Random", "Reexport", "Roots", "Statistics", "TestImages", "Unitful"]
git-tree-sha1 = "870a70a5a2f40e74b7bc07568d913800e6336bf4"
uuid = "8ad4436d-4835-5a14-8bce-3ae014d2950b"
version = "0.2.6"

[[Images]]
deps = ["AxisArrays", "Base64", "ColorVectorSpace", "FileIO", "Graphics", "ImageAxes", "ImageContrastAdjustment", "ImageCore", "ImageDistances", "ImageFiltering", "ImageMetadata", "ImageMorphology", "ImageQualityIndexes", "ImageShow", "ImageTransformations", "IndirectArrays", "OffsetArrays", "Random", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "StatsBase", "TiledIteration"]
git-tree-sha1 = "535bcaae047f017f4fd7331ee859b75f2b27e505"
uuid = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
version = "0.23.3"

[[IndirectArrays]]
git-tree-sha1 = "c2a145a145dc03a7620af1444e0264ef907bd44f"
uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959"
version = "0.5.1"

[[Inflate]]
git-tree-sha1 = "f5fc07d4e706b84f72d54eedcc1c13d92fb0871c"
uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9"
version = "0.1.2"

[[IniFile]]
deps = ["Test"]
git-tree-sha1 = "098e4d2c533924c921f9f9847274f2ad89e018b8"
uuid = "83e8ac13-25f8-5344-8a64-a9f2b223428f"
version = "0.5.0"

[[IntelOpenMP_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "d979e54b71da82f3a65b62553da4fc3d18c9004c"
uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0"
version = "2018.0.3+2"

[[InteractiveUtils]]
deps = ["Markdown"]
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"

[[Interpolations]]
deps = ["AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"]
git-tree-sha1 = "61aa005707ea2cebf47c8d780da8dc9bc4e0c512"
uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
version = "0.13.4"

[[IntervalSets]]
deps = ["Dates", "EllipsisNotation", "Statistics"]
git-tree-sha1 = "3cc368af3f110a767ac786560045dceddfc16758"
uuid = "8197267c-284f-5f27-9208-e0e47529a953"
version = "0.5.3"

[[Intervals]]
deps = ["Dates", "Printf", "RecipesBase", "Serialization", "TimeZones"]
git-tree-sha1 = "323a38ed1952d30586d0fe03412cde9399d3618b"
uuid = "d8418881-c3e1-53bb-8760-2df7ec849ed5"
version = "1.5.0"

[[InvertedIndices]]
deps = ["Test"]
git-tree-sha1 = "15732c475062348b0165684ffe28e85ea8396afc"
uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f"
version = "1.0.0"

[[IrrationalConstants]]
git-tree-sha1 = "f76424439413893a832026ca355fe273e93bce94"
uuid = "92d709cd-6900-40b7-9082-c6be49f344b6"
version = "0.1.0"

[[IterTools]]
git-tree-sha1 = "05110a2ab1fc5f932622ffea2a003221f4782c18"
uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
version = "1.3.0"

[[IterativeSolvers]]
deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"]
git-tree-sha1 = "1a8c6237e78b714e901e406c096fc8a65528af7d"
uuid = "42fd0dbc-a981-5370-80f2-aaf504508153"
version = "0.9.1"

[[IteratorInterfaceExtensions]]
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
uuid = "82899510-4779-5014-852e-03e436cf321d"
version = "1.0.0"

[[JLLWrappers]]
deps = ["Preferences"]
git-tree-sha1 = "642a199af8b68253517b80bd3bfd17eb4e84df6e"
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
version = "1.3.0"

[[JSON]]
deps = ["Dates", "Mmap", "Parsers", "Unicode"]
git-tree-sha1 = "8076680b162ada2a031f707ac7b4953e30667a37"
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
version = "0.21.2"

[[JpegTurbo_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "d735490ac75c5cb9f1b00d8b5509c11984dc6943"
uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8"
version = "2.1.0+0"

[[LAME_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c"
uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d"
version = "3.100.1+0"

[[LLVM]]
deps = ["CEnum", "Libdl", "Printf", "Unicode"]
git-tree-sha1 = "f57ac3fd2045b50d3db081663837ac5b4096947e"
uuid = "929cbde3-209d-540e-8aea-75f648917ca0"
version = "3.9.0"

[[LZO_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6"
uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac"
version = "2.10.1+0"

[[LaTeXStrings]]
git-tree-sha1 = "c7f1c695e06c01b95a67f0cd1d34994f3e7db104"
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
version = "1.2.1"

[[Latexify]]
deps = ["Formatting", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "Printf", "Requires"]
git-tree-sha1 = "a4b12a1bd2ebade87891ab7e36fdbce582301a92"
uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
version = "0.15.6"

[[LazyArtifacts]]
deps = ["Artifacts", "Pkg"]
uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3"

[[LibCURL]]
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"

[[LibCURL_jll]]
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"]
uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0"

[[LibGit2]]
deps = ["Base64", "NetworkOptions", "Printf", "SHA"]
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"

[[LibSSH2_jll]]
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"

[[LibVPX_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "12ee7e23fa4d18361e7c2cde8f8337d4c3101bc7"
uuid = "dd192d2f-8180-539f-9fb4-cc70b1dcf69a"
version = "1.10.0+0"

[[Libdl]]
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"

[[Libffi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "761a393aeccd6aa92ec3515e428c26bf99575b3b"
uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490"
version = "3.2.2+0"

[[Libgcrypt_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"]
git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae"
uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4"
version = "1.8.7+0"

[[Libglvnd_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"]
git-tree-sha1 = "7739f837d6447403596a75d19ed01fd08d6f56bf"
uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29"
version = "1.3.0+3"

[[Libgpg_error_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9"
uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8"
version = "1.42.0+0"

[[Libiconv_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "42b62845d70a619f063a7da093d995ec8e15e778"
uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531"
version = "1.16.1+1"

[[Libmount_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "9c30530bf0effd46e15e0fdcf2b8636e78cbbd73"
uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9"
version = "2.35.0+0"

[[Libtiff_jll]]
deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "Zlib_jll", "Zstd_jll"]
git-tree-sha1 = "340e257aada13f95f98ee352d316c3bed37c8ab9"
uuid = "89763e89-9b03-5906-acba-b20f662cd828"
version = "4.3.0+0"

[[Libuuid_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "7f3efec06033682db852f8b3bc3c1d2b0a0ab066"
uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700"
version = "2.36.0+0"

[[LinearAlgebra]]
deps = ["Libdl"]
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

[[LinearOperators]]
deps = ["FastClosures", "LinearAlgebra", "Printf", "SparseArrays", "TimerOutputs"]
git-tree-sha1 = "12a8ce0c3ef28df3cb372ca7ae964345251fb12d"
uuid = "5c8ed15e-5a4c-59e4-a42b-c7e8811fb125"
version = "1.3.1"

[[LogExpFunctions]]
deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"]
git-tree-sha1 = "3d682c07e6dd250ed082f883dc88aee7996bf2cc"
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
version = "0.3.0"

[[Logging]]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"

[[LsqFit]]
deps = ["Distributions", "ForwardDiff", "LinearAlgebra", "NLSolversBase", "OptimBase", "Random", "StatsBase"]
git-tree-sha1 = "91aa1442e63a77f101aff01dec5a821a17f43922"
uuid = "2fda8390-95c7-5789-9bda-21331edee243"
version = "0.12.1"

[[Lz4_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "5d494bc6e85c4c9b626ee0cab05daa4085486ab1"
uuid = "5ced341a-0733-55b8-9ab6-a4889d929147"
version = "1.9.3+0"

[[MKL_jll]]
deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"]
git-tree-sha1 = "c253236b0ed414624b083e6b72bfe891fbd2c7af"
uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7"
version = "2021.1.1+1"

[[MPIFiles]]
deps = ["AxisArrays", "CodecZlib", "Dates", "DelimitedFiles", "FileIO", "Graphics", "HDF5", "Images", "Inflate", "Interpolations", "LazyArtifacts", "LinearAlgebra", "Mmap", "Pkg", "Random", "SHA", "SparsityOperators", "Statistics", "Tar", "Test", "UUIDs", "Unitful"]
git-tree-sha1 = "58a02ad48932f257a6af4b169015a58fbc5d8051"
uuid = "371237a9-e6c1-5201-9adb-3d8cfa78fa9f"
version = "0.11.14"

[[MPIReco]]
deps = ["DSP", "Distributed", "DistributedArrays", "ImageUtils", "IniFile", "LinearAlgebra", "MPIFiles", "RegularizedLeastSquares", "SparseArrays"]
git-tree-sha1 = "2fff6e230b3f2daa1748ea8bfb059dbea6f23773"
uuid = "e4246700-6248-511e-8146-a1d1f47669d2"
version = "0.3.7"

[[MacroTools]]
deps = ["Markdown", "Random"]
git-tree-sha1 = "0fb723cd8c45858c22169b2e42269e53271a6df7"
uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
version = "0.5.7"

[[MappedArrays]]
git-tree-sha1 = "e8b359ef06ec72e8c030463fe02efe5527ee5142"
uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900"
version = "0.4.1"

[[Markdown]]
deps = ["Base64"]
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"

[[MbedTLS]]
deps = ["Dates", "MbedTLS_jll", "Random", "Sockets"]
git-tree-sha1 = "1c38e51c3d08ef2278062ebceade0e46cefc96fe"
uuid = "739be429-bea8-5141-9913-cc70e7f3736d"
version = "1.0.3"

[[MbedTLS_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"

[[Measures]]
git-tree-sha1 = "e498ddeee6f9fdb4551ce855a46f54dbd900245f"
uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e"
version = "0.3.1"

[[Memoize]]
deps = ["MacroTools"]
git-tree-sha1 = "2b1dfcba103de714d31c033b5dacc2e4a12c7caa"
uuid = "c03570c3-d221-55d1-a50c-7939bbd78826"
version = "0.4.4"

[[Missings]]
deps = ["DataAPI"]
git-tree-sha1 = "2ca267b08821e86c5ef4376cffed98a46c2cb205"
uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
version = "1.0.1"

[[Mmap]]
uuid = "a63ad114-7e13-5084-954f-fe012c677804"

[[Mocking]]
deps = ["ExprTools"]
git-tree-sha1 = "748f6e1e4de814b101911e64cc12d83a6af66782"
uuid = "78c3b35d-d492-501b-9361-3d52fe80e533"
version = "0.7.2"

[[MosaicViews]]
deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"]
git-tree-sha1 = "b34e3bc3ca7c94914418637cb10cc4d1d80d877d"
uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389"
version = "0.3.3"

[[MozillaCACerts_jll]]
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"

[[NLSolversBase]]
deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"]
git-tree-sha1 = "144bab5b1443545bc4e791536c9f1eacb4eed06a"
uuid = "d41bc354-129a-5804-8e4c-c37616107c6c"
version = "7.8.1"

[[NNlib]]
deps = ["Adapt", "ChainRulesCore", "Compat", "LinearAlgebra", "Pkg", "Requires", "Statistics"]
git-tree-sha1 = "3bc876dbff74cc9c4ece84ef9326da8ccd71c98f"
uuid = "872c559c-99b0-510c-b3b7-b6c96a88d5cd"
version = "0.7.28"

[[NaNMath]]
git-tree-sha1 = "bfe47e760d60b82b66b61d2d44128b62e3a369fb"
uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
version = "0.3.5"

[[NetworkOptions]]
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"

[[OffsetArrays]]
deps = ["Adapt"]
git-tree-sha1 = "c870a0d713b51e4b49be6432eff0e26a4325afee"
uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
version = "1.10.6"

[[Ogg_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "7937eda4681660b4d6aeeecc2f7e1c81c8ee4e2f"
uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051"
version = "1.3.5+0"

[[OpenSSL_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "15003dcb7d8db3c6c857fda14891a539a8f2705a"
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
version = "1.1.10+0"

[[OpenSpecFun_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1"
uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e"
version = "0.5.5+0"

[[OptimBase]]
deps = ["NLSolversBase", "Printf", "Reexport"]
git-tree-sha1 = "9cb1fee807b599b5f803809e85c81b582d2009d6"
uuid = "87e2bd06-a317-5318-96d9-3ecbac512eee"
version = "2.0.2"

[[Opus_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720"
uuid = "91d4177d-7536-5919-b921-800302f37372"
version = "1.3.2+0"

[[OrderedCollections]]
git-tree-sha1 = "85f8e6578bf1f9ee0d11e7bb1b1456435479d47c"
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
version = "1.4.1"

[[PCRE_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "b2a7af664e098055a7529ad1a900ded962bca488"
uuid = "2f80f16e-611a-54ab-bc61-aa92de5b98fc"
version = "8.44.0+0"

[[PDMats]]
deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"]
git-tree-sha1 = "4dd403333bcf0909341cfe57ec115152f937d7d8"
uuid = "90014a1f-27ba-587c-ab20-58faa44d9150"
version = "0.11.1"

[[PaddedViews]]
deps = ["OffsetArrays"]
git-tree-sha1 = "646eed6f6a5d8df6708f15ea7e02a7a2c4fe4800"
uuid = "5432bcbf-9aad-5242-b902-cca2824c8663"
version = "0.5.10"

[[Parameters]]
deps = ["OrderedCollections", "UnPack"]
git-tree-sha1 = "2276ac65f1e236e0a6ea70baff3f62ad4c625345"
uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a"
version = "0.12.2"

[[Parsers]]
deps = ["Dates"]
git-tree-sha1 = "bfd7d8c7fd87f04543810d9cbd3995972236ba1b"
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
version = "1.1.2"

[[Pixman_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "b4f5d02549a10e20780a24fce72bea96b6329e29"
uuid = "30392449-352a-5448-841d-b1acce4e97dc"
version = "0.40.1+0"

[[Pkg]]
deps = ["Artifacts", "Dates", "Downloads", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"]
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"

[[PlotThemes]]
deps = ["PlotUtils", "Requires", "Statistics"]
git-tree-sha1 = "a3a964ce9dc7898193536002a6dd892b1b5a6f1d"
uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a"
version = "2.0.1"

[[PlotUtils]]
deps = ["ColorSchemes", "Colors", "Dates", "Printf", "Random", "Reexport", "Statistics"]
git-tree-sha1 = "c67334c786157d6ef091ce622b365d3d60b1e2c4"
uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043"
version = "1.0.12"

[[Plots]]
deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "GeometryBasics", "JSON", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "PlotThemes", "PlotUtils", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "UUIDs"]
git-tree-sha1 = "0036d433cacff4767ff622be3cb2c281b773a2b4"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
version = "1.21.1"

[[Polynomials]]
deps = ["Intervals", "LinearAlgebra", "OffsetArrays", "RecipesBase"]
git-tree-sha1 = "0b15f3597b01eb76764dd03c3c23d6679a3c32c8"
uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45"
version = "1.2.1"

[[PooledArrays]]
deps = ["DataAPI", "Future"]
git-tree-sha1 = "cde4ce9d6f33219465b55162811d8de8139c0414"
uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720"
version = "1.2.1"

[[Preferences]]
deps = ["TOML"]
git-tree-sha1 = "00cfd92944ca9c760982747e9a1d0d5d86ab1e5a"
uuid = "21216c6a-2e73-6563-6e65-726566657250"
version = "1.2.2"

[[PrettyTables]]
deps = ["Crayons", "Formatting", "Markdown", "Reexport", "Tables"]
git-tree-sha1 = "0d1245a357cc61c8cd61934c07447aa569ff22e6"
uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
version = "1.1.0"

[[Primes]]
git-tree-sha1 = "afccf037da52fa596223e5a0e331ff752e0e845c"
uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae"
version = "0.5.0"

[[Printf]]
deps = ["Unicode"]
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"

[[ProgressMeter]]
deps = ["Distributed", "Printf"]
git-tree-sha1 = "afadeba63d90ff223a6a48d2009434ecee2ec9e8"
uuid = "92933f4c-e287-5a05-a399-4b506db050ca"
version = "1.7.1"

[[Qt5Base_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "xkbcommon_jll"]
git-tree-sha1 = "ad368663a5e20dbb8d6dc2fddeefe4dae0781ae8"
uuid = "ea2cea3b-5b76-57ae-a6ef-0a8af62496e1"
version = "5.15.3+0"

[[QuadGK]]
deps = ["DataStructures", "LinearAlgebra"]
git-tree-sha1 = "12fbe86da16df6679be7521dfb39fbc861e1dc7b"
uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
version = "2.4.1"

[[REPL]]
deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"]
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"

[[Random]]
deps = ["Serialization"]
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

[[RangeArrays]]
git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5"
uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d"
version = "0.3.2"

[[Ratios]]
deps = ["Requires"]
git-tree-sha1 = "7dff99fbc740e2f8228c6878e2aad6d7c2678098"
uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439"
version = "0.4.1"

[[RecipesBase]]
git-tree-sha1 = "44a75aa7a527910ee3d1751d1f0e4148698add9e"
uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
version = "1.1.2"

[[RecipesPipeline]]
deps = ["Dates", "NaNMath", "PlotUtils", "RecipesBase"]
git-tree-sha1 = "e377b29ebe56fadd8b40b04d8eb117c98d0a9960"
uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c"
version = "0.3.6"

[[Reexport]]
git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b"
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
version = "1.2.2"

[[RegularizedLeastSquares]]
deps = ["IterativeSolvers", "LinearAlgebra", "ProgressMeter", "Random", "SparseArrays", "SparsityOperators", "VectorizationBase"]
git-tree-sha1 = "9b09f112dc9ba316c676797af7b9c8dc8ce5c36d"
uuid = "1e9c538a-f78c-5de5-8ffb-0b6dbe892d23"
version = "0.7.2"

[[Requires]]
deps = ["UUIDs"]
git-tree-sha1 = "4036a3bd08ac7e968e27c203d45f5fff15020621"
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
version = "1.1.3"

[[Rmath]]
deps = ["Random", "Rmath_jll"]
git-tree-sha1 = "bf3188feca147ce108c76ad82c2792c57abe7b1f"
uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa"
version = "0.7.0"

[[Rmath_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "68db32dff12bb6127bac73c209881191bf0efbb7"
uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f"
version = "0.3.0+0"

[[Roots]]
deps = ["CommonSolve", "Printf", "Setfield"]
git-tree-sha1 = "8d68de19105123a98091ba713a836ea594c07b95"
uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"
version = "1.3.1"

[[Rotations]]
deps = ["LinearAlgebra", "StaticArrays", "Statistics"]
git-tree-sha1 = "2ed8d8a16d703f900168822d83699b8c3c1a5cd8"
uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc"
version = "1.0.2"

[[SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"

[[Scratch]]
deps = ["Dates"]
git-tree-sha1 = "0b4b7f1393cff97c33891da2a0bf69c6ed241fda"
uuid = "6c6a2e73-6563-6170-7368-637461726353"
version = "1.1.0"

[[SentinelArrays]]
deps = ["Dates", "Random"]
git-tree-sha1 = "54f37736d8934a12a200edea2f9206b03bdf3159"
uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c"
version = "1.3.7"

[[Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"

[[Setfield]]
deps = ["ConstructionBase", "Future", "MacroTools", "Requires"]
git-tree-sha1 = "fca29e68c5062722b5b4435594c3d1ba557072a3"
uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46"
version = "0.7.1"

[[SharedArrays]]
deps = ["Distributed", "Mmap", "Random", "Serialization"]
uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383"

[[Showoff]]
deps = ["Dates", "Grisu"]
git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de"
uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f"
version = "1.0.3"

[[SimpleTraits]]
deps = ["InteractiveUtils", "MacroTools"]
git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231"
uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d"
version = "0.9.4"

[[Sockets]]
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"

[[SortingAlgorithms]]
deps = ["DataStructures"]
git-tree-sha1 = "b3363d7460f7d098ca0912c69b082f75625d7508"
uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c"
version = "1.0.1"

[[SparseArrays]]
deps = ["LinearAlgebra", "Random"]
uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[[SparsityOperators]]
deps = ["CUDA", "FFTW", "LinearAlgebra", "LinearOperators", "Random", "Reexport", "SparseArrays", "Wavelets"]
git-tree-sha1 = "356b37bd54bf22a9a2bbe0ee01a7905ab7456dc2"
uuid = "a5ff1dd3-4e0a-50db-9022-6d011c1d5846"
version = "0.2.3"

[[SpecialFunctions]]
deps = ["ChainRulesCore", "LogExpFunctions", "OpenSpecFun_jll"]
git-tree-sha1 = "a322a9493e49c5f3a10b50df3aedaf1cdb3244b7"
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
version = "1.6.1"

[[StackViews]]
deps = ["OffsetArrays"]
git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c"
uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15"
version = "0.1.1"

[[Static]]
deps = ["IfElse"]
git-tree-sha1 = "2740ea27b66a41f9d213561a04573da5d3823d4b"
uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3"
version = "0.2.5"

[[StaticArrays]]
deps = ["LinearAlgebra", "Random", "Statistics"]
git-tree-sha1 = "3240808c6d463ac46f1c1cd7638375cd22abbccb"
uuid = "90137ffa-7385-5640-81b9-e52037218182"
version = "1.2.12"

[[Statistics]]
deps = ["LinearAlgebra", "SparseArrays"]
uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[[StatsAPI]]
git-tree-sha1 = "1958272568dc176a1d881acb797beb909c785510"
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
version = "1.0.0"

[[StatsBase]]
deps = ["DataAPI", "DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"]
git-tree-sha1 = "fed1ec1e65749c4d96fc20dd13bea72b55457e62"
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
version = "0.33.9"

[[StatsFuns]]
deps = ["IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"]
git-tree-sha1 = "20d1bb720b9b27636280f751746ba4abb465f19d"
uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
version = "0.9.9"

[[StringDistances]]
deps = ["Distances"]
git-tree-sha1 = "a4c05337dfe6c4963253939d2acbdfa5946e8e31"
uuid = "88034a9c-02f8-509d-84a9-84ec65e18404"
version = "0.10.0"

[[StructArrays]]
deps = ["Adapt", "DataAPI", "StaticArrays", "Tables"]
git-tree-sha1 = "1700b86ad59348c0f9f68ddc95117071f947072d"
uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
version = "0.6.1"

[[SuiteSparse]]
deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"]
uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9"

[[TOML]]
deps = ["Dates"]
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"

[[TableTraits]]
deps = ["IteratorInterfaceExtensions"]
git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39"
uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
version = "1.0.1"

[[Tables]]
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "TableTraits", "Test"]
git-tree-sha1 = "d0c690d37c73aeb5ca063056283fde5585a41710"
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
version = "1.5.0"

[[Tar]]
deps = ["ArgTools", "SHA"]
uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"

[[Test]]
deps = ["InteractiveUtils", "Logging", "Random", "Serialization"]
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[[TestImages]]
deps = ["AxisArrays", "ColorTypes", "FileIO", "OffsetArrays", "Pkg", "StringDistances"]
git-tree-sha1 = "db28237376a6b7ae9c9fe05880ece0ab8bb90b75"
uuid = "5e47fb64-e119-507b-a336-dd2b206d9990"
version = "1.6.1"

[[TiledIteration]]
deps = ["OffsetArrays"]
git-tree-sha1 = "52c5f816857bfb3291c7d25420b1f4aca0a74d18"
uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac"
version = "0.3.0"

[[TimeZones]]
deps = ["Dates", "Future", "LazyArtifacts", "Mocking", "Pkg", "Printf", "RecipesBase", "Serialization", "Unicode"]
git-tree-sha1 = "6c9040665b2da00d30143261aea22c7427aada1c"
uuid = "f269a46b-ccf7-5d73-abea-4c690281aa53"
version = "1.5.7"

[[TimerOutputs]]
deps = ["ExprTools", "Printf"]
git-tree-sha1 = "209a8326c4f955e2442c07b56029e88bb48299c7"
uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f"
version = "0.5.12"

[[TranscodingStreams]]
deps = ["Random", "Test"]
git-tree-sha1 = "216b95ea110b5972db65aa90f88d8d89dcb8851c"
uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
version = "0.9.6"

[[UUIDs]]
deps = ["Random", "SHA"]
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"

[[UnPack]]
git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b"
uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed"
version = "1.0.2"

[[Unicode]]
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"

[[Unitful]]
deps = ["ConstructionBase", "Dates", "LinearAlgebra", "Random"]
git-tree-sha1 = "a981a8ef8714cba2fd9780b22fd7a469e7aaf56d"
uuid = "1986cc42-f94f-5a68-af5c-568840ba703d"
version = "1.9.0"

[[VectorizationBase]]
deps = ["ArrayInterface", "Hwloc", "IfElse", "Libdl", "LinearAlgebra", "Static"]
git-tree-sha1 = "dfe4ad3f00e243f97280f08cb82ab4b685f5559b"
uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f"
version = "0.19.39"

[[Wavelets]]
deps = ["DSP", "FFTW", "LinearAlgebra", "Reexport", "SpecialFunctions", "Statistics"]
git-tree-sha1 = "e5903fb2bf93697a79d01383618ea0855256a337"
uuid = "29a6e085-ba6d-5f35-a997-948ac2efa89a"
version = "0.9.3"

[[Wayland_jll]]
deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "3e61f0b86f90dacb0bc0e73a0c5a83f6a8636e23"
uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89"
version = "1.19.0+0"

[[Wayland_protocols_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll"]
git-tree-sha1 = "2839f1c1296940218e35df0bbb220f2a79686670"
uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91"
version = "1.18.0+4"

[[WoodburyMatrices]]
deps = ["LinearAlgebra", "SparseArrays"]
git-tree-sha1 = "59e2ad8fd1591ea019a5259bd012d7aee15f995c"
uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6"
version = "0.5.3"

[[XML2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "1acf5bdf07aa0907e0a37d3718bb88d4b687b74a"
uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a"
version = "2.9.12+0"

[[XSLT_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"]
git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a"
uuid = "aed1982a-8fda-507f-9586-7b0439959a61"
version = "1.1.34+0"

[[Xorg_libX11_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll", "Xorg_xtrans_jll"]
git-tree-sha1 = "5be649d550f3f4b95308bf0183b82e2582876527"
uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc"
version = "1.6.9+4"

[[Xorg_libXau_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4e490d5c960c314f33885790ed410ff3a94ce67e"
uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec"
version = "1.0.9+4"

[[Xorg_libXcursor_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"]
git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd"
uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724"
version = "1.2.0+4"

[[Xorg_libXdmcp_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4fe47bd2247248125c428978740e18a681372dd4"
uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05"
version = "1.1.3+4"

[[Xorg_libXext_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3"
uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3"
version = "1.3.4+4"

[[Xorg_libXfixes_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4"
uuid = "d091e8ba-531a-589c-9de9-94069b037ed8"
version = "5.0.3+4"

[[Xorg_libXi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"]
git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246"
uuid = "a51aa0fd-4e3c-5386-b890-e753decda492"
version = "1.7.10+4"

[[Xorg_libXinerama_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"]
git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123"
uuid = "d1454406-59df-5ea1-beac-c340f2130bc3"
version = "1.1.4+4"

[[Xorg_libXrandr_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"]
git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631"
uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484"
version = "1.5.2+4"

[[Xorg_libXrender_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96"
uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa"
version = "0.9.10+4"

[[Xorg_libpthread_stubs_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "6783737e45d3c59a4a4c4091f5f88cdcf0908cbb"
uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74"
version = "0.1.0+3"

[[Xorg_libxcb_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"]
git-tree-sha1 = "daf17f441228e7a3833846cd048892861cff16d6"
uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b"
version = "1.13.0+3"

[[Xorg_libxkbfile_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "926af861744212db0eb001d9e40b5d16292080b2"
uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a"
version = "1.1.0+4"

[[Xorg_xcb_util_image_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "0fab0a40349ba1cba2c1da699243396ff8e94b97"
uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b"
version = "0.4.0+1"

[[Xorg_xcb_util_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll"]
git-tree-sha1 = "e7fd7b2881fa2eaa72717420894d3938177862d1"
uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5"
version = "0.4.0+1"

[[Xorg_xcb_util_keysyms_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "d1151e2c45a544f32441a567d1690e701ec89b00"
uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7"
version = "0.4.0+1"

[[Xorg_xcb_util_renderutil_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "dfd7a8f38d4613b6a575253b3174dd991ca6183e"
uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e"
version = "0.3.9+1"

[[Xorg_xcb_util_wm_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "e78d10aab01a4a154142c5006ed44fd9e8e31b67"
uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361"
version = "0.4.1+1"

[[Xorg_xkbcomp_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxkbfile_jll"]
git-tree-sha1 = "4bcbf660f6c2e714f87e960a171b119d06ee163b"
uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4"
version = "1.4.2+4"

[[Xorg_xkeyboard_config_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xkbcomp_jll"]
git-tree-sha1 = "5c8424f8a67c3f2209646d4425f3d415fee5931d"
uuid = "33bec58e-1273-512f-9401-5d533626f822"
version = "2.27.0+4"

[[Xorg_xtrans_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "79c31e7844f6ecf779705fbc12146eb190b7d845"
uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10"
version = "1.4.0+3"

[[Zlib_jll]]
deps = ["Libdl"]
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"

[[Zstd_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "cc4bf3fdde8b7e3e9fa0351bdeedba1cf3b7f6e6"
uuid = "3161d3a3-bdf6-5164-811a-617609db77b4"
version = "1.5.0+0"

[[libass_jll]]
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "acc685bcf777b2202a904cdcb49ad34c2fa1880c"
uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0"
version = "0.14.0+4"

[[libfdk_aac_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "7a5780a0d9c6864184b3a2eeeb833a0c871f00ab"
uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280"
version = "0.1.6+4"

[[libpng_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "94d180a6d2b5e55e447e2d27a29ed04fe79eb30c"
uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f"
version = "1.6.38+0"

[[libvorbis_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"]
git-tree-sha1 = "c45f4e40e7aafe9d086379e5578947ec8b95a8fb"
uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a"
version = "1.3.7+0"

[[nghttp2_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"

[[p7zip_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"

[[x264_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "d713c1ce4deac133e3334ee12f4adff07f81778f"
uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a"
version = "2020.7.14+2"

[[x265_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "487da2f8f2f0c8ee0e83f39d13037d6bbf0a45ab"
uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76"
version = "3.0.0+3"

[[xkbcommon_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll", "Wayland_protocols_jll", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"]
git-tree-sha1 = "ece2350174195bb31de1a63bea3a41ae1aa593b6"
uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd"
version = "0.9.1+5"
"""

# ╔═╡ Cell order:
# ╟─3dc2447c-9bac-11eb-2c55-a356da25ed08
# ╠═82da667e-11e6-474f-b388-5325baf83cac
# ╟─b3a4b435-d8a4-4d40-9a18-c294d4d8f942
# ╠═6545ea1c-c5f1-474c-93be-b86a9a85e021
# ╟─5dd4e6c3-eb71-4df6-9f90-bc392384f5f8
# ╠═36917ded-0b60-44e0-be11-784692a96b97
# ╟─fabfcd41-563e-45e1-b657-d36ae57735a9
# ╟─a6a61f0f-f34e-4e64-a40c-84f32d349615
# ╠═ca5764d5-5719-4d7c-bde4-6308ef12a872
# ╟─eeed6fe4-2a6f-477c-ab5f-971dbad7e5ef
# ╠═bce35624-154a-46c4-8f7e-15109d0f473d
# ╟─48cfa5b0-5c86-4afc-be82-6c9017675c8d
# ╠═902b5f9d-5320-4ffa-8e1f-1778fc415c75
# ╟─2ad4d959-a7c0-498f-8101-168718b56768
# ╠═037ff94d-3e90-4596-baed-694263200b1c
# ╟─fd8bd61a-940e-4799-a46e-08e04ccec5b3
# ╟─8572bc03-380b-460e-b3ce-f46d7a6dd86b
# ╟─ea314390-64ee-4597-83d4-941c6e5de64a
# ╟─517bcca3-2e03-459e-b656-7410bc23108e
# ╠═9a644b3e-7195-4389-b666-91722e95fa15
# ╟─da7cefff-fe8c-418d-b161-e59500af1bff
# ╠═b38c0c68-6830-48e3-8c6d-59a02f472fe3
# ╟─fc498516-a743-4b85-8af3-1052a763637a
# ╠═a08fbfdc-d3c0-4e64-8e5b-770893906f5b
# ╟─325f4196-f0aa-4781-bd6e-923025923d0f
# ╟─16447270-a584-4d50-96c1-fd5340542c56
# ╟─0849ef36-003b-4376-a2d9-64b5fa5ba041
# ╠═bcc103eb-ed60-4bf9-986f-92dd8f3db7e1
# ╟─38cb9e6a-0781-4047-a6c3-6da451d82605
# ╟─9c1cff7e-3daa-45a1-87ae-41b268b01826
# ╟─362beeab-1fc0-4386-b92e-a18f7d98ef95
# ╟─64bcdd37-d208-480e-a8ab-f1dbed80b782
# ╠═70edbec3-82ff-4980-aa2a-c7866a739488
# ╠═ad4f7a3d-98e1-408c-a9a6-d35a35f0a905
# ╟─da4073b7-abe9-441b-9af1-425b341a2c06
# ╟─67b4daed-bf84-45ad-b809-c234a477efea
# ╠═8be12329-c063-4008-9e97-0b4ba3b0ec8b
# ╟─5c4414b8-6fd3-4ff5-949c-87450b0ec46f
# ╠═52b7f31e-c9fa-4feb-8490-533accef9f10
# ╠═4d3cf4cb-5f5b-476b-a6b1-a1f93aa96a0e
# ╟─4ffb5972-0c52-4be1-aa7b-9dc94ed7c4bb
# ╟─6f32f17d-4ed2-4929-bc37-04cf06c8994c
# ╟─0ad5d465-841d-4364-81de-c476f281e928
# ╠═02243e99-fb29-40bb-89c7-3ceeed44c0a6
# ╟─1705d7c4-c9bb-41e3-8d15-49fc6fc93e62
# ╠═25bdc400-6681-48e4-97b3-fc614c3ea48c
# ╠═0c1115f6-2524-421c-8be6-492d39eed618
# ╟─e2db427b-2e3f-4ebc-907a-3af082ca5350
# ╟─3e80dbe6-e8e8-4492-b565-5731a62b095f
# ╟─24973fd9-9e62-4769-838c-2a7fa2bdff33
# ╠═6f5ef619-f8da-49cc-92f5-b8de0e72599d
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002


text:
using LinearAlgebraicRepresentation, ViewerGL, SparseArrays
Lar = LinearAlgebraicRepresentation; GL = ViewerGL

wall = Lar.svg2lar("test/svg/assembly/wall.svg", flag=false)
openings = Lar.svg2lar("test/svg/assembly/openings.svg", flag=false)
rectangle = Lar.svg2lar("test/svg/assembly/rectangle.svg", flag=false)
box = Lar.svg2lar("test/svg/assembly/box.svg", flag=false)

assembly = Lar.Struct([wall, openings, rectangle, box])
V,EV = Lar.struct2lar(assembly)
GL.VIEW([ GL.GLGrid(V,EV, GL.COLORS[1],1), GL.GLFrame2 ]);

assembly = Lar.Struct([wall, openings, rectangle])
V,EV = Lar.boolops(assembly, :|)
GL.VIEW([ GL.GLGrid(V,EV, GL.COLORS[1],1), GL.GLFrame2 ]);
V,FVs,EVs = Lar.arrange2D(V,EV)
GL.VIEW(GL.GLExplode(V,FVs,1.,1.,1.,99,1));

assembly = Lar.Struct([wall, openings, rectangle])
V,EV = Lar.boolops(assembly, :-)
diff = Lar.Struct([ (V,EV) ])
GL.VIEW([ GL.GLGrid(V,EV, GL.COLORS[1],1), GL.GLFrame2 ]);
V,FVs,EVs = Lar.arrange2D(V,EV)
GL.VIEW(GL.GLExplode(V,FVs,1.,1.,1.,99,1));

assembly = Lar.Struct([wall, openings, box])
V,EV = Lar.boolops(assembly, :&)
GL.VIEW([ GL.GLGrid(V,EV, GL.COLORS[1],1), GL.GLFrame2 ]);
V,FVs,EVs = Lar.arrange2D(V,EV)
GL.VIEW(GL.GLExplode(V,FVs,1.,1.,1.,99,1));

inner = Lar.Struct([ box,diff ])
V,EV = Lar.boolops( inner, :-)
GL.VIEW([ GL.GLGrid(V,EV, GL.COLORS[1],1), GL.GLFrame2 ]);
V,FVs,EVs = Lar.arrange2D(V,EV)
GL.VIEW(GL.GLExplode(V,FVs,1.,1.,1.,99,1));

W, copEV, copFE, boolmatrix = Lar.bool2d(inner)
FVs = Lar.triangulate2D(W, [copEV, copFE])
V = convert(Lar.Points, W')
GL.VIEW(GL.GLExplode(V,FVs,1.5,1.5,1.5,99,1));


text:
# BioBridgeR.APE
# ==============
#
# A module providing types and methods allowing compatiblity between BioJulia
# types and the classes of the APE package in R. This allows transfer of data
# between R (APE) and Julia (BioJulia) with the RCall.jl package.
#
# This file is a part of the BioJulia ecosystem.
# License is MIT: https://github.com/BioJulia/BioBridgeR.jl/blob/master/LICENSE.md

__precompile__()

module APE

export
    # Types
    DNAbin,
    # Constants
    DNAbin_A,
    DNAbin_C,
    DNAbin_G,
    DNAbin_T,
    DNAbin_M,
    DNAbin_R,
    DNAbin_W,
    DNAbin_S,
    DNAbin_Y,
    DNAbin_K,
    DNAbin_V,
    DNAbin_H,
    DNAbin_D,
    DNAbin_B,
    DNAbin_N,
    DNAbin_Gap

using BioSymbols: DNA, iscertain, isgap
import BioSymbols: BioSymbols, NucleicAcid
using BioSequences: BioSequence, DNASequence, DNAAlphabet
using Twiddle: swapbits
using RCall: RawSxp, RClass, protect, unprotect, isObject, isS4, rcall_p, allocArray, setclass!, unsafe_array
import RCall: rcopy, rcopytype, sexp

include("dnabin.jl")

end # Module BioBridgeR.jl APE


text:
using Hungarian
using Test
using LinearAlgebra
using DelimitedFiles

@testset "simple examples" begin
    A = [ 0.891171  0.0320582   0.564188  0.8999    0.620615;
          0.166402  0.861136    0.201398  0.911772  0.0796335;
          0.77272   0.782759    0.905982  0.800239  0.297333;
          0.561423  0.170607    0.615941  0.960503  0.981906;
          0.748248  0.00799335  0.554215  0.745299  0.42637]

    assign, cost = @inferred hungarian(A)
    @test assign == [2, 3, 5, 1, 4]

    B = [ 24     1     8;
           5     7    14;
           6    13    20;
          12    19    21;
          18    25     2]

    assign, cost = hungarian(B)
    @test assign == [2, 1, 0, 0, 3]
    @test cost == 8

    assign, cost = hungarian(B')
    @test assign == [2, 1, 5]
    @test cost == 8

    assign, cost = hungarian(ones(5,5) - I)
    @test assign == [1, 2, 3, 4, 5]
    @test cost == 0
end

@testset "forbidden edges" begin
    # result checked against Python package munkres: https://github.com/bmc/munkres/blob/master/munkres.py
    # Python code:
    #   m = Munkres()
    #   matrix = [[DISALLOWED, 1, 1], [1, 0, 1], [1, 1, 0]]
    #   m.compute(matrix)
    # Result: [(0, 1), (1, 0), (2, 2)]
    A = Union{Int, Missing}[missing 1 1; 1 0 1; 1 1 0]
    assign, cost = hungarian(A)
    @test assign == [2, 1, 3]
    @test cost == 2
end

@testset "issue #6" begin
    # load the cost matrix produced from the `solve_LSAP` function contained in the
    # [clue package](https://cran.r-project.org/web/packages/clue/index.html) in R.
    costMatrix = readdlm(joinpath(@__DIR__, "R-clue-cost.txt"))
    assignmentH, costH = hungarian(copy(transpose(costMatrix)))
    assignmentR = vec(readdlm(joinpath(@__DIR__, "R-clue-solution.txt"), Int64))
    costR = sum(costMatrix[ii, assignmentR[ii]] for ii in 1:size(costMatrix,1))
    @test costH ≤ costR
end


text:
export coamoeba

"""
    coamoeba(f; alg=Greedy(), options...)

Compute the coamoeba of `f` with the given algorithm `alg` which can be
* `Greedy()`
* `Coarse()`
* `Simple()`
but you probably only want to use `Greedy()` or `Coarse`.

The coamoeba is embedded in ``[0, 2π)^n`` where ``n`` is either 2 or 3 depending
on the polynomial. The algorithm approximate the coamoeba on a grid representing this
embedding.

## Example
```julia
@polyvar x y

# This uses the `Greedy()` algorithm
coamoeba(x^2 + y^2 + 1)
```

## Optional arguments
* `resolution=600`: The resolution of the grid if not passed explicitly.
* `membership_options=[MembershipTestOptions()](@ref)`: The options for the membership test.
* `test_domain`: Tuple `(xmin, xmax, ymin, ymax)` resp. `(xmin, xmax, ymin, ymax, zmin, zmax)`
from which start values for the membership test are drawn if necessary.
"""
function coamoeba(f::MP.AbstractPolynomial; alg::AbstractAlgorithm=Greedy(), kwargs...)
    if MP.nvariables(f) == 2
        fiber = CoamoebaFiber2D(f)
    elseif MP.nvariables(f) == 3
        fiber = CoamoebaFiber3D(f)
    else
        throw(error("Polynomial has $(MP.nvariables(f)) variables. Expected 2 or 3."))
    end
    coamoeba(fiber, f, alg; kwargs...)
end

function coamoeba(F::CoamoebaFiber2D, f::MP.AbstractPolynomial, alg;
    test_domain=default_coamoeba_domain(f),
    resolution=200,
    membership_options=MembershipTestOptions(ntries=20))

    grid = Grid2D((0.0, 2.0π), resolution)
    generator = DomainStartValueGenerator2D(test_domain...)

    _coamoeba(alg, F, f, grid, generator, membership_options)
end

function coamoeba(F::CoamoebaFiber3D, f::MP.AbstractPolynomial, alg;
    test_domain=(-5, 5, -5, 5, -5, 5),
    resolution=21,
    membership_options=MembershipTestOptions(ntries=20))

    grid = Grid3D((0.0, 2.0π), resolution)
    generator = DomainStartValueGenerator3D(test_domain...)

    _coamoeba(alg, F, f, grid, generator, membership_options)
end

function default_coamoeba_domain(f::MP.AbstractPolynomial)
    try
        return amoeba_carcase_domain_heuristic(f, factor=3.0)
    catch err
        return (-5, 5, -5, 5)
        # throw(error("You have to pass an explicit domain."))
    end
end

function _coamoeba(::Coarse, fiber::CoamoebaFiber2D, f, grid, generator, options)
    coamoeba = _coarse_coamoeba(f, grid)
    Coamoeba(coamoeba)
end

function _coamoeba(::Simple, fiber::CoamoebaFiber2D, f, grid, generator, options)
    coarse = Bitmap2D(_coarse_coamoeba(f, grid), grid)
    Coamoeba(simple_grid(fiber, grid, generator, _always_check, coarse, options=options).data)
end

function _coamoeba(::Greedy, fiber::CoamoebaFiber2D, f, grid, generator, options)
    start_values = fill(SVector(NaN, NaN), size(grid)...)
    B = Bitmap2D(_coarse_coamoeba(f, grid), grid)
    initial_queue, queued =initial_neighbour_queue(B.data)

    result = greedy_grid_memorized(fiber, grid, generator, initial_queue, start_values, B, queued)

    Coamoeba{2}(result.data)
end

function _coamoeba(::Simple, fiber, f, grid, generator, options)
    Coamoeba(simple_grid(fiber, grid, generator, options=options).data)
end

function _coamoeba(::Coarse, F::CoamoebaFiber3D, f, grid, gen, options)
    n1, n2, n3 = size(grid)
    coamoeba = falses(n1, n2, n3)
    x, y, z = MP.variables(f)
    for k0 = 1:n3
        f_z0 = MP.subs(f, z => cis(grid.zrange[k0]))
        grid_k0 = Grid2D(grid.xrange, grid.yrange)
        coarse_f_z0 = _coarse_coamoeba(f_z0, grid_k0)

        coamoeba[:,:,k0] .= coarse_f_z0
    end

    for j0 = 1:n2
        f_y0 = MP.subs(f, y => cis(grid.yrange[j0]))
        grid_j0 = Grid2D(grid.xrange, grid.zrange)
        coarse_f_y0 = _coarse_coamoeba(f_y0, grid_j0, @view coamoeba[:,j0,:])

        coamoeba[:,j0,:] .= coarse_f_y0
    end
    for i0 = 1:n1
        f_x0 = MP.subs(f, x => cis(grid.xrange[i0]))
        grid_i0 = Grid2D(grid.yrange, grid.zrange)
        coarse_f_x0 = _coarse_coamoeba(f_x0, grid_i0, @view coamoeba[i0,:,:])

        coamoeba[i0,:,:] .= coarse_f_x0
    end

    Coamoeba(coamoeba)
end

function _coamoeba(::Greedy, fiber::CoamoebaFiber3D, f, grid, generator, options)
    coarse = _coamoeba(Coarse(), fiber, f, grid, generator, options).data
    queued = copy(coarse)
    initial_queue = Int[]
    for k = 1:length(coarse)
        if coarse[k]
            addneighbours!(initial_queue, queued, k)
        end
    end
    bitmap = Bitmap3D(coarse, grid)
    Coamoeba(greedy_grid(fiber, grid, generator, initial_queue, bitmap, queued, options=options).data)
end

function _coarse_coamoeba(f, grid, coamoeba = falses(size(grid)))
    cvs = coefficients_vertices(f, newtonpolygon(f))
    partition = partition_work(length(grid))
    Threads.@threads for tid = 1:Threads.nthreads()
        r = partition[tid]
        for k in r
            if !coamoeba[k]
                coamoeba[k] = winding_number(cvs, grid[k]) != 0
            end
        end
    end
    coamoeba
end

"""
    coefficients_vertices(f, newt::NewtonPolygon)

Return a list of tuples `(c_k/|c_k|, v_k)` where `v_k` is the k-th vertex
of the Newton polygon and `c_k` the corresponding coefficient. The vertices
are in counter-clockwise orientation.
"""
function coefficients_vertices(f, newt::NewtonPolygon)
    map(vertices(newt)) do v
        for t in MP.terms(f)
            if MP.exponents(t) == v
                c = MP.coefficient(t)
                return (c / abs(c), v)
            end
        end
    end
end

const _inv_2π = inv(2π)

function winding_number(cvs, θ)
    # k_1 = length(cvs)
    c, vert = cvs[end]
    @inbounds prev_v = c * cis(muladd(vert[1], θ[1], vert[2] * θ[2]))
    w = 0.0im
    for k = 1:length(cvs)
        c, vert = cvs[k]
        @inbounds v = c * cis(muladd(vert[1], θ[1], vert[2] * θ[2]))
        w -= log(prev_v / v)
        prev_v = v
    end
    w *= _inv_2π
    round(Int, w.im)
end

function Base.show(io::IO, A::Coamoeba{2})
    n, m = size(A.data)
    println(io, "Coamoeba of size ", n, "×", m)
end
function Base.show(io::IO, A::Coamoeba{3})
    n1, n2, n3 = size(A.data)
    println(io, "Coamoeba of size ", n1, "×", n2, "×", n3)
end

function Base.show(io::IO, mime::MIME"text/html", A::Coamoeba)
    if inIJulia() && plotsdefined()
        show(io, mime, Main.Plots.plot(A))
    else
        show(io, A)
    end
end

@recipe function plot(M::Coamoeba{2})
    data = [ M.data M.data
             M.data M.data]
    G = Grid2D(-2π, 2π, -2π, 2π, size(data, 1), size(data, 2))
    @series begin
        xticks := ([-2π,-π, 0, π, 2π], ["-2\\pi", "-\\pi", "0", "\\pi", "2\\pi"])
        yticks := ([-2π,-π, 0, π, 2π], ["-2\\pi", "-\\pi", "0", "\\pi", "2\\pi"])
        Bitmap2D(data, G)
    end
end

@recipe function plot(M::Coamoeba{3})
    grid = Grid3D(xlims=(0,2π), ylims=(0,2π), zlims=(0,2π), res=size(M.data))
    @series begin
        xticks := ([-2π,-π, 0, π, 2π], ["-2\\pi", "-\\pi", "0", "\\pi", "2\\pi"])
        yticks := ([-2π,-π, 0, π, 2π], ["-2\\pi", "-\\pi", "0", "\\pi", "2\\pi"])
        zticks := ([-2π,-π, 0, π, 2π], ["-2\\pi", "-\\pi", "0", "\\pi", "2\\pi"])
        Bitmap3D(M.data, grid)
    end
end


text:
@testset "Reproducing Coles Results" begin
    @testset "Port Pirie example from Coles (2001)" begin

        data = Extremes.dataset("portpirie")

        # Fit of the GEV distribution by maximum likelihood
        fm = gevfit(data, :SeaLevel)

        # Parameter estimates
        θ̂ = fm.θ̂

        # Approximate variance-covariance matrix of the parameter estimates
        V̂ = Extremes.parametervar(fm)

        # correction factor for using ϕ instead of σ (computation using the delta method)
        c = [
            1.0 exp(θ̂[2]) 1.0
            exp(θ̂[2]) exp(2 * θ̂[2]) exp(θ̂[2])
            1.0 exp(θ̂[2]) 1.0
        ]

        # 10-year return level
        R₁₀ = returnlevel(fm, 10)
        R₁₀_cint = cint(R₁₀, 0.95)
        # 100-year return level
        R₁₀₀ = returnlevel(fm, 100)
        R₁₀₀_cint = cint(R₁₀₀, 0.95)

        # Parameter estimates in Coles
        θ = [3.87; log(0.198); -0.050]

        # Approximate variance-covariance matrix of the parameter estimates in Coles
        V = [
            0.000780 0.000197 -.00107
            0.000197 0.000410 -.000778
            -.00107 -.000778 0.00965
        ]

        @test θ̂ ≈ θ rtol = 0.1
        @test c .* V̂ ≈ V rtol = 0.1
        @test Extremes.loglike(fm.model, θ̂) ≈ 4.34 rtol = 0.1

        confint = cint(fm)
        @test confint[1] ≈ [3.82; 3.93] atol = .02
        @test confint[2] ≈ log.([0.158,0.238]) atol = .05
        @test confint[3] ≈ [-0.242; 0.142] atol = .02

        @test R₁₀.value[] ≈ 4.30 rtol = 0.1
        @test R₁₀_cint[] ≈ [4.19; 4.45] rtol = 0.1
        @test R₁₀₀.value[] ≈ 4.69 rtol = 0.1
        @test R₁₀₀_cint[] ≈ [4.5; 5.27] rtol = 0.1

    end

    @testset "Fremantle example from Coles (2001)" begin

        df = Extremes.dataset("fremantle")

        n = length(df[:, :SeaLevel])

        t = collect(1:n)

        fm = gevfit(df[:, :SeaLevel], locationcov = [Variable("t", t)])

        # Parameter estimates
        θ̂ = fm.θ̂

        # Variance of the parameter estimates
        V̂ = diag(Extremes.parametervar(fm))

        # Computing the variance of σ instead of ϕ with the delta method
        V̂[3] = exp(2 * θ̂[3]) * V̂[3]

        # Computing the standard errors of the parameters estimates
        Ŝ = sqrt.(V̂)

        # Values given in Coles (2001, Chap 6) for the temporal linear trend in μ
        θ = [1.38; 0.00203; log(0.124); -.125]
        S = [0.03; 0.00052; 0.010; 0.070]

        @test θ̂ ≈ θ rtol = 0.1
        @test Ŝ ≈ S rtol = 0.1
        @test Extremes.loglike(fm.model, θ̂) ≈ 49.9 rtol = 0.1

        evt = Variable("t", t)
        evt² = Variable("t²", t .^ 2)
        evSOI = Variable("SOI", df[:, :SOI])

        # Quadratic trend in μ
        fm = gevfit(df[:, :SeaLevel], locationcov = [evt, evt²])
        @test Extremes.loglike(fm.model, fm.θ̂) ≈ 50.6 rtol = 0.1

        # Linear trend in both μ and ϕ
        fm = gevfit(df[:, :SeaLevel], locationcov = [evt], logscalecov = [evt])
        @test Extremes.loglike(fm.model, fm.θ̂) ≈ 50.7 rtol = 0.1

        # μ as a function of the SOI
        fm = gevfit(df, :SeaLevel, locationcovid = [:SOI])
        @test Extremes.loglike(fm.model, fm.θ̂) ≈ 47.2 rtol = 0.1

        # Linear trend in μ as function of the time and the SOI
        fm = gevfit(df[:, :SeaLevel], locationcov = [evt, evSOI])
        @test Extremes.loglike(fm.model, fm.θ̂) ≈ 53.9 rtol = 0.1
        @test fm.θ̂[3] ≈ 0.055 rtol = 0.1

    end

    @testset "Rainfall example from Coles (2001)" begin
        df = Extremes.dataset("rain")

        threshold = 30

        data = filter(row -> row.Rainfall > threshold, df)

        y = data[:, :Rainfall] .- threshold

        fm = gpfit(y)

        θ̂ = fm.θ̂

        # Approximate variance-covariance matrix of the parameter estimates
        V̂ = Extremes.parametervar(fm)

        # correction factor for using ϕ instead of σ (computation using the delta method)
        c = [
            exp(2*θ̂[1]) exp(θ̂[1])
            exp(θ̂[1]) 1.0
        ]

        V̂ = c.*V̂
        V = [.9188 -.0655 ;
            -.0655 .0102]

        @test fm.θ̂ ≈ [log(7.44); 0.184] rtol = 0.1
        @test Extremes.loglike(fm.model, fm.θ̂) ≈ -485.1 rtol = 0.1
        @test V̂ ≈ V rtol = 0.1

        r = returnlevel(fm, threshold, size(df,1), 365, 100)

        @test r.value[] ≈ 106.3 rtol = .1

    end

    @testset "Dow Jones example from Coles (2001), Section 4.4.2" begin
        df = Extremes.dataset("dowjones")

        X = df[:,:Index]

        X̃ = 100*[ log(X[i+1]) - log(X[i])  for i in 1:(length(X)-1)]

        n = length(X̃)

        threshold = 2.0

        z = X̃[X̃ .> threshold] .- threshold

        fm = gpfit(z)

        θ̂ = fm.θ̂

        # Approximate variance-covariance matrix of the parameter estimates
        V̂ = Extremes.parametervar(fm)

        # correction factor for using ϕ instead of σ (computation using the delta method)
        c = [
            exp(2*θ̂[1]) exp(θ̂[1])
            exp(θ̂[1]) 1.0
        ]

        V̂ = c.*V̂

        # Test the Generalized Pareto estimates
        @test exp(fm.θ̂[1]) ≈ .495 rtol = 0.1
        @test fm.θ̂[2] ≈ .288 rtol = 0.1

        # Test the standard errors of estimates
        @test sqrt(V̂[1,1]) ≈ .150 rtol = 0.1
        @test sqrt(V̂[2,2]) ≈ .258 rtol = 0.1

    end
end


text:
export PopRates, PopState, FitVector
export initialize_pop, random_wright_sample, mean_fit

## difinition of the fitness structure

struct FitVector # Custom sparse array type for fitness vector stuff
    β0::Float64
    sind::Array{Int64,1} # sites under selection
    nind::Array{Int64,1} # neutral sites
    svals::Array{Float64,1} # Δ fitness if mutant
    βwt::Float64 # β0 + sum(β1), the wildtype fitness (zero bitvector)
    βmax::Float64 # β0 + sum(abs.(β1)) the maximum fitness
end

function FitVector(β0::Float64, β1::Array)
    # vector of fitness differences between wildtype and mutant
    FitVector(
        β0,
        findall(!iszero, β1),
        findall(iszero, β1),
        -β1[findall(!iszero, β1)],
        β0 + sum(β1)/2,
        β0 + sum(abs.(β1))/2
    )
end

function fitness(f::FitVector, x::BitArray)
    s = 0
    for (ii,val) in zip(f.sind,f.svals)
        if x[ii]
            s += val
        end
    end
    return s + f.βwt
end

# the fitness vector is stored in cachey sparsy form.
# unfortunately we may want to access it in a more conventional way
function β1_vector(f::FitVector)
    # vector of fitness differences f(wildtype) - f(mutant)
    a = zeros(Float64, maximum([maximum([0; f.sind]),maximum([0; f.nind])]))
    for (ii,val) in zip(f.sind,f.svals)
        a[ii] = -val
    end
    return(a)
end

mutable struct PopState{T}        # parameters defining a population state
    individuals::Vector{BitArray{1}}
    fitness::Vector{T}         # tendency toward excess birth
    offset::T # which fitness is currently the breakeven point
    size::Int
    time::T
end

# Parameters defining the simulaiton dynamics
struct PopRates        # parameters defining a population
    loci::Int64        #    = 2^8        number of loci on the genome
    κ::Float64         #    = 1000.        avg pop size
    λ::Float64        #    = 4 (population birth rate per individual (inverse generation time))
    ν::Float64         #    = 1.0e-3    mutation rate per site (per generation)
    χ::Float64        #    = 0.0        outcrossing rate (between 0 and one), rate of recombination events
    ρ::Float64         #    = 1.0e-2    how tightly two crossed genomes get wound together (# of crosses per nucleotide)
    β0::Float64     #    = 1.0        base (competetive) fitness
    βf::FitVector    #    = FitVector(β0,zeros(loci)) encodes fitness function efficiently
    f::Function     #    = (x->fitness(βf,x))    # mapping from genotype to fitness (increased birth + competion)
    # if you want epistasis, you can code it in by hand using this function.
    function PopRates(loci,κ,λ,ν,χ,ρ,β0,β1)
        # we make βf and f only accessible through inner constructors
        # this enforces their correctness
        if length(β1) == loci
            βf = FitVector(β0,β1)
            f = (x->fitness(βf,x))
            return new(loci,κ,λ,ν,χ,ρ,β0,βf,f)
        else
            error("Selection coefficients wrong length")
        end
    end
end

# default constructor method
function PopRates(;
    loci = 2^8, κ = 1000, λ = 4, ν = 1.0e-3, χ = 0.0, ρ = 1.0e-2, β0 = 1.0,
    β1 = zeros(loci))
    PopRates(loci,κ,λ,ν,χ,ρ,β0,β1)
end

# updating method, pass an old PopRates, and some keywords for parameter changes
function PopRates(par::PopRates;
    loci = par.loci, κ = par.κ, λ = par.λ, ν = par.ν, χ = par.χ, ρ = par.ρ, β0 = par.β0,
    β1 = β1_vector(par.βf))
    PopRates(loci,κ,λ,ν,χ,ρ,β0,β1)
end

function mean_fit(par::PopRates)
    par.β0 + mean( β1_vector(par.βf)' *(1 .- 2 .* wright_sample(par)) for ii in 1:100)/2
end

## Equilibrium Sampling
# We assume that the population is very near the maximum

function pop_ne(par::PopRates)
    par.κ/par.λ
end

function pop_θ(par::PopRates)
    2*pop_ne(par)*(par.ν*par.λ)/2
end

"""
Sample from Wright equilibrium
"""
function random_wright_sample(θ_wt, θ_mut, σ)
    k = rejection_sample_k(θ_wt, θ_mut, σ)
    rand(Beta(θ_wt + k, θ_mut)) # frequency
end

function wright_sample(par::PopRates)
    freq = zeros(par.loci)
    θ_ref = pop_θ(par)
    ne = pop_ne(par)
    # set the selected frequencies
    for (ii, val) in zip(par.βf.sind, par.βf.svals)
        if val < 0 # if mutant has a disadvantage
            freq[ii] = 1 -random_wright_sample(θ_ref, θ_ref, 2*ne*abs(val))
        else # if the mutant has an advantage
            freq[ii] = random_wright_sample(θ_ref, θ_ref, 2*ne*abs(val))
        end
    end
    for ii in par.βf.nind # for the neutral indices, sample with σ = 0
        freq[ii] = random_wright_sample(θ_ref, θ_ref, 0)
    end
    return freq
end

"""
Generate individuals with site entries equal to 1 according to binomial
frequencies
"""
function initialize_pop(frequencies::Vector, pop_size::Int, par::PopRates; time = 0.0)
    genomes = mapreduce(p->rand(Bernoulli(p), pop_size),hcat,frequencies)
    individuals = [BitArray(genomes[ii,:]) for ii in 1:pop_size]
    fitness = par.f.(individuals)
    offset = sum(fitness)/par.κ
    pop = PopState(
        individuals,
        fitness,
        offset,
        pop_size,
        time
        )
end

# asumption of neutrality
function initialize_pop(par::PopRates; pop_size = ceil(Int, par.κ))
    initialize_pop(wright_sample(par), pop_size, par) # draw each site from Wright eq distribution
end

# simpler specification for constant frequencies
# useful for indicating pure wildtype
function initialize_pop(freq::Real, par::PopRates; pop_size = ceil(Int, par.κ))
initialize_pop([freq for ii in 1:par.loci], pop_size, par)
end

"""
Recalculate the caches
"""
function renew_fitness(pop::PopState, par::PopRates)
    pop.fitness = par.f.(pop.individuals)
    pop.offset = sum(pop.fitness)/par.κ
    pop.size = length(pop.individuals)
end

max_stars_repo_name: StatPhysBio/Tomoko

max_issues_repo_name: StatPhysBio/Tomoko

max_forks_repo_name: StatPhysBio/Tomoko


text:
# This file is a part of ParallelProcessingTools.jl, licensed under the MIT License (MIT).

__precompile__(true)

module ParallelProcessingTools

using Base.Threads
using Distributed

include("threadsafe.jl")
include("threadlocal.jl")
include("onthreads.jl")
include("onprocs.jl")
include("workpartition.jl")

end # module


text:
@testset "Composition" begin
    function string_nucleotide_count(::Type{DNA}, seq::AbstractString)
        counts = Dict{DNA, Int}(
            DNA_A => 0,
            DNA_C => 0,
            DNA_G => 0,
            DNA_T => 0,
            DNA_N => 0 )
        for c in seq
            counts[convert(DNA, c)] += 1
        end
        return counts
    end

    function string_nucleotide_count(::Type{RNA}, seq::AbstractString)
        counts = Dict{RNA, Int}(
            RNA_A => 0,
            RNA_C => 0,
            RNA_G => 0,
            RNA_U => 0,
            RNA_N => 0 )
        for c in seq
            counts[convert(RNA, c)] += 1
        end
        return counts
    end

    function check_nucleotide_count(::Type{DNA}, seq::AbstractString)
        string_counts = string_nucleotide_count(DNA, seq)
        seq_counts = composition(DNASequence(seq))
        return string_counts[DNA_A] == seq_counts[DNA_A] &&
               string_counts[DNA_C] == seq_counts[DNA_C] &&
               string_counts[DNA_G] == seq_counts[DNA_G] &&
               string_counts[DNA_T] == seq_counts[DNA_T] &&
               string_counts[DNA_N] == seq_counts[DNA_N]
    end

    function check_nucleotide_count(::Type{RNA}, seq::AbstractString)
        string_counts = string_nucleotide_count(RNA, seq)
        seq_counts = composition(RNASequence(seq))
        return string_counts[RNA_A] == seq_counts[RNA_A] &&
               string_counts[RNA_C] == seq_counts[RNA_C] &&
               string_counts[RNA_G] == seq_counts[RNA_G] &&
               string_counts[RNA_U] == seq_counts[RNA_U] &&
               string_counts[RNA_N] == seq_counts[RNA_N]
    end

    function check_kmer_nucleotide_count(::Type{DNA}, seq::AbstractString)
        string_counts = string_nucleotide_count(DNA, seq)
        kmer_counts = composition(DNAKmer(seq))
        return string_counts[DNA_A] == kmer_counts[DNA_A] &&
               string_counts[DNA_C] == kmer_counts[DNA_C] &&
               string_counts[DNA_G] == kmer_counts[DNA_G] &&
               string_counts[DNA_T] == kmer_counts[DNA_T] &&
               string_counts[DNA_N] == kmer_counts[DNA_N]
    end

    function check_kmer_nucleotide_count(::Type{RNA}, seq::AbstractString)
        string_counts = string_nucleotide_count(RNA, seq)
        kmer_counts = composition(RNAKmer(seq))
        return string_counts[RNA_A] == kmer_counts[RNA_A] &&
               string_counts[RNA_C] == kmer_counts[RNA_C] &&
               string_counts[RNA_G] == kmer_counts[RNA_G] &&
               string_counts[RNA_U] == kmer_counts[RNA_U] &&
               string_counts[RNA_N] == kmer_counts[RNA_N]
    end

    global reps = 10
    for len in [1, 10, 32, 1000, 10000, 100000]
        @test all(Bool[check_nucleotide_count(DNA, random_dna(len)) for _ in 1:reps])
        @test all(Bool[check_nucleotide_count(RNA, random_rna(len)) for _ in 1:reps])
    end

    @test composition(aa"MTTQAPMFTQPLQSVVV")[AA_E] === 0
    @test composition(aa"MTTQAPMFTQPLQSVVV")[AA_A] === 1
    @test composition(aa"MTTQAPMFTQPLQSVVV")[AA_P] === 2
    @test composition(aa"MTTQAPMFTQPLQSVVV")[AA_V] === 3

    let comp = composition(ReferenceSequence(dna"AGTTATGN"))
        @test comp[DNA_A] === 2
        @test comp[DNA_C] === 0
        @test comp[DNA_G] === 2
        @test comp[DNA_T] === 3
        @test comp[DNA_N] === 1
    end

    for len in [1, 10, 32]
        @test all(Bool[check_kmer_nucleotide_count(DNA, random_dna_kmer(len)) for _ in 1:reps])
        @test all(Bool[check_kmer_nucleotide_count(RNA, random_rna_kmer(len)) for _ in 1:reps])
    end

    comp = composition(dna"ACGT")
    @test merge!(comp, composition(dna"ACGT")) === comp
    @test comp == composition(dna"ACGT"^2)

    for _ in 1:30
        m, n = rand(0:1000), rand(0:1000)
        seq1 = DNASequence(random_dna(m))
        seq2 = DNASequence(random_dna(n))
        @test composition(seq1 * seq2) == merge(composition(seq1), composition(seq2))
    end

    comp = composition(each(DNAKmer{2}, dna"ACGTACGT"))
    @test comp[DNAKmer("AC")] == 2
    @test comp[DNAKmer("CG")] == 2
    @test comp[DNAKmer("GT")] == 2
    @test comp[DNAKmer("TA")] == 1
    @test comp[DNAKmer("AA")] == 0

    comp = composition(each(DNAKmer{3}, dna"ACGTACGT"))
    @test comp[DNAKmer("ACG")] == 2
    @test comp[DNAKmer("CGT")] == 2
    @test comp[DNAKmer("GTA")] == 1
    @test comp[DNAKmer("TAC")] == 1
    @test comp[DNAKmer("AAA")] == 0

    comp = composition(DNASequence[dna"ATCG", dna"GCTA", dna"ATCGG",
                                   dna"ATCG", dna"ATCG", dna"GCTA"])
    @test comp[dna"ATCG"] == 3
    @test comp[dna"GCTA"] == 2
    @test comp[dna"ATCGG"] == 1
end