From ff19216e08deae936b99f06e2ef2bd52f2705cd4 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Mon, 22 Sep 2025 15:51:10 -0400 Subject: [PATCH 01/12] Add ShroffCelegansModelsCore --- ShroffCelegansModelsCore/Manifest.toml | 803 ++++++++++++++++++ ShroffCelegansModelsCore/Project.toml | 28 + ShroffCelegansModelsCore/src/MIPAVIO.jl | 116 +++ .../src/ParametricSplines.jl | 67 ++ .../src/ShroffCelegansModelsCore.jl | 43 + .../src/annotation_untwist.jl | 307 +++++++ ShroffCelegansModelsCore/src/area.jl | 33 + ShroffCelegansModelsCore/src/average.jl | 120 +++ ShroffCelegansModelsCore/src/build_model.jl | 86 ++ ShroffCelegansModelsCore/src/datasets.jl | 104 +++ ShroffCelegansModelsCore/src/mesh.jl | 76 ++ .../src/model_time_series.jl | 131 +++ .../src/parse_worm_dataset_path.jl | 197 +++++ ShroffCelegansModelsCore/src/points.jl | 34 + ShroffCelegansModelsCore/src/precompile.jl | 13 + ShroffCelegansModelsCore/src/show.jl | 6 + ShroffCelegansModelsCore/src/straighten.jl | 20 + ShroffCelegansModelsCore/src/types.jl | 138 +++ ShroffCelegansModelsCore/src/util.jl | 14 + 19 files changed, 2336 insertions(+) create mode 100644 ShroffCelegansModelsCore/Manifest.toml create mode 100644 ShroffCelegansModelsCore/Project.toml create mode 100644 ShroffCelegansModelsCore/src/MIPAVIO.jl create mode 100644 ShroffCelegansModelsCore/src/ParametricSplines.jl create mode 100644 ShroffCelegansModelsCore/src/ShroffCelegansModelsCore.jl create mode 100644 ShroffCelegansModelsCore/src/annotation_untwist.jl create mode 100644 ShroffCelegansModelsCore/src/area.jl create mode 100644 ShroffCelegansModelsCore/src/average.jl create mode 100644 ShroffCelegansModelsCore/src/build_model.jl create mode 100644 ShroffCelegansModelsCore/src/datasets.jl create mode 100644 ShroffCelegansModelsCore/src/mesh.jl create mode 100644 ShroffCelegansModelsCore/src/model_time_series.jl create mode 100644 ShroffCelegansModelsCore/src/parse_worm_dataset_path.jl create mode 100644 ShroffCelegansModelsCore/src/points.jl create mode 100644 ShroffCelegansModelsCore/src/precompile.jl create mode 100644 ShroffCelegansModelsCore/src/show.jl create mode 100644 ShroffCelegansModelsCore/src/straighten.jl create mode 100644 ShroffCelegansModelsCore/src/types.jl create mode 100644 ShroffCelegansModelsCore/src/util.jl diff --git a/ShroffCelegansModelsCore/Manifest.toml b/ShroffCelegansModelsCore/Manifest.toml new file mode 100644 index 0000000..490f219 --- /dev/null +++ b/ShroffCelegansModelsCore/Manifest.toml @@ -0,0 +1,803 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.11.6" +manifest_format = "2.0" +project_hash = "6029b9298ef3020013709acd1209c5d1ebfc295c" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + + [deps.AbstractFFTs.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.AliasTables]] +deps = ["PtrArrays", "Random"] +git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" +uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" +version = "1.1.3" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.2" + +[[deps.ArrayLayouts]] +deps = ["FillArrays", "LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "120e392af69350960b1d3b89d41dcc1d66543858" +uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" +version = "1.11.2" +weakdeps = ["SparseArrays"] + + [deps.ArrayLayouts.extensions] + ArrayLayoutsSparseArraysExt = "SparseArrays" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" + +[[deps.BSplineKit]] +deps = ["ArrayLayouts", "BandedMatrices", "FastGaussQuadrature", "ForwardDiff", "LinearAlgebra", "PrecompileTools", "Random", "Reexport", "SparseArrays", "Static", "StaticArrays", "StaticArraysCore", "StatsAPI"] +git-tree-sha1 = "48b9300555c54256c12a539a3025f8d2075bea6a" +uuid = "093aae92-e908-43d7-9660-e50ee39d5a0a" +version = "0.19.1" + +[[deps.BandedMatrices]] +deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra", "PrecompileTools"] +git-tree-sha1 = "e35c672b239c5105f597963c33e740eeb46cf0ab" +uuid = "aae01518-5342-5314-be14-df237901396f" +version = "1.9.4" + + [deps.BandedMatrices.extensions] + BandedMatricesSparseArraysExt = "SparseArrays" + CliqueTreesExt = "CliqueTrees" + + [deps.BandedMatrices.weakdeps] + CliqueTrees = "60701a23-6482-424a-84db-faee86b9b1f8" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" + +[[deps.CSV]] +deps = ["CodecZlib", "Dates", "FilePathsBase", "InlineStrings", "Mmap", "Parsers", "PooledArrays", "PrecompileTools", "SentinelArrays", "Tables", "Unicode", "WeakRefStrings", "WorkerUtilities"] +git-tree-sha1 = "deddd8725e5e1cc49ee205a1964256043720a6c3" +uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" +version = "0.10.15" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.8" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools"] +git-tree-sha1 = "cda2cfaebb4be89c9084adaca7dd7333369715c5" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.1" + +[[deps.CommonWorldInvalidations]] +git-tree-sha1 = "ae52d1c52048455e85a387fbee9be553ec2b68d0" +uuid = "f70d9fcc-98c5-4d4a-abd7-e4cdeebd8ca8" +version = "1.0.0" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "0037835448781bb46feb39866934e243886d756a" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.18.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.1.1+0" + +[[deps.Crayons]] +git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "4.1.1" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataFrames]] +deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "c967271c27a95160e30432e011b58f42cd7501b5" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "1.8.0" + +[[deps.DataStructures]] +deps = ["OrderedCollections"] +git-tree-sha1 = "6c72198e6a101cccdd4c9731d3985e904ba26037" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.19.1" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.DocStringExtensions]] +git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.5" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.EarCut_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" +uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" +version = "2.2.4+0" + +[[deps.Extents]] +git-tree-sha1 = "b309b36a9e02fe7be71270dd8c0fd873625332b4" +uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" +version = "0.1.6" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "Libdl", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "97f08406df914023af55ade2f843c39e99c5d969" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.10.0" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6d6219a004b8cf1e0b4dbe27a2860b8e04eba0be" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.11+0" + +[[deps.FastGaussQuadrature]] +deps = ["LinearAlgebra", "SpecialFunctions", "StaticArrays"] +git-tree-sha1 = "fd923962364b645f3719855c88f7074413a6ad92" +uuid = "442a2c76-b920-505d-bb47-c5924d526838" +version = "1.0.2" + +[[deps.FilePathsBase]] +deps = ["Compat", "Dates"] +git-tree-sha1 = "3bab2c5aa25e7840a4b065805c0cdfc01f3068d2" +uuid = "48062228-2e41-5def-b9a4-89aafe57970f" +version = "0.9.24" + + [deps.FilePathsBase.extensions] + FilePathsBaseMmapExt = "Mmap" + FilePathsBaseTestExt = "Test" + + [deps.FilePathsBase.weakdeps] + Mmap = "a63ad114-7e13-5084-954f-fe012c677804" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "173e4d8f14230a7523ae11b9a3fa9edb3e0efd78" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.14.0" + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + + [deps.FillArrays.weakdeps] + PDMats = "90014a1f-27ba-587c-ab20-58faa44d9150" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "dc41303865a16274ecb8450c220021ce1e0cf05f" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "1.2.1" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" +version = "1.11.0" + +[[deps.GeometryBasics]] +deps = ["EarCut_jll", "Extents", "IterTools", "LinearAlgebra", "PrecompileTools", "Random", "StaticArrays"] +git-tree-sha1 = "1f5a80f4ed9f5a4aada88fc2db456e637676414b" +uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" +version = "0.5.10" + + [deps.GeometryBasics.extensions] + GeometryBasicsGeoInterfaceExt = "GeoInterface" + + [deps.GeometryBasics.weakdeps] + GeoInterface = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" + +[[deps.HDF5]] +deps = ["Compat", "HDF5_jll", "Libdl", "MPIPreferences", "Mmap", "Preferences", "Printf", "Random", "Requires", "UUIDs"] +git-tree-sha1 = "e856eef26cf5bf2b0f95f8f4fc37553c72c8641c" +uuid = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" +version = "0.17.2" + + [deps.HDF5.extensions] + MPIExt = "MPI" + + [deps.HDF5.weakdeps] + MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" + +[[deps.HDF5_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] +git-tree-sha1 = "e94f84da9af7ce9c6be049e9067e511e17ff89ec" +uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" +version = "1.14.6+0" + +[[deps.Hwloc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "XML2_jll", "Xorg_libpciaccess_jll"] +git-tree-sha1 = "3d468106a05408f9f7b6f161d9e7715159af247b" +uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" +version = "2.12.2+0" + +[[deps.IfElse]] +git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" +uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" +version = "0.1.1" + +[[deps.InlineStrings]] +git-tree-sha1 = "8f3d257792a522b4601c24a577954b0a8cd7334d" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.5" + + [deps.InlineStrings.extensions] + ArrowTypesExt = "ArrowTypes" + ParsersExt = "Parsers" + + [deps.InlineStrings.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "ec1debd61c300961f98064cfb21287613ad7f303" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2025.2.0+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" + +[[deps.InvertedIndices]] +git-tree-sha1 = "6da3c4316095de0f5ee2ebd875df8721e7e0bdbe" +uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" +version = "1.3.1" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "e2222959fbc6c19554dc15174c81bf7bf3aa691c" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.4" + +[[deps.IterTools]] +git-tree-sha1 = "42d5f897009e7ff2cf88db414a389e5ed1bdd023" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.10.0" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.1" + +[[deps.JSON3]] +deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] +git-tree-sha1 = "411eccfe8aba0814ffa0fdf4860913ed09c34975" +uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" +version = "1.14.3" + + [deps.JSON3.extensions] + JSON3ArrowExt = ["ArrowTypes"] + + [deps.JSON3.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + +[[deps.LRUCache]] +git-tree-sha1 = "5519b95a490ff5fe629c4a7aa3b3dfc9160498b3" +uuid = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637" +version = "1.6.2" +weakdeps = ["Serialization"] + + [deps.LRUCache.extensions] + SerializationExt = ["Serialization"] + +[[deps.LaTeXStrings]] +git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.4.0" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" +version = "1.11.0" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.6.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.7.2+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.18.0+0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +version = "1.11.0" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.29" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] +git-tree-sha1 = "282cadc186e7b2ae0eeadbd7a4dffed4196ae2aa" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2025.2.0+0" + +[[deps.MPICH_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "d72d0ecc3f76998aac04e446547259b9ae4c265f" +uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" +version = "4.3.1+0" + +[[deps.MPIPreferences]] +deps = ["Libdl", "Preferences"] +git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" +uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +version = "0.1.11" + +[[deps.MPItrampoline_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "e214f2a20bdd64c04cd3e4ff62d3c9be7e969a59" +uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" +version = "5.5.4+0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.6+0" + +[[deps.MicrosoftMPI_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "bc95bf4149bf535c09602e3acdf950d9b4376227" +uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" +version = "10.1.4+3" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" +version = "1.11.0" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.12.12" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.1.3" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.27+1" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.5+0" + +[[deps.OpenMPI_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] +git-tree-sha1 = "ec764453819f802fc1e144bfe750c454181bd66d" +uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" +version = "5.0.8+0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "2ae7d4ddec2e13ad3bddf5c0796f7547cf682391" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.2+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.6+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.8.1" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.3" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.11.0" +weakdeps = ["REPL"] + + [deps.Pkg.extensions] + REPLExt = "REPL" + +[[deps.PooledArrays]] +deps = ["DataAPI", "Future"] +git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" +uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" +version = "1.4.3" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.1" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.5.0" + +[[deps.PrettyTables]] +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "REPL", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "60f23271568238b236899d00fc290e43d1f2658f" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "3.0.10" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" + +[[deps.PtrArrays]] +git-tree-sha1 = "1d36ef11a9aaf1e8b74dacc6a731dd1de8fd493d" +uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" +version = "1.3.0" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9da16da70037ba9d701192e27befedefb91ec284" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.11.2" + + [deps.QuadGK.extensions] + QuadGKEnzymeExt = "Enzyme" + + [deps.QuadGK.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets", "StyledStrings", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" +version = "1.11.0" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "712fb0231ee6f9120e005ccd56297abbc053e7e0" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.8" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +version = "1.11.0" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.2" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.11.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "41852b8679f78c8d8961eeadc8f62cef861a52e3" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.5.1" + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + + [deps.SpecialFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + +[[deps.Static]] +deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools"] +git-tree-sha1 = "f737d444cb0ad07e61b3c1bef8eb91203c321eff" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "1.2.0" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "b8693004b385c842357406e3af647701fe783f98" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.15" + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + + [deps.StaticArrays.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.3" + +[[deps.Statistics]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.11.1" +weakdeps = ["SparseArrays"] + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.1" + +[[deps.StatsBase]] +deps = ["AliasTables", "DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "2c962245732371acd51700dbb268af311bddd719" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.6" + +[[deps.StringManipulation]] +deps = ["PrecompileTools"] +git-tree-sha1 = "725421ae8e530ec29bcbdddbe91ff8053421d023" +uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" +version = "0.4.1" + +[[deps.StructTypes]] +deps = ["Dates", "UUIDs"] +git-tree-sha1 = "159331b30e94d7b11379037feeb9b690950cace8" +uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" +version = "1.11.0" + +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.0" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.7.0+0" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "f2c1efbc8f3a609aadf318094f8fc5204bdaf344" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.12.1" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.11.3" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" + +[[deps.WeakRefStrings]] +deps = ["DataAPI", "InlineStrings", "Parsers"] +git-tree-sha1 = "b1be2855ed9ed8eac54e5caff2afcdb442d52c23" +uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5" +version = "1.4.2" + +[[deps.WorkerUtilities]] +git-tree-sha1 = "cd1659ba0d57b71a464a29e64dbc67cfe83d54e7" +uuid = "76eceee3-57b5-4d4a-8e66-0e911cebbf60" +version = "1.6.1" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "59071150afa35787c1656ba234cf03fdf8e2603f" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.13.8+0" + +[[deps.Xorg_libpciaccess_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "4909eb8f1cbf6bd4b1c30dd18b2ead9019ef2fad" +uuid = "a65dc6b1-eb27-53a1-bb3e-dea574b5389e" +version = "0.18.1+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.2.13+1" + +[[deps.libaec_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1aa23f01927b2dac46db77a56b31088feee0a491" +uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" +version = "1.1.4+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.11.0+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.59.0+0" + +[[deps.oneTBB_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d5a767a3bb77135a99e433afe0eb14cd7f6914c3" +uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" +version = "2022.0.0+0" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" diff --git a/ShroffCelegansModelsCore/Project.toml b/ShroffCelegansModelsCore/Project.toml new file mode 100644 index 0000000..faa2506 --- /dev/null +++ b/ShroffCelegansModelsCore/Project.toml @@ -0,0 +1,28 @@ +name = "ShroffCelegansModelsCore" +uuid = "e23caf7b-3362-4cb0-a14a-545330a3115b" +authors = ["Mark Kittisopikul and contributors"] +version = "1.0.0-DEV" + +[deps] +BSplineKit = "093aae92-e908-43d7-9660-e50ee39d5a0a" +CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" +FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" +HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" +JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" +LRUCache = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Missings = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" + +[compat] +HDF5 = "0.17.2" +JSON3 = "1.14.3" +Missings = "1.2.0" +Statistics = "1.11.1" +StatsBase = "0.34.6" diff --git a/ShroffCelegansModelsCore/src/MIPAVIO.jl b/ShroffCelegansModelsCore/src/MIPAVIO.jl new file mode 100644 index 0000000..73134ee --- /dev/null +++ b/ShroffCelegansModelsCore/src/MIPAVIO.jl @@ -0,0 +1,116 @@ +""" + MIPAVIO + +MIPAV (Medical Image Processing, Analysis, and Visualization) Input / Output +utility module. + +MIPAV is a Java program from the National Institutes of Health +""" +module MIPAVIO + using DataFrames: DataFrame + using GeometryBasics: Point3, Point3f + using CSV: CSV + using ShroffCelegansModelsCore: Datasets + using Statistics: mean + + export mipav_df_to_points, mipav_df_to_point_dict + + function mipav_df_to_points(df::DataFrame) + map(df.x_voxels, df.y_voxels, df.z_voxels) do x,y,z + Point3(x,y,z) + end + end + + function mipav_df_to_point_dict(df::DataFrame) + map(df.name, df.x_voxels, df.y_voxels, df.z_voxels) do name, x,y,z + name => Point3(x,y,z) + end |> Dict{eltype(df.name), Point3{eltype(df.x_voxels)}} + end + + function get_integrated_annotations_path(ds::Datasets.NormalizedDataset, time_offset=1) + data_path = joinpath("integrated_annotation","annotations.csv") + return get_model_csv(ds, data_path, time_offset) + end + + function get_integrated_annotations(ds::Datasets.NormalizedDataset, time_offset=1; validate = true) + path = get_integrated_annotations_path(ds, time_offset) + df = CSV.read(path, DataFrame) + if validate + names = df.name + for k in keys(ds.cell_key.mapping) + if string(k) ∉ names + #error("$k is not in $(ds.path)") + @warn "$k is not in $(path)" + end + end + end + return df + end + + function get_integrated_annotations(::Type{Dict}, args...) + df = get_integrated_annotations(args...) + return Dict(row[1] => Point3(row[2], row[3], row[4]) for row in eachrow(Matrix(df))) + end + + function get_model_csv(ds::Datasets.NormalizedDataset, data_path, time_offset=1)::Union{Missing, String} + timepoint = range(ds.cell_key)[time_offset] + if timepoint ∈ ds.cell_key.outliers + return missing + else + filepath = joinpath(ds.path, "Decon_reg_$(timepoint)", "Decon_reg_$(timepoint)_results", data_path) + @info "Filepath" filepath + if isfile(filepath) + return filepath + else + throw(ArgumentError("$filepath is not a file on disk and is not marked as an outlier.")) + end + end + end + + function get_straightened_lattice(ds::Datasets.NormalizedDataset, time_offset=1) + data_path = joinpath("straightened_lattice", "straightened_lattice.csv") + return CSV.read(get_model_csv(ds, data_path, time_offset), DataFrame) + end + + function get_straightened_lattice_xy_center(ds::Datasets.NormalizedDataset, time_offset=1) + csv = get_straightened_lattice(ds, time_offset) + m = Matrix(csv[1:2:end, 2:3] .+ csv[2:2:end, 2:3])./2 + Point3f(mean(eachrow(m))..., 0) + end + + #= + function get_straightened_lattice_xy_center(ds::Datasets.NormalizedDataset, time_offset=1) + csv = get_straightened_lattice(ds, time_offset) + m = Matrix(csv[1:2:end, 2:3] .+ csv[2:2:end, 2:3])./2 + Point3f(mean(eachrow(m))..., 0) + end + =# + + function get_straightened_annotations(ds::Datasets.NormalizedDataset, time_offset=1)::Union{Missing, String} + timepoint = range(ds.cell_key)[time_offset] + if timepoint ∈ ds.cell_key.outliers + return missing + else + filepath = joinpath(ds.path, "Decon_reg_$(timepoint)", "Decon_reg_$(timepoint)_results", "straightened_annotations", "straightened_annotations.csv") + if isfile(filepath) + return filepath + else + throw(ArgumentError("$filepath is not a file on disk and is not marked as an outlier.")) + end + end + end + + function load_straightened_annotations_over_time(dataset::Datasets.NormalizedDataset, offsets = 1:length(range(dataset.cell_key))) + annotations = map(offsets) do time_offset + path = get_straightened_annotations(dataset, time_offset) + if ismissing(path) + return missing + end + annotation_df = CSV.read(path, DataFrame) + pts = Point3f.(eachrow(Matrix(annotation_df)[:, 2:4])) + pts .-= get_straightened_lattice_xy_center(dataset, time_offset) + Dict(annotation_df[:,1] .=> pts) + end + return annotations + end +end \ No newline at end of file diff --git a/ShroffCelegansModelsCore/src/ParametricSplines.jl b/ShroffCelegansModelsCore/src/ParametricSplines.jl new file mode 100644 index 0000000..f8a1b90 --- /dev/null +++ b/ShroffCelegansModelsCore/src/ParametricSplines.jl @@ -0,0 +1,67 @@ +module ParametricSplines + using BSplineKit: BSplineKit, knots, Derivative, BSplineOrder, Natural, SplineInterpolation + using QuadGK: QuadGK, quadgk + using DataFrames: DataFrame + using GeometryBasics: Point, Point3 + using LinearAlgebra: norm + + #export NDParametricSplineInterpolation + export interpolate_natural_cubic_spline + + #= + struct NDParametricSplineInterpolation{T} + splines::Vector{T} + end + function (itps::NDParametricSplineInterpolation)(time) + Point{length(itps.splines)}(map(itps.splines) do s + s(time) + end) + end + function Base.getindex(itps::NDParametricSplineInterpolation, elements...) + getindex(itps.splines, elements...) + end + function Base.:*(d::Derivative, s::NDParametricSplineInterpolation) + NDParametricSplineInterpolation(d .* s.splines) + end + BSplineKit.knots(s::NDParametricSplineInterpolation) = knots(first(s.splines)) + function QuadGK.quadgk(s::NDParametricSplineInterpolation) + d = Derivative(1) * s + quadgk(unique(knots(s))...) do t + norm(d(t)) + end + end + function QuadGK.quadgk() + end + =# + + function QuadGK.quadgk(s::SplineInterpolation) + d = Derivative(1) * s + quadgk(unique(knots(s))...) do t + norm(d(t)) + end + end +# ╔═╡ d323b169-b352-46ad-9d35-a4da784cc710 +""" + interpolate_natural_cubic_spline(time, data) +""" +function interpolate_natural_cubic_spline(time, data::Union{AbstractMatrix, DataFrame}) + #= + itp_columns = interpolate_natural_cubic_spline.((time,), eachcol(data)) + NDParametricSplineInterpolation(itp_columns) + =# + return interpolate_natural_cubic_spline(time, Point3.(Vector.(eachrow(data)))) +end + +#= +# ╔═╡ 96d3a2f4-93ce-43aa-99d8-2fc1fbb21b1e +function interpolate_natural_cubic_spline(time, data::Vector{<: Point3}) + interpolate_natural_cubic_spline(time, stack(data; dims=1)) +end +=# + +# ╔═╡ 86b367d5-506d-4ed8-a3ca-a356e4b5be1a +function interpolate_natural_cubic_spline(time, data::AbstractVector) + return BSplineKit.interpolate(time, data, BSplineOrder(4), Natural()) +end + +end \ No newline at end of file diff --git a/ShroffCelegansModelsCore/src/ShroffCelegansModelsCore.jl b/ShroffCelegansModelsCore/src/ShroffCelegansModelsCore.jl new file mode 100644 index 0000000..d67d7f5 --- /dev/null +++ b/ShroffCelegansModelsCore/src/ShroffCelegansModelsCore.jl @@ -0,0 +1,43 @@ +module ShroffCelegansModelsCore + using CSV + using DataFrames + using GeometryBasics + using LinearAlgebra + using BSplineKit + using QuadGK + using LRUCache + using FFTW + using Dates + using PrecompileTools: @setup_workload, @compile_workload + + include("datasets.jl") + include("MIPAVIO.jl") + + include("util.jl") + include("ParametricSplines.jl") + include("types.jl") + + using .ParametricSplines + using .Types + + include("build_model.jl") + include("mesh.jl") + include("straighten.jl") + + include("average.jl") + + using .Datasets + + include("show.jl") + include("points.jl") + + using .Points + + include("model_time_series.jl") + include("area.jl") + + include("annotation_untwist.jl") + # include("parse_worm_dataset_path.jl") + + include("precompile.jl") +end \ No newline at end of file diff --git a/ShroffCelegansModelsCore/src/annotation_untwist.jl b/ShroffCelegansModelsCore/src/annotation_untwist.jl new file mode 100644 index 0000000..6fff3d6 --- /dev/null +++ b/ShroffCelegansModelsCore/src/annotation_untwist.jl @@ -0,0 +1,307 @@ +""" + nearest_central_pt(model::AbstractCelegansModel, pts::AbstractVector{<: Point}, expansion_factor = 1.0) + +Find the nearest central point on the model to each annotation point. + +# Arguments +- `model::AbstractCelegansModel`: The model to use for finding the nearest central point. +- `pts::AbstractVector{<: Point}`: The annotation points to find the nearest central point. +- `expansion_factor::Union{Vector{<: Real}, Real}=1.0`: The expansion factor to use for the distance check. + +# Returns +- A tuple of three vectors: the spline parameter, the nearest central point, and the distance to the nearest central point. +""" +function nearest_central_pt(model::AbstractCelegansModel, pts::AbstractVector{<: Point}, expansion_factor = 1.0) + # Sample points along the central spline + cs = ShroffCelegansModels.central_spline(model) + Npts = length(model) + z = LinRange(0, 1, Npts) + central_pts = cs.(z) + + # For each sampled point calculate the maximum radius of the cross section + max_r_func = ShroffCelegansModels.max_radius_function(model) + radius = max_r_func.(z) + + # For each annotation point, find the nearest central point + arg_pt_dist = map(pts) do pt + # Distance between the annotation point and each sampled point along the central spline + unbounded_dist = norm.(central_pts .- pt) + # bound check + a = 1 + dist = copy(unbounded_dist) + for ef in expansion_factor + # Set all distances larger than the radius times the expansion factor to infinity + dist[unbounded_dist .> radius .* ef] .= Inf + # Find the index of the central point with the smallest distance + a = argmin(dist) + if dist[a] != Inf + # If we found a point, then we are done with this point + break + end + # Otherwise, reset the distances and try with a larger expansion factor + dist = copy(unbounded_dist) + end + # Return a tuple of the spline parameter, the nearest central point, and the distance to the nearest central point + z[a], central_pts[a], dist[a] + end + second = x->x[2] + # Split each tuple into three vectors + return first.(arg_pt_dist), second.(arg_pt_dist), last.(arg_pt_dist) +end + +""" + get_central_point_parameters(model::AbstractCelegansModel, pts::AbstractVector{<: Point}, central_spline_voxel_distances::AbstractVector{<: Real}) + +Get the parameters of the central spline for each annotation point given a +central spline voxel distance. +""" +function get_central_point_parameters( + model::AbstractCelegansModel, + pts::AbstractVector{<: Point}, + central_spline_voxel_distances::AbstractVector{<: Real} +) + cs = ShroffCelegansModels.central_spline(model) + Npts = length(model) + z = LinRange(0, 1, Npts) + central_pts = cs.(z) + central_pts_dist = [0; cumsum(norm.(diff(central_pts)))] + indices = map(central_spline_voxel_distances) do d + findlast(<=(d + 0.1), central_pts_dist) + end + spline_param = z[indices] + central_pts = central_pts[indices] + pt_to_central_dist = norm.(central_pts .- pts) + return spline_param, central_pts, pt_to_central_dist +end + +function max_radius_function(model) + function max_radius(z) + tss = transverse_splines(model) + central_pt = central_spline(model)(z) + radii = map(tss) do ts + norm(ts(z) - central_pt) + end + return maximum(radii) + end +end + +function nearest_central_plane(model::AbstractCelegansModel, pts::AbstractVector{<: Point}) + cs = ShroffCelegansModels.central_spline(model) + dcs = Derivative(1)*cs + + Npts = length(model) + r = LinRange(0, 1, Npts) + central_pts = cs.(r) + + + ts1 = ShroffCelegansModels.transverse_spline(model, 1) + right = ts1.(r) + right_vec = right .- ncp + right_norm = norm.(right_vec) + # right_vec_unit = right_vec ./ right_norm + # TODO: change to maximum radial distance + max_radial_dist = right_norm + + normal_vecs = normalize.(dcs.(r)) + + d = central_pts .⋅ normal_vecs + + arg_pt_dist = map(pts) do pt + dist_to_plane = abs.(d .- (normal_vecs .⋅ pt)) + dist_to_central = norm.(central_pts .- pt) + dist_along_plane = dist_to_central.^2 - dist_to_plane.^2 + a = argmin(dist_to_central) + r[a], central_pts[a], dist_to_plane[a] + end + second = x->x[2] + first.(arg_pt_dist), second.(arg_pt_dist), last.(arg_pt_dist) +end + +""" + untwist_annotations(model::AbstractCelegansModel, pts::AbstractVector{<: Point}) + +Untwist the annotations by computing their position relative to the central spline of the model. + +# Arguments + +- `model::AbstractCelegansModel`: The model to use for untwisting. +- `pts::AbstractVector{<: Point}`: The annotation points to untwist. + +# Returns +- `Vector{Point3}`: The untwisted annotation points. + +# Example +```julia +using ShroffCelegansModels +using ShroffCelegansModels.MIPAVIO + +dataset = ShroffCelegansModels.NormalizedDataset("X:/shrofflab/OD1599_NU/120619_Pos2/Decon_reg/RegB") +mts = ShroffCelegansModels.ModelTimeSeries(dataset) +model = mts(1) +df = MIPAVIO.get_integrated_annotations(dataset, 1) +pts = MIPAVIO.mipav_df_to_points(df) +ShroffCelegansModels.untwist_annotations(model, pts) +``` + +# Notes +- The function uses the central spline of the model to untwist the annotations. +- The function uses the first transverse spline of the model to determine the right direction. +- The function uses the derivative of the central spline to determine the normal direction. + +# Algorithm +1. Compute the nearest point on the central spline to each annotation point. +2. Compute the angle between the right direction and the annotation point. +3. Compute the distance between the central spline and the annotation point. +4. Compute the untwisted annotation point using the angle and distance. +5. Return the untwisted annotation points. +""" +function untwist_annotations( + model::AbstractCelegansModel, + pts::AbstractVector{<: Point}, + central_spline_voxel_distances::Union{AbstractVector{<: Real},Nothing} = nothing +) + thresholds = [1.0, 1.05, 1.10, 1.15, 1.20, 1.25, 1.30, 1.35, 1.40, 1.45, 1.5, 2.0, 2.5] + + # For each point, find the nearest point along the central spline + # t is the spline parameter + # ncp is the nearest central point + # pts_norm is the distance from the point to the central spline + if isnothing(central_spline_voxel_distances) + t, ncp, pts_norm = nearest_central_pt(model, pts, thresholds) + else + t, ncp, pts_norm = get_central_point_parameters(model, pts, central_spline_voxel_distances) + end + + # Objective: Compute the angle between the right direction and the point + # The first transverse spline is used to determine which direction is the right side + ts1 = ShroffCelegansModels.transverse_spline(model, 1) + right = ts1.(t) + + # Obtain the central spline and its derivative + # The derivative should point along the spline + cs = ShroffCelegansModels.central_spline(model) + dcs = Derivative(1)*cs + + # Obtain the vector from the nearest central point to the annotation + pts_vec = pts .- ncp + pts_vec_unit = pts_vec ./ pts_norm + + # Obtain the vector from the nearest central point to the right direction + right_vec = right .- ncp + right_norm = norm.(right_vec) + right_vec_unit = right_vec ./ right_norm + + # Compute the cross product between the right direction and the annotation direction + c = right_vec_unit .× pts_vec_unit + # Compute the sign of the cross product and the derivative of the central spline + # This indicates whether the cross product is pointing + s = sign.(dcs.(t) .⋅ c) + + # Compute the angle between the right direction and the annotation direction + # by taking the arctangent of signed magnitude of the cross product + # with the dot product of the right direction and the annotation direction + angles = atan.(norm.(c) .*s, right_vec_unit .⋅ pts_vec_unit) + + # Obtain the straightened, untwisted, model + smodel = StraightenedCelegansModel(model) + scs = central_spline(smodel) + # Compute the z-coordinate of the nearest central point on the straightened model + z = last.(scs.(t)) + + # The returned untwisted annotation points are computed using the angle and distance + # between the central spline and the annotation point + # The z-coordinate is the same as that of the nearest central point on the straightened model + return map(zip(angles,pts_norm,z)) do (angle, dist,z) + Point3(cos(angle)*dist, sin(angle)*dist, z) + end +end + +function untwist_annotation( + model::AbstractCelegansModel, + pt::Point, + central_spline_voxel_distance::Union{Real,Nothing} = nothing # "z" +) + pts = [pt] + central_spline_voxel_distances = + isnothing(central_spline_voxel_distance) ? + nothing : + [central_spline_voxel_distance] + return only(untwist_annotations(model, pts, central_spline_voxel_distances)) +end + +""" + untwist_annotations(dataset::NormalizedDataset, timepoint::Int=1) + +Untwist the annotations at a specific timepoint in the dataset. + +# Arguments +- `dataset::NormalizedDataset`: The dataset to use for untwisting. +- `timepoint::Int=1`: The timepoint to use for untwisting, where 1 indicates of the first time point of the dataset. + +# Returns +- `Dict{String, Vector{Point3}}`: The untwisted annotations using the annotation name as a the key + +# Example +```julia +using ShroffCelegansModels + +dataset = ShroffCelegansModels.NormalizedDataset("X:/shrofflab/OD1599_NU/120619_Pos2/Decon_reg/RegB") +# Obtain the untwisted annotations for the C3 cell at timepoint 71 +c3_pt = ShroffCelegansModels.untwist_annotations(dataset, 71)["C3"] +``` +""" +function untwist_annotations(dataset::NormalizedDataset, timepoint::Int=1) + mts = ModelTimeSeries(dataset) + try + df = MIPAVIO.get_integrated_annotations(dataset, timepoint) + pts = MIPAVIO.mipav_df_to_points(df) + return Dict(df.name .=> untwist_annotations(mts(timepoint), pts)) + catch err + return missing + end +end + +function twisted_annotations(dataset::NormalizedDataset, timepoint::Int=1) + try + df = MIPAVIO.get_integrated_annotations(dataset, timepoint) + pts = MIPAVIO.mipav_df_to_points(df) + return Dict(df.name .=> pts) + catch err + return missing + end +end + +function distance_to_twisted_annotation(model::AbstractCelegansModel, pt::Point) + # Sample points along the central spline + cs = ShroffCelegansModels.central_spline(model) + dcs = Derivative(1)*cs + Npts = length(model) + z = LinRange(0, 1, Npts) + central_pts = cs.(z) + annotation_vecs = -(central_pts .- pt) + annotation_norms = norm.(annotation_vecs) + unit_annotation_vecs = annotation_vecs ./ annotation_norms + + ts1 = ShroffCelegansModels.transverse_spline(model, 1) + right = ts1.(z) + right_vecs = right .- central_pts + right_norms = norm.(right_vecs) + unit_right_vecs = right_vecs ./ right_norms + + # Compute the cross product between the right direction and the annotation direction + c = unit_right_vecs .× unit_annotation_vecs + + central_spline_vecs = dcs.(z) + central_spline_norms = norm.(central_spline_vecs) + unit_central_spline_vecs = central_spline_vecs ./ central_spline_norms + + # Compute the sign of the cross product and the derivative of the central spline + # This indicates whether the cross product is pointing + s = sign.(unit_central_spline_vecs .⋅ c) + + # by taking the arctangent of signed magnitude of the cross product + # with the dot product of the right direction and the annotation direction + angles = atan.(norm.(c) .*s, unit_right_vecs .⋅ unit_annotation_vecs) + + return (; annotation_norms, angles, unit_annotation_vecs, unit_right_vecs, unit_central_spline_vecs, c, central_pts, right_vecs, right_norms) +end \ No newline at end of file diff --git a/ShroffCelegansModelsCore/src/area.jl b/ShroffCelegansModelsCore/src/area.jl new file mode 100644 index 0000000..a5c9670 --- /dev/null +++ b/ShroffCelegansModelsCore/src/area.jl @@ -0,0 +1,33 @@ +function radial_cross_section(model::AbstractCelegansModel, p) + _central_spline = central_spline(model) + center = _central_spline(p) + map(transverse_splines(model)) do transverse_spline + norm(transverse_spline(p) - center) + end +end + +function cross_section_area(model::AbstractCelegansModel, p) + radii = radial_cross_section(model, p) + radii_hat = fft(radii) + N = length(radii) + _sum_of_square_norm = sum(radii_hat) do radius_hat + abs2(radius_hat) + end + return _sum_of_square_norm*π/N^2 +end + +function volume_by_cross_section(model::AbstractCelegansModel; delta = 0.001) + # integrate along the z-axis + _central_spline = central_spline(model) + last_z = _central_spline(0)[3] + last_area = cross_section_area(model, 0) + volume = 0 + for p in delta:delta:1 + z = _central_spline(p)[3] + area = cross_section_area(model, p) + volume += (area + last_area)/2 * (z-last_z) + last_z = z + last_area = area + end + return volume +end \ No newline at end of file diff --git a/ShroffCelegansModelsCore/src/average.jl b/ShroffCelegansModelsCore/src/average.jl new file mode 100644 index 0000000..3eb265a --- /dev/null +++ b/ShroffCelegansModelsCore/src/average.jl @@ -0,0 +1,120 @@ +using Statistics +using StatsBase +using Missings + +const psuedo_seam_cells = ("a0L", "H0L", "H1L", "H2L", "V1L", "V2L", "V3L", "V4L", "V5L", "V6L", "TL") + +function average(models::Vector{<: AbstractCelegansModel}, weights::AbstractWeights = uweights(length(models)); n_upsample::Int = 0) + _names = map(models) do model + #parent(model).names[1:2:end] + ShroffCelegansModels.Types.names(model)[1:2:end] + end + + common_names = intersect(_names..., psuedo_seam_cells) + for psc in psuedo_seam_cells + if psc ∉ common_names + @warn "$psc is missing from average" + end + end + unique_names = unique(vcat(_names...)) + distinct_names = setdiff(unique_names, common_names) + #filter!(!startswith("a"), distinct_names) + # @info "Names" distinct_names + # common_names = psuedo_seam_cells + # common_names = distinct_names + # common_names = intersect(_names...) + + original_knot_pairs = map(models) do model + twisted_model = if model isa Types.StraightenedCelegansModel + parent(model) + else + model + end + #twisted_model = parent(model) + original_knots = knots(central_spline(twisted_model))[4:end-3] + n = unique(twisted_model.names[1:2:end]) + common_pairs = Iterators.filter(t->(t[2] ∈ common_names),zip(original_knots,n)) + common_names = last.(common_pairs) + #= + if length(common_names) > length(psuedo_seam_cells) + println.(common_names) + end + =# + last.(common_pairs) .=> first.(common_pairs) + end + + original_knots = map(x->last.(x), original_knot_pairs) + + for i in 1:n_upsample + original_knots = map(upsample, original_knots) + end + + #display(original_knots) + + z_positions = map(models, original_knots) do model, original_knots + # twisted_model = parent(model) + # original_knots = knots(central_spline(twisted_model))[4:end-3] + central_spline(model).(original_knots) .|> x->x[3] + end + + # return z_positions + + # avg_z_position = (z_positions[1] + z_positions[2])./2 + # avg_z_position = sum(z_positions) ./ length(z_positions) + avg_z_position = mean(z_positions, weights) + # std_z_position = std(z_positions, weights) + + t_positions = map(models, original_knots) do model, original_knots + # twisted_model = parent(model) + # original_knots = knots(central_spline(twisted_model))[4:end-3] + _transverse_splines = transverse_splines(model) + + map(_transverse_splines) do s + s.(original_knots) + end + end + + t_positions = mean(stack.(t_positions), weights) + + # return t_positions + new_knots = avg_z_position ./ avg_z_position[end] + + normalized_knots = map(original_knots) do original_knots + original_knots ./ original_knots[end] + end + + avg_knots = mean(normalized_knots, weights) + + new_knots = avg_knots + + avg_transverse_splines = map(eachcol(t_positions)) do avg_transverse_points + interpolate_natural_cubic_spline(new_knots, collect(avg_transverse_points)) + end + + avg_central_points = map(avg_z_position) do azp + Point3(0,0,azp) + end + avg_central_spline = interpolate_natural_cubic_spline(new_knots, avg_central_points) + + # return avg_z_position ./ avg_z_position[end] + + # TODO: Change add R names back + right_common_names = replace.(common_names, 'L' => 'R') + model_names = vec(permutedims([[common_names...] [right_common_names...]], (2,1))) + return CelegansModel(avg_transverse_splines, avg_central_spline, model_names) + + # return avg_z_position, t_positions, avg_transverse_splines + return avg_transverse_splines, avg_central_spline, common_names +end + +function upsample(v::Vector{T}) where T + N = length(v) + upsampled = T[] + sizehint!(upsampled, 2N-1) + for (a,b) in zip(@view(v[1:end-1]), @view(v[2:end])) + push!(upsampled, a) + push!(upsampled, (a+b)/2) + end + push!(upsampled, v[end]) + return upsampled +end \ No newline at end of file diff --git a/ShroffCelegansModelsCore/src/build_model.jl b/ShroffCelegansModelsCore/src/build_model.jl new file mode 100644 index 0000000..0dac15f --- /dev/null +++ b/ShroffCelegansModelsCore/src/build_model.jl @@ -0,0 +1,86 @@ +# ╔═╡ cc0554ba-27b7-4669-8053-be473cf96bfa +function build_celegans_model( + path::String; + update_cross_sections::Bool = true, +) + df_lattice = CSV.read(path, DataFrame) + names = df_lattice[:,1] + if update_cross_sections + cross_section_path = joinpath(dirname(path), "..", "model_crossSections") + if isdir(cross_section_path) + cross_section_files = readdir(cross_section_path) + n_cross_sections = size(df_lattice,1) ÷ 2 + cross_sections = map(0:n_cross_sections-1) do i + filename = "latticeCrossSection_$i.csv" + if filename in cross_section_files + CSV.read(joinpath(cross_section_path, filename), DataFrame; header=2) + else + nothing + end + end + return build_celegans_model(df_lattice; cross_sections, names) + end + end + return build_celegans_model(df_lattice; names) +end + +function build_celegans_model(df_lattice::DataFrame; cross_sections::Vector{<: Union{Nothing, DataFrame}} = Union{Nothing, DataFrame}[], names = String3[]) + seam_cell_data = df_lattice[:,2:4] + left_seam_cells = seam_cell_data[1:2:end, :] + right_seam_cells = seam_cell_data[2:2:end, :] + return build_celegans_model(left_seam_cells, right_seam_cells, cross_sections, names) +end + +# ╔═╡ 322eb672-bde2-4857-a275-32639f39408a +function build_celegans_model(left_seam_cells, right_seam_cells, cross_sections::Vector=Union{Nothing,DataFrame}[], names::Vector{<:AbstractString} = String3[]) + P = Point3 + # left_seam_cells = Float32.(left_seam_cells) + # right_seam_cells = Float32.(right_seam_cells) + centers = map(eachrow((left_seam_cells .+ right_seam_cells)./2)) do row + P(row...) + end + deltaLengths = norm.(diff(centers)) + afTime = [+0; cumsum(deltaLengths)] + afTime ./= afTime[end] + # afTime = Float32.(afTime) + + right_spline = + interpolate_natural_cubic_spline(afTime, right_seam_cells) + left_spline = + interpolate_natural_cubic_spline(afTime, left_seam_cells) + center_spline = + interpolate_natural_cubic_spline(afTime, centers) + central_spline_d1 = Derivative(1) * center_spline + + # Calculate vectors at each afTime + forward_vector_afTime = central_spline_d1.(afTime) + right_vector_afTime = (right_spline.(afTime) - left_spline.(afTime))./2 + radii = norm.(right_vector_afTime) + normal_vector_afTime = normalize.(cross.( + forward_vector_afTime, + right_vector_afTime + )) .* radii + circle_points = get_circle_points.(right_vector_afTime, normal_vector_afTime, centers) + if !isempty(cross_sections) + CP = eltype(eltype(circle_points)) + for i in eachindex(circle_points) + if !isnothing(cross_sections[i]) + circle_points[i] = map(eachrow(cross_sections[i])) do row + CP(row...) + CP(centers[i,:]...) + end + end + end + end + n_circle_points = length(first(circle_points)) + contourSplines = map(1:n_circle_points) do c + contourPoints = map(circle_points) do pts + pts[c] + end + contourSpline = interpolate_natural_cubic_spline(afTime, contourPoints) + end + model = CelegansModel(contourSplines, center_spline, names) + #return contourSplines + return model +end + +build_celegans_model(::Missing) = missing \ No newline at end of file diff --git a/ShroffCelegansModelsCore/src/datasets.jl b/ShroffCelegansModelsCore/src/datasets.jl new file mode 100644 index 0000000..f84b571 --- /dev/null +++ b/ShroffCelegansModelsCore/src/datasets.jl @@ -0,0 +1,104 @@ +module Datasets + using JSON3: JSON3 + using CSV, DataFrames + + export Dataset, CellKey, NormalizedDataset + + abstract type AbstractDataset end + + const CELL_KEY_FILE_NAME = "cell_key.json" + const CELL_KEY_CSV_NAME = "CellKey.csv" + + struct Dataset{JO <: JSON3.Object} <: AbstractDataset + path::String + cell_key::JO + end + function Dataset(path::String) + path = abspath(path) + isdir(path) || error("Dataset path, \"$path\", does not exist as a directory.") + cell_key_path = joinpath(dirname(path), CELL_KEY_CSV_NAME) + if isfile(cell_key_path) + return _Dataset(path, cell_key_path) + end + cell_key_path = joinpath(dirname(path), CELL_KEY_FILE_NAME) + return _Dataset(path, cell_key_path) + end + function _Dataset(path::String, cell_key_path::String) + if endswith(cell_key_path, ".json") + return Dataset(path, JSON3.read(cell_key_path)) + end + if endswith(cell_key_path, ".csv") + return NormalizedDataset(path, parse_cell_key_csv(cell_key_path)) + end + error("Cell Key path, $cell_key_path, does not exist as a file.") + end + + struct CellKey + name::String + start::Int + stop::Int # end + mapping::Dict{Symbol,String} + outliers::Vector{Int} + end + const _cell_key_keys = (:end, :mapping, :name, :outliers, :start) + function CellKey(jo::JSON3.Object) + _cell_key_keys ⊆ keys(jo) || return ArgumentError("JSON3.Object must contain the following keys: $_cell_key_keys") + CellKey(jo.name, jo.start, jo.end, jo.mapping, jo.outliers) + end + function CellKey(df::DataFrame) + name = df[1,1] + start = df[2,1] isa AbstractString ? parse(Int, df[2,1]) : df[2,1] + stop = df[2,2] isa AbstractString ? parse(Int, df[2,2]) : df[2,2] + row = 3 + if ismissing(df[3,1]) || + ismissing(df[3,2]) || + isa(df[3,1], Int) || + isa(df[3,2], Int) || + !isnothing(tryparse(Int, df[3,1])) && + !isnothing(tryparse(Int, df[3,2])) + outliers = Int[ + isa(x, AbstractString) ? parse(Int, x) : x + for x in df[3,:] if !ismissing(x) + ] + row = 4 + end + mapping = Dict{Symbol,String}(Symbol(k) => v for (k,v) in zip(df[row:end,1], df[row:end,2]) if !ismissing(k) && !ismissing(v)) + return CellKey(name, start, stop, mapping, outliers) + end + function Base.getproperty(ck::CellKey, s::Symbol) + if s == :end + s = :stop + end + return Base.getfield(ck, s) + end + function Base.range(ck::CellKey) + r = range(ck.start, ck.stop) + rd = setdiff(r, ck.outliers) + real_start = minimum(rd) + real_stop = maximum(rd) + return range(real_start, real_stop) + end + + struct NormalizedDataset <: AbstractDataset + path::String + cell_key::CellKey + end + function NormalizedDataset(path::String) + ds = Dataset(path) + return NormalizedDataset(ds) + end + function NormalizedDataset(ds::Dataset) + return NormalizedDataset(ds.path, CellKey(ds.cell_key)) + end + function NormalizedDataset(ds::NormalizedDataset) + return NormalizedDataset(ds.path, ds.cell_key) + end + function parse_cell_key_csv(path::AbstractString) + try + df = CSV.read(path, DataFrame, header=0) + return CellKey(df) + catch e + error("Error reading CSV file: $path") + end + end +end diff --git a/ShroffCelegansModelsCore/src/mesh.jl b/ShroffCelegansModelsCore/src/mesh.jl new file mode 100644 index 0000000..280920a --- /dev/null +++ b/ShroffCelegansModelsCore/src/mesh.jl @@ -0,0 +1,76 @@ + function get_model_contour_mesh(model_contours_path::AbstractString) + sections = get_model_contour_sections(model_contours_path) + get_model_contour_mesh(sections) + end + function get_model_contour_mesh( + sections::Vector{Matrix{Float64}}; + ellipse_points::Int=size(first(sections),1) + ) + pts = vcat(map(sections) do section + Point3f.(eachrow(section)) + end...) + return get_model_contour_mesh(pts; ellipse_points) + end + function get_sections(model::AbstractCelegansModel) + r = LinRange(0, 1, length(model)) + _transverse_splines = transverse_splines(model) + sections = map(r) do t + Point3f.(t .|> _transverse_splines) + end + return sections + end + function get_model_contour_mesh(model::AbstractCelegansModel; kwargs...) + sections = get_sections(model) + return get_model_contour_mesh(sections; kwargs...) + end + function get_model_contour_mesh( + sections::Vector{Vector{Point3f}}; + ellipse_points=length(first(sections)), + kwargs... + ) + pts = vcat(sections...) + get_model_contour_mesh(pts; ellipse_points, kwargs...) + end + function get_model_contour_mesh( + pts::Vector{Point3f}; + ellipse_points::Int, + transform_points = identity + ) + if transform_points != identity + pts = transform_points.(pts) + end + npts = length(pts) + #mesh(GeometryBasics.Mesh(pts, faces[1:964])) + A = mod1.(1:ellipse_points, ellipse_points) + B = mod1.(2:ellipse_points+1, ellipse_points) + C = B .+ ellipse_points + D = A .+ ellipse_points + faces = QuadFace.(A,B,C,D) + faces = vec(faces .+ + reshape(QuadFace.(eachrow( + [ellipse_points ellipse_points ellipse_points ellipse_points] .* (0:length(pts)÷ellipse_points-2) + )), 1,:) + ) + M = GeometryBasics.Mesh(pts, faces) + end + function get_model_manifold_mesh_components( + model::AbstractCelegansModel; + transform_points = identity + ) + r = LinRange(0, 1, length(model)) + _splines = [transverse_spline(model,1) central_spline(model) transverse_spline(model,17)] + sections = map(r) do t + Point3f.(t .|> _splines) + end + pts = transform_points.(Iterators.flatten(sections)) + offsets = (0:length(pts)÷3-2) .* (QuadFace(3,3,3,3),) + faces = QuadFace[(1,2,5,4) (2,3,6,5)] .+ offsets + return pts, vec(faces) + end + function get_model_manifold_mesh( + model::AbstractCelegansModel; + transform_points = identity + ) + pts, faces = get_model_manifold_mesh_components(model; transform_points) + return GeometryBasics.Mesh(pts, faces) + end \ No newline at end of file diff --git a/ShroffCelegansModelsCore/src/model_time_series.jl b/ShroffCelegansModelsCore/src/model_time_series.jl new file mode 100644 index 0000000..6e2e33b --- /dev/null +++ b/ShroffCelegansModelsCore/src/model_time_series.jl @@ -0,0 +1,131 @@ +struct ModelTimeSeries{Model <: AbstractCelegansModel, Cache <: LRU{<:AbstractString, Union{Model,Missing}}} + dataset::NormalizedDataset + cache::Cache +end +ModelTimeSeries(dataset::NormalizedDataset; max_cache_size = 2) = + ModelTimeSeries(dataset, LRU{String, Union{CelegansModel,Missing}}(; maxsize = max_cache_size)) +function (mts::ModelTimeSeries)(time_offset::Integer) + try + timepoint = range(mts.dataset.cell_key)[time_offset] + lattice_filepath = get_lattice_filepath(mts.dataset, timepoint) + ds = mts.dataset + get!(mts.cache, lattice_filepath) do + if timepoint ∈ ds.cell_key.outliers + return missing + elseif !isfile(lattice_filepath) + @warn("$lattice_filepath is not a file on disk and is not marked as an outlier.") + return missing + else + return build_celegans_model(lattice_filepath) + end + end + catch err + if err isa BoundsError + @warn "BoundsError" time_offset timepoint lattice_filepath + return nothing + else + rethrow(err) + end + end +end + +struct StraightenedModelTimeSeries{Model <: AbstractCelegansModel, Cache <: LRU{<: AbstractString, Union{Model,Missing}}, ModelTS <: ModelTimeSeries} + modelTimeSeries::ModelTS + cache::Cache +end +function StraightenedModelTimeSeries(dataset::NormalizedDataset, model_cache::LRU, straightened_model_cache::LRU) + mts = ModelTimeSeries(dataset, model_cache) + return StraightenedModelTimeSeries(mts, straightened_model_cache) +end +function StraightenedModelTimeSeries(dataset::NormalizedDataset; max_cache_size = 2) + mts = ModelTimeSeries(dataset; max_cache_size) + StraightenedModelTimeSeries(mts, LRU{String, Union{StraightenedCelegansModel,Missing}}(; maxsize = max_cache_size)) +end +function (smts::StraightenedModelTimeSeries)(time_offset::Integer)::Union{Nothing, Missing, StraightenedCelegansModel} + mts = smts.modelTimeSeries + try + timepoint = range(mts.dataset.cell_key)[time_offset] + lattice_filepath = get_lattice_filepath(mts.dataset, timepoint) + get!(smts.cache, lattice_filepath) do + model = mts(time_offset) + if ismissing(model) + missing + else + StraightenedCelegansModel(model) + end + end + catch err + if err isa BoundsError + return nothing + else + rethrow() + end + end +end +function (smts::StraightenedModelTimeSeries)(time_offset, n_upsample=0) + next = nextModelIndex(smts, time_offset) + prev = prevModelIndex(smts, time_offset) + if isnothing(next) && isnothing(prev) + return nothing + end + if isnothing(next) + return average([smts(prev)]; n_upsample) + end + if isnothing(prev) + return average([smts(next)]; n_upsample) + end + if next == prev + model = smts(next) + if !isnothing(model) + return average([model]; n_upsample) + else + return nothing + end + end + models = [smts(prev), smts(next)] + if isnothing(models[1]) && isnothing(models[2]) + return nothing + elseif isnothing(models[1]) + return average([models[2]]; n_upsample) + elseif isnothing(models[2]) + return average([models[1]]; n_upsample) + else + return average(models, AnalyticWeights([next - time_offset, time_offset - prev]); n_upsample) + end +end + +function get_lattice(ds::NormalizedDataset, time_offset=1)::Union{Missing, String} + timepoint = range(ds.cell_key)[time_offset] + if timepoint ∈ ds.cell_key.outliers + return missing + else + filepath = joinpath(ds.path, "Decon_reg_$(timepoint)", "Decon_reg_$(timepoint)_results", "lattice_final", "lattice.csv") + if isfile(filepath) + return filepath + else + @warn("$filepath is not a file on disk and is not marked as an outlier.") + return missing + end + end +end + +function get_lattice_filepath(ds::NormalizedDataset, timepoint::Integer)::String + filepath = joinpath(ds.path, "Decon_reg_$(timepoint)", "Decon_reg_$(timepoint)_results", "lattice_final", "lattice.csv") + return filepath +end + +function nextModelIndex(smts::StraightenedModelTimeSeries, index) + index = ceil(Int, index) + while ismissing(smts(index)) + index += 1 + end + return index +end + +function prevModelIndex(smts::StraightenedModelTimeSeries, index) + index = floor(Int, index) + while ismissing(smts(index)) + index -= 1 + end + return index +end \ No newline at end of file diff --git a/ShroffCelegansModelsCore/src/parse_worm_dataset_path.jl b/ShroffCelegansModelsCore/src/parse_worm_dataset_path.jl new file mode 100644 index 0000000..fdf4651 --- /dev/null +++ b/ShroffCelegansModelsCore/src/parse_worm_dataset_path.jl @@ -0,0 +1,197 @@ +using Dates + +function parse_worm_dataset_path(s::String) + date_pattern = r"\d{6}" + position_pattern = r"Pos\d+" + date_match = match(date_pattern, s) + position_match = match(position_pattern, s) + if isnothing(position_match) + position_pattern = r"UTP \d+" + position_match = match(position_pattern, s) + end + return date_match, position_match +end + +function date_position_tag(s::String) + date_match, position_match = parse_worm_dataset_path(s) + if isnothing(date_match) + if isnothing(position_match) + error("Unable to parse date and position from $s") + else + return position_match.match + end + else + if isnothing(position_match) + return date_match.match + else + return string(date_match.match, "_", position_match.match) + end + end + # not reachable +end + +using HDF5 + +const annotations_cache = Dict{Tuple{String, UnitRange, Bool}, Vector}() +const annotation_position_cache = Dict{String, Any}() +#const my_annotation_position_cache = Dict{String, Any}() +const my_annotation_position_cache = Dict{String, Vector{Vector{Point3{Float64}}}}() + +include("demo_averaging/load_straightened_annotations_over_time.jl") +include("demo_averaging/get_cell_trajectory_dict.jl") + +include("demo_averaging/save_cache.jl") + +# initialize my_annotation_position_cache +@info "Loading straightened annotation positions..." +load_annotation_cache() +@info "Loading warped annotation positions..." +load_annotations_cache() + + +function save_annotation_position_cache( + filename::String, + datasets::Dict{String, Vector{ShroffCelegansModels.Datasets.NormalizedDataset}}, + cache::Dict{String, Vector{Vector{Point3{Float64}}}}; + num_timepoints::Union{Symbol, Int} = :raw, + expand_annotations::Bool = false, + append_seam_cells::Bool = true +) + h5open(filename, "w") do h5f + for (group_name, embryos) in datasets + h5g = create_group(h5f, group_name) + println("group_name: $group_name") + for embryo in embryos + println("embryo.path: $(embryo.path)") + try + tag = date_position_tag(embryo.path) + while haskey(h5g, tag) + error("Tag $tag already exists in $group_name") + end + # h5g[tag] = stack(cache[embryo.path]) + # h5g[tag] = stack(get_cell_trajectory_dict(embryo; use_myuntwist = true)) + #data = stack(get_cell_trajectory_dict(embryo; use_myuntwist = true)) + dict = get_cell_trajectory_dict(embryo; use_myuntwist = true) + dict = filter(dict) do p + haskey(embryo.cell_key.mapping, Symbol(first(p))) + end + smts = StraightenedModelTimeSeries(embryo) + annotation_names = map(collect(keys(dict))) do name + # get(embryo.cell_key.mapping, Symbol(name), name) + embryo.cell_key.mapping[Symbol(name)] + end + if num_timepoints == :raw + num_timepoints = length(range(embryo.cell_key)) + elseif num_timepoints isa Symbol + error("Invalid num_timepoints: $num_timepoints") + end + timepoints = LinRange(0, 1, num_timepoints) + data = map(values(dict)) do spline + if ismissing(spline) + fill(Point3{Float64}(NaN, NaN, NaN), num_timepoints) + else + spline.(timepoints) + end + end + if !isempty(data) + data = stack(data) + data = reshape(reinterpret(Float64, data), (3, size(data)...)) + else + data = zeros(Float64, 3, num_timepoints, 0) + end + #data = reinterpret(Float64, data) + #data = reshape(data, (3, size(data)...)) + # h5d = create_dataset(h5g, tag, datatype(Point3{Float64}), size(data)) + + # Add seam cells + if append_seam_cells + left_seam_cell_names = psuedo_seam_cells + right_seam_cell_names = replace.(left_seam_cell_names, 'L' => 'R') + seam_cell_names = vec(stack([left_seam_cell_names, right_seam_cell_names]; dims=1)) + smts_length = length(range(embryo.cell_key)) + seam_cell_data = map(timepoints) do ntp + # convert normalized time to timepoint + tp = ntp * (smts_length - 1) + 1 + # straightened model + model = smts(tp) + if isnothing(model) + @info "Model is nothing" ntp tp smts_length + end + right_spline = transverse_spline(model, 1) + left_spline = transverse_spline(model, 17) + pts = BSplineKit.SplineInterpolations.interpolation_points(right_spline) + dict = Dict(Types.names(model) .=> vec(stack((left_spline.(pts), right_spline.(pts)); dims=1))) + seam_cell_locations = map(seam_cell_names) do name + if haskey(dict, name) + dict[name] + else + @warn "Seam cell $name not found $(embryo.path) $ntp $tp" + Point3{Float64}(NaN, NaN, NaN) + end + end + return seam_cell_locations + end + seam_cell_data = stack(seam_cell_data; dims=1) + seam_cell_data = reshape(reinterpret(Float64, seam_cell_data), (3, size(seam_cell_data)...)) + append!(annotation_names, seam_cell_names) + data = cat(data, seam_cell_data; dims=3) + end + + if expand_annotations + h5g2 = create_group(h5g, tag) + for (i, name) in enumerate(annotation_names) + annotation_data = @view data[:,:,i] + h5d = create_dataset(h5g2, name, Float64, size(annotation_data)) + write_dataset(h5d, datatype(Float64), annotation_data) + end + attributed_obj = h5g2 + else + h5d = create_dataset(h5g, tag, Float64, size(data)) + write_dataset(h5d, datatype(Float64), data) + attrs(h5d)["annotation_names"] = annotation_names + attributed_obj = h5d + end + attrs(attributed_obj)["path"] = embryo.path + attrs(attributed_obj)["normalized_time"] = collect(timepoints) + attrs(attributed_obj)["standard_minutes_post_fertilization"] = collect(timepoints .* 420 .+ 420) + catch err + #display(err) + # println(err) + if err isa KeyError + println(err) + else + rethrow(err) + end + end + end + end + end +end + +function save_annotation_position_cache_all_dated(datasets::Dict{String, Vector{Datasets.NormalizedDataset}}; clear = true) + # Clear caches + if clear + empty!(annotation_position_cache) + empty!(my_annotation_position_cache) + empty!(annotations_cache) + end + + date_str = "$(Dates.today())" + date_str = replace(date_str, "-" => "_") + for (timepoints, expanded) in Iterators.product((:raw, 420), (true, false)) + tp_str = string(timepoints) + if expanded + tp_str *= "_expanded" + end + cache_file = "embryos_$(tp_str)_$date_str.h5" + save_annotation_position_cache( + cache_file, + datasets, + my_annotation_position_cache; + num_timepoints = timepoints, + expand_annotations = expanded, + append_seam_cells = true + ) + @info "Saved annotation position cache to $cache_file" timepoints expanded + end +end \ No newline at end of file diff --git a/ShroffCelegansModelsCore/src/points.jl b/ShroffCelegansModelsCore/src/points.jl new file mode 100644 index 0000000..586b80d --- /dev/null +++ b/ShroffCelegansModelsCore/src/points.jl @@ -0,0 +1,34 @@ +module Points + +using ..Types: AbstractCelegansModel, lattice_knots, transverse_splines, names +export points, lattice, cross_sections, CrossSections + +function points(model::AbstractCelegansModel) + splines = transverse_splines(model) + r = LinRange(0, 1, length(model)) + pts = map(splines) do spline + spline.(r) + end + hcat(pts...) +end + +function lattice(model::AbstractCelegansModel) + splines = transverse_splines(model) + r = lattice_knots(model) + pts = map(splines) do spline + spline.(r) + end + hcat(pts...) +end + +struct CrossSections{P <: Vector{<: Pair}} + sections::P +end + +function cross_sections(model::AbstractCelegansModel) + _names = names(model)[1:2:end] + CrossSections(_names .=> copy.(eachrow(lattice(model)))) +end + + +end \ No newline at end of file diff --git a/ShroffCelegansModelsCore/src/precompile.jl b/ShroffCelegansModelsCore/src/precompile.jl new file mode 100644 index 0000000..0e5b248 --- /dev/null +++ b/ShroffCelegansModelsCore/src/precompile.jl @@ -0,0 +1,13 @@ +@setup_workload begin + lattice_final_path = joinpath(pkgdir(ShroffCelegansModelsCore), "test", "fixtures", "lattice.csv") + @compile_workload begin + try + model = ShroffCelegansModelsCore.build_celegans_model(lattice_final_path) + smodel = ShroffCelegansModelsCore.StraightenedCelegansModel(model) + get_model_contour_mesh(model) + get_model_contour_mesh(smodel) + catch err + Base.showerror(stdout, err, Base.catch_backtrace()) + end + end +end \ No newline at end of file diff --git a/ShroffCelegansModelsCore/src/show.jl b/ShroffCelegansModelsCore/src/show.jl new file mode 100644 index 0000000..ce30fa3 --- /dev/null +++ b/ShroffCelegansModelsCore/src/show.jl @@ -0,0 +1,6 @@ +function Base.show(io::IO, m::MIME"text/plain", model::T) where T <: AbstractCelegansModel + println(io, T) + for f in fieldnames(T) + println(io, " ", f) + end +end \ No newline at end of file diff --git a/ShroffCelegansModelsCore/src/straighten.jl b/ShroffCelegansModelsCore/src/straighten.jl new file mode 100644 index 0000000..605f5e8 --- /dev/null +++ b/ShroffCelegansModelsCore/src/straighten.jl @@ -0,0 +1,20 @@ +# ╔═╡ 9d9e7f86-dc98-4d5b-a0cd-e6a19af34e45 +function straighten_celegans_model(model::CelegansModel) + r = LinRange(0, 1, length(model)) + s = let central_spline_d1 = Derivative(1) * model.central_spline + dr = diff(r) + s = cumsum(norm.(central_spline_d1.(r)) .* dr[1]) + end + sections_radii = map(r) do x + map(model.transverse_splines) do s + norm(s(x) - model.central_spline(x)) + end + end + normal_vector = Point3f(0.0, 0.0, 1.0) + right_vector = Point3f(1.0, 0.0, 0.0) + ap_vector = Point3f(0.0, 1.0, 0.0) + circ_pts = get_circle_points(right_vector, normal_vector, Point3f(0.0, 0.0, 0.0)) + map(zip(sections_radii,s)) do (radii, ds) + Point3f.(circ_pts .* radii .+ (ap_vector*ds,)) + end +end \ No newline at end of file diff --git a/ShroffCelegansModelsCore/src/types.jl b/ShroffCelegansModelsCore/src/types.jl new file mode 100644 index 0000000..6c34ca4 --- /dev/null +++ b/ShroffCelegansModelsCore/src/types.jl @@ -0,0 +1,138 @@ +module Types + using GeometryBasics: Point, Point3f, Point3 + using QuadGK: quadgk + using LinearAlgebra: norm + using BSplineKit: Derivative, knots + import BSplineKit.SplineInterpolations: interpolation_points + + using ..ParametricSplines: interpolate_natural_cubic_spline + + export AbstractCelegansModel, CelegansModel, CachedCelegansModel, StraightenedCelegansModel + export central_spline, central_spline_d1 + export transverse_spline, num_transverse_splines, transverse_splines + export lattice_knots + export model_length + export names + export interpolation_points + + abstract type AbstractCelegansModel{S} end + central_spline_d1(model::AbstractCelegansModel) = Derivative(1) * central_spline(model) + model_length(model::AbstractCelegansModel) = first(quadgk(central_spline(model))) + length(model::AbstractCelegansModel) = ceil(Int, model_length(model)) + 1 + Base.length(model::AbstractCelegansModel) = length(model) + transverse_splines(model::AbstractCelegansModel) = map(1:num_transverse_splines(model)) do i + transverse_spline(model, i) + end + lattice_knots(model::AbstractCelegansModel) = knots(central_spline(model))[4:end-3] + interpolation_points(model::AbstractCelegansModel) = interpolation_points(first(transverse_splines(model))) + + struct CelegansModel{S, N} <: AbstractCelegansModel{S} + transverse_splines::Vector{S} + central_spline::S + names::Vector{N} + end + + central_coordinate(model::CelegansModel, t::Float64) = model.central_spline(t) + central_spline(model::CelegansModel) = model.central_spline + transverse_spline(model::CelegansModel, i::Integer) = model.transverse_splines[i] + num_transverse_splines(model::CelegansModel) = Base.length(model.transverse_splines) + names(model::CelegansModel) = model.names + + struct CachedCelegansModel{S} <: AbstractCelegansModel{S} + model::CelegansModel{S} + central_spline_d1::S + model_length::Float64 + length::Int + function CachedCelegansModel(model::AbstractCelegansModel{S}) where S + new{S}( + model, + central_spline_d1(model), + model_length(model), + length(model) + ) + end + end + central_coordinate(model::CachedCelegansModel, t::Float64) = central_coordinate(model.model, t) + central_spline(model::CachedCelegansModel) = central_spline(model.model) + transverse_spline(model::CachedCelegansModel, i::Integer) = transverse_spline(model.model, i) + central_spline_d1(model::CachedCelegansModel) = model.central_spline_d1 + model_length(model::CachedCelegansModel) = model.model_length + length(model::CachedCelegansModel) = model.length + Base.length(model::CachedCelegansModel) = length(model) + parent(model::CachedCelegansModel) = model.model + Base.parent(model::CachedCelegansModel) = parent(model) + num_transverse_splines(model::CachedCelegansModel) = num_transverse_splines(parent(model)) + names(model::CachedCelegansModel) = names(parent(model)) + + + + struct StraightenedTransverseSpline{S} + transverse_spline::S + central_spline::S + straightened_central_spline::S + transverse_vector::Point3f + end + function (s::StraightenedTransverseSpline)(t) + r = norm(s.transverse_spline(t) - s.central_spline(t)) + return s.straightened_central_spline(t) + r*s.transverse_vector + end + function StraightenedTransverseSpline(model, straightened_model, i::Integer) + degree = 360/Base.length(model.transverse_splines)*(i-1) + StraightenedTransverseSpline( + model.transverse_splines[i], + model.central_spline, + straightened_model.central_spline, + Point3f(cosd(degree), sind(degree), 0) + ) + end + interpolation_points(sts::StraightenedTransverseSpline) = interpolation_points(sts.transverse_spline) + + struct StraightenedCelegansModel{S} <: AbstractCelegansModel{S} + twisted_model::CelegansModel{S} + central_spline::S + end + function StraightenedCelegansModel(twisted_model::CelegansModel{S}) where S + d = central_spline_d1(twisted_model) + r = LinRange(0, 1, length(twisted_model)) + n = norm.(d.(r)) + s = cumsum([0; (n[1:end-1] .+ n[2:end])./2]) .* step(r) + #z = interpolate_natural_cubic_spline([0,0.25,0.5,0.75,1],[0.0,0.0,0.0,0.0,0.0]) + s = map(s) do z + Point3(0, 0, z) + end + central_straightened = interpolate_natural_cubic_spline(collect(r), s) + #S([z, z, central_straightened]) + #typeof(central_straighted) + StraightenedCelegansModel( + twisted_model, + central_straightened + ) + end + function transverse_spline(smodel::StraightenedCelegansModel, i) + return StraightenedTransverseSpline(smodel.twisted_model, smodel, i) + end + parent(smodel::StraightenedCelegansModel) = smodel.twisted_model + Base.parent(smodel::StraightenedCelegansModel) = parent(smodel) + central_spline(smodel::StraightenedCelegansModel) = smodel.central_spline + length(smodel::StraightenedCelegansModel) = length(parent(smodel)) + num_transverse_splines(model::StraightenedCelegansModel) = num_transverse_splines(parent(model)) + names(model::StraightenedCelegansModel) = names(parent(model)) + lattice_knots(model::StraightenedCelegansModel) = lattice_knots(parent(model)) + + """ + RadialCelegansModel + + The radial C. elegans model consists of a 3-dimensional parametric spline describing the central axis of the worm. + The transverse axes that run from anterior to posterior are defined by their radial distance from the the central spline + along regular radial spokes normal to the derivative of the central spline. These are modeled as 1-dimensional interpolate_natural_cubic_spline + cubic splines. + + This differs from `CelegansModel` where the transverse_splines are 3-dimensional parameteric splines rather than 1-dimensional splines. + """ + struct RadialCelegansModel{C,R} <: AbstractCelegansModel{C} + transverse_splines::Vector{R} + central_spline::C + names::Vector{String} + end + +end \ No newline at end of file diff --git a/ShroffCelegansModelsCore/src/util.jl b/ShroffCelegansModelsCore/src/util.jl new file mode 100644 index 0000000..96ee8ee --- /dev/null +++ b/ShroffCelegansModelsCore/src/util.jl @@ -0,0 +1,14 @@ +const get_circle_points = let N=32, θ = (0:N-1)//N*2, cθ = cospi.(θ), sθ = sinpi.(θ) + function _get_circle_points(right_vector, normal_vector, center_point) + # This could be precomputed once + #= + θ = LinRange(0, 2π, 33)[1:end-1] + cθ = cos.(θ) + sθ = sin.(θ) + =# + map(cθ, sθ) do c, s + # This is done to match mipav + right_vector*c + normal_vector*s + center_point + end + end +end \ No newline at end of file From 9a4b240779d2af3fc3c2b0413d689a553aa14702 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Mon, 22 Sep 2025 16:41:57 -0400 Subject: [PATCH 02/12] Add test fixture to core for precompilation --- .../test/fixtures/lattice.csv | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 ShroffCelegansModelsCore/test/fixtures/lattice.csv diff --git a/ShroffCelegansModelsCore/test/fixtures/lattice.csv b/ShroffCelegansModelsCore/test/fixtures/lattice.csv new file mode 100644 index 0000000..ee7f877 --- /dev/null +++ b/ShroffCelegansModelsCore/test/fixtures/lattice.csv @@ -0,0 +1,30 @@ +name,x_voxels,y_voxels,z_voxels,R,G,B +a0L,195.97067,178.42632,192.82758,255,255,255 +a0R,205.72282,191.17865,160.226,255,255,255 +H0L,160.43826,285.92215,242.20377,255,255,255 +H0R,203.20029,327.54312,187.63791,255,255,255 +H1L,91.85581,303.10947,179.9281,255,255,255 +H1R,157.36949,334.55258,140.4563,255,255,255 +H2L,103.04024,210.11894,129.78345,255,255,255 +H2R,186.88806,233.83644,107.38234,255,255,255 +V1L,127.986465,143.09319,128.56294,255,255,255 +V1R,197.757,147.5629,109.8419,255,255,255 +V2L,138.03006,82.63126,127.19537,255,255,255 +V2R,191.63826,69.81546,156.15752,255,255,255 +V3L,108.53674,123.997574,154.49594,255,255,255 +V3R,135.06374,89.337296,211.64114,255,255,255 +V4L,102.896484,159.45047,169.14429,255,255,255 +V4R,124.21839,144.10689,219.9511,255,255,255 +QL,102.62361,200.74202,160.73094,255,255,255 +QR,116.48996,212.23213,212.06146,255,255,255 +V5L,159.85123,259.1043,195.01169,255,255,255 +V5R,139.79425,234.0893,242.91919,255,255,255 +V6L,175.77122,182.80353,188.1056,255,255,255 +V6R,145.4298,164.18112,237.1674,255,255,255 +a1L,192.82039,150.30984,198.40149,255,255,255 +a1R,174.73495,116.21337,205.18045,255,255,255 +TL,206.6915,174.7693,154.60092,255,255,255 +TR,205.69138,160.05684,145.31961,255,255,255 +a2L,203.54361,191.1746,124.293655,255,255,255 +a2R,204.04729,182.33946,118.979744,255,255,255 + From 82ef3f41f513d250ab28950392a550dc179dd097 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Mon, 22 Sep 2025 16:58:06 -0400 Subject: [PATCH 03/12] Change references to non-core to core --- .../src/annotation_untwist.jl | 38 +++++++++++-------- ShroffCelegansModelsCore/src/average.jl | 2 +- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/ShroffCelegansModelsCore/src/annotation_untwist.jl b/ShroffCelegansModelsCore/src/annotation_untwist.jl index 6fff3d6..5004a4d 100644 --- a/ShroffCelegansModelsCore/src/annotation_untwist.jl +++ b/ShroffCelegansModelsCore/src/annotation_untwist.jl @@ -13,13 +13,13 @@ Find the nearest central point on the model to each annotation point. """ function nearest_central_pt(model::AbstractCelegansModel, pts::AbstractVector{<: Point}, expansion_factor = 1.0) # Sample points along the central spline - cs = ShroffCelegansModels.central_spline(model) + cs = ShroffCelegansModelsCore.central_spline(model) Npts = length(model) z = LinRange(0, 1, Npts) central_pts = cs.(z) # For each sampled point calculate the maximum radius of the cross section - max_r_func = ShroffCelegansModels.max_radius_function(model) + max_r_func = ShroffCelegansModelsCore.max_radius_function(model) radius = max_r_func.(z) # For each annotation point, find the nearest central point @@ -60,7 +60,7 @@ function get_central_point_parameters( pts::AbstractVector{<: Point}, central_spline_voxel_distances::AbstractVector{<: Real} ) - cs = ShroffCelegansModels.central_spline(model) + cs = ShroffCelegansModelsCore.central_spline(model) Npts = length(model) z = LinRange(0, 1, Npts) central_pts = cs.(z) @@ -86,7 +86,7 @@ function max_radius_function(model) end function nearest_central_plane(model::AbstractCelegansModel, pts::AbstractVector{<: Point}) - cs = ShroffCelegansModels.central_spline(model) + cs = ShroffCelegansModelsCore.central_spline(model) dcs = Derivative(1)*cs Npts = length(model) @@ -94,7 +94,7 @@ function nearest_central_plane(model::AbstractCelegansModel, pts::AbstractVector central_pts = cs.(r) - ts1 = ShroffCelegansModels.transverse_spline(model, 1) + ts1 = ShroffCelegansModelsCore.transverse_spline(model, 1) right = ts1.(r) right_vec = right .- ncp right_norm = norm.(right_vec) @@ -133,14 +133,14 @@ Untwist the annotations by computing their position relative to the central spli # Example ```julia using ShroffCelegansModels -using ShroffCelegansModels.MIPAVIO +using ShroffCelegansModelsCore.MIPAVIO -dataset = ShroffCelegansModels.NormalizedDataset("X:/shrofflab/OD1599_NU/120619_Pos2/Decon_reg/RegB") -mts = ShroffCelegansModels.ModelTimeSeries(dataset) +dataset = ShroffCelegansModelsCore.NormalizedDataset("X:/shrofflab/OD1599_NU/120619_Pos2/Decon_reg/RegB") +mts = ShroffCelegansModelsCore.ModelTimeSeries(dataset) model = mts(1) df = MIPAVIO.get_integrated_annotations(dataset, 1) pts = MIPAVIO.mipav_df_to_points(df) -ShroffCelegansModels.untwist_annotations(model, pts) +ShroffCelegansModelsCore.untwist_annotations(model, pts) ``` # Notes @@ -174,12 +174,12 @@ function untwist_annotations( # Objective: Compute the angle between the right direction and the point # The first transverse spline is used to determine which direction is the right side - ts1 = ShroffCelegansModels.transverse_spline(model, 1) + ts1 = ShroffCelegansModelsCore.transverse_spline(model, 1) right = ts1.(t) # Obtain the central spline and its derivative # The derivative should point along the spline - cs = ShroffCelegansModels.central_spline(model) + cs = ShroffCelegansModelsCore.central_spline(model) dcs = Derivative(1)*cs # Obtain the vector from the nearest central point to the annotation @@ -229,6 +229,14 @@ function untwist_annotation( return only(untwist_annotations(model, pts, central_spline_voxel_distances)) end +function untwist_annotation( + model::AbstractCelegansModel, + pt::AbstractArray, +) + pt = Point3(pt) + return untwist_annotation(model, pt, central_spline_voxel_distance) +end + """ untwist_annotations(dataset::NormalizedDataset, timepoint::Int=1) @@ -245,9 +253,9 @@ Untwist the annotations at a specific timepoint in the dataset. ```julia using ShroffCelegansModels -dataset = ShroffCelegansModels.NormalizedDataset("X:/shrofflab/OD1599_NU/120619_Pos2/Decon_reg/RegB") +dataset = ShroffCelegansModelsCore.NormalizedDataset("X:/shrofflab/OD1599_NU/120619_Pos2/Decon_reg/RegB") # Obtain the untwisted annotations for the C3 cell at timepoint 71 -c3_pt = ShroffCelegansModels.untwist_annotations(dataset, 71)["C3"] +c3_pt = ShroffCelegansModelsCore.untwist_annotations(dataset, 71)["C3"] ``` """ function untwist_annotations(dataset::NormalizedDataset, timepoint::Int=1) @@ -273,7 +281,7 @@ end function distance_to_twisted_annotation(model::AbstractCelegansModel, pt::Point) # Sample points along the central spline - cs = ShroffCelegansModels.central_spline(model) + cs = ShroffCelegansModelsCore.central_spline(model) dcs = Derivative(1)*cs Npts = length(model) z = LinRange(0, 1, Npts) @@ -282,7 +290,7 @@ function distance_to_twisted_annotation(model::AbstractCelegansModel, pt::Point) annotation_norms = norm.(annotation_vecs) unit_annotation_vecs = annotation_vecs ./ annotation_norms - ts1 = ShroffCelegansModels.transverse_spline(model, 1) + ts1 = ShroffCelegansModelsCore.transverse_spline(model, 1) right = ts1.(z) right_vecs = right .- central_pts right_norms = norm.(right_vecs) diff --git a/ShroffCelegansModelsCore/src/average.jl b/ShroffCelegansModelsCore/src/average.jl index 3eb265a..9dfd072 100644 --- a/ShroffCelegansModelsCore/src/average.jl +++ b/ShroffCelegansModelsCore/src/average.jl @@ -7,7 +7,7 @@ const psuedo_seam_cells = ("a0L", "H0L", "H1L", "H2L", "V1L", "V2L", "V3L", "V4L function average(models::Vector{<: AbstractCelegansModel}, weights::AbstractWeights = uweights(length(models)); n_upsample::Int = 0) _names = map(models) do model #parent(model).names[1:2:end] - ShroffCelegansModels.Types.names(model)[1:2:end] + ShroffCelegansModelsCore.Types.names(model)[1:2:end] end common_names = intersect(_names..., psuedo_seam_cells) From e0720ae66a02fabcffd7c4685be4d6b226ee6265 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Thu, 26 Jun 2025 11:09:41 -0400 Subject: [PATCH 04/12] Add web changes for fix_annotation_ap_axis.jl --- src/demo_averaging/fix_annotation_ap_axis.jl | 19 +++++++++---------- web/scripts/web_fix_annotation_ap_axis.jl | 6 ++++-- web/static/index.html | 1 + 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/demo_averaging/fix_annotation_ap_axis.jl b/src/demo_averaging/fix_annotation_ap_axis.jl index 53314cd..5741430 100644 --- a/src/demo_averaging/fix_annotation_ap_axis.jl +++ b/src/demo_averaging/fix_annotation_ap_axis.jl @@ -80,10 +80,10 @@ function fix_annotation_ap_axis( ] ) f[7, :] = buttongrid = GridLayout(tellwidth = false) - prev_button = buttongrid[1, 1] = Button(f, label = "Previous") - reset_button = buttongrid[1, 2] = Button(f, label = "Reset") - update_button = buttongrid[1, 3] = Button(f, label = "Update") - next_button = buttongrid[1, 4] = Button(f, label = "Next") + prev_button = buttongrid[1, 1] = Makie.Makie.Button(f, label = "Previous") + reset_button = buttongrid[1, 2] = Makie.Button(f, label = "Reset") + update_button = buttongrid[1, 3] = Makie.Button(f, label = "Update") + next_button = buttongrid[1, 4] = Makie.Button(f, label = "Next") n_upsample = 2 @@ -670,16 +670,16 @@ function fix_annotation_ap_axis_persist_server(; port = ANNOTATION_PERSIST_SERVE if column_count == 0 @info "Creating columns in HDF5 group $group_name" original_position_group = create_dataset( - h5g, "original_position", Float64, (3,1), max_dims = (3,-1), chunk=(3,16) + h5g, "original_position", Float64, ((3,1), (3,-1)), chunk=(3,16) ) new_position_group = create_dataset( - h5g, "new_position", Float64, (3,1), max_dims = (3,-1), chunk=(3,16) + h5g, "new_position", Float64, ((3,1), (3,-1)), chunk=(3,16) ) timestamp_group = create_dataset( - h5g, "timestamp", Float64, (1,), max_dims = (-1,), chunk=(16,) + h5g, "timestamp", Float64, ((1,), (-1,)), chunk=(16,) ) ip_address_group = create_dataset( - h5g, "ip_address", UInt64, (1,), max_dims = (-1,), chunk=(16,) + h5g, "ip_address", UInt64, ((1,), (-1,)), chunk=(16,) ) elseif column_count == length(column_names) @info "Columns already exist in HDF5 group $group_name" @@ -732,7 +732,6 @@ function shutdown_server() close(s) end - function load_annotation_changes_cache(filepath = joinpath(@__DIR__, "..", "..", "annotation_changes.h5")) # changes = Dict{String,Pair{Vector{Point3{Float64}},Vector{Point3{Float64}}}}() changes = Dict{String,Pair{Point3{Float64},Point3{Float64}}}() @@ -855,4 +854,4 @@ function update_annotations_cache( annotations_cache[annotations_cache_key][timepoint][string(annotation_symbol)] = swapyz_unscale(new_pt) end return annotations_cache -end \ No newline at end of file +end diff --git a/web/scripts/web_fix_annotation_ap_axis.jl b/web/scripts/web_fix_annotation_ap_axis.jl index 73d09c4..3a329ad 100644 --- a/web/scripts/web_fix_annotation_ap_axis.jl +++ b/web/scripts/web_fix_annotation_ap_axis.jl @@ -15,20 +15,21 @@ function web_debug_annotation_ap_axis(datasets = datasets) DOM.li(k), DOM.ul( map(collect(keys(datasets[k]))) do i - DOM.li(DOM.a(datasets[k][i].path, href="/debug_annotation_ap_axis/$k/$i")) + DOM.li(DOM.a(datasets[k][i].path, href="/fix_annotation_ap_axis/$k/$i")) end ) end ) ) server = Server( - "shroff-data.int.janelia.org", 9281; + "shroff-data.int.janelia.org", 9381; proxy_url="https://shroff-data.int.janelia.org/fix_annotation_ap_axis/" ) route!(server, "/" => App(menu)) for k in keys(datasets) for i in keys(datasets[k]) route!(server, "/$k/$i" => App(; title="$k[$i]: Shroff C. elegans fix annotation AP axis") do + empty!(annotations_cache) return fix_annotation_ap_axis(avg_models, datasets[k][i]; use_myuntwist=true); end) end @@ -37,6 +38,7 @@ function web_debug_annotation_ap_axis(datasets = datasets) end function web_main() + Threads.@spawn fix_annotation_ap_axis_persist_server() WGLMakie.activate!(; resize_to = :body) server = web_debug_annotation_ap_axis() end diff --git a/web/static/index.html b/web/static/index.html index 0f8309a..45eb7fe 100644 --- a/web/static/index.html +++ b/web/static/index.html @@ -9,6 +9,7 @@

Internal Shroff Data

  • Debug Annotation AP Axis
  • Debug Annotation AP Axis (Live untwisting!)
  • Debug Annotation AP Axis Retrack (Live untwisting!)
  • +
  • Fix Annotation AP Axis
  • Mesh Scatter
    • Mesh Scatter Average Edited
    • From a28356a7d9eb5b9fd8cc7a9d9cdec9e676b79bdc Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Tue, 30 Sep 2025 07:50:28 -0400 Subject: [PATCH 05/12] Prune dependencies --- Project.toml | 18 +- web/Manifest.toml | 686 ++++++++++++++++------------------------------ 2 files changed, 240 insertions(+), 464 deletions(-) diff --git a/Project.toml b/Project.toml index aedcb47..4818e05 100644 --- a/Project.toml +++ b/Project.toml @@ -6,7 +6,6 @@ version = "1.0.0-DEV" [deps] BSplineKit = "093aae92-e908-43d7-9660-e50ee39d5a0a" CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" -CircStats = "2f6764a1-d620-4564-9394-76eb7c776766" ColorSchemes = "35d6a980-a343-548e-a6ea-1d62b119f2f4" Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" CoordinateTransformations = "150eb455-5306-5404-9cee-2592286d6298" @@ -14,21 +13,15 @@ DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" -ImageContrastAdjustment = "f332f351-ec65-5f6a-b3d1-319c6670881a" -ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" -ImageFiltering = "6a3955dd-da59-5b1f-98d4-e7296123deb5" -IndirectArrays = "9b13fd28-a010-5f03-acff-a1bbcff69959" InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" LRUCache = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" Missings = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" Observables = "510215fc-4207-5dde-b226-833fc4488ee2" Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" @@ -36,25 +29,22 @@ PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca" QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -Rotations = "6038ab10-8711-5258-84ad-4b1120ba62dc" +Sockets = "6462fe0b-24de-5631-8697-dd941f90decc" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" ThinPlateSplines = "1d861738-f48e-4029-b1d3-81ce6bc7f5ab" TiffImages = "731e570b-9d59-4bfa-96dc-6df516fadf69" -UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228" [compat] BSplineKit = "0.18, 0.19" -CircStats = "1" Dates = "1.11.0" -FiniteDifferences = "0.12" +GeometryBasics = "0.4.11, 0.5" HDF5 = "0.17.2" -ImageContrastAdjustment = "0.3" -ImageCore = "0.10" Interpolations = "0.15, 0.16" -MakieCore = "0.8, 0.9" +Makie = "0.24.6" ProgressMeter = "1" +Sockets = "1.11.0" ThinPlateSplines = "0.1, 0.2.0" julia = "1" diff --git a/web/Manifest.toml b/web/Manifest.toml index f6c1924..a19f421 100644 --- a/web/Manifest.toml +++ b/web/Manifest.toml @@ -1,6 +1,6 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.11.5" +julia_version = "1.11.7" manifest_format = "2.0" project_hash = "b6de7f73656daa59cf3ddd435064a84acb8999d5" @@ -20,35 +20,11 @@ git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" version = "0.4.5" -[[deps.Accessors]] -deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"] -git-tree-sha1 = "3b86719127f50670efe356bc11073d84b4ed7a5d" -uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" -version = "0.1.42" - - [deps.Accessors.extensions] - AxisKeysExt = "AxisKeys" - IntervalSetsExt = "IntervalSets" - LinearAlgebraExt = "LinearAlgebra" - StaticArraysExt = "StaticArrays" - StructArraysExt = "StructArrays" - TestExt = "Test" - UnitfulExt = "Unitful" - - [deps.Accessors.weakdeps] - AxisKeys = "94b1ba4f-4ee9-5380-92f1-94cde586c3c5" - IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" - LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" - Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" - [[deps.Adapt]] deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "f7817e2e585aa6d924fd714df1e2a84be7896c60" +git-tree-sha1 = "7e35fca2bdfba44d797c53dfe63a51fabf39bfc0" uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "4.3.0" +version = "4.4.0" weakdeps = ["SparseArrays", "StaticArrays"] [deps.Adapt.extensions] @@ -76,43 +52,11 @@ version = "0.4.2" uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" version = "1.1.2" -[[deps.ArrayInterface]] -deps = ["Adapt", "LinearAlgebra"] -git-tree-sha1 = "9606d7832795cbef89e06a550475be300364a8aa" -uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.19.0" - - [deps.ArrayInterface.extensions] - ArrayInterfaceBandedMatricesExt = "BandedMatrices" - ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" - ArrayInterfaceCUDAExt = "CUDA" - ArrayInterfaceCUDSSExt = "CUDSS" - ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" - ArrayInterfaceChainRulesExt = "ChainRules" - ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" - ArrayInterfaceReverseDiffExt = "ReverseDiff" - ArrayInterfaceSparseArraysExt = "SparseArrays" - ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" - ArrayInterfaceTrackerExt = "Tracker" - - [deps.ArrayInterface.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" - ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - [[deps.ArrayLayouts]] -deps = ["FillArrays", "LinearAlgebra"] -git-tree-sha1 = "4e25216b8fea1908a0ce0f5d87368587899f75be" +deps = ["FillArrays", "LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "120e392af69350960b1d3b89d41dcc1d66543858" uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" -version = "1.11.1" +version = "1.11.2" weakdeps = ["SparseArrays"] [deps.ArrayLayouts.extensions] @@ -136,15 +80,15 @@ version = "1.1.0" [[deps.AxisArrays]] deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] -git-tree-sha1 = "16351be62963a67ac4083f748fdb3cca58bfd52f" +git-tree-sha1 = "4126b08903b777c88edf1754288144a0492c05ad" uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" -version = "0.4.7" +version = "0.4.8" [[deps.BSplineKit]] deps = ["ArrayLayouts", "BandedMatrices", "FastGaussQuadrature", "ForwardDiff", "LinearAlgebra", "PrecompileTools", "Random", "Reexport", "SparseArrays", "Static", "StaticArrays", "StaticArraysCore", "StatsAPI"] -git-tree-sha1 = "8950181792e94c20b204b4d25cba7f2399c5b386" +git-tree-sha1 = "48b9300555c54256c12a539a3025f8d2075bea6a" uuid = "093aae92-e908-43d7-9660-e50ee39d5a0a" -version = "0.19.0" +version = "0.19.1" [[deps.BandedMatrices]] deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra", "PrecompileTools"] @@ -165,9 +109,9 @@ uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" version = "1.11.0" [[deps.BaseDirs]] -git-tree-sha1 = "03fea4a4efe25d2069c2d5685155005fc251c0a1" +git-tree-sha1 = "bca794632b8a9bbe159d56bf9e31c422671b35e0" uuid = "18cc8868-cbac-4acf-b575-c8ff214dc66f" -version = "1.3.0" +version = "1.3.2" [[deps.BitFlags]] git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" @@ -176,9 +120,9 @@ version = "0.1.9" [[deps.Bonito]] deps = ["Base64", "CodecZlib", "Colors", "Dates", "Deno_jll", "HTTP", "Hyperscript", "LinearAlgebra", "Markdown", "MsgPack", "Observables", "RelocatableFolders", "SHA", "Sockets", "Tables", "ThreadPools", "URIs", "UUIDs", "WidgetsBase"] -git-tree-sha1 = "548dd16e479145c8ba8f8545b854ccc898a43ff6" +git-tree-sha1 = "fba5fbd21c53c731c1a291e27d50edee096950a3" uuid = "824d6782-a2ef-11e9-3a09-e5662e0c26f8" -version = "4.0.5" +version = "4.1.3" [[deps.Bzip2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -221,9 +165,9 @@ version = "1.1.1" [[deps.CairoMakie]] deps = ["CRC32c", "Cairo", "Cairo_jll", "Colors", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools"] -git-tree-sha1 = "0afa2b4ac444b9412130d68493941e1af462e26a" +git-tree-sha1 = "f8caabc5a1c1fb88bcbf9bc4078e5656a477afd0" uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" -version = "0.12.18" +version = "0.15.6" [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] @@ -231,28 +175,16 @@ git-tree-sha1 = "fde3bf89aead2e723284a8ff9cdf5b551ed700e8" uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" version = "1.18.5+0" -[[deps.CatIndices]] -deps = ["CustomUnitRanges", "OffsetArrays"] -git-tree-sha1 = "a0f80a09780eed9b1d106a1bf62041c2efc995bc" -uuid = "aafaddc9-749c-510e-ac4f-586e18779b91" -version = "0.2.2" - [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "1713c74e00545bfe14605d2a2be1712de8fbcb58" +git-tree-sha1 = "e4c6a16e77171a5f5e25e9646617ab1c276c5607" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.25.1" +version = "1.26.0" weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] ChainRulesCoreSparseArraysExt = "SparseArrays" -[[deps.CircStats]] -deps = ["Distributions", "HypothesisTests", "LinearAlgebra", "SpecialFunctions", "Statistics"] -git-tree-sha1 = "ecfe2e9a260c4723026b4a71460cf0420def9e40" -uuid = "2f6764a1-d620-4564-9394-76eb7c776766" -version = "1.0.4" - [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" @@ -267,21 +199,25 @@ version = "0.4.1" [[deps.ColorSchemes]] deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] -git-tree-sha1 = "403f2d8e209681fcbd9468a8514efff3ea08452e" +git-tree-sha1 = "b0fd3f56fa442f81e0a47815c92245acfaaa4e34" uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" -version = "3.29.0" +version = "3.31.0" [[deps.ColorTypes]] deps = ["FixedPointNumbers", "Random"] -git-tree-sha1 = "b10d0b65641d57b8b4d5e234446582de5047050d" +git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.11.5" +version = "0.12.1" +weakdeps = ["StyledStrings"] + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" [[deps.ColorVectorSpace]] deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] -git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" +git-tree-sha1 = "8b3b6f87ce8f65a2b4f857528fd8d70086cd72b1" uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.10.0" +version = "0.11.0" weakdeps = ["SpecialFunctions"] [deps.ColorVectorSpace.extensions] @@ -293,16 +229,6 @@ git-tree-sha1 = "37ea44092930b1811e666c3bc38065d7d87fcc74" uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" version = "0.13.1" -[[deps.Combinatorics]] -git-tree-sha1 = "8010b6bb3388abe68d95743dcbea77650bb2eddf" -uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" -version = "1.0.3" - -[[deps.CommonSolve]] -git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" -uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" -version = "0.2.4" - [[deps.CommonSubexpressions]] deps = ["MacroTools"] git-tree-sha1 = "cda2cfaebb4be89c9084adaca7dd7333369715c5" @@ -316,9 +242,9 @@ version = "1.0.0" [[deps.Compat]] deps = ["TOML", "UUIDs"] -git-tree-sha1 = "8ae8d32e09f0dcf42a36b90d4e17f5dd2e4c4215" +git-tree-sha1 = "0037835448781bb46feb39866934e243886d756a" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.16.0" +version = "4.18.0" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -329,19 +255,11 @@ deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" version = "1.1.1+0" -[[deps.CompositionsBase]] -git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" -uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" -version = "0.1.2" -weakdeps = ["InverseFunctions"] - - [deps.CompositionsBase.extensions] - CompositionsBaseInverseFunctionsExt = "InverseFunctions" - -[[deps.ComputationalResources]] -git-tree-sha1 = "52cb3ec90e8a8bea0e62e275ba577ad0f74821f7" -uuid = "ed09eef8-17a6-5b46-8889-db040fac31e3" -version = "0.3.2" +[[deps.ComputePipeline]] +deps = ["Observables", "Preferences"] +git-tree-sha1 = "cb1299fee09da21e65ec88c1ff3a259f8d0b5802" +uuid = "95dc2771-c249-4cd0-9c9f-1f3b4330693c" +version = "0.1.4" [[deps.ConcurrentUtilities]] deps = ["Serialization", "Sockets"] @@ -376,11 +294,6 @@ git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" version = "4.1.1" -[[deps.CustomUnitRanges]] -git-tree-sha1 = "1a3f97f907e6dd8983b744d2642651bb162a3f7a" -uuid = "dc8bdbbb-1ca9-579f-8c36-e416f6a65cce" -version = "1.0.2" - [[deps.DataAPI]] git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" @@ -388,15 +301,15 @@ version = "1.16.0" [[deps.DataFrames]] deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] -git-tree-sha1 = "fb61b4812c49343d7ef0b533ba982c46021938a6" +git-tree-sha1 = "c967271c27a95160e30432e011b58f42cd7501b5" uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "1.7.0" +version = "1.8.0" [[deps.DataStructures]] -deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" +deps = ["OrderedCollections"] +git-tree-sha1 = "6c72198e6a101cccdd4c9731d3985e904ba26037" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.22" +version = "0.19.1" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -488,9 +401,9 @@ version = "0.0.20230411+1" [[deps.ExactPredicates]] deps = ["IntervalArithmetic", "Random", "StaticArrays"] -git-tree-sha1 = "b3f2ff58735b5f024c392fde763f29b057e4b025" +git-tree-sha1 = "83231673ea4d3d6008ac74dc5079e77ab2209d8f" uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" -version = "2.2.8" +version = "2.2.9" [[deps.ExceptionUnwrapping]] deps = ["Test"] @@ -500,9 +413,9 @@ version = "0.1.11" [[deps.Expat_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "d55dffd9ae73ff72f1c0482454dcf2ec6c6c4a63" +git-tree-sha1 = "7bb1361afdb33c7f2b085aa49ea8fe1b0fb14e58" uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.6.5+0" +version = "2.7.1+0" [[deps.Extents]] git-tree-sha1 = "b309b36a9e02fe7be71270dd8c0fd873625332b4" @@ -511,27 +424,21 @@ version = "0.1.6" [[deps.FFMPEG]] deps = ["FFMPEG_jll"] -git-tree-sha1 = "53ebe7511fa11d33bec688a9178fac4e49eeee00" +git-tree-sha1 = "83dc665d0312b41367b7263e8a4d172eac1897f4" uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" -version = "0.4.2" +version = "0.4.4" [[deps.FFMPEG_jll]] deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] -git-tree-sha1 = "466d45dc38e15794ec7d5d63ec03d776a9aff36e" +git-tree-sha1 = "eaa040768ea663ca695d442be1bc97edfe6824f2" uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" -version = "4.4.4+1" - -[[deps.FFTViews]] -deps = ["CustomUnitRanges", "FFTW"] -git-tree-sha1 = "cbdf14d1e8c7c8aacbe8b19862e0179fd08321c2" -uuid = "4f61f5a4-77b1-5117-aa51-3ab5ef4ef0cd" -version = "0.3.2" +version = "6.1.3+0" [[deps.FFTW]] -deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] -git-tree-sha1 = "797762812ed063b9b94f6cc7742bc8883bb5e69e" +deps = ["AbstractFFTs", "FFTW_jll", "Libdl", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "97f08406df914023af55ade2f843c39e99c5d969" uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "1.9.0" +version = "1.10.0" [[deps.FFTW_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -578,9 +485,9 @@ version = "1.11.0" [[deps.FillArrays]] deps = ["LinearAlgebra"] -git-tree-sha1 = "6a70198746448456524cb442b8af316927ff3e1a" +git-tree-sha1 = "173e4d8f14230a7523ae11b9a3fa9edb3e0efd78" uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.13.0" +version = "1.14.0" weakdeps = ["PDMats", "SparseArrays", "Statistics"] [deps.FillArrays.extensions] @@ -588,12 +495,6 @@ weakdeps = ["PDMats", "SparseArrays", "Statistics"] FillArraysSparseArraysExt = "SparseArrays" FillArraysStatisticsExt = "Statistics" -[[deps.FiniteDifferences]] -deps = ["ChainRulesCore", "LinearAlgebra", "Printf", "Random", "Richardson", "SparseArrays", "StaticArrays"] -git-tree-sha1 = "06d76c780d657729cf20821fb5832c6cc4dfd0b5" -uuid = "26cc04aa-876d-5657-8c51-4c34ba976000" -version = "0.12.32" - [[deps.FixedPointNumbers]] deps = ["Statistics"] git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" @@ -602,9 +503,9 @@ version = "0.8.5" [[deps.Fontconfig_jll]] deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] -git-tree-sha1 = "301b5d5d731a0654825f1f2e906990f7141a106b" +git-tree-sha1 = "f85dac9a96a01087df6e3a749840015a0ca3817d" uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" -version = "2.16.0+0" +version = "2.17.1+0" [[deps.Format]] git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" @@ -613,9 +514,9 @@ version = "1.3.7" [[deps.ForwardDiff]] deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "910febccb28d493032495b7009dce7d7f7aee554" +git-tree-sha1 = "dc41303865a16274ecb8450c220021ce1e0cf05f" uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "1.0.1" +version = "1.2.1" weakdeps = ["StaticArrays"] [deps.ForwardDiff.extensions] @@ -652,9 +553,9 @@ version = "1.11.0" [[deps.GLFW]] deps = ["GLFW_jll"] -git-tree-sha1 = "13c52cdd876a31240da16dfb51363aed42740325" +git-tree-sha1 = "40412e58ec374029de3d4ad7c13e1a52aa1e149f" uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" -version = "3.4.4" +version = "3.4.5" [[deps.GLFW_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll", "libdecor_jll", "xkbcommon_jll"] @@ -664,32 +565,27 @@ version = "3.4.0+2" [[deps.GLMakie]] deps = ["ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeTypeAbstraction", "GLFW", "GeometryBasics", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Observables", "PrecompileTools", "Printf", "ShaderAbstractions", "StaticArrays"] -git-tree-sha1 = "8753fba3356131357b5cd02500fe80c3668535d0" +git-tree-sha1 = "0d27753bf95dc7c5e3952189a1bec78b5ac7b784" uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.10.18" - -[[deps.GeoFormatTypes]] -git-tree-sha1 = "8e233d5167e63d708d41f87597433f59a0f213fe" -uuid = "68eda718-8dee-11e9-39e7-89f7f65f511f" -version = "0.4.4" - -[[deps.GeoInterface]] -deps = ["DataAPI", "Extents", "GeoFormatTypes"] -git-tree-sha1 = "294e99f19869d0b0cb71aef92f19d03649d028d5" -uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" -version = "1.4.1" +version = "0.13.6" [[deps.GeometryBasics]] -deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] -git-tree-sha1 = "b62f2b2d76cee0d61a2ef2b3118cd2a3215d3134" +deps = ["EarCut_jll", "Extents", "IterTools", "LinearAlgebra", "PrecompileTools", "Random", "StaticArrays"] +git-tree-sha1 = "1f5a80f4ed9f5a4aada88fc2db456e637676414b" uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" -version = "0.4.11" +version = "0.5.10" + + [deps.GeometryBasics.extensions] + GeometryBasicsGeoInterfaceExt = "GeoInterface" -[[deps.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" + [deps.GeometryBasics.weakdeps] + GeoInterface = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" + +[[deps.GettextRuntime_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll"] +git-tree-sha1 = "45288942190db7c5f760f59c04495064eedf9340" +uuid = "b0724c58-0f36-5564-988d-3bb0596ebc4a" +version = "0.22.4+0" [[deps.Giflib_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -698,10 +594,10 @@ uuid = "59f7168a-df46-5410-90c8-f2779963d0ec" version = "5.2.3+0" [[deps.Glib_jll]] -deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] -git-tree-sha1 = "fee60557e4f19d0fe5cd169211fdda80e494f4e8" +deps = ["Artifacts", "GettextRuntime_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "50c11ffab2a3d50192a228c313f05b5b5dc5acb2" uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.84.0+0" +version = "2.86.0+0" [[deps.Glob]] git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" @@ -722,9 +618,9 @@ version = "1.3.15+0" [[deps.GridLayoutBase]] deps = ["GeometryBasics", "InteractiveUtils", "Observables"] -git-tree-sha1 = "dc6bed05c15523624909b3953686c5f5ffa10adc" +git-tree-sha1 = "93d5c27c8de51687a2c70ec0716e6e76f298416f" uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" -version = "0.11.1" +version = "0.11.2" [[deps.Grisu]] git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" @@ -751,9 +647,9 @@ version = "1.14.6+0" [[deps.HTTP]] deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] -git-tree-sha1 = "f93655dc73d7a0b4a368e3c0bce296ae035ad76e" +git-tree-sha1 = "ed5e9c58612c4e081aecdb6e1a479e18462e041e" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.16" +version = "1.10.17" [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"] @@ -762,10 +658,10 @@ uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" version = "8.5.1+0" [[deps.Hwloc_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "92f65c4d78ce8cdbb6b68daf88889950b0a99d11" +deps = ["Artifacts", "JLLWrappers", "Libdl", "XML2_jll", "Xorg_libpciaccess_jll"] +git-tree-sha1 = "3d468106a05408f9f7b6f161d9e7715159af247b" uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.12.1+0" +version = "2.12.2+0" [[deps.HypergeometricFunctions]] deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] @@ -779,12 +675,6 @@ git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" version = "0.0.5" -[[deps.HypothesisTests]] -deps = ["Combinatorics", "Distributions", "LinearAlgebra", "Printf", "Random", "Roots", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] -git-tree-sha1 = "15319d5a767eb386bc4b702d5e025a0be62be293" -uuid = "09f84164-cd44-5f33-b23f-e6b0d136a0d5" -version = "0.11.5" - [[deps.IfElse]] git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" @@ -802,24 +692,12 @@ git-tree-sha1 = "eb49b82c172811fd2c86759fa0553a2221feb909" uuid = "c817782e-172a-44cc-b673-b171935fbb9e" version = "0.1.7" -[[deps.ImageContrastAdjustment]] -deps = ["ImageBase", "ImageCore", "ImageTransformations", "Parameters"] -git-tree-sha1 = "eb3d4365a10e3f3ecb3b115e9d12db131d28a386" -uuid = "f332f351-ec65-5f6a-b3d1-319c6670881a" -version = "0.3.12" - [[deps.ImageCore]] deps = ["ColorVectorSpace", "Colors", "FixedPointNumbers", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "PrecompileTools", "Reexport"] git-tree-sha1 = "8c193230235bbcee22c8066b0374f63b5683c2d3" uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" version = "0.10.5" -[[deps.ImageFiltering]] -deps = ["CatIndices", "ComputationalResources", "DataStructures", "FFTViews", "FFTW", "ImageBase", "ImageCore", "LinearAlgebra", "OffsetArrays", "PrecompileTools", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "TiledIteration"] -git-tree-sha1 = "eea3a5095c0c5f143e62773164ab11f67e43c4bb" -uuid = "6a3955dd-da59-5b1f-98d4-e7296123deb5" -version = "0.7.10" - [[deps.ImageIO]] deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs", "WebP"] git-tree-sha1 = "696144904b76e1ca433b886b4e7edd067d76cbf7" @@ -832,12 +710,6 @@ git-tree-sha1 = "2a81c3897be6fbcde0802a0ebe6796d0562f63ec" uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" version = "0.9.10" -[[deps.ImageTransformations]] -deps = ["AxisAlgorithms", "CoordinateTransformations", "ImageBase", "ImageCore", "Interpolations", "OffsetArrays", "Rotations", "StaticArrays"] -git-tree-sha1 = "dfde81fafbe5d6516fb864dc79362c5c6b973c82" -uuid = "02fcd773-0e25-5acc-982a-7f6622650795" -version = "0.10.2" - [[deps.Imath_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "0936ba688c6d201805a83da835b55c61a180db52" @@ -855,9 +727,9 @@ uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" version = "0.1.5" [[deps.InlineStrings]] -git-tree-sha1 = "6a9fde685a7ac1eb3495f8e812c5a7c3711c2d5e" +git-tree-sha1 = "8f3d257792a522b4601c24a577954b0a8cd7334d" uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" -version = "1.4.3" +version = "1.4.5" [deps.InlineStrings.extensions] ArrowTypesExt = "ArrowTypes" @@ -869,9 +741,9 @@ version = "1.4.3" [[deps.IntelOpenMP_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] -git-tree-sha1 = "0f14a5456bdc6b9731a5682f439a672750a09e48" +git-tree-sha1 = "ec1debd61c300961f98064cfb21287613ad7f303" uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2025.0.4+0" +version = "2025.2.0+0" [[deps.InteractiveUtils]] deps = ["Markdown"] @@ -879,23 +751,24 @@ uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" version = "1.11.0" [[deps.Interpolations]] -deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] -git-tree-sha1 = "88a101217d7cb38a7b481ccd50d21876e1d1b0e0" +deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] +git-tree-sha1 = "65d505fa4c0d7072990d659ef3fc086eb6da8208" uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" -version = "0.15.1" -weakdeps = ["Unitful"] +version = "0.16.2" +weakdeps = ["ForwardDiff", "Unitful"] [deps.Interpolations.extensions] + InterpolationsForwardDiffExt = "ForwardDiff" InterpolationsUnitfulExt = "Unitful" [[deps.IntervalArithmetic]] -deps = ["CRlibm", "MacroTools", "OpenBLASConsistentFPCSR_jll", "Random", "RoundingEmulator"] -git-tree-sha1 = "694c52705f8b23dc5b39eeac629dc3059a168a40" +deps = ["CRlibm", "MacroTools", "OpenBLASConsistentFPCSR_jll", "Printf", "Random", "RoundingEmulator"] +git-tree-sha1 = "815e74f416953c348c9da1d1bc977bbc97c84e18" uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -version = "0.22.35" -weakdeps = ["DiffRules", "ForwardDiff", "IntervalSets", "LinearAlgebra", "RecipesBase", "SparseArrays"] +version = "1.0.0" [deps.IntervalArithmetic.extensions] + IntervalArithmeticArblibExt = "Arblib" IntervalArithmeticDiffRulesExt = "DiffRules" IntervalArithmeticForwardDiffExt = "ForwardDiff" IntervalArithmeticIntervalSetsExt = "IntervalSets" @@ -903,6 +776,15 @@ weakdeps = ["DiffRules", "ForwardDiff", "IntervalSets", "LinearAlgebra", "Recipe IntervalArithmeticRecipesBaseExt = "RecipesBase" IntervalArithmeticSparseArraysExt = "SparseArrays" + [deps.IntervalArithmetic.weakdeps] + Arblib = "fb37089c-8514-4489-9461-98f9c8763369" + DiffRules = "b552c78f-8df3-52c6-915a-8e097449b14b" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + [[deps.IntervalSets]] git-tree-sha1 = "5fbb102dcb8b1a858111ae81d56682376130517d" uuid = "8197267c-284f-5f27-9208-e0e47529a953" @@ -952,9 +834,9 @@ version = "1.0.0" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] -git-tree-sha1 = "a007feb38b422fbdab534406aeca1b86823cb4d6" +git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.7.0" +version = "1.7.1" [[deps.JSON]] deps = ["Dates", "Mmap", "Parsers", "Unicode"] @@ -982,21 +864,21 @@ version = "0.1.6" [[deps.JpegTurbo_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "eac1206917768cb54957c65a615460d87b455fc1" +git-tree-sha1 = "4255f0032eafd6451d707a51d5f0248b8a165e4d" uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" -version = "3.1.1+0" +version = "3.1.3+0" [[deps.KernelDensity]] deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] -git-tree-sha1 = "7d703202e65efa1369de1279c162b915e245eed1" +git-tree-sha1 = "ba51324b894edaf1df3ab16e2cc6bc3280a2f1a7" uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" -version = "0.6.9" +version = "0.6.10" [[deps.LAME_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "170b660facf5df5de098d866564877e119141cbd" +git-tree-sha1 = "059aabebaa7c82ccb853dd4a0ee9d17796f7e1bc" uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" -version = "3.100.2+0" +version = "3.100.3+0" [[deps.LERC_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -1089,21 +971,21 @@ version = "1.18.0+0" [[deps.Libmount_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "a31572773ac1b745e0343fe5e2c8ddda7a37e997" +git-tree-sha1 = "3acf07f130a76f87c041cfb2ff7d7284ca67b072" uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" -version = "2.41.0+0" +version = "2.41.2+0" [[deps.Libtiff_jll]] deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] -git-tree-sha1 = "4ab7581296671007fc33f07a721631b8855f4b1d" +git-tree-sha1 = "f04133fe05eff1667d2054c53d59f9122383fe05" uuid = "89763e89-9b03-5906-acba-b20f662cd828" -version = "4.7.1+0" +version = "4.7.2+0" [[deps.Libuuid_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "321ccef73a96ba828cd51f2ab5b9f917fa73945a" +git-tree-sha1 = "2a7a12fc0a4e7fb773450d17975322aa77142106" uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" -version = "2.41.0+0" +version = "2.41.2+0" [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] @@ -1138,15 +1020,15 @@ version = "1.1.0" [[deps.MKL_jll]] deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] -git-tree-sha1 = "5de60bc6cb3899cd318d80d627560fae2e2d99ae" +git-tree-sha1 = "282cadc186e7b2ae0eeadbd7a4dffed4196ae2aa" uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2025.0.1+1" +version = "2025.2.0+0" [[deps.MPICH_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "3aa3210044138a1749dbd350a9ba8680869eb503" +git-tree-sha1 = "d72d0ecc3f76998aac04e446547259b9ae4c265f" uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.3.0+1" +version = "4.3.1+0" [[deps.MPIPreferences]] deps = ["Libdl", "Preferences"] @@ -1156,9 +1038,9 @@ version = "0.1.11" [[deps.MPItrampoline_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "ff91ca13c7c472cef700f301c8d752bc2aaff1a8" +git-tree-sha1 = "e214f2a20bdd64c04cd3e4ff62d3c9be7e969a59" uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.5.3+0" +version = "5.5.4+0" [[deps.MacroTools]] git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" @@ -1166,28 +1048,16 @@ uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" version = "0.5.16" [[deps.Makie]] -deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "Dates", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageBase", "ImageIO", "InteractiveUtils", "Interpolations", "IntervalSets", "InverseFunctions", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun", "Unitful"] -git-tree-sha1 = "be3051d08b78206fb5e688e8d70c9e84d0264117" +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "ComputePipeline", "Contour", "Dates", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageBase", "ImageIO", "InteractiveUtils", "Interpolations", "IntervalSets", "InverseFunctions", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "PNGFiles", "Packing", "Pkg", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun", "Unitful"] +git-tree-sha1 = "368542cde25d381e44d84c3c4209764f05f4ef19" uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.21.18" - -[[deps.MakieCore]] -deps = ["ColorTypes", "GeometryBasics", "IntervalSets", "Observables"] -git-tree-sha1 = "9019b391d7d086e841cbeadc13511224bd029ab3" -uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" -version = "0.8.12" +version = "0.24.6" [[deps.MappedArrays]] git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" version = "0.4.2" -[[deps.MarchingCubes]] -deps = ["PrecompileTools", "StaticArrays"] -git-tree-sha1 = "0e893025924b6becbae4109f8020ac0e12674b01" -uuid = "299715c1-40a9-479a-aaf9-4a633d36f717" -version = "0.1.11" - [[deps.Markdown]] deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" @@ -1195,9 +1065,9 @@ version = "1.11.0" [[deps.MathTeXEngine]] deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] -git-tree-sha1 = "31a99cb7537f812e1d6be893a71804c35979f1be" +git-tree-sha1 = "a370fef694c109e1950836176ed0d5eabbb65479" uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" -version = "0.6.4" +version = "0.6.6" [[deps.MbedTLS]] deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] @@ -1212,9 +1082,9 @@ version = "2.28.6+0" [[deps.MeshIO]] deps = ["ColorTypes", "FileIO", "GeometryBasics", "Printf"] -git-tree-sha1 = "14a12d9153b1a1a22d669eede58b2ea2164ff138" +git-tree-sha1 = "c009236e222df68e554c7ce5c720e4a33cc0c23f" uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" -version = "0.4.13" +version = "0.5.3" [[deps.MicrosoftMPI_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1285,10 +1155,10 @@ weakdeps = ["Adapt"] OffsetArraysAdaptExt = "Adapt" [[deps.Ogg_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6aa4566bb7ae78498a5e68943863fa8b5231b59" uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" -version = "1.3.5+1" +version = "1.3.6+0" [[deps.OpenBLASConsistentFPCSR_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] @@ -1320,9 +1190,9 @@ version = "0.8.5+0" [[deps.OpenMPI_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] -git-tree-sha1 = "047b66eb62f3cae59ed260ebb9075a32a04350f1" +git-tree-sha1 = "ec764453819f802fc1e144bfe750c454181bd66d" uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.7+2" +version = "5.0.8+0" [[deps.OpenSSL]] deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] @@ -1332,9 +1202,9 @@ version = "1.5.0" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "9216a80ff3682833ac4b733caa8c00390620ba5d" +git-tree-sha1 = "2ae7d4ddec2e13ad3bddf5c0796f7547cf682391" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.5.0+0" +version = "3.5.2+0" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] @@ -1344,9 +1214,9 @@ version = "0.5.6+0" [[deps.Opus_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6703a85cb3781bd5909d48730a67205f3f31a575" +git-tree-sha1 = "c392fc5dd032381919e3b22dd32d6443760ce7ea" uuid = "91d4177d-7536-5919-b921-800302f37372" -version = "1.3.3+0" +version = "1.5.2+0" [[deps.OrderedCollections]] git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" @@ -1384,15 +1254,9 @@ version = "0.5.12" [[deps.Pango_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] -git-tree-sha1 = "275a9a6d85dc86c24d03d1837a0010226a96f540" +git-tree-sha1 = "1f7f9bbd5f7a2e5a9f7d96e51c9754454ea7f60b" uuid = "36c8627f-9965-5494-a995-c6b170f724f3" -version = "1.56.3+0" - -[[deps.Parameters]] -deps = ["OrderedCollections", "UnPack"] -git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" -uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" -version = "0.12.3" +version = "1.56.4+0" [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] @@ -1446,15 +1310,15 @@ version = "1.2.1" [[deps.Preferences]] deps = ["TOML"] -git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" +git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.3" +version = "1.5.0" [[deps.PrettyTables]] -deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "1101cd475833706e4d0e7b122218257178f48f34" +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "REPL", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "5e9fe23c86d3ca630baa1efcad78575a27f158b2" uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "2.4.0" +version = "3.0.11" [[deps.Printf]] deps = ["Unicode"] @@ -1463,9 +1327,9 @@ version = "1.11.0" [[deps.ProgressMeter]] deps = ["Distributed", "Printf"] -git-tree-sha1 = "13c5103482a8ed1536a54c08d0e742ae3dca2d42" +git-tree-sha1 = "fbb92c6c56b34e1a2c4c36058f68f332bec840e7" uuid = "92933f4c-e287-5a05-a399-4b506db050ca" -version = "1.10.4" +version = "1.11.0" [[deps.PtrArrays]] git-tree-sha1 = "1d36ef11a9aaf1e8b74dacc6a731dd1de8fd493d" @@ -1490,12 +1354,6 @@ version = "2.11.2" [deps.QuadGK.weakdeps] Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" -[[deps.Quaternions]] -deps = ["LinearAlgebra", "Random", "RealDot"] -git-tree-sha1 = "994cc27cdacca10e68feb291673ec3a76aa2fae9" -uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" -version = "0.7.6" - [[deps.REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "StyledStrings", "Unicode"] uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" @@ -1521,12 +1379,6 @@ weakdeps = ["FixedPointNumbers"] [deps.Ratios.extensions] RatiosFixedPointNumbersExt = "FixedPointNumbers" -[[deps.RealDot]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" -uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" -version = "0.1.0" - [[deps.RecipesBase]] deps = ["PrecompileTools"] git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" @@ -1550,12 +1402,6 @@ git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" uuid = "ae029012-a4dd-5104-9daa-d747884805df" version = "1.3.1" -[[deps.Richardson]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "48f038bfd83344065434089c2a79417f38715c41" -uuid = "708f8203-808e-40c0-ba2d-98a6953ed40d" -version = "1.4.2" - [[deps.Rmath]] deps = ["Random", "Rmath_jll"] git-tree-sha1 = "852bd0f55565a9e973fcfee83a84413270224dc4" @@ -1568,36 +1414,6 @@ git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" version = "0.5.1+0" -[[deps.Roots]] -deps = ["Accessors", "CommonSolve", "Printf"] -git-tree-sha1 = "3ac13765751ffc81e3531223782d9512f6023f71" -uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.2.7" - - [deps.Roots.extensions] - RootsChainRulesCoreExt = "ChainRulesCore" - RootsForwardDiffExt = "ForwardDiff" - RootsIntervalRootFindingExt = "IntervalRootFinding" - RootsSymPyExt = "SymPy" - RootsSymPyPythonCallExt = "SymPyPythonCall" - - [deps.Roots.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - IntervalRootFinding = "d2bf35a9-74e0-55ec-b149-d360ff49b807" - SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" - SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c" - -[[deps.Rotations]] -deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] -git-tree-sha1 = "5680a9276685d392c87407df00d57c9924d9f11e" -uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "1.7.1" -weakdeps = ["RecipesBase"] - - [deps.Rotations.extensions] - RotationsRecipesBaseExt = "RecipesBase" - [[deps.RoundingEmulator]] git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" @@ -1613,11 +1429,16 @@ git-tree-sha1 = "fea870727142270bdf7624ad675901a1ee3b4c87" uuid = "fdea26ae-647d-5447-a871-4b548cad5224" version = "3.7.1" +[[deps.SciMLPublic]] +git-tree-sha1 = "ed647f161e8b3f2973f24979ec074e8d084f1bee" +uuid = "431bcebd-1456-4ced-9d72-93c2757fff0b" +version = "1.0.0" + [[deps.Scratch]] deps = ["Dates"] -git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" +git-tree-sha1 = "9b81b8393e50b7d4e6d0a9f14e192294d3b7c109" uuid = "6c6a2e73-6563-6170-7368-637461726353" -version = "1.2.1" +version = "1.3.0" [[deps.SentinelArrays]] deps = ["Dates", "Random"] @@ -1630,10 +1451,10 @@ uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" version = "1.11.0" [[deps.ShaderAbstractions]] -deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] -git-tree-sha1 = "79123bc60c5507f035e6d1d9e563bb2971954ec8" +deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays"] +git-tree-sha1 = "818554664a2e01fc3784becb2eb3a82326a604b6" uuid = "65257c39-d410-5151-9873-9b3e5be5013e" -version = "0.4.1" +version = "0.5.0" [[deps.SharedArrays]] deps = ["Distributed", "Mmap", "Random", "Serialization"] @@ -1647,7 +1468,7 @@ uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" version = "1.0.3" [[deps.ShroffCelegansModels]] -deps = ["BSplineKit", "CSV", "CircStats", "ColorSchemes", "Colors", "CoordinateTransformations", "DataFrames", "Dates", "FFTW", "FileIO", "FiniteDifferences", "FixedPointNumbers", "GeometryBasics", "HDF5", "ImageContrastAdjustment", "ImageCore", "ImageFiltering", "IndirectArrays", "InteractiveUtils", "Interpolations", "JSON3", "LRUCache", "LinearAlgebra", "Makie", "MakieCore", "Missings", "Observables", "Pkg", "PrecompileTools", "Printf", "ProgressMeter", "QuadGK", "Rotations", "StaticArrays", "Statistics", "StatsBase", "ThinPlateSplines", "TiffImages", "UnicodePlots"] +deps = ["BSplineKit", "CSV", "ColorSchemes", "Colors", "CoordinateTransformations", "DataFrames", "Dates", "FFTW", "FileIO", "FixedPointNumbers", "GeometryBasics", "HDF5", "InteractiveUtils", "Interpolations", "JSON3", "LRUCache", "LinearAlgebra", "Makie", "Missings", "Observables", "Pkg", "PrecompileTools", "Printf", "ProgressMeter", "QuadGK", "Sockets", "StaticArrays", "Statistics", "StatsBase", "ThinPlateSplines", "TiffImages"] path = ".." uuid = "28a312d2-d9d3-46a7-98c1-9c09f12e8c99" version = "1.0.0-DEV" @@ -1665,15 +1486,15 @@ version = "1.2.0" [[deps.SimpleTraits]] deps = ["InteractiveUtils", "MacroTools"] -git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +git-tree-sha1 = "be8eeac05ec97d379347584fa9fe2f5f76795bcb" uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.9.4" +version = "0.9.5" [[deps.Sixel]] deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] -git-tree-sha1 = "2da10356e31327c7096832eb9cd86307a50b1eb6" +git-tree-sha1 = "0494aed9501e7fb65daba895fb7fd57cc38bc743" uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" -version = "0.1.3" +version = "0.1.5" [[deps.Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" @@ -1681,9 +1502,9 @@ version = "1.11.0" [[deps.SortingAlgorithms]] deps = ["DataStructures"] -git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.2.1" +version = "1.2.2" [[deps.SparseArrays]] deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] @@ -1713,27 +1534,16 @@ uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" version = "0.1.2" [[deps.Static]] -deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools"] -git-tree-sha1 = "f737d444cb0ad07e61b3c1bef8eb91203c321eff" +deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools", "SciMLPublic"] +git-tree-sha1 = "1e44e7b1dbb5249876d84c32466f8988a6b41bbb" uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "1.2.0" - -[[deps.StaticArrayInterface]] -deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Static"] -git-tree-sha1 = "96381d50f1ce85f2663584c8e886a6ca97e60554" -uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" -version = "1.8.0" -weakdeps = ["OffsetArrays", "StaticArrays"] - - [deps.StaticArrayInterface.extensions] - StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" - StaticArrayInterfaceStaticArraysExt = "StaticArrays" +version = "1.3.0" [[deps.StaticArrays]] deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "0feb6b9031bd5c51f9072393eb5ab3efd31bf9e4" +git-tree-sha1 = "b8693004b385c842357406e3af647701fe783f98" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.13" +version = "1.9.15" weakdeps = ["ChainRulesCore", "Statistics"] [deps.StaticArrays.extensions] @@ -1763,9 +1573,9 @@ version = "1.7.1" [[deps.StatsBase]] deps = ["AliasTables", "DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "b81c5035922cc89c2d9523afc6c54be512411466" +git-tree-sha1 = "2c962245732371acd51700dbb268af311bddd719" uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.34.5" +version = "0.34.6" [[deps.StatsFuns]] deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] @@ -1786,9 +1596,9 @@ version = "0.4.1" [[deps.StructArrays]] deps = ["ConstructionBase", "DataAPI", "Tables"] -git-tree-sha1 = "9537ef82c42cdd8c5d443cbc359110cbb36bae10" +git-tree-sha1 = "8ad2e38cbb812e29348719cc63580ec1dfeb9de4" uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.6.21" +version = "0.7.1" [deps.StructArrays.extensions] StructArraysAdaptExt = "Adapt" @@ -1859,11 +1669,11 @@ version = "1.11.0" [[deps.ThinPlateSplines]] deps = ["LinearAlgebra", "Test", "Tullio"] -git-tree-sha1 = "82fbbf52cf7ed71d9bb9336b1d308e34426c3714" +git-tree-sha1 = "d89e50bd102d3d0b63a65007f4c04fca488541b1" repo-rev = "mkitti-geometrybasics-ext" repo-url = "https://github.com/mkitti/ThinPlateSplines.jl.git" uuid = "1d861738-f48e-4029-b1d3-81ce6bc7f5ab" -version = "0.2.0" +version = "0.2.1" weakdeps = ["GeometryBasics"] [deps.ThinPlateSplines.extensions] @@ -1877,15 +1687,9 @@ version = "2.1.1" [[deps.TiffImages]] deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "PrecompileTools", "ProgressMeter", "SIMD", "UUIDs"] -git-tree-sha1 = "02aca429c9885d1109e58f400c333521c13d48a0" +git-tree-sha1 = "98b9352a24cb6a2066f9ababcc6802de9aed8ad8" uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" -version = "0.11.4" - -[[deps.TiledIteration]] -deps = ["OffsetArrays", "StaticArrayInterface"] -git-tree-sha1 = "1176cc31e867217b06928e2f140c90bd1bc88283" -uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" -version = "0.5.0" +version = "0.11.6" [[deps.TranscodingStreams]] git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" @@ -1916,20 +1720,15 @@ version = "0.3.8" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" [[deps.URIs]] -git-tree-sha1 = "cbbebadbcc76c5ca1cc4b4f3b0614b3e603b5000" +git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a" uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" -version = "1.5.2" +version = "1.6.1" [[deps.UUIDs]] deps = ["Random", "SHA"] uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" version = "1.11.0" -[[deps.UnPack]] -git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" -uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" -version = "1.0.2" - [[deps.Unicode]] uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" version = "1.11.0" @@ -1940,63 +1739,44 @@ git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" version = "0.4.1" -[[deps.UnicodePlots]] -deps = ["ColorSchemes", "ColorTypes", "Contour", "Crayons", "Dates", "LinearAlgebra", "MarchingCubes", "NaNMath", "PrecompileTools", "Printf", "SparseArrays", "StaticArrays", "StatsBase"] -git-tree-sha1 = "24c0e2df19eb3f894d28a64e7486926f38de8a49" -uuid = "b8865327-cd53-5732-bb35-84acbb429228" -version = "3.7.2" - - [deps.UnicodePlots.extensions] - FreeTypeExt = ["FileIO", "FreeType"] - ImageInTerminalExt = "ImageInTerminal" - IntervalSetsExt = "IntervalSets" - TermExt = "Term" - UnitfulExt = "Unitful" - - [deps.UnicodePlots.weakdeps] - FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" - FreeType = "b38be410-82b0-50bf-ab77-7b57e271db43" - ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254" - IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" - Term = "22787eb5-b846-44ae-b979-8e399b8463ab" - Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" - [[deps.Unitful]] deps = ["Dates", "LinearAlgebra", "Random"] -git-tree-sha1 = "d2282232f8a4d71f79e85dc4dd45e5b12a6297fb" +git-tree-sha1 = "cec2df8cf14e0844a8c4d770d12347fda5931d72" uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" -version = "1.23.1" -weakdeps = ["ConstructionBase", "ForwardDiff", "InverseFunctions", "Printf"] +version = "1.25.0" [deps.Unitful.extensions] ConstructionBaseUnitfulExt = "ConstructionBase" ForwardDiffExt = "ForwardDiff" InverseFunctionsUnitfulExt = "InverseFunctions" + LatexifyExt = ["Latexify", "LaTeXStrings"] PrintfExt = "Printf" + [deps.Unitful.weakdeps] + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" + Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" + Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" + [[deps.VideoIO]] deps = ["ColorTypes", "Dates", "Downloads", "FFMPEG", "FFMPEG_jll", "FileIO", "Glob", "ImageCore", "PrecompileTools", "Scratch"] -git-tree-sha1 = "4b1cbd724eda8ea7316a3379b0b36c5116d67ed9" +git-tree-sha1 = "6b765689dbcc4f5d4b66469ea5d88a0cc26615ce" uuid = "d6d074c3-1acf-5d4c-9a43-ef38773959a2" -version = "1.1.1" +version = "1.2.0" [[deps.WGLMakie]] deps = ["Bonito", "Colors", "FileIO", "FreeTypeAbstraction", "GeometryBasics", "Hyperscript", "LinearAlgebra", "Makie", "Observables", "PNGFiles", "PrecompileTools", "RelocatableFolders", "ShaderAbstractions", "StaticArrays"] -git-tree-sha1 = "676bd14390033825be847e138108a1c53701407d" +git-tree-sha1 = "2e3a387f0f71ffb9b1cf5dd48e81581010d667dd" uuid = "276b4fcb-3e11-5398-bf8b-a0c2d153d008" -version = "0.10.18" +version = "0.13.6" [[deps.Wayland_jll]] -deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "XML2_jll"] -git-tree-sha1 = "49be0be57db8f863a902d59c0083d73281ecae8e" +deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "96478df35bbc2f3e1e791bc7a3d0eeee559e60e9" uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" -version = "1.23.1+0" - -[[deps.Wayland_protocols_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "54b8a029ac145ebe8299463447fd1590b2b1d92f" -uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91" -version = "1.44.0+0" +version = "1.24.0+0" [[deps.WeakRefStrings]] deps = ["DataAPI", "InlineStrings", "Parsers"] @@ -2029,9 +1809,9 @@ version = "1.6.1" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "b8b243e47228b4a3877f1dd6aee0c5d56db7fcf4" +git-tree-sha1 = "80d3930c6347cfce7ccf96bd3bafdf079d9c0390" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.13.6+1" +version = "2.13.9+0" [[deps.XZ_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -2071,9 +1851,9 @@ version = "1.3.7+0" [[deps.Xorg_libXfixes_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] -git-tree-sha1 = "9caba99d38404b285db8801d5c45ef4f4f425a6d" +git-tree-sha1 = "75e00946e43621e09d431d9b95818ee751e6b2ef" uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" -version = "6.0.1+0" +version = "6.0.2+0" [[deps.Xorg_libXi_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] @@ -2099,6 +1879,12 @@ git-tree-sha1 = "7ed9347888fac59a618302ee38216dd0379c480d" uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" version = "0.9.12+0" +[[deps.Xorg_libpciaccess_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "4909eb8f1cbf6bd4b1c30dd18b2ead9019ef2fad" +uuid = "a65dc6b1-eb27-53a1-bb3e-dea574b5389e" +version = "0.18.1+0" + [[deps.Xorg_libxcb_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXau_jll", "Xorg_libXdmcp_jll"] git-tree-sha1 = "bfcaf7ec088eaba362093393fe11aa141fa15422" @@ -2148,21 +1934,21 @@ version = "0.2.3+0" [[deps.libaec_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "f5733a5a9047722470b95a81e1b172383971105c" +git-tree-sha1 = "1aa23f01927b2dac46db77a56b31088feee0a491" uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" -version = "1.1.3+0" +version = "1.1.4+0" [[deps.libaom_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "522c1df09d05a71785765d19c9524661234738e9" +git-tree-sha1 = "4bba74fa59ab0755167ad24f98800fe5d727175b" uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" -version = "3.11.0+0" +version = "3.12.1+0" [[deps.libass_jll]] deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "e17c115d55c5fbb7e52ebedb427a0dca79d4484e" +git-tree-sha1 = "125eedcb0a4a0bba65b657251ce1d27c8714e9d6" uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" -version = "0.15.2+0" +version = "0.17.4+0" [[deps.libblastrampoline_jll]] deps = ["Artifacts", "Libdl"] @@ -2177,15 +1963,15 @@ version = "0.2.2+0" [[deps.libfdk_aac_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "8a22cf860a7d27e4f3498a0fe0811a7957badb38" +git-tree-sha1 = "646634dd19587a56ee2f1199563ec056c5f228df" uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" -version = "2.0.3+0" +version = "2.0.4+0" [[deps.libpng_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "002748401f7b520273e2b506f61cab95d4701ccf" +git-tree-sha1 = "07b6a107d926093898e82b3b1db657ebe33134ec" uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" -version = "1.6.48+0" +version = "1.6.50+0" [[deps.libsixel_jll]] deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "libpng_jll"] @@ -2194,16 +1980,16 @@ uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" version = "1.10.5+0" [[deps.libvorbis_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] -git-tree-sha1 = "490376214c4721cdaca654041f635213c6165cb3" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll"] +git-tree-sha1 = "11e1772e7f3cc987e9d3de991dd4f6b2602663a5" uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" -version = "1.3.7+2" +version = "1.3.8+0" [[deps.libwebp_jll]] deps = ["Artifacts", "Giflib_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libglvnd_jll", "Libtiff_jll", "libpng_jll"] -git-tree-sha1 = "d2408cac540942921e7bd77272c32e58c33d8a77" +git-tree-sha1 = "4e4282c4d846e11dce56d74fa8040130b7a95cb3" uuid = "c5f90fcd-3b7e-5836-afba-fc50a0988cb2" -version = "1.5.0+0" +version = "1.6.0+0" [[deps.nghttp2_jll]] deps = ["Artifacts", "Libdl"] @@ -2222,19 +2008,19 @@ uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" version = "17.4.0+2" [[deps.x264_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "14cc7083fc6dff3cc44f2bc435ee96d06ed79aa7" uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" -version = "2021.5.5+0" +version = "10164.0.1+0" [[deps.x265_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e7b67590c14d487e734dcb925924c5dc43ec85f3" uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" -version = "3.5.0+0" +version = "4.1.0+0" [[deps.xkbcommon_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Wayland_jll", "Wayland_protocols_jll", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] -git-tree-sha1 = "c950ae0a3577aec97bfccf3381f66666bc416729" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] +git-tree-sha1 = "fbf139bce07a534df0e699dbb5f5cc9346f95cc1" uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd" -version = "1.8.1+0" +version = "1.9.2+0" From 0d65edbed16d339b69dd2ecf7a42136901ada417 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Tue, 30 Sep 2025 07:52:43 -0400 Subject: [PATCH 06/12] Qualify dependencies under ShroffCelegansModels --- scripts/launch_show_average_annotations.jl | 10 +- src/ShroffCelegansModels.jl | 104 ++++++++++-------- src/animate_untwist.jl | 6 +- src/demo_averaging/average_sliders.jl | 6 +- .../get_cell_trajectory_dict.jl | 4 +- ...et_group_annotation_positions_over_time.jl | 2 +- src/demo_averaging/modelio.jl | 10 +- src/demo_averaging/seam_cell_pts.jl | 4 +- .../show_average_annotations.jl | 8 +- src/demo_averaging/smooth_polar_dct1.jl | 6 +- src/demo_averaging/stretched_analysis.jl | 4 +- src/makie.jl | 32 +++--- 12 files changed, 106 insertions(+), 90 deletions(-) diff --git a/scripts/launch_show_average_annotations.jl b/scripts/launch_show_average_annotations.jl index 58cfbd9..816065f 100644 --- a/scripts/launch_show_average_annotations.jl +++ b/scripts/launch_show_average_annotations.jl @@ -1,12 +1,12 @@ using Pkg #using Revise cd(dirname(@__DIR__)) -Pkg.activate(dirname(@__DIR__)) -using JSON3 +#Pkg.activate(dirname(@__DIR__)) using ShroffCelegansModels -using Printf -using HDF5 -using ThinPlateSplines # tps_solve +using ShroffCelegansModels.JSON3 +using ShroffCelegansModels.Printf +using ShroffCelegansModels.HDF5 +using ShroffCelegansModels.ThinPlateSplines # tps_solve using InteractiveUtils @info "Loading demo_averaging.jl..." diff --git a/src/ShroffCelegansModels.jl b/src/ShroffCelegansModels.jl index 0becc40..9d9484e 100644 --- a/src/ShroffCelegansModels.jl +++ b/src/ShroffCelegansModels.jl @@ -1,47 +1,63 @@ module ShroffCelegansModels - using CSV - #using Makie - using Makie - using DataFrames - using GeometryBasics - #using ColorSchemes - using LinearAlgebra - using BSplineKit - using QuadGK - using LRUCache - using FFTW - using Dates - using PrecompileTools: @setup_workload, @compile_workload - - include("datasets.jl") - include("MIPAVIO.jl") - - include("util.jl") - include("ParametricSplines.jl") - include("types.jl") - - using .ParametricSplines - using .Types - - include("build_model.jl") - include("mesh.jl") - include("straighten.jl") - - include("average.jl") - - using .Datasets - - include("show.jl") - include("points.jl") - - using .Points - - include("model_time_series.jl") - include("area.jl") - - include("annotation_untwist.jl") - include("parse_worm_dataset_path.jl") - - include("precompile.jl") + using BSplineKit + using CSV + using ColorSchemes: ColorSchemes + using Colors: Colors + using CoordinateTransformations: CoordinateTransformations + using DataFrames + using Dates + using FFTW + using FileIO: FileIO + using FixedPointNumbers: FixedPointNumbers + using GeometryBasics + using HDF5: HDF5 + using Interpolations: Interpolations + using JSON3: JSON3 + using LRUCache + using LinearAlgebra + using Makie + using Missings: Missings + using Observables: Observables + using Pkg: Pkg + using PrecompileTools: @setup_workload, @compile_workload + using ProgressMeter: ProgressMeter + using QuadGK + using Sockets: Sockets + using StaticArrays: StaticArrays + using Statistics: Statistics + using StatsBase: StatsBase + using ThinPlateSplines: ThinPlateSplines + using TiffImages: TiffImages + + include("datasets.jl") + include("MIPAVIO.jl") + + include("util.jl") + include("ParametricSplines.jl") + include("types.jl") + + using .ParametricSplines + using .Types + + include("build_model.jl") + include("mesh.jl") + include("straighten.jl") + + include("average.jl") + + using .Datasets + + include("show.jl") + include("points.jl") + + using .Points + + include("model_time_series.jl") + include("area.jl") + + include("annotation_untwist.jl") + include("parse_worm_dataset_path.jl") + + include("precompile.jl") end diff --git a/src/animate_untwist.jl b/src/animate_untwist.jl index 11e4cca..f1a4e5d 100644 --- a/src/animate_untwist.jl +++ b/src/animate_untwist.jl @@ -147,7 +147,7 @@ function animate_untwist(smodel; fig = nothing) sleep(1) for rep in 1:3 - mesh!(ax, M; shading = MakieCore.automatic, color = [i for c in 1:length(model) for i in 1:3], colormap = :buda) + mesh!(ax, M; shading = Makie.automatic, color = [i for c in 1:length(model) for i in 1:3], colormap = :buda) sleep(1) for i in 0:10:100 @@ -257,7 +257,7 @@ function controllable_untwist(smodel; fig = nothing) # for rep in 1:3 time = Observable(0) - mesh!(ax, M; shading = MakieCore.automatic, color = [i for c in 1:length(model) for i in 1:3], colormap = :buda) + mesh!(ax, M; shading = Makie.automatic, color = [i for c in 1:length(model) for i in 1:3], colormap = :buda) # sleep(1) on(time) do t @@ -356,4 +356,4 @@ function record_untwist(smodel) record(untwist_fig, "untwist.mp4", 0:600) do t untwist_time[] = t end -end \ No newline at end of file +end diff --git a/src/demo_averaging/average_sliders.jl b/src/demo_averaging/average_sliders.jl index e30acb1..9006a40 100644 --- a/src/demo_averaging/average_sliders.jl +++ b/src/demo_averaging/average_sliders.jl @@ -13,7 +13,7 @@ function average_sliders(models::Vector{<:AbstractCelegansModel}) n_ellipse_pts = length(transverse_splines(model)) colorscheme = :cyclic_wrwbw_40_90_c42_n256 - shading = MakieCore.automatic + shading = Makie.automatic color=colorschemes[colorscheme][1:256÷n_ellipse_pts:256] colorrange = (1,n_ellipse_pts) @@ -92,7 +92,7 @@ function average_sliders(smts::ShroffCelegansModels.StraightenedModelTimeSeries) n_ellipse_pts = length(transverse_splines(model)) colorscheme = :cyclic_wrwbw_40_90_c42_n256 - shading = MakieCore.automatic + shading = Makie.automatic color=colorschemes[colorscheme][1:256÷n_ellipse_pts:256] colorrange = (1,n_ellipse_pts) @@ -173,4 +173,4 @@ function record_average_sliders(smts::ShroffCelegansModels.StraightenedModelTime set_close_to!(sg.sliders[1], i) println(i) end -end \ No newline at end of file +end diff --git a/src/demo_averaging/get_cell_trajectory_dict.jl b/src/demo_averaging/get_cell_trajectory_dict.jl index 06da757..79e2775 100644 --- a/src/demo_averaging/get_cell_trajectory_dict.jl +++ b/src/demo_averaging/get_cell_trajectory_dict.jl @@ -1,4 +1,4 @@ -using BSplineKit +using ShroffCelegansModels.BSplineKit function get_cell_trajectory_dict(dataset::ShroffCelegansModels.Datasets.NormalizedDataset; use_myuntwist = false) annotations = load_straightened_annotations_over_time(dataset; use_myuntwist) @@ -31,4 +31,4 @@ function get_cell_trajectory_dict(dataset::ShroffCelegansModels.Datasets.Normali end |> Dict return cell_trajectory_dict -end \ No newline at end of file +end diff --git a/src/demo_averaging/get_group_annotation_positions_over_time.jl b/src/demo_averaging/get_group_annotation_positions_over_time.jl index bd4f157..3d1d4fe 100644 --- a/src/demo_averaging/get_group_annotation_positions_over_time.jl +++ b/src/demo_averaging/get_group_annotation_positions_over_time.jl @@ -53,4 +53,4 @@ function get_group_annotation_positions_over_time(datasets, cache) end end # Vector{Vector{Dict{String, Point3{Float64}}}} # dataset, normalized time, name => position return group_annotation_positions_over_time -end \ No newline at end of file +end diff --git a/src/demo_averaging/modelio.jl b/src/demo_averaging/modelio.jl index cd6aa9e..8f376f0 100644 --- a/src/demo_averaging/modelio.jl +++ b/src/demo_averaging/modelio.jl @@ -1,8 +1,8 @@ -using HDF5 -using Printf -using BSplineKit: SplineInterpolation -using GeometryBasics: Point3f, Point3 -using Makie +using ShroffCelegansModels.HDF5 +using ShroffCelegansModels.Printf +using ShroffCelegansModels.BSplineKit: SplineInterpolation +using ShroffCelegansModels.GeometryBasics: Point3f, Point3 +using ShroffCelegansModels.Makie function save_celegans_model( parent::Union{HDF5.File, HDF5.Group}, diff --git a/src/demo_averaging/seam_cell_pts.jl b/src/demo_averaging/seam_cell_pts.jl index 5c26023..40d3f61 100644 --- a/src/demo_averaging/seam_cell_pts.jl +++ b/src/demo_averaging/seam_cell_pts.jl @@ -1,7 +1,7 @@ -using BSplineKit.SplineInterpolations: interpolation_points +using ShroffCelegansModels.BSplineKit.SplineInterpolations: interpolation_points function seam_cell_pts(model, n_upsample) pts = interpolation_points(model)[1:2^n_upsample:end] _transverse_splines = transverse_splines(model) [_transverse_splines[1].(pts); _transverse_splines[17].(pts)] -end \ No newline at end of file +end diff --git a/src/demo_averaging/show_average_annotations.jl b/src/demo_averaging/show_average_annotations.jl index 0c5d26d..a5796ba 100644 --- a/src/demo_averaging/show_average_annotations.jl +++ b/src/demo_averaging/show_average_annotations.jl @@ -1,7 +1,7 @@ -using ProgressMeter -using Statistics: mean, var -using CoordinateTransformations -using FFTW: fftfreq, fft, ifft +using ShroffCelegansModels.ProgressMeter +using ShroffCelegansModels.Statistics: mean, var +using ShroffCelegansModels.CoordinateTransformations +using ShroffCelegansModels.FFTW: fftfreq, fft, ifft include("../makie.jl") include("get_group_annotation_positions_over_time.jl") diff --git a/src/demo_averaging/smooth_polar_dct1.jl b/src/demo_averaging/smooth_polar_dct1.jl index 5487688..ccbf7cd 100644 --- a/src/demo_averaging/smooth_polar_dct1.jl +++ b/src/demo_averaging/smooth_polar_dct1.jl @@ -1,5 +1,5 @@ -using CoordinateTransformations -using FFTW: fftfreq, fft, ifft +using ShroffCelegansModels.CoordinateTransformations +using ShroffCelegansModels.FFTW: fftfreq, fft, ifft function smooth_polar_dct1(positions_over_time, σ_r, σ_θ, σ_z = 0) G(σ,s) = exp.(-fftfreq(s,s).^2 ./2 ./ σ^2) @@ -48,4 +48,4 @@ function smooth_polar_dct1(positions_over_time, σ_r, σ_θ, σ_z = 0) end return positions_over_time # return @view positions_over_time[1:N] -end \ No newline at end of file +end diff --git a/src/demo_averaging/stretched_analysis.jl b/src/demo_averaging/stretched_analysis.jl index 67823c0..49e61e3 100644 --- a/src/demo_averaging/stretched_analysis.jl +++ b/src/demo_averaging/stretched_analysis.jl @@ -1,4 +1,4 @@ -using CircStats +# using CircStats function stretched_analysis(smodel) model = parent(smodel) @@ -12,4 +12,4 @@ function stretched_analysis(smodel) st1_pts = t1_pts .- cs_pts .+ scs_pts to_cylindrical = CoordinateTransformations.CylindricalFromCartesian() θ = to_cylindrical.(st1_pts) .|> x->x.θ -end \ No newline at end of file +end diff --git a/src/makie.jl b/src/makie.jl index fa64fb4..92dbd77 100644 --- a/src/makie.jl +++ b/src/makie.jl @@ -1,9 +1,9 @@ using ShroffCelegansModels: AbstractCelegansModel, transverse_splines, get_model_contour_mesh, num_transverse_splines -using ColorSchemes: colorschemes -using MakieCore: MakieCore -using GeometryBasics: Point3, Point3f +using ShroffCelegansModels.ColorSchemes: colorschemes +using ShroffCelegansModels.Makie: Makie +using ShroffCelegansModels.GeometryBasics: Point3, Point3f using ShroffCelegansModels.Points: cross_sections -using Observables: throttle +using ShroffCelegansModels.Observables: throttle function plot_celegans_model(model::AbstractCelegansModel) r = LinRange(0, 1, length(model)) @@ -39,10 +39,10 @@ const cyclic_colorschemes = [ ] -function MakieCore.mesh( +function Makie.mesh( model::AbstractCelegansModel; colorscheme = :cyclic_tritanopic_cwrk_40_100_c20_n256, - shading = MakieCore.automatic, + shading = Makie.automatic, n_ellipse_pts = num_transverse_splines(model), color=repeat(colorschemes[colorscheme][1:256÷n_ellipse_pts:256], length(model)), colorrange = (1,n_ellipse_pts), @@ -61,11 +61,11 @@ function MakieCore.mesh( ) end -function MakieCore.mesh!( +function Makie.mesh!( axis, model::AbstractCelegansModel; colorscheme = :cyclic_wrwbw_40_90_c42_n256, - shading = MakieCore.automatic, + shading = Makie.automatic, n_ellipse_pts = num_transverse_splines(model), color=repeat(colorschemes[colorscheme][1:256÷n_ellipse_pts:256], length(model)), colorrange = (1,n_ellipse_pts), @@ -85,12 +85,12 @@ function MakieCore.mesh!( ) end -MakieCore.convert_arguments(P::Type{<: MakieCore.Mesh}, model::AbstractCelegansModel) = - MakieCore.convert_arguments(P, get_model_contour_mesh(model)) -MakieCore.convert_arguments(P::Type{<: MakieCore.Mesh}, model::AbstractCelegansModel, f::Function) = - MakieCore.convert_arguments(P, get_model_contour_mesh(model, transform_points = f)) +Makie.convert_arguments(P::Type{<: Makie.Mesh}, model::AbstractCelegansModel) = + Makie.convert_arguments(P, get_model_contour_mesh(model)) +Makie.convert_arguments(P::Type{<: Makie.Mesh}, model::AbstractCelegansModel, f::Function) = + Makie.convert_arguments(P, get_model_contour_mesh(model, transform_points = f)) -function MakieCore.convert_arguments(P::Type{<: MakieCore.Lines}, model::AbstractCelegansModel, f::Function = identity) +function Makie.convert_arguments(P::Type{<: Makie.Lines}, model::AbstractCelegansModel, f::Function = identity) splines = transverse_splines(model) r = LinRange(0, 1, length(model)) pts = map(splines) do spline @@ -106,11 +106,11 @@ function MakieCore.convert_arguments(P::Type{<: MakieCore.Lines}, model::Abstrac pts = permutedims(hcat(pts, gaps), [2,1]) |> vec pts = vcat(pts...) pts = f.(pts) - MakieCore.convert_arguments(P, pts) + Makie.convert_arguments(P, pts) end -#function MakieCore.convert_arguments(P::Type{<: MakieCore.Text}, model::AbstractCelegansModel, f::Function = identity) -function MakieCore.text!(ax, model::AbstractCelegansModel, f::Function = identity) +#function Makie.convert_arguments(P::Type{<: Makie.Text}, model::AbstractCelegansModel, f::Function = identity) +function Makie.text!(ax, model::AbstractCelegansModel, f::Function = identity) pts = ShroffCelegansModels.interpolation_points(model) splines = transverse_splines(model) # This probably swapped. 1 should be right, 17 should be left From ad800c3e979e5c907544dd71c0f399b360e66fe3 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Tue, 30 Sep 2025 07:53:10 -0400 Subject: [PATCH 07/12] Update fix_annotation_ap_axis.jl for Makie 0.24 --- src/demo_averaging/fix_annotation_ap_axis.jl | 108 +++++++++++++------ web/scripts/web_fix_annotation_ap_axis.jl | 3 +- 2 files changed, 75 insertions(+), 36 deletions(-) diff --git a/src/demo_averaging/fix_annotation_ap_axis.jl b/src/demo_averaging/fix_annotation_ap_axis.jl index 5741430..4742d42 100644 --- a/src/demo_averaging/fix_annotation_ap_axis.jl +++ b/src/demo_averaging/fix_annotation_ap_axis.jl @@ -1,10 +1,12 @@ -using Makie using ShroffCelegansModels -using Printf -using GeometryBasics -using JSON3 -using Dates -using Sockets +using ShroffCelegansModels.Makie +using ShroffCelegansModels.Printf +using ShroffCelegansModels.GeometryBasics +using ShroffCelegansModels.JSON3 +using ShroffCelegansModels.Dates +using ShroffCelegansModels.Sockets +using ShroffCelegansModels.HDF5 + const ANNOTATION_PERSIST_SERVER_PORT = 3129 @@ -223,6 +225,7 @@ function fix_annotation_ap_axis( twisted_seam_cell_text = Observable(String.([tmodel.names[2:2:end]; tmodel.names[1:2:end]])) + twisted_mesh_plot = mesh!( ax_twisted, twisted_mesh; @@ -232,18 +235,31 @@ function fix_annotation_ap_axis( alpha = 0.5, inspectable = false ) - connect!(twisted_mesh_plot.visible, contour_mesh_toggle.active) + #connect!(twisted_mesh_plot.visible, contour_mesh_toggle.active) + twisted_mesh_plot.visible = false + on(contour_mesh_toggle.active) do v + twisted_mesh_plot.visible = v + end lines!(ax_twisted, twisted_central_spline) scatter!(ax_twisted, twisted_central_pts) cs_lines = lines!(ax_twisted, twisted_central_line_match) - connect!(cs_lines.visible, central_spline_lines_toggle.active) + #connect!(cs_lines.visible, central_spline_lines_toggle.active) + cs_lines.visible = false + on(central_spline_lines_toggle.active) do v + cs_lines.visible = v + end meshscatter!(ax_twisted, twisted_seam_cells; markersize = 1.0, color = :gray, alpha = 0.5, transparency = true) ms_annotation_cells = meshscatter!(ax_twisted, twisted_annotation_cells; markersize = 1.0, color = use_myuntwist ? :gold : :blue, alpha = 0.5, transparency = true) text!(ax_twisted, twisted_seam_cell_labels; text = twisted_seam_cell_text, align = (:right, :bottom)) ann_txt = text!(ax_twisted, twisted_annotation_cells; text = twisted_annotation_text, align = (:right, :bottom)) - connect!(ann_txt.visible, annotation_text_toggle.active) + #connect!(ann_txt.visible, annotation_text_toggle.active) + annotation_text_toggle.active = false + on(annotation_text_toggle.active) do v + ann_txt.visible = v + end @info "twisted_seam_cell_labels" twisted_seam_cell_labels[] tmodel.names + distances = Observable(Float64[]) selected_distance = Observable(0.0) distance_central_pts = Observable(Point3f[]) @@ -254,21 +270,26 @@ function fix_annotation_ap_axis( Npts = length(tmodel) z = LinRange(0, 1, Npts) max_distance = Observable(Float64[]) - lines!(ax_distance, central_spline_arc_lengths, distances) + distances_lines = lines!(ax_distance, central_spline_arc_lengths[], distances[]) hlines!(ax_distance, selected_distance) - lines!(ax_distance, central_spline_arc_lengths, max_distance) - scatter!(ax_distance, central_spline_arc_lengths, distances, color = distances, colormap = Reverse(:viridis)) - scatter!(ax_twisted, distance_central_pts, color = distances, colormap = Reverse(:viridis)) + max_distance_lines = lines!(ax_distance, central_spline_arc_lengths[], max_distance) + distances_scatter = scatter!(ax_distance, central_spline_arc_lengths[], distances[], color = distances[], colormap = Reverse(:viridis)) + distance_central_pts_scatter = scatter!(ax_twisted, distance_central_pts, color = distances[], colormap = Reverse(:viridis)) selected_twisted_annotation_cell = Observable([twisted_annotation_cells[][selected_annotation_idx[]]]) meshscatter!(ax_twisted, selected_twisted_annotation_cell, color = :red, markersize=1.1) + + #= ratio = @lift try $distances ./ $max_distance catch err ones(size($max_distance)) end - lines!(ax_ratio, central_spline_arc_lengths, ratio) - hlines!(ax_ratio, 1.0, linestyle = :dash) + =# + ratio = Observable(distances[]) + ratio_lines = lines!(ax_ratio, central_spline_arc_lengths[], ratio) + # hlines!(ax_ratio, 1.0, linestyle = :dash) + hlines!(ax_ratio, 1.0, linestyle = :solid) nt_obs = Observable(0.0) @@ -344,7 +365,8 @@ function fix_annotation_ap_axis( on(throttle(0.1, expansion_factor_slider.value)) do expansion_factor_value # TODO compute value from timepoint slider - value = time_normalized_slider.value[] + # value = time_normalized_slider.value[] + value = nt_obs[] tmodel = mts_nt(value) annotation_positions = twisted_annotation_positions(value) if !ismissing(tmodel) @@ -365,6 +387,7 @@ function fix_annotation_ap_axis( function plot_distance(idx) + println("plot_distance") selected_annotation_idx[] = idx #println(idx) try @@ -376,19 +399,32 @@ function fix_annotation_ap_axis( Npts = length(tmodel) z = LinRange(0, 1, Npts) central_pts = swapyz_scale.(cs.(z)) - central_spline_arc_lengths.val = [0; cumsum(norm.(diff(central_pts)))] - distance_central_pts[] = central_pts + # central_spline_arc_lengths.val = [0; cumsum(norm.(diff(central_pts)))] + _central_spline_arc_lengths = [0; cumsum(norm.(diff(central_pts)))] + central_spline_arc_lengths[] = _central_spline_arc_lengths + # distance_central_pts[] = central_pts max_r = ShroffCelegansModels.max_radius_function(tmodel) expansion_factor_value = expansion_factor_slider.value[] - max_distance[] = max_r.(z) .* voxel_size .* expansion_factor_value + _max_distance = max_r.(z) .* voxel_size .* expansion_factor_value + # max_distance[] = max_r.(z) .* voxel_size .* expansion_factor_value + Makie.update!(max_distance_lines, arg1 = _central_spline_arc_lengths, arg2 = _max_distance) pt = twisted_annotation_cells[][idx] - distances[] = norm.(central_pts .- pt) + _distances = norm.(central_pts .- pt) + distances[] = _distances + #distances[] = norm.(central_pts .- pt) + Makie.update!(distances_lines, arg1 = _central_spline_arc_lengths, arg2 = _distances) + Makie.update!(distances_scatter, arg1 = _central_spline_arc_lengths, arg2 = _distances, color = _distances) + Makie.update!(distance_central_pts_scatter, arg1 = central_pts, color = _distances) + + _ratio = _distances ./ _max_distance + Makie.update!(ratio_lines, arg1 = _central_spline_arc_lengths, arg2 = _ratio) + #autolimits!(ax_distance) #ylims!(ax_distance, nothing) - limits!(ax_distance, (0, 200), (0, maximum(distances[]))) - limits!(ax_ratio, (0, 200), (0, maximum(ratio[]))) + limits!(ax_distance, (0, 200), (0, maximum(_distances))) + limits!(ax_ratio, (0, 200), (0, maximum(_ratio))) selected_distance[] = norm(twisted_central_pts[][idx] - pt) selected_annotation_name[] = twisted_annotation_text[][idx] @@ -414,14 +450,15 @@ function fix_annotation_ap_axis( original_z_positions = let idx=1 Observable((x->x[idx][2]).(original_annotation_positions_over_time)) end - lines!(ax_z, cell_key_range, original_z_positions; color = :gray, linestyle = :dash, label = "Original Z positions") + lines!(ax_z, cell_key_range, original_z_positions; color = :gray, linestyle = :solid, label = "Original Z positions") + z_lines = lines!(ax_z, cell_key_range, z_positions) vlines!(ax_z, timepoint_slider.value, color = :red) DataInspector(ax_z) selected_z_position = Observable(z_positions[][timepoint_slider.value[]-first(cell_key_range)+1]) - vlines!(ax_distance, selected_z_position; color = :red, linestyle = :dash) - vlines!(ax_ratio, selected_z_position; color = :red, linestyle = :dash) + vlines!(ax_distance, selected_z_position; color = :red, linestyle = :solid) + vlines!(ax_ratio, selected_z_position; color = :red, linestyle = :solid) #common_annotations_text = collect(keys(annotation_dict)) common_annotations_text = _annotation_text @@ -435,13 +472,17 @@ function fix_annotation_ap_axis( group_name = annotation_change_group_name(dataset.path, timepoint, annotation_name) if haskey(h5f, group_name) @info "Loading annotation changes from annotations_changes.h5" group_name annotation_idx annotation_name - new_position = h5f[group_name]["new_position"][:,end] - straight_annotation_positions_over_time[time_idx][annotation_idx] = Point3f( - new_position[1], - new_position[2], - new_position[3] - ) - @info "Loaded" new_position + try + new_position = h5f[group_name]["new_position"][:,end] + straight_annotation_positions_over_time[time_idx][annotation_idx] = Point3f( + new_position[1], + new_position[2], + new_position[3] + ) + @info "Loaded" new_position + catch err + println(err) + end end end end @@ -570,9 +611,6 @@ function fix_annotation_ap_axis( f end -using Sockets -using HDF5 - @kwdef struct AnnotationChange ip_address::UInt64 dataset_path::String diff --git a/web/scripts/web_fix_annotation_ap_axis.jl b/web/scripts/web_fix_annotation_ap_axis.jl index 3a329ad..7c5ac5b 100644 --- a/web/scripts/web_fix_annotation_ap_axis.jl +++ b/web/scripts/web_fix_annotation_ap_axis.jl @@ -1,5 +1,6 @@ using WGLMakie using Bonito +using Revise if abspath(PROGRAM_FILE) == @__FILE__ @@ -22,7 +23,7 @@ function web_debug_annotation_ap_axis(datasets = datasets) ) ) server = Server( - "shroff-data.int.janelia.org", 9381; + string(Sockets.getaddrinfo("shroff-data.int.janelia.org")), 9381; proxy_url="https://shroff-data.int.janelia.org/fix_annotation_ap_axis/" ) route!(server, "/" => App(menu)) From 6f10e8d0604876b28fe4c992d8205eab28ba4f0d Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Tue, 30 Sep 2025 08:00:59 -0400 Subject: [PATCH 08/12] Fix CI --- .github/workflows/CI.yml | 6 ++++-- Project.toml | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index d616f7c..5c6eb6d 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -18,8 +18,10 @@ jobs: fail-fast: false matrix: version: - - '1.0' - - '1.9' + - '1' + - '1.10' + - '1.11' + - '1.12' - 'nightly' os: - ubuntu-latest diff --git a/Project.toml b/Project.toml index 4818e05..cc1532d 100644 --- a/Project.toml +++ b/Project.toml @@ -44,7 +44,7 @@ HDF5 = "0.17.2" Interpolations = "0.15, 0.16" Makie = "0.24.6" ProgressMeter = "1" -Sockets = "1.11.0" +Sockets = "1" ThinPlateSplines = "0.1, 0.2.0" julia = "1" From 3ac209818415825a003fcc44ebc0440845ca1421 Mon Sep 17 00:00:00 2001 From: Kittisopikul Date: Wed, 8 Oct 2025 14:19:02 -0400 Subject: [PATCH 09/12] Use Core in ShroffCelegansModels.jl --- Project.toml | 1 + .../src/ShroffCelegansModelsCore.jl | 1 + src/MIPAVIO.jl | 116 ------- src/ParametricSplines.jl | 67 ---- src/ShroffCelegansModels.jl | 64 ++-- src/annotation_untwist.jl | 307 ------------------ src/area.jl | 33 -- src/average.jl | 120 ------- src/build_model.jl | 86 ----- src/datasets.jl | 104 ------ src/demo_averaging/loading.jl | 11 +- src/mesh.jl | 76 ----- src/model_time_series.jl | 131 -------- src/parse_worm_dataset_path.jl | 23 +- src/points.jl | 34 -- src/precompile.jl | 13 - src/show.jl | 6 - src/straighten.jl | 20 -- src/types.jl | 138 -------- src/util.jl | 14 - 20 files changed, 62 insertions(+), 1303 deletions(-) delete mode 100644 src/MIPAVIO.jl delete mode 100644 src/ParametricSplines.jl delete mode 100644 src/annotation_untwist.jl delete mode 100644 src/area.jl delete mode 100644 src/average.jl delete mode 100644 src/build_model.jl delete mode 100644 src/datasets.jl delete mode 100644 src/mesh.jl delete mode 100644 src/model_time_series.jl delete mode 100644 src/points.jl delete mode 100644 src/precompile.jl delete mode 100644 src/show.jl delete mode 100644 src/straighten.jl delete mode 100644 src/types.jl delete mode 100644 src/util.jl diff --git a/Project.toml b/Project.toml index cc1532d..bb5f357 100644 --- a/Project.toml +++ b/Project.toml @@ -29,6 +29,7 @@ PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca" QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +ShroffCelegansModelsCore = "e23caf7b-3362-4cb0-a14a-545330a3115b" Sockets = "6462fe0b-24de-5631-8697-dd941f90decc" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" diff --git a/ShroffCelegansModelsCore/src/ShroffCelegansModelsCore.jl b/ShroffCelegansModelsCore/src/ShroffCelegansModelsCore.jl index d67d7f5..58147b1 100644 --- a/ShroffCelegansModelsCore/src/ShroffCelegansModelsCore.jl +++ b/ShroffCelegansModelsCore/src/ShroffCelegansModelsCore.jl @@ -20,6 +20,7 @@ module ShroffCelegansModelsCore using .ParametricSplines using .Types + # rename to build_celegans_model? include("build_model.jl") include("mesh.jl") include("straighten.jl") diff --git a/src/MIPAVIO.jl b/src/MIPAVIO.jl deleted file mode 100644 index dbe4d91..0000000 --- a/src/MIPAVIO.jl +++ /dev/null @@ -1,116 +0,0 @@ -""" - MIPAVIO - -MIPAV (Medical Image Processing, Analysis, and Visualization) Input / Output -utility module. - -MIPAV is a Java program from the National Institutes of Health -""" -module MIPAVIO - using DataFrames: DataFrame - using GeometryBasics: Point3, Point3f - using CSV: CSV - using ShroffCelegansModels: Datasets - using Statistics: mean - - export mipav_df_to_points, mipav_df_to_point_dict - - function mipav_df_to_points(df::DataFrame) - map(df.x_voxels, df.y_voxels, df.z_voxels) do x,y,z - Point3(x,y,z) - end - end - - function mipav_df_to_point_dict(df::DataFrame) - map(df.name, df.x_voxels, df.y_voxels, df.z_voxels) do name, x,y,z - name => Point3(x,y,z) - end |> Dict{eltype(df.name), Point3{eltype(df.x_voxels)}} - end - - function get_integrated_annotations_path(ds::Datasets.NormalizedDataset, time_offset=1) - data_path = joinpath("integrated_annotation","annotations.csv") - return get_model_csv(ds, data_path, time_offset) - end - - function get_integrated_annotations(ds::Datasets.NormalizedDataset, time_offset=1; validate = true) - path = get_integrated_annotations_path(ds, time_offset) - df = CSV.read(path, DataFrame) - if validate - names = df.name - for k in keys(ds.cell_key.mapping) - if string(k) ∉ names - #error("$k is not in $(ds.path)") - @warn "$k is not in $(path)" - end - end - end - return df - end - - function get_integrated_annotations(::Type{Dict}, args...) - df = get_integrated_annotations(args...) - return Dict(row[1] => Point3(row[2], row[3], row[4]) for row in eachrow(Matrix(df))) - end - - function get_model_csv(ds::Datasets.NormalizedDataset, data_path, time_offset=1)::Union{Missing, String} - timepoint = range(ds.cell_key)[time_offset] - if timepoint ∈ ds.cell_key.outliers - return missing - else - filepath = joinpath(ds.path, "Decon_reg_$(timepoint)", "Decon_reg_$(timepoint)_results", data_path) - @info "Filepath" filepath - if isfile(filepath) - return filepath - else - throw(ArgumentError("$filepath is not a file on disk and is not marked as an outlier.")) - end - end - end - - function get_straightened_lattice(ds::Datasets.NormalizedDataset, time_offset=1) - data_path = joinpath("straightened_lattice", "straightened_lattice.csv") - return CSV.read(get_model_csv(ds, data_path, time_offset), DataFrame) - end - - function get_straightened_lattice_xy_center(ds::Datasets.NormalizedDataset, time_offset=1) - csv = get_straightened_lattice(ds, time_offset) - m = Matrix(csv[1:2:end, 2:3] .+ csv[2:2:end, 2:3])./2 - Point3f(mean(eachrow(m))..., 0) - end - - #= - function get_straightened_lattice_xy_center(ds::Datasets.NormalizedDataset, time_offset=1) - csv = get_straightened_lattice(ds, time_offset) - m = Matrix(csv[1:2:end, 2:3] .+ csv[2:2:end, 2:3])./2 - Point3f(mean(eachrow(m))..., 0) - end - =# - - function get_straightened_annotations(ds::Datasets.NormalizedDataset, time_offset=1)::Union{Missing, String} - timepoint = range(ds.cell_key)[time_offset] - if timepoint ∈ ds.cell_key.outliers - return missing - else - filepath = joinpath(ds.path, "Decon_reg_$(timepoint)", "Decon_reg_$(timepoint)_results", "straightened_annotations", "straightened_annotations.csv") - if isfile(filepath) - return filepath - else - throw(ArgumentError("$filepath is not a file on disk and is not marked as an outlier.")) - end - end - end - - function load_straightened_annotations_over_time(dataset::Datasets.NormalizedDataset, offsets = 1:length(range(dataset.cell_key))) - annotations = map(offsets) do time_offset - path = get_straightened_annotations(dataset, time_offset) - if ismissing(path) - return missing - end - annotation_df = CSV.read(path, DataFrame) - pts = Point3f.(eachrow(Matrix(annotation_df)[:, 2:4])) - pts .-= get_straightened_lattice_xy_center(dataset, time_offset) - Dict(annotation_df[:,1] .=> pts) - end - return annotations - end -end \ No newline at end of file diff --git a/src/ParametricSplines.jl b/src/ParametricSplines.jl deleted file mode 100644 index f8a1b90..0000000 --- a/src/ParametricSplines.jl +++ /dev/null @@ -1,67 +0,0 @@ -module ParametricSplines - using BSplineKit: BSplineKit, knots, Derivative, BSplineOrder, Natural, SplineInterpolation - using QuadGK: QuadGK, quadgk - using DataFrames: DataFrame - using GeometryBasics: Point, Point3 - using LinearAlgebra: norm - - #export NDParametricSplineInterpolation - export interpolate_natural_cubic_spline - - #= - struct NDParametricSplineInterpolation{T} - splines::Vector{T} - end - function (itps::NDParametricSplineInterpolation)(time) - Point{length(itps.splines)}(map(itps.splines) do s - s(time) - end) - end - function Base.getindex(itps::NDParametricSplineInterpolation, elements...) - getindex(itps.splines, elements...) - end - function Base.:*(d::Derivative, s::NDParametricSplineInterpolation) - NDParametricSplineInterpolation(d .* s.splines) - end - BSplineKit.knots(s::NDParametricSplineInterpolation) = knots(first(s.splines)) - function QuadGK.quadgk(s::NDParametricSplineInterpolation) - d = Derivative(1) * s - quadgk(unique(knots(s))...) do t - norm(d(t)) - end - end - function QuadGK.quadgk() - end - =# - - function QuadGK.quadgk(s::SplineInterpolation) - d = Derivative(1) * s - quadgk(unique(knots(s))...) do t - norm(d(t)) - end - end -# ╔═╡ d323b169-b352-46ad-9d35-a4da784cc710 -""" - interpolate_natural_cubic_spline(time, data) -""" -function interpolate_natural_cubic_spline(time, data::Union{AbstractMatrix, DataFrame}) - #= - itp_columns = interpolate_natural_cubic_spline.((time,), eachcol(data)) - NDParametricSplineInterpolation(itp_columns) - =# - return interpolate_natural_cubic_spline(time, Point3.(Vector.(eachrow(data)))) -end - -#= -# ╔═╡ 96d3a2f4-93ce-43aa-99d8-2fc1fbb21b1e -function interpolate_natural_cubic_spline(time, data::Vector{<: Point3}) - interpolate_natural_cubic_spline(time, stack(data; dims=1)) -end -=# - -# ╔═╡ 86b367d5-506d-4ed8-a3ca-a356e4b5be1a -function interpolate_natural_cubic_spline(time, data::AbstractVector) - return BSplineKit.interpolate(time, data, BSplineOrder(4), Natural()) -end - -end \ No newline at end of file diff --git a/src/ShroffCelegansModels.jl b/src/ShroffCelegansModels.jl index 9d9484e..c4fb6ac 100644 --- a/src/ShroffCelegansModels.jl +++ b/src/ShroffCelegansModels.jl @@ -28,36 +28,50 @@ module ShroffCelegansModels using StatsBase: StatsBase using ThinPlateSplines: ThinPlateSplines using TiffImages: TiffImages + using ShroffCelegansModelsCore: + ShroffCelegansModelsCore, + get_circle_points, + build_celegans_model, + get_model_contour_mesh, + get_sections, + get_model_manifold_mesh_components, + straighten_celegans_model, + psuedo_seam_cells, + average, + upsample, + ModelTimeSeries, + StraightenedModelTimeSeries, + get_lattice, + get_lattice_filepath, + nextModelIndex, + prevModelIndex, + radial_cross_section, + cross_section_area, + volume_by_cross_section, + nearest_central_pt, + get_central_point_parameters, + max_radius_function, + nearest_central_plane, + untwist_annotations, + untwist_annotation, + twisted_annotations, + distance_to_twisted_annotation - include("datasets.jl") - include("MIPAVIO.jl") + using ShroffCelegansModelsCore.Datasets + using ShroffCelegansModelsCore.MIPAVIO: MIPAVIO + using ShroffCelegansModelsCore.ParametricSplines + using ShroffCelegansModelsCore.Types + using ShroffCelegansModelsCore.Points - include("util.jl") - include("ParametricSplines.jl") - include("types.jl") + # Straightened annotations + const annotations_cache = Dict{Tuple{String, UnitRange, Bool}, Vector}() + # Warped annotations, with MIPAV straightening + const annotation_position_cache = Dict{String, Any}() + # Warped annotations, with Mark's straightening + const my_annotation_position_cache = Dict{String, Vector{Vector{Point3{Float64}}}}() - using .ParametricSplines - using .Types - include("build_model.jl") - include("mesh.jl") - include("straighten.jl") - include("average.jl") - - using .Datasets - - include("show.jl") - include("points.jl") - - using .Points - - include("model_time_series.jl") - include("area.jl") - - include("annotation_untwist.jl") include("parse_worm_dataset_path.jl") - include("precompile.jl") - end diff --git a/src/annotation_untwist.jl b/src/annotation_untwist.jl deleted file mode 100644 index 6fff3d6..0000000 --- a/src/annotation_untwist.jl +++ /dev/null @@ -1,307 +0,0 @@ -""" - nearest_central_pt(model::AbstractCelegansModel, pts::AbstractVector{<: Point}, expansion_factor = 1.0) - -Find the nearest central point on the model to each annotation point. - -# Arguments -- `model::AbstractCelegansModel`: The model to use for finding the nearest central point. -- `pts::AbstractVector{<: Point}`: The annotation points to find the nearest central point. -- `expansion_factor::Union{Vector{<: Real}, Real}=1.0`: The expansion factor to use for the distance check. - -# Returns -- A tuple of three vectors: the spline parameter, the nearest central point, and the distance to the nearest central point. -""" -function nearest_central_pt(model::AbstractCelegansModel, pts::AbstractVector{<: Point}, expansion_factor = 1.0) - # Sample points along the central spline - cs = ShroffCelegansModels.central_spline(model) - Npts = length(model) - z = LinRange(0, 1, Npts) - central_pts = cs.(z) - - # For each sampled point calculate the maximum radius of the cross section - max_r_func = ShroffCelegansModels.max_radius_function(model) - radius = max_r_func.(z) - - # For each annotation point, find the nearest central point - arg_pt_dist = map(pts) do pt - # Distance between the annotation point and each sampled point along the central spline - unbounded_dist = norm.(central_pts .- pt) - # bound check - a = 1 - dist = copy(unbounded_dist) - for ef in expansion_factor - # Set all distances larger than the radius times the expansion factor to infinity - dist[unbounded_dist .> radius .* ef] .= Inf - # Find the index of the central point with the smallest distance - a = argmin(dist) - if dist[a] != Inf - # If we found a point, then we are done with this point - break - end - # Otherwise, reset the distances and try with a larger expansion factor - dist = copy(unbounded_dist) - end - # Return a tuple of the spline parameter, the nearest central point, and the distance to the nearest central point - z[a], central_pts[a], dist[a] - end - second = x->x[2] - # Split each tuple into three vectors - return first.(arg_pt_dist), second.(arg_pt_dist), last.(arg_pt_dist) -end - -""" - get_central_point_parameters(model::AbstractCelegansModel, pts::AbstractVector{<: Point}, central_spline_voxel_distances::AbstractVector{<: Real}) - -Get the parameters of the central spline for each annotation point given a -central spline voxel distance. -""" -function get_central_point_parameters( - model::AbstractCelegansModel, - pts::AbstractVector{<: Point}, - central_spline_voxel_distances::AbstractVector{<: Real} -) - cs = ShroffCelegansModels.central_spline(model) - Npts = length(model) - z = LinRange(0, 1, Npts) - central_pts = cs.(z) - central_pts_dist = [0; cumsum(norm.(diff(central_pts)))] - indices = map(central_spline_voxel_distances) do d - findlast(<=(d + 0.1), central_pts_dist) - end - spline_param = z[indices] - central_pts = central_pts[indices] - pt_to_central_dist = norm.(central_pts .- pts) - return spline_param, central_pts, pt_to_central_dist -end - -function max_radius_function(model) - function max_radius(z) - tss = transverse_splines(model) - central_pt = central_spline(model)(z) - radii = map(tss) do ts - norm(ts(z) - central_pt) - end - return maximum(radii) - end -end - -function nearest_central_plane(model::AbstractCelegansModel, pts::AbstractVector{<: Point}) - cs = ShroffCelegansModels.central_spline(model) - dcs = Derivative(1)*cs - - Npts = length(model) - r = LinRange(0, 1, Npts) - central_pts = cs.(r) - - - ts1 = ShroffCelegansModels.transverse_spline(model, 1) - right = ts1.(r) - right_vec = right .- ncp - right_norm = norm.(right_vec) - # right_vec_unit = right_vec ./ right_norm - # TODO: change to maximum radial distance - max_radial_dist = right_norm - - normal_vecs = normalize.(dcs.(r)) - - d = central_pts .⋅ normal_vecs - - arg_pt_dist = map(pts) do pt - dist_to_plane = abs.(d .- (normal_vecs .⋅ pt)) - dist_to_central = norm.(central_pts .- pt) - dist_along_plane = dist_to_central.^2 - dist_to_plane.^2 - a = argmin(dist_to_central) - r[a], central_pts[a], dist_to_plane[a] - end - second = x->x[2] - first.(arg_pt_dist), second.(arg_pt_dist), last.(arg_pt_dist) -end - -""" - untwist_annotations(model::AbstractCelegansModel, pts::AbstractVector{<: Point}) - -Untwist the annotations by computing their position relative to the central spline of the model. - -# Arguments - -- `model::AbstractCelegansModel`: The model to use for untwisting. -- `pts::AbstractVector{<: Point}`: The annotation points to untwist. - -# Returns -- `Vector{Point3}`: The untwisted annotation points. - -# Example -```julia -using ShroffCelegansModels -using ShroffCelegansModels.MIPAVIO - -dataset = ShroffCelegansModels.NormalizedDataset("X:/shrofflab/OD1599_NU/120619_Pos2/Decon_reg/RegB") -mts = ShroffCelegansModels.ModelTimeSeries(dataset) -model = mts(1) -df = MIPAVIO.get_integrated_annotations(dataset, 1) -pts = MIPAVIO.mipav_df_to_points(df) -ShroffCelegansModels.untwist_annotations(model, pts) -``` - -# Notes -- The function uses the central spline of the model to untwist the annotations. -- The function uses the first transverse spline of the model to determine the right direction. -- The function uses the derivative of the central spline to determine the normal direction. - -# Algorithm -1. Compute the nearest point on the central spline to each annotation point. -2. Compute the angle between the right direction and the annotation point. -3. Compute the distance between the central spline and the annotation point. -4. Compute the untwisted annotation point using the angle and distance. -5. Return the untwisted annotation points. -""" -function untwist_annotations( - model::AbstractCelegansModel, - pts::AbstractVector{<: Point}, - central_spline_voxel_distances::Union{AbstractVector{<: Real},Nothing} = nothing -) - thresholds = [1.0, 1.05, 1.10, 1.15, 1.20, 1.25, 1.30, 1.35, 1.40, 1.45, 1.5, 2.0, 2.5] - - # For each point, find the nearest point along the central spline - # t is the spline parameter - # ncp is the nearest central point - # pts_norm is the distance from the point to the central spline - if isnothing(central_spline_voxel_distances) - t, ncp, pts_norm = nearest_central_pt(model, pts, thresholds) - else - t, ncp, pts_norm = get_central_point_parameters(model, pts, central_spline_voxel_distances) - end - - # Objective: Compute the angle between the right direction and the point - # The first transverse spline is used to determine which direction is the right side - ts1 = ShroffCelegansModels.transverse_spline(model, 1) - right = ts1.(t) - - # Obtain the central spline and its derivative - # The derivative should point along the spline - cs = ShroffCelegansModels.central_spline(model) - dcs = Derivative(1)*cs - - # Obtain the vector from the nearest central point to the annotation - pts_vec = pts .- ncp - pts_vec_unit = pts_vec ./ pts_norm - - # Obtain the vector from the nearest central point to the right direction - right_vec = right .- ncp - right_norm = norm.(right_vec) - right_vec_unit = right_vec ./ right_norm - - # Compute the cross product between the right direction and the annotation direction - c = right_vec_unit .× pts_vec_unit - # Compute the sign of the cross product and the derivative of the central spline - # This indicates whether the cross product is pointing - s = sign.(dcs.(t) .⋅ c) - - # Compute the angle between the right direction and the annotation direction - # by taking the arctangent of signed magnitude of the cross product - # with the dot product of the right direction and the annotation direction - angles = atan.(norm.(c) .*s, right_vec_unit .⋅ pts_vec_unit) - - # Obtain the straightened, untwisted, model - smodel = StraightenedCelegansModel(model) - scs = central_spline(smodel) - # Compute the z-coordinate of the nearest central point on the straightened model - z = last.(scs.(t)) - - # The returned untwisted annotation points are computed using the angle and distance - # between the central spline and the annotation point - # The z-coordinate is the same as that of the nearest central point on the straightened model - return map(zip(angles,pts_norm,z)) do (angle, dist,z) - Point3(cos(angle)*dist, sin(angle)*dist, z) - end -end - -function untwist_annotation( - model::AbstractCelegansModel, - pt::Point, - central_spline_voxel_distance::Union{Real,Nothing} = nothing # "z" -) - pts = [pt] - central_spline_voxel_distances = - isnothing(central_spline_voxel_distance) ? - nothing : - [central_spline_voxel_distance] - return only(untwist_annotations(model, pts, central_spline_voxel_distances)) -end - -""" - untwist_annotations(dataset::NormalizedDataset, timepoint::Int=1) - -Untwist the annotations at a specific timepoint in the dataset. - -# Arguments -- `dataset::NormalizedDataset`: The dataset to use for untwisting. -- `timepoint::Int=1`: The timepoint to use for untwisting, where 1 indicates of the first time point of the dataset. - -# Returns -- `Dict{String, Vector{Point3}}`: The untwisted annotations using the annotation name as a the key - -# Example -```julia -using ShroffCelegansModels - -dataset = ShroffCelegansModels.NormalizedDataset("X:/shrofflab/OD1599_NU/120619_Pos2/Decon_reg/RegB") -# Obtain the untwisted annotations for the C3 cell at timepoint 71 -c3_pt = ShroffCelegansModels.untwist_annotations(dataset, 71)["C3"] -``` -""" -function untwist_annotations(dataset::NormalizedDataset, timepoint::Int=1) - mts = ModelTimeSeries(dataset) - try - df = MIPAVIO.get_integrated_annotations(dataset, timepoint) - pts = MIPAVIO.mipav_df_to_points(df) - return Dict(df.name .=> untwist_annotations(mts(timepoint), pts)) - catch err - return missing - end -end - -function twisted_annotations(dataset::NormalizedDataset, timepoint::Int=1) - try - df = MIPAVIO.get_integrated_annotations(dataset, timepoint) - pts = MIPAVIO.mipav_df_to_points(df) - return Dict(df.name .=> pts) - catch err - return missing - end -end - -function distance_to_twisted_annotation(model::AbstractCelegansModel, pt::Point) - # Sample points along the central spline - cs = ShroffCelegansModels.central_spline(model) - dcs = Derivative(1)*cs - Npts = length(model) - z = LinRange(0, 1, Npts) - central_pts = cs.(z) - annotation_vecs = -(central_pts .- pt) - annotation_norms = norm.(annotation_vecs) - unit_annotation_vecs = annotation_vecs ./ annotation_norms - - ts1 = ShroffCelegansModels.transverse_spline(model, 1) - right = ts1.(z) - right_vecs = right .- central_pts - right_norms = norm.(right_vecs) - unit_right_vecs = right_vecs ./ right_norms - - # Compute the cross product between the right direction and the annotation direction - c = unit_right_vecs .× unit_annotation_vecs - - central_spline_vecs = dcs.(z) - central_spline_norms = norm.(central_spline_vecs) - unit_central_spline_vecs = central_spline_vecs ./ central_spline_norms - - # Compute the sign of the cross product and the derivative of the central spline - # This indicates whether the cross product is pointing - s = sign.(unit_central_spline_vecs .⋅ c) - - # by taking the arctangent of signed magnitude of the cross product - # with the dot product of the right direction and the annotation direction - angles = atan.(norm.(c) .*s, unit_right_vecs .⋅ unit_annotation_vecs) - - return (; annotation_norms, angles, unit_annotation_vecs, unit_right_vecs, unit_central_spline_vecs, c, central_pts, right_vecs, right_norms) -end \ No newline at end of file diff --git a/src/area.jl b/src/area.jl deleted file mode 100644 index a5c9670..0000000 --- a/src/area.jl +++ /dev/null @@ -1,33 +0,0 @@ -function radial_cross_section(model::AbstractCelegansModel, p) - _central_spline = central_spline(model) - center = _central_spline(p) - map(transverse_splines(model)) do transverse_spline - norm(transverse_spline(p) - center) - end -end - -function cross_section_area(model::AbstractCelegansModel, p) - radii = radial_cross_section(model, p) - radii_hat = fft(radii) - N = length(radii) - _sum_of_square_norm = sum(radii_hat) do radius_hat - abs2(radius_hat) - end - return _sum_of_square_norm*π/N^2 -end - -function volume_by_cross_section(model::AbstractCelegansModel; delta = 0.001) - # integrate along the z-axis - _central_spline = central_spline(model) - last_z = _central_spline(0)[3] - last_area = cross_section_area(model, 0) - volume = 0 - for p in delta:delta:1 - z = _central_spline(p)[3] - area = cross_section_area(model, p) - volume += (area + last_area)/2 * (z-last_z) - last_z = z - last_area = area - end - return volume -end \ No newline at end of file diff --git a/src/average.jl b/src/average.jl deleted file mode 100644 index 3eb265a..0000000 --- a/src/average.jl +++ /dev/null @@ -1,120 +0,0 @@ -using Statistics -using StatsBase -using Missings - -const psuedo_seam_cells = ("a0L", "H0L", "H1L", "H2L", "V1L", "V2L", "V3L", "V4L", "V5L", "V6L", "TL") - -function average(models::Vector{<: AbstractCelegansModel}, weights::AbstractWeights = uweights(length(models)); n_upsample::Int = 0) - _names = map(models) do model - #parent(model).names[1:2:end] - ShroffCelegansModels.Types.names(model)[1:2:end] - end - - common_names = intersect(_names..., psuedo_seam_cells) - for psc in psuedo_seam_cells - if psc ∉ common_names - @warn "$psc is missing from average" - end - end - unique_names = unique(vcat(_names...)) - distinct_names = setdiff(unique_names, common_names) - #filter!(!startswith("a"), distinct_names) - # @info "Names" distinct_names - # common_names = psuedo_seam_cells - # common_names = distinct_names - # common_names = intersect(_names...) - - original_knot_pairs = map(models) do model - twisted_model = if model isa Types.StraightenedCelegansModel - parent(model) - else - model - end - #twisted_model = parent(model) - original_knots = knots(central_spline(twisted_model))[4:end-3] - n = unique(twisted_model.names[1:2:end]) - common_pairs = Iterators.filter(t->(t[2] ∈ common_names),zip(original_knots,n)) - common_names = last.(common_pairs) - #= - if length(common_names) > length(psuedo_seam_cells) - println.(common_names) - end - =# - last.(common_pairs) .=> first.(common_pairs) - end - - original_knots = map(x->last.(x), original_knot_pairs) - - for i in 1:n_upsample - original_knots = map(upsample, original_knots) - end - - #display(original_knots) - - z_positions = map(models, original_knots) do model, original_knots - # twisted_model = parent(model) - # original_knots = knots(central_spline(twisted_model))[4:end-3] - central_spline(model).(original_knots) .|> x->x[3] - end - - # return z_positions - - # avg_z_position = (z_positions[1] + z_positions[2])./2 - # avg_z_position = sum(z_positions) ./ length(z_positions) - avg_z_position = mean(z_positions, weights) - # std_z_position = std(z_positions, weights) - - t_positions = map(models, original_knots) do model, original_knots - # twisted_model = parent(model) - # original_knots = knots(central_spline(twisted_model))[4:end-3] - _transverse_splines = transverse_splines(model) - - map(_transverse_splines) do s - s.(original_knots) - end - end - - t_positions = mean(stack.(t_positions), weights) - - # return t_positions - new_knots = avg_z_position ./ avg_z_position[end] - - normalized_knots = map(original_knots) do original_knots - original_knots ./ original_knots[end] - end - - avg_knots = mean(normalized_knots, weights) - - new_knots = avg_knots - - avg_transverse_splines = map(eachcol(t_positions)) do avg_transverse_points - interpolate_natural_cubic_spline(new_knots, collect(avg_transverse_points)) - end - - avg_central_points = map(avg_z_position) do azp - Point3(0,0,azp) - end - avg_central_spline = interpolate_natural_cubic_spline(new_knots, avg_central_points) - - # return avg_z_position ./ avg_z_position[end] - - # TODO: Change add R names back - right_common_names = replace.(common_names, 'L' => 'R') - model_names = vec(permutedims([[common_names...] [right_common_names...]], (2,1))) - return CelegansModel(avg_transverse_splines, avg_central_spline, model_names) - - # return avg_z_position, t_positions, avg_transverse_splines - return avg_transverse_splines, avg_central_spline, common_names -end - -function upsample(v::Vector{T}) where T - N = length(v) - upsampled = T[] - sizehint!(upsampled, 2N-1) - for (a,b) in zip(@view(v[1:end-1]), @view(v[2:end])) - push!(upsampled, a) - push!(upsampled, (a+b)/2) - end - push!(upsampled, v[end]) - return upsampled -end \ No newline at end of file diff --git a/src/build_model.jl b/src/build_model.jl deleted file mode 100644 index 0dac15f..0000000 --- a/src/build_model.jl +++ /dev/null @@ -1,86 +0,0 @@ -# ╔═╡ cc0554ba-27b7-4669-8053-be473cf96bfa -function build_celegans_model( - path::String; - update_cross_sections::Bool = true, -) - df_lattice = CSV.read(path, DataFrame) - names = df_lattice[:,1] - if update_cross_sections - cross_section_path = joinpath(dirname(path), "..", "model_crossSections") - if isdir(cross_section_path) - cross_section_files = readdir(cross_section_path) - n_cross_sections = size(df_lattice,1) ÷ 2 - cross_sections = map(0:n_cross_sections-1) do i - filename = "latticeCrossSection_$i.csv" - if filename in cross_section_files - CSV.read(joinpath(cross_section_path, filename), DataFrame; header=2) - else - nothing - end - end - return build_celegans_model(df_lattice; cross_sections, names) - end - end - return build_celegans_model(df_lattice; names) -end - -function build_celegans_model(df_lattice::DataFrame; cross_sections::Vector{<: Union{Nothing, DataFrame}} = Union{Nothing, DataFrame}[], names = String3[]) - seam_cell_data = df_lattice[:,2:4] - left_seam_cells = seam_cell_data[1:2:end, :] - right_seam_cells = seam_cell_data[2:2:end, :] - return build_celegans_model(left_seam_cells, right_seam_cells, cross_sections, names) -end - -# ╔═╡ 322eb672-bde2-4857-a275-32639f39408a -function build_celegans_model(left_seam_cells, right_seam_cells, cross_sections::Vector=Union{Nothing,DataFrame}[], names::Vector{<:AbstractString} = String3[]) - P = Point3 - # left_seam_cells = Float32.(left_seam_cells) - # right_seam_cells = Float32.(right_seam_cells) - centers = map(eachrow((left_seam_cells .+ right_seam_cells)./2)) do row - P(row...) - end - deltaLengths = norm.(diff(centers)) - afTime = [+0; cumsum(deltaLengths)] - afTime ./= afTime[end] - # afTime = Float32.(afTime) - - right_spline = - interpolate_natural_cubic_spline(afTime, right_seam_cells) - left_spline = - interpolate_natural_cubic_spline(afTime, left_seam_cells) - center_spline = - interpolate_natural_cubic_spline(afTime, centers) - central_spline_d1 = Derivative(1) * center_spline - - # Calculate vectors at each afTime - forward_vector_afTime = central_spline_d1.(afTime) - right_vector_afTime = (right_spline.(afTime) - left_spline.(afTime))./2 - radii = norm.(right_vector_afTime) - normal_vector_afTime = normalize.(cross.( - forward_vector_afTime, - right_vector_afTime - )) .* radii - circle_points = get_circle_points.(right_vector_afTime, normal_vector_afTime, centers) - if !isempty(cross_sections) - CP = eltype(eltype(circle_points)) - for i in eachindex(circle_points) - if !isnothing(cross_sections[i]) - circle_points[i] = map(eachrow(cross_sections[i])) do row - CP(row...) + CP(centers[i,:]...) - end - end - end - end - n_circle_points = length(first(circle_points)) - contourSplines = map(1:n_circle_points) do c - contourPoints = map(circle_points) do pts - pts[c] - end - contourSpline = interpolate_natural_cubic_spline(afTime, contourPoints) - end - model = CelegansModel(contourSplines, center_spline, names) - #return contourSplines - return model -end - -build_celegans_model(::Missing) = missing \ No newline at end of file diff --git a/src/datasets.jl b/src/datasets.jl deleted file mode 100644 index f84b571..0000000 --- a/src/datasets.jl +++ /dev/null @@ -1,104 +0,0 @@ -module Datasets - using JSON3: JSON3 - using CSV, DataFrames - - export Dataset, CellKey, NormalizedDataset - - abstract type AbstractDataset end - - const CELL_KEY_FILE_NAME = "cell_key.json" - const CELL_KEY_CSV_NAME = "CellKey.csv" - - struct Dataset{JO <: JSON3.Object} <: AbstractDataset - path::String - cell_key::JO - end - function Dataset(path::String) - path = abspath(path) - isdir(path) || error("Dataset path, \"$path\", does not exist as a directory.") - cell_key_path = joinpath(dirname(path), CELL_KEY_CSV_NAME) - if isfile(cell_key_path) - return _Dataset(path, cell_key_path) - end - cell_key_path = joinpath(dirname(path), CELL_KEY_FILE_NAME) - return _Dataset(path, cell_key_path) - end - function _Dataset(path::String, cell_key_path::String) - if endswith(cell_key_path, ".json") - return Dataset(path, JSON3.read(cell_key_path)) - end - if endswith(cell_key_path, ".csv") - return NormalizedDataset(path, parse_cell_key_csv(cell_key_path)) - end - error("Cell Key path, $cell_key_path, does not exist as a file.") - end - - struct CellKey - name::String - start::Int - stop::Int # end - mapping::Dict{Symbol,String} - outliers::Vector{Int} - end - const _cell_key_keys = (:end, :mapping, :name, :outliers, :start) - function CellKey(jo::JSON3.Object) - _cell_key_keys ⊆ keys(jo) || return ArgumentError("JSON3.Object must contain the following keys: $_cell_key_keys") - CellKey(jo.name, jo.start, jo.end, jo.mapping, jo.outliers) - end - function CellKey(df::DataFrame) - name = df[1,1] - start = df[2,1] isa AbstractString ? parse(Int, df[2,1]) : df[2,1] - stop = df[2,2] isa AbstractString ? parse(Int, df[2,2]) : df[2,2] - row = 3 - if ismissing(df[3,1]) || - ismissing(df[3,2]) || - isa(df[3,1], Int) || - isa(df[3,2], Int) || - !isnothing(tryparse(Int, df[3,1])) && - !isnothing(tryparse(Int, df[3,2])) - outliers = Int[ - isa(x, AbstractString) ? parse(Int, x) : x - for x in df[3,:] if !ismissing(x) - ] - row = 4 - end - mapping = Dict{Symbol,String}(Symbol(k) => v for (k,v) in zip(df[row:end,1], df[row:end,2]) if !ismissing(k) && !ismissing(v)) - return CellKey(name, start, stop, mapping, outliers) - end - function Base.getproperty(ck::CellKey, s::Symbol) - if s == :end - s = :stop - end - return Base.getfield(ck, s) - end - function Base.range(ck::CellKey) - r = range(ck.start, ck.stop) - rd = setdiff(r, ck.outliers) - real_start = minimum(rd) - real_stop = maximum(rd) - return range(real_start, real_stop) - end - - struct NormalizedDataset <: AbstractDataset - path::String - cell_key::CellKey - end - function NormalizedDataset(path::String) - ds = Dataset(path) - return NormalizedDataset(ds) - end - function NormalizedDataset(ds::Dataset) - return NormalizedDataset(ds.path, CellKey(ds.cell_key)) - end - function NormalizedDataset(ds::NormalizedDataset) - return NormalizedDataset(ds.path, ds.cell_key) - end - function parse_cell_key_csv(path::AbstractString) - try - df = CSV.read(path, DataFrame, header=0) - return CellKey(df) - catch e - error("Error reading CSV file: $path") - end - end -end diff --git a/src/demo_averaging/loading.jl b/src/demo_averaging/loading.jl index 586c0a6..e33f754 100644 --- a/src/demo_averaging/loading.jl +++ b/src/demo_averaging/loading.jl @@ -70,12 +70,17 @@ end =# # Straightened annotations -const annotations_cache = Dict{Tuple{String, UnitRange, Bool}, Vector}() +# const annotations_cache = Dict{Tuple{String, UnitRange, Bool}, Vector}() # Warped annotations, with MIPAV straightening -const annotation_position_cache = Dict{String, Any}() +# const annotation_position_cache = Dict{String, Any}() #const my_annotation_position_cache = Dict{String, Any}() # Warped annotations, with Mark's straightening -const my_annotation_position_cache = Dict{String, Vector{Vector{Point3{Float64}}}}() +# const my_annotation_position_cache = Dict{String, Vector{Vector{Point3{Float64}}}}() + +using ShroffCelegansModels: + annotations_cache, # Straighted annotations + annotations_position_cache, # Warped annotations + my_annotation_position_cache # Warped annotations with Mark's straightening # TODO: Move from demo_averaging:408 # const annotations_cache = Dict{Tuple{String, UnitRange, Bool}, Vector}() diff --git a/src/mesh.jl b/src/mesh.jl deleted file mode 100644 index 280920a..0000000 --- a/src/mesh.jl +++ /dev/null @@ -1,76 +0,0 @@ - function get_model_contour_mesh(model_contours_path::AbstractString) - sections = get_model_contour_sections(model_contours_path) - get_model_contour_mesh(sections) - end - function get_model_contour_mesh( - sections::Vector{Matrix{Float64}}; - ellipse_points::Int=size(first(sections),1) - ) - pts = vcat(map(sections) do section - Point3f.(eachrow(section)) - end...) - return get_model_contour_mesh(pts; ellipse_points) - end - function get_sections(model::AbstractCelegansModel) - r = LinRange(0, 1, length(model)) - _transverse_splines = transverse_splines(model) - sections = map(r) do t - Point3f.(t .|> _transverse_splines) - end - return sections - end - function get_model_contour_mesh(model::AbstractCelegansModel; kwargs...) - sections = get_sections(model) - return get_model_contour_mesh(sections; kwargs...) - end - function get_model_contour_mesh( - sections::Vector{Vector{Point3f}}; - ellipse_points=length(first(sections)), - kwargs... - ) - pts = vcat(sections...) - get_model_contour_mesh(pts; ellipse_points, kwargs...) - end - function get_model_contour_mesh( - pts::Vector{Point3f}; - ellipse_points::Int, - transform_points = identity - ) - if transform_points != identity - pts = transform_points.(pts) - end - npts = length(pts) - #mesh(GeometryBasics.Mesh(pts, faces[1:964])) - A = mod1.(1:ellipse_points, ellipse_points) - B = mod1.(2:ellipse_points+1, ellipse_points) - C = B .+ ellipse_points - D = A .+ ellipse_points - faces = QuadFace.(A,B,C,D) - faces = vec(faces .+ - reshape(QuadFace.(eachrow( - [ellipse_points ellipse_points ellipse_points ellipse_points] .* (0:length(pts)÷ellipse_points-2) - )), 1,:) - ) - M = GeometryBasics.Mesh(pts, faces) - end - function get_model_manifold_mesh_components( - model::AbstractCelegansModel; - transform_points = identity - ) - r = LinRange(0, 1, length(model)) - _splines = [transverse_spline(model,1) central_spline(model) transverse_spline(model,17)] - sections = map(r) do t - Point3f.(t .|> _splines) - end - pts = transform_points.(Iterators.flatten(sections)) - offsets = (0:length(pts)÷3-2) .* (QuadFace(3,3,3,3),) - faces = QuadFace[(1,2,5,4) (2,3,6,5)] .+ offsets - return pts, vec(faces) - end - function get_model_manifold_mesh( - model::AbstractCelegansModel; - transform_points = identity - ) - pts, faces = get_model_manifold_mesh_components(model; transform_points) - return GeometryBasics.Mesh(pts, faces) - end \ No newline at end of file diff --git a/src/model_time_series.jl b/src/model_time_series.jl deleted file mode 100644 index 6e2e33b..0000000 --- a/src/model_time_series.jl +++ /dev/null @@ -1,131 +0,0 @@ -struct ModelTimeSeries{Model <: AbstractCelegansModel, Cache <: LRU{<:AbstractString, Union{Model,Missing}}} - dataset::NormalizedDataset - cache::Cache -end -ModelTimeSeries(dataset::NormalizedDataset; max_cache_size = 2) = - ModelTimeSeries(dataset, LRU{String, Union{CelegansModel,Missing}}(; maxsize = max_cache_size)) -function (mts::ModelTimeSeries)(time_offset::Integer) - try - timepoint = range(mts.dataset.cell_key)[time_offset] - lattice_filepath = get_lattice_filepath(mts.dataset, timepoint) - ds = mts.dataset - get!(mts.cache, lattice_filepath) do - if timepoint ∈ ds.cell_key.outliers - return missing - elseif !isfile(lattice_filepath) - @warn("$lattice_filepath is not a file on disk and is not marked as an outlier.") - return missing - else - return build_celegans_model(lattice_filepath) - end - end - catch err - if err isa BoundsError - @warn "BoundsError" time_offset timepoint lattice_filepath - return nothing - else - rethrow(err) - end - end -end - -struct StraightenedModelTimeSeries{Model <: AbstractCelegansModel, Cache <: LRU{<: AbstractString, Union{Model,Missing}}, ModelTS <: ModelTimeSeries} - modelTimeSeries::ModelTS - cache::Cache -end -function StraightenedModelTimeSeries(dataset::NormalizedDataset, model_cache::LRU, straightened_model_cache::LRU) - mts = ModelTimeSeries(dataset, model_cache) - return StraightenedModelTimeSeries(mts, straightened_model_cache) -end -function StraightenedModelTimeSeries(dataset::NormalizedDataset; max_cache_size = 2) - mts = ModelTimeSeries(dataset; max_cache_size) - StraightenedModelTimeSeries(mts, LRU{String, Union{StraightenedCelegansModel,Missing}}(; maxsize = max_cache_size)) -end -function (smts::StraightenedModelTimeSeries)(time_offset::Integer)::Union{Nothing, Missing, StraightenedCelegansModel} - mts = smts.modelTimeSeries - try - timepoint = range(mts.dataset.cell_key)[time_offset] - lattice_filepath = get_lattice_filepath(mts.dataset, timepoint) - get!(smts.cache, lattice_filepath) do - model = mts(time_offset) - if ismissing(model) - missing - else - StraightenedCelegansModel(model) - end - end - catch err - if err isa BoundsError - return nothing - else - rethrow() - end - end -end -function (smts::StraightenedModelTimeSeries)(time_offset, n_upsample=0) - next = nextModelIndex(smts, time_offset) - prev = prevModelIndex(smts, time_offset) - if isnothing(next) && isnothing(prev) - return nothing - end - if isnothing(next) - return average([smts(prev)]; n_upsample) - end - if isnothing(prev) - return average([smts(next)]; n_upsample) - end - if next == prev - model = smts(next) - if !isnothing(model) - return average([model]; n_upsample) - else - return nothing - end - end - models = [smts(prev), smts(next)] - if isnothing(models[1]) && isnothing(models[2]) - return nothing - elseif isnothing(models[1]) - return average([models[2]]; n_upsample) - elseif isnothing(models[2]) - return average([models[1]]; n_upsample) - else - return average(models, AnalyticWeights([next - time_offset, time_offset - prev]); n_upsample) - end -end - -function get_lattice(ds::NormalizedDataset, time_offset=1)::Union{Missing, String} - timepoint = range(ds.cell_key)[time_offset] - if timepoint ∈ ds.cell_key.outliers - return missing - else - filepath = joinpath(ds.path, "Decon_reg_$(timepoint)", "Decon_reg_$(timepoint)_results", "lattice_final", "lattice.csv") - if isfile(filepath) - return filepath - else - @warn("$filepath is not a file on disk and is not marked as an outlier.") - return missing - end - end -end - -function get_lattice_filepath(ds::NormalizedDataset, timepoint::Integer)::String - filepath = joinpath(ds.path, "Decon_reg_$(timepoint)", "Decon_reg_$(timepoint)_results", "lattice_final", "lattice.csv") - return filepath -end - -function nextModelIndex(smts::StraightenedModelTimeSeries, index) - index = ceil(Int, index) - while ismissing(smts(index)) - index += 1 - end - return index -end - -function prevModelIndex(smts::StraightenedModelTimeSeries, index) - index = floor(Int, index) - while ismissing(smts(index)) - index -= 1 - end - return index -end \ No newline at end of file diff --git a/src/parse_worm_dataset_path.jl b/src/parse_worm_dataset_path.jl index fdf4651..d4dced9 100644 --- a/src/parse_worm_dataset_path.jl +++ b/src/parse_worm_dataset_path.jl @@ -32,21 +32,17 @@ end using HDF5 -const annotations_cache = Dict{Tuple{String, UnitRange, Bool}, Vector}() -const annotation_position_cache = Dict{String, Any}() -#const my_annotation_position_cache = Dict{String, Any}() -const my_annotation_position_cache = Dict{String, Vector{Vector{Point3{Float64}}}}() - include("demo_averaging/load_straightened_annotations_over_time.jl") include("demo_averaging/get_cell_trajectory_dict.jl") include("demo_averaging/save_cache.jl") # initialize my_annotation_position_cache -@info "Loading straightened annotation positions..." -load_annotation_cache() -@info "Loading warped annotation positions..." -load_annotations_cache() +@info "Not loading annotation position cache..." +#@info "Loading straightened annotation positions..." +#load_annotation_cache() +#@info "Loading warped annotation positions..." +#load_annotations_cache() function save_annotation_position_cache( @@ -168,7 +164,14 @@ function save_annotation_position_cache( end end -function save_annotation_position_cache_all_dated(datasets::Dict{String, Vector{Datasets.NormalizedDataset}}; clear = true) +# TODO: type the caches +function save_annotation_position_cache_all_dated( + datasets::Dict{String, Vector{Datasets.NormalizedDataset}}, + annotation_position_cache = annotation_position_cache, + my_annotation_position_cache = my_annotation_position_cache, + annotations_cache = annotations_cache; + clear = true +) # Clear caches if clear empty!(annotation_position_cache) diff --git a/src/points.jl b/src/points.jl deleted file mode 100644 index 586b80d..0000000 --- a/src/points.jl +++ /dev/null @@ -1,34 +0,0 @@ -module Points - -using ..Types: AbstractCelegansModel, lattice_knots, transverse_splines, names -export points, lattice, cross_sections, CrossSections - -function points(model::AbstractCelegansModel) - splines = transverse_splines(model) - r = LinRange(0, 1, length(model)) - pts = map(splines) do spline - spline.(r) - end - hcat(pts...) -end - -function lattice(model::AbstractCelegansModel) - splines = transverse_splines(model) - r = lattice_knots(model) - pts = map(splines) do spline - spline.(r) - end - hcat(pts...) -end - -struct CrossSections{P <: Vector{<: Pair}} - sections::P -end - -function cross_sections(model::AbstractCelegansModel) - _names = names(model)[1:2:end] - CrossSections(_names .=> copy.(eachrow(lattice(model)))) -end - - -end \ No newline at end of file diff --git a/src/precompile.jl b/src/precompile.jl deleted file mode 100644 index 27d6b77..0000000 --- a/src/precompile.jl +++ /dev/null @@ -1,13 +0,0 @@ -@setup_workload begin - lattice_final_path = joinpath(pkgdir(ShroffCelegansModels), "test", "fixtures", "lattice.csv") - @compile_workload begin - try - model = ShroffCelegansModels.build_celegans_model(lattice_final_path) - smodel = ShroffCelegansModels.StraightenedCelegansModel(model) - get_model_contour_mesh(model) - get_model_contour_mesh(smodel) - catch err - Base.showerror(stdout, err, Base.catch_backtrace()) - end - end -end \ No newline at end of file diff --git a/src/show.jl b/src/show.jl deleted file mode 100644 index ce30fa3..0000000 --- a/src/show.jl +++ /dev/null @@ -1,6 +0,0 @@ -function Base.show(io::IO, m::MIME"text/plain", model::T) where T <: AbstractCelegansModel - println(io, T) - for f in fieldnames(T) - println(io, " ", f) - end -end \ No newline at end of file diff --git a/src/straighten.jl b/src/straighten.jl deleted file mode 100644 index 605f5e8..0000000 --- a/src/straighten.jl +++ /dev/null @@ -1,20 +0,0 @@ -# ╔═╡ 9d9e7f86-dc98-4d5b-a0cd-e6a19af34e45 -function straighten_celegans_model(model::CelegansModel) - r = LinRange(0, 1, length(model)) - s = let central_spline_d1 = Derivative(1) * model.central_spline - dr = diff(r) - s = cumsum(norm.(central_spline_d1.(r)) .* dr[1]) - end - sections_radii = map(r) do x - map(model.transverse_splines) do s - norm(s(x) - model.central_spline(x)) - end - end - normal_vector = Point3f(0.0, 0.0, 1.0) - right_vector = Point3f(1.0, 0.0, 0.0) - ap_vector = Point3f(0.0, 1.0, 0.0) - circ_pts = get_circle_points(right_vector, normal_vector, Point3f(0.0, 0.0, 0.0)) - map(zip(sections_radii,s)) do (radii, ds) - Point3f.(circ_pts .* radii .+ (ap_vector*ds,)) - end -end \ No newline at end of file diff --git a/src/types.jl b/src/types.jl deleted file mode 100644 index 6c34ca4..0000000 --- a/src/types.jl +++ /dev/null @@ -1,138 +0,0 @@ -module Types - using GeometryBasics: Point, Point3f, Point3 - using QuadGK: quadgk - using LinearAlgebra: norm - using BSplineKit: Derivative, knots - import BSplineKit.SplineInterpolations: interpolation_points - - using ..ParametricSplines: interpolate_natural_cubic_spline - - export AbstractCelegansModel, CelegansModel, CachedCelegansModel, StraightenedCelegansModel - export central_spline, central_spline_d1 - export transverse_spline, num_transverse_splines, transverse_splines - export lattice_knots - export model_length - export names - export interpolation_points - - abstract type AbstractCelegansModel{S} end - central_spline_d1(model::AbstractCelegansModel) = Derivative(1) * central_spline(model) - model_length(model::AbstractCelegansModel) = first(quadgk(central_spline(model))) - length(model::AbstractCelegansModel) = ceil(Int, model_length(model)) + 1 - Base.length(model::AbstractCelegansModel) = length(model) - transverse_splines(model::AbstractCelegansModel) = map(1:num_transverse_splines(model)) do i - transverse_spline(model, i) - end - lattice_knots(model::AbstractCelegansModel) = knots(central_spline(model))[4:end-3] - interpolation_points(model::AbstractCelegansModel) = interpolation_points(first(transverse_splines(model))) - - struct CelegansModel{S, N} <: AbstractCelegansModel{S} - transverse_splines::Vector{S} - central_spline::S - names::Vector{N} - end - - central_coordinate(model::CelegansModel, t::Float64) = model.central_spline(t) - central_spline(model::CelegansModel) = model.central_spline - transverse_spline(model::CelegansModel, i::Integer) = model.transverse_splines[i] - num_transverse_splines(model::CelegansModel) = Base.length(model.transverse_splines) - names(model::CelegansModel) = model.names - - struct CachedCelegansModel{S} <: AbstractCelegansModel{S} - model::CelegansModel{S} - central_spline_d1::S - model_length::Float64 - length::Int - function CachedCelegansModel(model::AbstractCelegansModel{S}) where S - new{S}( - model, - central_spline_d1(model), - model_length(model), - length(model) - ) - end - end - central_coordinate(model::CachedCelegansModel, t::Float64) = central_coordinate(model.model, t) - central_spline(model::CachedCelegansModel) = central_spline(model.model) - transverse_spline(model::CachedCelegansModel, i::Integer) = transverse_spline(model.model, i) - central_spline_d1(model::CachedCelegansModel) = model.central_spline_d1 - model_length(model::CachedCelegansModel) = model.model_length - length(model::CachedCelegansModel) = model.length - Base.length(model::CachedCelegansModel) = length(model) - parent(model::CachedCelegansModel) = model.model - Base.parent(model::CachedCelegansModel) = parent(model) - num_transverse_splines(model::CachedCelegansModel) = num_transverse_splines(parent(model)) - names(model::CachedCelegansModel) = names(parent(model)) - - - - struct StraightenedTransverseSpline{S} - transverse_spline::S - central_spline::S - straightened_central_spline::S - transverse_vector::Point3f - end - function (s::StraightenedTransverseSpline)(t) - r = norm(s.transverse_spline(t) - s.central_spline(t)) - return s.straightened_central_spline(t) + r*s.transverse_vector - end - function StraightenedTransverseSpline(model, straightened_model, i::Integer) - degree = 360/Base.length(model.transverse_splines)*(i-1) - StraightenedTransverseSpline( - model.transverse_splines[i], - model.central_spline, - straightened_model.central_spline, - Point3f(cosd(degree), sind(degree), 0) - ) - end - interpolation_points(sts::StraightenedTransverseSpline) = interpolation_points(sts.transverse_spline) - - struct StraightenedCelegansModel{S} <: AbstractCelegansModel{S} - twisted_model::CelegansModel{S} - central_spline::S - end - function StraightenedCelegansModel(twisted_model::CelegansModel{S}) where S - d = central_spline_d1(twisted_model) - r = LinRange(0, 1, length(twisted_model)) - n = norm.(d.(r)) - s = cumsum([0; (n[1:end-1] .+ n[2:end])./2]) .* step(r) - #z = interpolate_natural_cubic_spline([0,0.25,0.5,0.75,1],[0.0,0.0,0.0,0.0,0.0]) - s = map(s) do z - Point3(0, 0, z) - end - central_straightened = interpolate_natural_cubic_spline(collect(r), s) - #S([z, z, central_straightened]) - #typeof(central_straighted) - StraightenedCelegansModel( - twisted_model, - central_straightened - ) - end - function transverse_spline(smodel::StraightenedCelegansModel, i) - return StraightenedTransverseSpline(smodel.twisted_model, smodel, i) - end - parent(smodel::StraightenedCelegansModel) = smodel.twisted_model - Base.parent(smodel::StraightenedCelegansModel) = parent(smodel) - central_spline(smodel::StraightenedCelegansModel) = smodel.central_spline - length(smodel::StraightenedCelegansModel) = length(parent(smodel)) - num_transverse_splines(model::StraightenedCelegansModel) = num_transverse_splines(parent(model)) - names(model::StraightenedCelegansModel) = names(parent(model)) - lattice_knots(model::StraightenedCelegansModel) = lattice_knots(parent(model)) - - """ - RadialCelegansModel - - The radial C. elegans model consists of a 3-dimensional parametric spline describing the central axis of the worm. - The transverse axes that run from anterior to posterior are defined by their radial distance from the the central spline - along regular radial spokes normal to the derivative of the central spline. These are modeled as 1-dimensional interpolate_natural_cubic_spline - cubic splines. - - This differs from `CelegansModel` where the transverse_splines are 3-dimensional parameteric splines rather than 1-dimensional splines. - """ - struct RadialCelegansModel{C,R} <: AbstractCelegansModel{C} - transverse_splines::Vector{R} - central_spline::C - names::Vector{String} - end - -end \ No newline at end of file diff --git a/src/util.jl b/src/util.jl deleted file mode 100644 index 96ee8ee..0000000 --- a/src/util.jl +++ /dev/null @@ -1,14 +0,0 @@ -const get_circle_points = let N=32, θ = (0:N-1)//N*2, cθ = cospi.(θ), sθ = sinpi.(θ) - function _get_circle_points(right_vector, normal_vector, center_point) - # This could be precomputed once - #= - θ = LinRange(0, 2π, 33)[1:end-1] - cθ = cos.(θ) - sθ = sin.(θ) - =# - map(cθ, sθ) do c, s - # This is done to match mipav - right_vector*c + normal_vector*s + center_point - end - end -end \ No newline at end of file From 6342f6aa7ba28296284929e4750cc4d69f34b9e8 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Wed, 8 Oct 2025 16:14:14 -0400 Subject: [PATCH 10/12] Add annotation untwist candidate code --- .../src/annotation_untwist.jl | 81 ++++++++++++++++++- 1 file changed, 77 insertions(+), 4 deletions(-) diff --git a/ShroffCelegansModelsCore/src/annotation_untwist.jl b/ShroffCelegansModelsCore/src/annotation_untwist.jl index 5004a4d..107a82c 100644 --- a/ShroffCelegansModelsCore/src/annotation_untwist.jl +++ b/ShroffCelegansModelsCore/src/annotation_untwist.jl @@ -49,6 +49,56 @@ function nearest_central_pt(model::AbstractCelegansModel, pts::AbstractVector{<: return first.(arg_pt_dist), second.(arg_pt_dist), last.(arg_pt_dist) end +function get_central_spline_distance_to_pts( + model::AbstractCelegansModel, + pts::AbstractVector{<: Point} +) + cs = ShroffCelegansModelsCore.central_spline(model) + Npts = length(model) + z = LinRange(0, 1, Npts) + central_pts = cs.(z) + map(pts) do pt + norm.(central_pts .- pt) + end +end + +function get_central_spline_distance_to_pt( + model::AbstractCelegansModel, + pt::Point +) + cs = ShroffCelegansModelsCore.central_spline(model) + Npts = length(model) + z = LinRange(0, 1, Npts) + central_pts = cs.(z) + norm.(central_pts .- pt) +end + +get_central_spline_distance_to_pt( + model::AbstractCelegansModel, + pt::AbstractArray +) = get_central_spline_distance_to_pt(model, Point3(pt)) + +function findlocalminima(v::AbstractVector{<: Real}) + N = length(v) + minima = BitVector(undef, N) + minima[1] = false + minima[N] = false + for i in 2:N-1 + minima[i] = (v[i] < v[i-1]) && (v[i] < v[i+1]) + end + return findall(minima) +end + +function get_untwisted_annotation_candidates( + model::AbstractCelegansModel, + pt::Point +) + dists = get_central_spline_distance_to_pt(model, pt) + minima_indices = findlocalminima(dists) + candidates = untwist_annotations(model, repeat([pt], length(minima_indices)), nothing; central_point_indices = minima_indices) + return collect(zip(candidates, dists[minima_indices])) +end + """ get_central_point_parameters(model::AbstractCelegansModel, pts::AbstractVector{<: Point}, central_spline_voxel_distances::AbstractVector{<: Real}) @@ -74,6 +124,24 @@ function get_central_point_parameters( return spline_param, central_pts, pt_to_central_dist end +function get_central_point_parameters_from_indices( + model::AbstractCelegansModel, + pts::AbstractVector{<: Point}, + indices::AbstractVector{<: Integer} +) + cs = ShroffCelegansModelsCore.central_spline(model) + Npts = length(model) + z = LinRange(0, 1, Npts) + central_pts = cs.(z) + spline_param = z[indices] + central_pts = central_pts[indices] + pt_to_central_dist = norm.(central_pts .- pts) + return spline_param, central_pts, pt_to_central_dist +end + +""" + max_radius_function(model::AbstractCelegansModel) +""" function max_radius_function(model) function max_radius(z) tss = transverse_splines(model) @@ -158,7 +226,8 @@ ShroffCelegansModelsCore.untwist_annotations(model, pts) function untwist_annotations( model::AbstractCelegansModel, pts::AbstractVector{<: Point}, - central_spline_voxel_distances::Union{AbstractVector{<: Real},Nothing} = nothing + central_spline_voxel_distances::Union{AbstractVector{<: Real},Nothing} = nothing; + central_point_indices::Union{AbstractVector{<: Integer},Nothing} = nothing ) thresholds = [1.0, 1.05, 1.10, 1.15, 1.20, 1.25, 1.30, 1.35, 1.40, 1.45, 1.5, 2.0, 2.5] @@ -166,10 +235,14 @@ function untwist_annotations( # t is the spline parameter # ncp is the nearest central point # pts_norm is the distance from the point to the central spline - if isnothing(central_spline_voxel_distances) - t, ncp, pts_norm = nearest_central_pt(model, pts, thresholds) + if isnothing(central_point_indices) + if isnothing(central_spline_voxel_distances) + t, ncp, pts_norm = nearest_central_pt(model, pts, thresholds) + else + t, ncp, pts_norm = get_central_point_parameters(model, pts, central_spline_voxel_distances) + end else - t, ncp, pts_norm = get_central_point_parameters(model, pts, central_spline_voxel_distances) + t, ncp, pts_norm = get_central_point_parameters_from_indices(model, pts, central_point_indices) end # Objective: Compute the angle between the right direction and the point From 143ba5c7c4419722dfb03e6eaf3214486ef34fb8 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Wed, 8 Oct 2025 16:15:37 -0400 Subject: [PATCH 11/12] Add get_untwisted_annotation_candidates with abstract_array --- ShroffCelegansModelsCore/src/annotation_untwist.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ShroffCelegansModelsCore/src/annotation_untwist.jl b/ShroffCelegansModelsCore/src/annotation_untwist.jl index 107a82c..0dabb3b 100644 --- a/ShroffCelegansModelsCore/src/annotation_untwist.jl +++ b/ShroffCelegansModelsCore/src/annotation_untwist.jl @@ -99,6 +99,11 @@ function get_untwisted_annotation_candidates( return collect(zip(candidates, dists[minima_indices])) end +get_untwisted_annotation_candidates( + model::AbstractCelegansModel, + pt::AbstractArray +) = get_untwisted_annotation_candidates(model, Point3(pt)) + """ get_central_point_parameters(model::AbstractCelegansModel, pts::AbstractVector{<: Point}, central_spline_voxel_distances::AbstractVector{<: Real}) From b2824907354fb8b942a3b2d1750243b2e1437d4f Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Thu, 9 Oct 2025 10:31:58 -0400 Subject: [PATCH 12/12] Refer save_annotation_position_cache to Core --- ShroffCelegansModelsCore/src/parse_worm_dataset_path.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ShroffCelegansModelsCore/src/parse_worm_dataset_path.jl b/ShroffCelegansModelsCore/src/parse_worm_dataset_path.jl index fdf4651..d167149 100644 --- a/ShroffCelegansModelsCore/src/parse_worm_dataset_path.jl +++ b/ShroffCelegansModelsCore/src/parse_worm_dataset_path.jl @@ -51,7 +51,7 @@ load_annotations_cache() function save_annotation_position_cache( filename::String, - datasets::Dict{String, Vector{ShroffCelegansModels.Datasets.NormalizedDataset}}, + datasets::Dict{String, Vector{ShroffCelegansModelsCore.Datasets.NormalizedDataset}}, cache::Dict{String, Vector{Vector{Point3{Float64}}}}; num_timepoints::Union{Symbol, Int} = :raw, expand_annotations::Bool = false,