finished frontend preprocessing UI connection, small changes to interactivity

This commit is contained in:
Pixelguy14 2025-12-01 12:11:49 -06:00
parent 8b1c2d2722
commit b95b8e500c
10 changed files with 965 additions and 668 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ log/*
R_original_scripts/
test/results/
test/binarization_results/
Manifest.toml

View File

@ -101,15 +101,15 @@ version = "0.4.0"
[[deps.ArrayInterface]]
deps = ["Adapt", "LinearAlgebra"]
git-tree-sha1 = "dbd8c3bbbdbb5c2778f85f4422c39960eac65a42"
git-tree-sha1 = "d81ae5489e13bc03567d4fbbb06c546a5e53c857"
uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
version = "7.20.0"
version = "7.22.0"
[deps.ArrayInterface.extensions]
ArrayInterfaceBandedMatricesExt = "BandedMatrices"
ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices"
ArrayInterfaceCUDAExt = "CUDA"
ArrayInterfaceCUDSSExt = "CUDSS"
ArrayInterfaceCUDSSExt = ["CUDSS", "CUDA"]
ArrayInterfaceChainRulesCoreExt = "ChainRulesCore"
ArrayInterfaceChainRulesExt = "ChainRules"
ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore"
@ -238,9 +238,9 @@ version = "1.1.1"
[[deps.CairoMakie]]
deps = ["CRC32c", "Cairo", "Cairo_jll", "Colors", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools"]
git-tree-sha1 = "6d76f05dbc8b7a52deaa7cdabe901735ae7b6724"
git-tree-sha1 = "9bd45574379e50579a78774334f4a1f1238c0af5"
uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
version = "0.13.1"
version = "0.13.10"
[[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"]
@ -295,9 +295,9 @@ version = "0.15.8"
[[deps.CodeTracking]]
deps = ["InteractiveUtils", "UUIDs"]
git-tree-sha1 = "980f01d6d3283b3dbdfd7ed89405f96b7256ad57"
git-tree-sha1 = "9ce926a33a8608421a4d45c012884165b3fcd3ee"
uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
version = "2.0.1"
version = "2.0.2"
[[deps.CodecBase]]
deps = ["TranscodingStreams"]
@ -313,9 +313,9 @@ version = "0.7.8"
[[deps.ColorBrewer]]
deps = ["Colors", "JSON"]
git-tree-sha1 = "e771a63cc8b539eca78c85b0cabd9233d6c8f06f"
git-tree-sha1 = "07da79661b919001e6863b81fc572497daa58349"
uuid = "a2cac450-b92f-5266-8821-25eda20663c8"
version = "0.4.1"
version = "0.4.2"
[[deps.ColorSchemes]]
deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"]
@ -358,9 +358,9 @@ version = "1.0.0"
[[deps.Compat]]
deps = ["TOML", "UUIDs"]
git-tree-sha1 = "0037835448781bb46feb39866934e243886d756a"
git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "4.18.0"
version = "4.18.1"
weakdeps = ["Dates", "LinearAlgebra"]
[deps.Compat.extensions]
@ -473,9 +473,9 @@ 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 = "d8928e9169ff76c6281f39a659f9bca3a573f24c"
uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
version = "1.7.0"
version = "1.8.1"
[[deps.DataStructures]]
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
@ -501,9 +501,9 @@ version = "1.16.2+0"
[[deps.DelaunayTriangulation]]
deps = ["AdaptivePredicates", "EnumX", "ExactPredicates", "Random"]
git-tree-sha1 = "5620ff4ee0084a6ab7097a27ba0c19290200b037"
git-tree-sha1 = "783b21581a051ac91a3921ee37e26a23ed7f57a6"
uuid = "927a84f5-c5f4-47a5-9785-b46e178433df"
version = "1.6.4"
version = "1.6.5"
[[deps.DelimitedFiles]]
deps = ["Mmap"]
@ -529,9 +529,9 @@ version = "1.11.0"
[[deps.Distributions]]
deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"]
git-tree-sha1 = "3e6d038b77f22791b8e3472b7c633acea1ecac06"
git-tree-sha1 = "3bc002af51045ca3b47d2e1787d6ce02e68b943a"
uuid = "31c24e10-a181-5473-b8eb-7969acd0382f"
version = "0.25.120"
version = "0.25.122"
[deps.Distributions.extensions]
DistributionsChainRulesCoreExt = "ChainRulesCore"
@ -550,9 +550,9 @@ version = "0.9.5"
[[deps.Documenter]]
deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "CodecZlib", "Dates", "DocStringExtensions", "Downloads", "Git", "IOCapture", "InteractiveUtils", "JSON", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "TOML", "Test", "Unicode"]
git-tree-sha1 = "352b9a04e74edd16429aec79f033620cf8e780d4"
git-tree-sha1 = "70c521ca3a23c576e12655d15963977c9766c26b"
uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
version = "1.15.0"
version = "1.16.0"
[[deps.DotEnv]]
deps = ["PrecompileTools"]
@ -596,9 +596,9 @@ version = "0.1.11"
[[deps.Expat_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"]
git-tree-sha1 = "7bb1361afdb33c7f2b085aa49ea8fe1b0fb14e58"
git-tree-sha1 = "27af30de8b5445644e8ffe3bcb0d72049c089cf1"
uuid = "2e619515-83b5-522b-bb60-26c02a35a201"
version = "2.7.1+0"
version = "2.7.3+0"
[[deps.ExproniconLite]]
git-tree-sha1 = "c13f0b150373771b0fdc1713c97860f8df12e6c2"
@ -612,9 +612,9 @@ version = "0.1.6"
[[deps.EzXML]]
deps = ["Printf", "XML2_jll"]
git-tree-sha1 = "680a39c9aadce7c721b68d979e66dc65d2021aa6"
git-tree-sha1 = "7ea1aa5869e2626ccae84480e4f37185bc6f41d3"
uuid = "8f5d6c58-4d21-5cfd-889c-e3ad7ee6a615"
version = "1.2.2"
version = "1.2.3"
[[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"]
@ -673,9 +673,9 @@ version = "1.11.0"
[[deps.FillArrays]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "173e4d8f14230a7523ae11b9a3fa9edb3e0efd78"
git-tree-sha1 = "5bfcd42851cf2f1b303f51525a54dc5e98d408a3"
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
version = "1.14.0"
version = "1.15.0"
weakdeps = ["PDMats", "SparseArrays", "Statistics"]
[deps.FillArrays.extensions]
@ -743,9 +743,9 @@ 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 = "487ffeede54553565023a107529434ff585060ae"
git-tree-sha1 = "d16b3b912164f0fd90a393e8c3b6f5a4ec073fde"
uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a"
version = "0.11.2"
version = "0.11.11"
[[deps.GMP_jll]]
deps = ["Artifacts", "Libdl"]
@ -766,9 +766,9 @@ version = "0.5.1"
[[deps.Genie]]
deps = ["ArgParse", "Base64", "Dates", "Distributed", "DotEnv", "EzXML", "FilePathsBase", "HTTP", "HttpCommon", "Inflector", "JSON3", "JuliaFormatter", "Logging", "LoggingExtras", "LoweredCodeUtils", "MIMEs", "Markdown", "Millboard", "Nettle", "OrderedCollections", "Pkg", "REPL", "Random", "Reexport", "Revise", "SHA", "Serialization", "Sockets", "UUIDs", "Unicode", "XML2_jll", "YAML"]
git-tree-sha1 = "6b1283b541f467ae6830d6066535bd6f73a3e808"
git-tree-sha1 = "86356a37e97b135ee86ec1f0e1dd8fc52830dcff"
uuid = "c43c736e-a2d1-11e8-161f-af95117fbd1e"
version = "5.31.1"
version = "5.33.17"
[[deps.GenieAutoReload]]
deps = ["Distributed", "Genie", "Logging", "Revise"]
@ -784,9 +784,9 @@ version = "2.12.1"
[[deps.GenieFramework]]
deps = ["GarishPrint", "Genie", "GenieAutoReload", "GenieDevTools", "GeniePackageManager", "Reexport", "Revise", "Stipple", "StipplePivotTable", "StipplePlotly", "StippleTable", "StippleTabs", "StippleUI"]
git-tree-sha1 = "d35a79434728f5d04ed0d07ff19a250821133da6"
git-tree-sha1 = "4dcc51e8dbaf7d02ba80a2dbebc7b05eb477cc03"
uuid = "a59fdf5c-6bf0-4f5d-949c-a137c9e2f353"
version = "2.8.0"
version = "2.10.0"
[[deps.GeniePackageManager]]
deps = ["Base64", "Genie", "Pkg"]
@ -896,9 +896,9 @@ version = "1.0.2"
[[deps.HTTP]]
deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"]
git-tree-sha1 = "ed5e9c58612c4e081aecdb6e1a479e18462e041e"
git-tree-sha1 = "5e6fe50ae7f23d171f44e311c2960294aaa0beb5"
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
version = "1.10.17"
version = "1.10.19"
[[deps.HarfBuzz_jll]]
deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"]
@ -937,9 +937,9 @@ version = "0.3.28"
[[deps.IOCapture]]
deps = ["Logging", "Random"]
git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770"
git-tree-sha1 = "0ee181ec08df7d7c911901ea38baf16f755114dc"
uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89"
version = "0.2.5"
version = "1.0.0"
[[deps.IfElse]]
git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1"
@ -1124,9 +1124,9 @@ weakdeps = ["Unitful"]
[[deps.IntervalArithmetic]]
deps = ["CRlibm", "MacroTools", "OpenBLASConsistentFPCSR_jll", "Printf", "Random", "RoundingEmulator"]
git-tree-sha1 = "815e74f416953c348c9da1d1bc977bbc97c84e18"
git-tree-sha1 = "02b61501dbe6da3b927cc25dacd7ce32390ee970"
uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253"
version = "1.0.0"
version = "1.0.2"
[deps.IntervalArithmetic.extensions]
IntervalArithmeticArblibExt = "Arblib"
@ -1147,12 +1147,13 @@ version = "1.0.0"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
[[deps.IntervalSets]]
git-tree-sha1 = "5fbb102dcb8b1a858111ae81d56682376130517d"
git-tree-sha1 = "03b4f40b4987baa6a653a21f6f33f902af6255f3"
uuid = "8197267c-284f-5f27-9208-e0e47529a953"
version = "0.7.11"
weakdeps = ["Random", "RecipesBase", "Statistics"]
version = "0.7.12"
weakdeps = ["Printf", "Random", "RecipesBase", "Statistics"]
[deps.IntervalSets.extensions]
IntervalSetsPrintfExt = "Printf"
IntervalSetsRandomExt = "Random"
IntervalSetsRecipesBaseExt = "RecipesBase"
IntervalSetsStatisticsExt = "Statistics"
@ -1173,9 +1174,9 @@ uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f"
version = "1.3.1"
[[deps.IrrationalConstants]]
git-tree-sha1 = "e2222959fbc6c19554dc15174c81bf7bf3aa691c"
git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758"
uuid = "92d709cd-6900-40b7-9082-c6be49f344b6"
version = "0.2.4"
version = "0.2.6"
[[deps.Isoband]]
deps = ["isoband_jll"]
@ -1247,9 +1248,9 @@ version = "1.0.62"
[[deps.JuliaInterpreter]]
deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"]
git-tree-sha1 = "d8337622fe53c05d16f031df24daf0270e53bc64"
git-tree-sha1 = "b6c76964c65ebf8309460fb8f0f437b4a59d809b"
uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a"
version = "0.10.5"
version = "0.10.7"
[[deps.KernelDensity]]
deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"]
@ -1429,35 +1430,37 @@ version = "1.11.0"
[[deps.LoggingExtras]]
deps = ["Dates", "Logging"]
git-tree-sha1 = "f02b56007b064fbfddb4c9cd60161b6dd0f40df3"
git-tree-sha1 = "f00544d95982ea270145636c181ceda21c4e2575"
uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36"
version = "1.1.0"
version = "1.2.0"
[[deps.LoopVectorization]]
deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"]
git-tree-sha1 = "e5afce7eaf5b5ca0d444bcb4dc4fd78c54cbbac0"
git-tree-sha1 = "a9fc7883eb9b5f04f46efb9a540833d1fad974b3"
uuid = "bdcacae8-1622-11e9-2a5c-532679323890"
version = "0.12.172"
version = "0.12.173"
[deps.LoopVectorization.extensions]
ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"]
ForwardDiffNNlibExt = ["ForwardDiff", "NNlib"]
SpecialFunctionsExt = "SpecialFunctions"
[deps.LoopVectorization.weakdeps]
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
NNlib = "872c559c-99b0-510c-b3b7-b6c96a88d5cd"
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
[[deps.LoweredCodeUtils]]
deps = ["CodeTracking", "Compiler", "JuliaInterpreter"]
git-tree-sha1 = "73b98709ad811a6f81d84e105f4f695c229385ba"
git-tree-sha1 = "e24491cb83551e44a69b9106c50666dea9d953ab"
uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b"
version = "3.4.3"
version = "3.4.4"
[[deps.MIMEs]]
git-tree-sha1 = "65f28ad4b594aebe22157d6fac869786a255b7eb"
git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691"
uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65"
version = "0.1.4"
version = "1.1.0"
[[deps.MKL_jll]]
deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"]
@ -1472,15 +1475,15 @@ 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", "PNGFiles", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun", "Unitful"]
git-tree-sha1 = "9680336a5b67f9f9f6eaa018f426043a8cd68200"
git-tree-sha1 = "1d7d16f0e02ec063becd7a140f619b2ffe5f2b11"
uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
version = "0.22.1"
version = "0.22.10"
[[deps.MakieCore]]
deps = ["ColorTypes", "GeometryBasics", "IntervalSets", "Observables"]
git-tree-sha1 = "c731269d5a2c85ffdc689127a9ba6d73e978a4b1"
git-tree-sha1 = "c3159eb1e3aa3e409edbb71f4035ed8b1fc16e23"
uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b"
version = "0.9.0"
version = "0.9.5"
[[deps.ManualMemory]]
git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd"
@ -1505,9 +1508,9 @@ version = "0.1.2"
[[deps.MathTeXEngine]]
deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"]
git-tree-sha1 = "a370fef694c109e1950836176ed0d5eabbb65479"
git-tree-sha1 = "7eb8cdaa6f0e8081616367c10b31b9d9b34bb02a"
uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53"
version = "0.6.6"
version = "0.6.7"
[[deps.MbedTLS]]
deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"]
@ -1594,9 +1597,9 @@ version = "1.0.0"
[[deps.NearestNeighbors]]
deps = ["Distances", "StaticArrays"]
git-tree-sha1 = "ca7e18198a166a1f3eb92a3650d53d94ed8ca8a1"
git-tree-sha1 = "17399deebfc0ef7d7a97225776571d13adf01a36"
uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce"
version = "0.4.22"
version = "0.4.23"
[[deps.Netpbm]]
deps = ["FileIO", "ImageCore", "ImageMetadata"]
@ -1670,9 +1673,9 @@ version = "3.2.4+0"
[[deps.OpenJpeg_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libtiff_jll", "LittleCMS_jll", "libpng_jll"]
git-tree-sha1 = "7dc7028a10d1408e9103c0a77da19fdedce4de6c"
git-tree-sha1 = "215a6666fee6d6b3a6e75f2cc22cb767e2dd393a"
uuid = "643b3616-a352-519d-856d-80112ee9badc"
version = "2.5.4+0"
version = "2.5.5+0"
[[deps.OpenLibm_jll]]
deps = ["Artifacts", "Libdl"]
@ -1686,10 +1689,10 @@ uuid = "9bd350c2-7e96-507f-8002-3f2e150b4e1b"
version = "9.9.2+0"
[[deps.OpenSSL]]
deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"]
git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e"
deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "NetworkOptions", "OpenSSL_jll", "Sockets"]
git-tree-sha1 = "386b47442468acfb1add94bf2d85365dea10cbab"
uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c"
version = "1.5.0"
version = "1.6.0"
[[deps.OpenSSL_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"]
@ -1721,9 +1724,13 @@ version = "10.42.0+1"
[[deps.PDMats]]
deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"]
git-tree-sha1 = "f07c06228a1c670ae4c87d1276b92c7c597fdda0"
git-tree-sha1 = "d922b4d80d1e12c658da7785e754f4796cc1d60d"
uuid = "90014a1f-27ba-587c-ab20-58faa44d9150"
version = "0.11.35"
version = "0.11.36"
weakdeps = ["StatsBase"]
[deps.PDMats.extensions]
StatsBaseExt = "StatsBase"
[[deps.PNGFiles]]
deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"]
@ -1745,9 +1752,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 = "1f7f9bbd5f7a2e5a9f7d96e51c9754454ea7f60b"
git-tree-sha1 = "0662b083e11420952f2e62e17eddae7fc07d5997"
uuid = "36c8627f-9965-5494-a995-c6b170f724f3"
version = "1.56.4+0"
version = "1.57.0+0"
[[deps.Parameters]]
deps = ["OrderedCollections", "UnPack"]
@ -1784,15 +1791,27 @@ version = "0.3.3"
[[deps.PlotUtils]]
deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "StableRNGs", "Statistics"]
git-tree-sha1 = "3ca9a356cd2e113c420f2c13bea19f8d3fb1cb18"
git-tree-sha1 = "26ca162858917496748aad52bb5d3be4d26a228a"
uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043"
version = "1.4.3"
version = "1.4.4"
[[deps.PlotlyBase]]
deps = ["ColorSchemes", "Dates", "DelimitedFiles", "DocStringExtensions", "JSON", "LaTeXStrings", "Logging", "Parameters", "Pkg", "REPL", "Requires", "Statistics", "UUIDs"]
git-tree-sha1 = "56baf69781fc5e61607c3e46227ab17f7040ffa2"
deps = ["ColorSchemes", "Colors", "Dates", "DelimitedFiles", "DocStringExtensions", "JSON", "LaTeXStrings", "Logging", "Parameters", "Pkg", "REPL", "Requires", "Statistics", "UUIDs"]
git-tree-sha1 = "28278bb0053da0fd73537be94afd1682cc5a0a83"
uuid = "a03496cd-edff-5a9b-9e67-9cda94a718b5"
version = "0.8.19"
version = "0.8.21"
[deps.PlotlyBase.extensions]
DataFramesExt = "DataFrames"
DistributionsExt = "Distributions"
IJuliaExt = "IJulia"
JSON3Ext = "JSON3"
[deps.PlotlyBase.weakdeps]
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a"
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
[[deps.PolyesterWeave]]
deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"]
@ -1842,10 +1861,10 @@ uuid = "21216c6a-2e73-6563-6e65-726566657250"
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 = "6b8e2f0bae3f678811678065c09571c1619da219"
uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
version = "2.4.0"
version = "3.1.0"
[[deps.Printf]]
deps = ["Unicode"]
@ -1967,9 +1986,9 @@ version = "1.3.1"
[[deps.Revise]]
deps = ["CodeTracking", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "REPL", "Requires", "UUIDs", "Unicode"]
git-tree-sha1 = "d852eba0cc08181083a58d5eb9dccaec3129cb03"
git-tree-sha1 = "85d94c2be31f58728cd69d13f2e0bdd7ecf6dfe9"
uuid = "295af30f-e4ad-537b-8983-00126c2a3abe"
version = "3.9.0"
version = "3.12.1"
weakdeps = ["Distributed"]
[deps.Revise.extensions]
@ -1977,9 +1996,9 @@ weakdeps = ["Distributed"]
[[deps.Rmath]]
deps = ["Random", "Rmath_jll"]
git-tree-sha1 = "852bd0f55565a9e973fcfee83a84413270224dc4"
git-tree-sha1 = "5b3d50eb374cea306873b371d3f8d3915a018f0b"
uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa"
version = "0.8.0"
version = "0.9.0"
[[deps.Rmath_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"]
@ -2008,9 +2027,9 @@ version = "0.7.0"
[[deps.SIMD]]
deps = ["PrecompileTools"]
git-tree-sha1 = "fea870727142270bdf7624ad675901a1ee3b4c87"
git-tree-sha1 = "e24dc23107d426a096d3eae6c165b921e74c18e4"
uuid = "fdea26ae-647d-5447-a871-4b548cad5224"
version = "3.7.1"
version = "3.7.2"
[[deps.SIMDTypes]]
git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c"
@ -2125,9 +2144,9 @@ version = "1.11.0"
[[deps.SpecialFunctions]]
deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"]
git-tree-sha1 = "41852b8679f78c8d8961eeadc8f62cef861a52e3"
git-tree-sha1 = "f2685b435df2613e25fc10ad8c26dddb8640f547"
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
version = "2.5.1"
version = "2.6.1"
weakdeps = ["ChainRulesCore"]
[deps.SpecialFunctions.extensions]
@ -2135,9 +2154,9 @@ weakdeps = ["ChainRulesCore"]
[[deps.StableRNGs]]
deps = ["Random"]
git-tree-sha1 = "95af145932c2ed859b63329952ce8d633719f091"
git-tree-sha1 = "4f96c596b8c8258cc7d3b19797854d368f243ddc"
uuid = "860ef19b-820b-49d6-a774-d7a799459cd3"
version = "1.0.3"
version = "1.0.4"
[[deps.StackViews]]
deps = ["OffsetArrays"]
@ -2147,9 +2166,9 @@ version = "0.1.2"
[[deps.Static]]
deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools", "SciMLPublic"]
git-tree-sha1 = "1e44e7b1dbb5249876d84c32466f8988a6b41bbb"
git-tree-sha1 = "49440414711eddc7227724ae6e570c7d5559a086"
uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3"
version = "1.3.0"
version = "1.3.1"
[[deps.StaticArrayInterface]]
deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Static"]
@ -2174,9 +2193,9 @@ weakdeps = ["ChainRulesCore", "Statistics"]
StaticArraysStatisticsExt = "Statistics"
[[deps.StaticArraysCore]]
git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682"
git-tree-sha1 = "6ab403037779dae8c514bad259f32a447262455a"
uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c"
version = "1.4.3"
version = "1.4.4"
[[deps.Statistics]]
deps = ["LinearAlgebra"]
@ -2196,15 +2215,15 @@ version = "1.7.1"
[[deps.StatsBase]]
deps = ["AliasTables", "DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"]
git-tree-sha1 = "2c962245732371acd51700dbb268af311bddd719"
git-tree-sha1 = "064b532283c97daae49e544bb9cb413c26511f8c"
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
version = "0.34.6"
version = "0.34.8"
[[deps.StatsFuns]]
deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"]
git-tree-sha1 = "8e45cecc66f3b42633b8ce14d431e8e57a3e242e"
git-tree-sha1 = "91f091a8716a6bb38417a6e6f274602a19aaa685"
uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
version = "1.5.0"
version = "1.5.2"
weakdeps = ["ChainRulesCore", "InverseFunctions"]
[deps.StatsFuns.extensions]
@ -2225,9 +2244,9 @@ weakdeps = ["DataFrames", "JSON", "OffsetArrays"]
[[deps.StipplePivotTable]]
deps = ["Stipple", "StippleUI", "Tables"]
git-tree-sha1 = "77bb654bf22c50872878ccf4653949d95808a055"
git-tree-sha1 = "98d96b177125630eb5d273b3e705aec22bb4ec86"
uuid = "adab0226-ee3c-44de-8f2f-393b1bf1e936"
version = "0.3.2"
version = "0.4.3"
[[deps.StipplePlotly]]
deps = ["DataFrames", "Genie", "Requires", "Stipple"]
@ -2275,9 +2294,9 @@ version = "0.4.1"
[[deps.StructArrays]]
deps = ["ConstructionBase", "DataAPI", "Tables"]
git-tree-sha1 = "8ad2e38cbb812e29348719cc63580ec1dfeb9de4"
git-tree-sha1 = "a2c37d815bf00575332b7bd0389f771cb7987214"
uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
version = "0.7.1"
version = "0.7.2"
[deps.StructArrays.extensions]
StructArraysAdaptExt = "Adapt"
@ -2417,9 +2436,9 @@ version = "0.4.1"
[[deps.Unitful]]
deps = ["Dates", "LinearAlgebra", "Random"]
git-tree-sha1 = "cec2df8cf14e0844a8c4d770d12347fda5931d72"
git-tree-sha1 = "83360bda12f61c250835830cc40b64f487cc2230"
uuid = "1986cc42-f94f-5a68-af5c-568840ba703d"
version = "1.25.0"
version = "1.25.1"
[deps.Unitful.extensions]
ConstructionBaseUnitfulExt = "ConstructionBase"
@ -2479,9 +2498,9 @@ version = "1.6.1"
[[deps.XML2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"]
git-tree-sha1 = "04a51d15436a572301b5abbb9d099713327e9fc4"
git-tree-sha1 = "80d3930c6347cfce7ccf96bd3bafdf079d9c0390"
uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a"
version = "2.10.4+0"
version = "2.13.9+0"
[[deps.XZ_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"]
@ -2533,9 +2552,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"]
@ -2599,9 +2618,9 @@ version = "1.6.0+0"
[[deps.YAML]]
deps = ["Base64", "Dates", "Printf", "StringEncodings"]
git-tree-sha1 = "2f58ac39f64b41fb812340347525be3b590cce3b"
git-tree-sha1 = "a1c0c7585346251353cddede21f180b96388c403"
uuid = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
version = "0.4.14"
version = "0.4.16"
[[deps.Zlib_jll]]
deps = ["Libdl"]
@ -2622,9 +2641,9 @@ version = "2.38.0+0"
[[deps.at_spi2_core_jll]]
deps = ["Artifacts", "Dbus_jll", "Glib_jll", "JLLWrappers", "Libdl", "Xorg_libXtst_jll"]
git-tree-sha1 = "120f41bc9540b8f137e5e5dea65845ee4f089f9e"
git-tree-sha1 = "87819499fbacf7606859f6d7f31fa97d5db5452a"
uuid = "0fc3237b-ac94-5853-b45c-d43d59a06200"
version = "2.57.1+0"
version = "2.58.1+0"
[[deps.gdk_pixbuf_jll]]
deps = ["Artifacts", "Glib_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Xorg_libX11_jll", "libpng_jll"]
@ -2634,9 +2653,9 @@ version = "2.42.13+0"
[[deps.iso_codes_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"]
git-tree-sha1 = "4d295b7797afbe24ad5d0452f673b901a81c43c3"
git-tree-sha1 = "9200917315ff176d445ccc759945ea3fdb7c49c3"
uuid = "bf975903-5238-5d20-8243-bc370bc1e7e5"
version = "4.17.0+0"
version = "4.18.0+0"
[[deps.isoband_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
@ -2646,9 +2665,9 @@ version = "0.2.3+0"
[[deps.libaom_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"]
git-tree-sha1 = "4bba74fa59ab0755167ad24f98800fe5d727175b"
git-tree-sha1 = "371cc681c00a3ccc3fbc5c0fb91f58ba9bec1ecf"
uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b"
version = "3.12.1+0"
version = "3.13.1+0"
[[deps.libass_jll]]
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Zlib_jll"]
@ -2710,9 +2729,9 @@ version = "1.59.0+0"
[[deps.oneTBB_jll]]
deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"]
git-tree-sha1 = "d5a767a3bb77135a99e433afe0eb14cd7f6914c3"
git-tree-sha1 = "1350188a69a6e46f799d3945beef36435ed7262f"
uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e"
version = "2022.0.0+0"
version = "2022.0.0+1"
[[deps.p7zip_jll]]
deps = ["Artifacts", "Libdl"]

View File

@ -6,6 +6,7 @@ https://codeberg.org/LabABI/JuliaMSI
1. Make sure you have Julia installed and at least Julia version 1.6, If not, follow the next installation guide which contains the latest files and instructions for [juliaup](https://github.com/JuliaLang/juliaup) (recommended) alternatively, you can follow the official Julia installation instructions at [julia](https://julialang.org/downloads/platform/).
2. Download and decompress the following repository (You can download the repository from [download](https://codeberg.org/LabABI/JuliaMSI/archive/main.zip) or locate the option manually at the top right of the page, in the box with [•••] (More operations). For a more advanced method using Git, use this link: https://codeberg.org/LabABI/JuliaMSI.git).
3. Ensure that you have decompressed the ZIP file and know the working directory where it is located (the folder on your computer where you saved the JuliaMSI files).
4. Julia Version 1.11 is required. You might need to downgrade your whole Julia installation to support it.
## Load User Interface
1. Set the working directory to where JuliaMSI is located (the specific location of the folder on your computer where you decompressed the ZIP) in your terminal.<br>

781
app.jl

File diff suppressed because it is too large Load Diff

View File

@ -32,25 +32,48 @@
<div class="row items-center">
<q-input standout="custom-standout" class="q-ma-sm cursor-pointer col" v-model="full_route" readonly
:label="batch_file_count > 0 ? batch_file_count + ' file(s) in batch' : 'Select an imzMl / mzML file'"
v-on:click="btnSearch=true">
v-on:click="!is_processing && (btnSearch=true)" :disable="is_processing">
<template v-slot:append>
<q-icon name="search" v-on:click="btnSearch=true" class="cursor-pointer" />
<q-icon name="search" v-on:click="!is_processing && (btnSearch=true)" class="cursor-pointer" />
</template>
</q-input>
<q-btn class="q-ma-sm" icon="add" v-on:click="btnAddBatch=true" label="Add"></q-btn>
<q-btn class="q-ma-sm" icon="clear" v-on:click="clear_batch_btn=true" :disable="batch_file_count === 0"
<q-btn class="q-ma-sm" icon="add" v-on:click="btnAddBatch=true" label="Add" :disable="is_processing"></q-btn>
<q-btn class="q-ma-sm" icon="clear" v-on:click="clear_batch_btn=true" :disable="is_processing || batch_file_count === 0"
label="Clear"></q-btn>
</div>
<!-- Mask Configuration -->
<div class="row items-center q-mb-md">
<q-toggle v-model="maskEnabled" label="Apply Mask During Preprocessing" color="green" class="q-mr-md" />
<q-toggle v-model="maskEnabled" label="Apply Mask During Preprocessing" color="green" class="q-mr-md" :disable="is_processing" />
</div>
<!-- Subset Processing -->
<q-card class="q-mb-md" flat bordered>
<q-card-section>
<div class="row items-center no-wrap">
<div class="col">
<div class="text-subtitle2">Quick Test (Subset Processing)</div>
<div class="text-caption">Process only the first N spectra to quickly test parameters.</div>
</div>
<div class="col-auto">
<q-toggle v-model="enable_subset_processing" color="primary" :disable="is_processing" />
</div>
</div>
<div v-if="enable_subset_processing" class="q-mt-sm">
<q-input standout="custom-standout" type="number" v-model.number="spectra_subset_size" label="Number of Spectra to Process" :min="1" :readonly="is_processing">
<template v-slot:prepend>
<q-icon name="functions" />
</template>
</q-input>
</div>
</q-card-section>
</q-card>
<p>{{msg}}</p>
<!-- Spectrum Selection for Visualization -->
<div class="row items-center q-mb-md">
<div class="text-subtitle2 q-mr-md">Preview Spectrum:</div>
<q-btn-dropdown class="q-ma-sm" :loading="progressSpectraPlot" :disable="btnSpectraDisable"
<q-btn-dropdown class="q-ma-sm" :loading="is_processing" :disable="is_processing"
label="Generate Spectra" icon="play_arrow">
<q-list>
<q-item clickable v-close-popup v-on:click="createMeanPlot=true">
@ -72,73 +95,78 @@
<div class="row col-6">
<div class="st-col col-3 col-sm-3 q-ma-sm">
<q-input standout="custom-standout" step="1" v-model="idSpectrum" label="Spectrum ID" type="number"
hint="Not for Mean/Sum plots."></q-input>
hint="Not for Mean/Sum plots." :readonly="is_processing"></q-input>
</div>
<div class="st-col col-3 col-sm-3 q-ma-sm">
<q-input standout="custom-standout" step="1" v-model="xCoord" label="X coord" type="number" :rules="[
val => !btnSpectraDisable ? ( val >= 0 || 'Needs to be bigger than 0') : true
]"></q-input>
val => !SpectraEnabled ? ( val >= 0 || 'Needs to be bigger than 0') : true
]" :readonly="is_processing"></q-input>
</div>
<div class="st-col col-3 col-sm-3 q-ma-sm">
<q-input standout="custom-standout" step="1" v-model="yCoord" label="Y coord" type="number" :rules="[
val => !btnSpectraDisable ? ( val >= 0 || 'Needs to be bigger than 0') : true
]"></q-input>
val => !SpectraEnabled ? ( val >= 0 || 'Needs to be bigger than 0') : true
]" :readonly="is_processing"></q-input>
</div>
</div>
</div>
<!-- Internal Standards (Fixed First Item) -->
<q-card class="q-mb-md">
<!-- Internal Standards (Collapsible) -->
<q-expansion-item
icon="science"
label="Internal Standards"
caption="Manage reference peaks for calibration"
class="q-mb-md"
>
<q-card>
<q-card-section>
<div class="text-h6">Internal Standards</div>
<div class="text-caption">Reference peaks for calibration, alignment and precise suggestion calculations</div>
</q-card-section>
<q-card-section>
<q-toggle v-model="enable_standards" v-on:click="enable_standards" label="Use Internal Standards" color="primary" class="q-mb-md" />
<q-toggle v-model="enable_standards" v-on:click="enable_standards" label="Use Internal Standards" color="primary" class="q-mb-md" :disable="is_processing" />
<!-- Keep your existing reference_peaks_list implementation -->
<q-list bordered separator class="q-mt-md">
<q-item v-for="(peak, index) in reference_peaks_list" :key="index">
<q-item-section avatar>
<q-btn flat round icon="delete" color="negative" v-on:click="action_index = index; remove_peak_trigger = true"></q-btn>
<q-btn flat round icon="delete" color="negative" v-on:click="action_index = index; remove_peak_trigger = true" :disable="is_processing"></q-btn>
</q-item-section>
<q-item-section>
<div class="row q-col-gutter-sm">
<div class="col-6">
<q-input standout="custom-standout" label="m/z" type="number" step="0.0001"
v-model="peak.mz" :rules="[val => !!val || 'Required', val => val > 0 || 'Must be positive']"></q-input>
v-model="peak.mz" :rules="[val => !!val || 'Required', val => val > 0 || 'Must be positive']" :readonly="is_processing"></q-input>
</div>
<div class="col-6">
<q-input standout="custom-standout" label="Label (optional)" v-model="peak.label"></q-input>
<q-input standout="custom-standout" label="Label (optional)" v-model="peak.label" :readonly="is_processing"></q-input>
</div>
</div>
</q-item-section>
</q-item>
<q-item>
<q-item-section>
<q-btn class="q-ma-sm btn-style" icon="add" label="Add Reference Peak" v-on:click="addReferencePeak=true"></q-btn>
<q-btn class="q-ma-sm btn-style" icon="add" label="Add Reference Peak" v-on:click="addReferencePeak=true" :disable="is_processing"></q-btn>
</q-item-section>
</q-item>
</q-list>
<div class="row justify-end q-mt-sm">
<q-btn class="q-ma-sm" icon="functions" v-on:click="recalculate_suggestions_btn=true" label="Recalculate Suggestions" outline hint="Re-run automatic parameter suggestion using the current list of internal standards."/>
<q-btn class="q-ma-sm" dense icon="get_app" v-on:click="export_standards_btn=true" label="Export" outline :disable="is_processing" hint="Export standards list to a JSON file." />
<q-btn class="q-ma-sm" dense icon="upload_file" v-on:click="import_standards_btn=true" label="Import" outline :disable="is_processing" hint="Import standards list from a JSON file." />
<q-btn class="q-ma-sm" icon="functions" v-on:click="recalculate_suggestions_btn=true" label="Recalculate Suggestions" outline hint="Re-run automatic parameter suggestion using the current list of internal standards." :disable="is_processing"/>
</div>
</q-card-section>
</q-card>
</q-expansion-item>
<!-- Reorderable Preprocessing Steps -->
<div class="text-h6 q-mb-md">Preprocessing Pipeline</div>
<q-list bordered>
<q-list bordered :disable="is_processing">
<q-expansion-item v-for="(step, index) in pipeline_step_order" :key="step.name"
:label="step.label" group="preprocessing-steps"
:class="step.enabled ? '' : 'text-grey'">
:class="step.enabled ? '' : 'text-grey'" :disable="is_processing">
<!-- Header with controls -->
<template v-slot:header>
<q-item-section avatar>
<div class="row no-wrap">
<q-btn flat round icon="arrow_upward" size="sm"
:disable="index === 0" v-on:click.stop="action_index = index; move_step_up_trigger = true"></q-btn>
:disable="is_processing || index === 0" v-on:click.stop="action_index = index; move_step_up_trigger = true"></q-btn>
<q-btn flat round icon="arrow_downward" size="sm"
:disable="index === pipeline_step_order.length - 1" v-on:click.stop="action_index = index; move_step_down_trigger = true"></q-btn>
:disable="is_processing || index === pipeline_step_order.length - 1" v-on:click.stop="action_index = index; move_step_down_trigger = true"></q-btn>
</div>
</q-item-section>
@ -147,31 +175,31 @@
</q-item-section>
<q-item-section side>
<q-toggle v-model="step.enabled" color="green" v-on:click.stop="action_index = index; toggle_step_trigger = true" />
<q-toggle v-model="step.enabled" color="green" v-on:click.stop="action_index = index; toggle_step_trigger = true" :disable="is_processing" />
</q-item-section>
</template>
<!-- Step-specific parameters -->
<q-card v-if="step.name === 'stabilization'">
<q-card-section>
<q-radio v-model="stabilization_method" val="sqrt" label="SQRT" />
<q-radio v-model="stabilization_method" val="log" label="LOG" />
<q-radio v-model="stabilization_method" val="log2" label="LOG 2" />
<q-radio v-model="stabilization_method" val="log10" label="LOG 10" />
<q-radio v-model="stabilization_method" val="log1p" label="LOG 1P" />
<q-radio v-model="stabilization_method" val="sqrt" label="SQRT" :disable="is_processing" />
<q-radio v-model="stabilization_method" val="log" label="LOG" :disable="is_processing" />
<q-radio v-model="stabilization_method" val="log2" label="LOG 2" :disable="is_processing" />
<q-radio v-model="stabilization_method" val="log10" label="LOG 10" :disable="is_processing" />
<q-radio v-model="stabilization_method" val="log1p" label="LOG 1P" :disable="is_processing" />
</q-card-section>
</q-card>
<q-card v-if="step.name === 'smoothing'">
<q-card-section>
<q-radio v-model="smoothing_method" val="sg" label="Savitzky-Golay" />
<q-radio v-model="smoothing_method" val="ma" label="Moving Average" />
<q-radio v-model="smoothing_method" val="sg" label="Savitzky-Golay" :disable="is_processing" />
<q-radio v-model="smoothing_method" val="ma" label="Moving Average" :disable="is_processing" />
<div class="row q-col-gutter-sm q-mt-md">
<div class="col-6">
<q-input standout="custom-standout" label="Window Size" v-model="smoothing_window" type="number" />
<q-input standout="custom-standout" label="Window Size" v-model="smoothing_window" type="number" :readonly="is_processing" />
</div>
<div class="col-6">
<q-input standout="custom-standout" label="Order (Savitzky-Golay)" v-model="smoothing_order" type="number" />
<q-input standout="custom-standout" label="Order (Savitzky-Golay)" v-model="smoothing_order" type="number" :readonly="is_processing" />
</div>
</div>
</q-card-section>
@ -183,9 +211,9 @@
<div class="text-caption">The algorithm to use for baseline correction.</div>
</q-card-section>
<q-card-section>
<q-radio v-model="baseline_method" val="snip" label="SNIP" hint="Sensitive Nonlinear Iterative Peak clipping." /><br>
<q-radio v-model="baseline_method" val="convex_hull" label="CONVEX HULL" hint="Finds the lower convex hull of the spectrum." /><br>
<q-radio v-model="baseline_method" val="median" label="MEDIAN" hint="Moving median filter." /><br>
<q-radio v-model="baseline_method" val="snip" label="SNIP" hint="Sensitive Nonlinear Iterative Peak clipping." :disable="is_processing" /><br>
<q-radio v-model="baseline_method" val="convex_hull" label="CONVEX HULL" hint="Finds the lower convex hull of the spectrum." :disable="is_processing" /><br>
<q-radio v-model="baseline_method" val="median" label="MEDIAN" hint="Moving median filter." :disable="is_processing" /><br>
</q-card-section>
<q-card-section>
<div class="text-h6">Parameters</div>
@ -194,11 +222,11 @@
<div class="row q-col-gutter-sm">
<div class="col-6">
<q-input standout="custom-standout" label="Iterations (for SNIP)" type="number"
:placeholder="suggested_baseline_iterations" v-model="baseline_iterations" hint="The number of iterations for the SNIP algorithm. A higher number results in a more aggressive baseline."></q-input>
:placeholder="suggested_baseline_iterations" v-model="baseline_iterations" hint="The number of iterations for the SNIP algorithm. A higher number results in a more aggressive baseline." :readonly="is_processing"></q-input>
</div>
<div class="col-6">
<q-input standout="custom-standout" label="Window (for Median)" type="number"
:placeholder="suggested_baseline_window" v-model="baseline_window" hint="The window size for the median method, determining the local region for median calculation."></q-input>
:placeholder="suggested_baseline_window" v-model="baseline_window" hint="The window size for the median method, determining the local region for median calculation." :readonly="is_processing"></q-input>
</div>
</div>
</q-card-section>
@ -210,10 +238,10 @@
<div class="text-caption">The normalization method to apply.</div>
</q-card-section>
<q-card-section>
<q-radio v-model="normalization_method" val="tic" label="TIC" hint="Total Ion Current normalization (divides by the sum of intensities)." /><br>
<q-radio v-model="normalization_method" val="median" label="MEDIAN" hint="Divides by the median intensity." /><br>
<q-radio v-model="normalization_method" val="rms" label="RMS" hint="Root Mean Square normalization." /><br>
<q-radio v-model="normalization_method" val="none" label="NONE" hint="No normalization is applied." /><br>
<q-radio v-model="normalization_method" val="tic" label="TIC" hint="Total Ion Current normalization (divides by the sum of intensities)." :disable="is_processing" /><br>
<q-radio v-model="normalization_method" val="median" label="MEDIAN" hint="Divides by the median intensity." :disable="is_processing" /><br>
<q-radio v-model="normalization_method" val="rms" label="RMS" hint="Root Mean Square normalization." :disable="is_processing" /><br>
<q-radio v-model="normalization_method" val="none" label="NONE" hint="No normalization is applied." :disable="is_processing" /><br>
</q-card-section>
</q-card>
@ -223,9 +251,9 @@
<div class="text-caption">The alignment algorithm.</div>
</q-card-section>
<q-card-section>
<q-radio v-model="alignment_method" val="lowess" label="LOWESS" hint="Locally Weighted Scatterplot Smoothing regression." /><br>
<q-radio v-model="alignment_method" val="linear" label="LINEAR" hint="Linear regression." /><br>
<q-radio v-model="alignment_method" val="ransac" label="RANSAC" hint="Random Sample Consensus algorithm for robust fitting." /><br>
<q-radio v-model="alignment_method" val="lowess" label="LOWESS" hint="Locally Weighted Scatterplot Smoothing regression." :disable="is_processing" /><br>
<q-radio v-model="alignment_method" val="linear" label="LINEAR" hint="Linear regression." :disable="is_processing" /><br>
<q-radio v-model="alignment_method" val="ransac" label="RANSAC" hint="Random Sample Consensus algorithm for robust fitting." :disable="is_processing" /><br>
</q-card-section>
<q-card-section>
<div class="text-h6">Parameters</div>
@ -234,23 +262,23 @@
<div class="row q-col-gutter-sm">
<div class="col-6">
<q-input standout="custom-standout" label="Span (for LOWESS)" type="number" step="0.01"
:placeholder="suggested_alignment_span" v-model="alignment_span" :rules="[val => val >= 0.0 && val <= 1.0 || 'Needs to be between 0 and 1']" hint="The span parameter for LOWESS regression, controlling smoothness (0.0 to 1.0)."></q-input>
:placeholder="suggested_alignment_span" v-model="alignment_span" :rules="[val => val >= 0.0 && val <= 1.0 || 'Needs to be between 0 and 1']" hint="The span parameter for LOWESS regression, controlling smoothness (0.0 to 1.0)." :readonly="is_processing"></q-input>
</div>
<div class="col-6">
<q-input standout="custom-standout" label="Tolerance" type="number" step="0.001"
:placeholder="suggested_alignment_tolerance" v-model="alignment_tolerance" hint="The tolerance for matching peaks between the target and reference spectrum."></q-input>
:placeholder="suggested_alignment_tolerance" v-model="alignment_tolerance" hint="The tolerance for matching peaks between the target and reference spectrum." :readonly="is_processing"></q-input>
</div>
</div>
<q-select standout="custom-standout" label="Tolerance Unit" v-model="alignment_tolerance_unit"
:options="['mz', 'ppm']" class="q-mt-md" hint="The unit for tolerance, either 'mz' (absolute) or 'ppm' (relative)."></q-select>
:options="['mz', 'ppm']" class="q-mt-md" hint="The unit for tolerance, either 'mz' (absolute) or 'ppm' (relative)." :disable="is_processing"></q-select>
<div class="row q-col-gutter-sm q-mt-md">
<div class="col-6">
<q-input standout="custom-standout" label="Max Shift PPM" type="number"
:placeholder="suggested_alignment_max_shift_ppm" v-model="alignment_max_shift_ppm" hint="The maximum allowed m/z shift in ppm to prevent spurious peak matches."></q-input>
:placeholder="suggested_alignment_max_shift_ppm" v-model="alignment_max_shift_ppm" hint="The maximum allowed m/z shift in ppm to prevent spurious peak matches." :readonly="is_processing"></q-input>
</div>
<div class="col-6">
<q-input standout="custom-standout" label="Min Matched Peaks" type="number"
:placeholder="suggested_alignment_min_matched_peaks" v-model="alignment_min_matched_peaks" hint="The minimum number of matching peaks required to perform the alignment."></q-input>
:placeholder="suggested_alignment_min_matched_peaks" v-model="alignment_min_matched_peaks" hint="The minimum number of matching peaks required to perform the alignment." :readonly="is_processing"></q-input>
</div>
</div>
</q-card-section>
@ -265,12 +293,12 @@
<div class="col-6">
<q-input standout="custom-standout" label="Fit Order" type="number"
:placeholder="suggested_calibration_fit_order" v-model="calibration_fit_order"
hint="Polynomial order for the calibration curve (e.g., 1 or 2)."></q-input>
hint="Polynomial order for the calibration curve (e.g., 1 or 2)." :readonly="is_processing"></q-input>
</div>
<div class="col-6">
<q-input standout="custom-standout" label="PPM Tolerance" type="number"
:placeholder="suggested_calibration_ppm_tolerance" v-model="calibration_ppm_tolerance"
hint="PPM tolerance for matching reference peaks to internal standards."></q-input>
hint="PPM tolerance for matching reference peaks to internal standards." :readonly="is_processing"></q-input>
</div>
</div>
</q-card-section>
@ -282,9 +310,9 @@
<div class="text-caption">The peak detection algorithm.</div>
</q-card-section>
<q-card-section>
<q-radio v-model="peak_picking_method" val="profile" label="PROFILE" hint="For profile-mode data, using local maxima and quality filters." /><br>
<q-radio v-model="peak_picking_method" val="wavelet" label="WAVELET" hint="Continuous Wavelet Transform (CWT) based peak detection." /><br>
<q-radio v-model="peak_picking_method" val="centroid" label="CENTROID" hint="For centroid-mode data, essentially a filtering step." /><br>
<q-radio v-model="peak_picking_method" val="profile" label="PROFILE" hint="For profile-mode data, using local maxima and quality filters." :disable="is_processing" /><br>
<q-radio v-model="peak_picking_method" val="wavelet" label="WAVELET" hint="Continuous Wavelet Transform (CWT) based peak detection." :disable="is_processing" /><br>
<q-radio v-model="peak_picking_method" val="centroid" label="CENTROID" hint="For centroid-mode data, essentially a filtering step." :disable="is_processing" /><br>
</q-card-section>
<q-card-section>
<div class="text-h6">Parameters</div>
@ -293,35 +321,35 @@
<div class="row q-col-gutter-sm">
<div class="col-6">
<q-input standout="custom-standout" label="Signal to Noise Threshold" type="number" step="0.1"
:placeholder="suggested_peak_picking_snr_threshold" v-model="peak_picking_snr_threshold" hint="Signal-to-Noise Ratio threshold. Peaks with SNR below this value are discarded."></q-input>
:placeholder="suggested_peak_picking_snr_threshold" v-model="peak_picking_snr_threshold" hint="Signal-to-Noise Ratio threshold. Peaks with SNR below this value are discarded." :readonly="is_processing"></q-input>
</div>
<div class="col-6">
<q-input standout="custom-standout" label="Half Window Size" type="number"
:placeholder="suggested_peak_picking_half_window" v-model="peak_picking_half_window" hint="Number of data points to the left and right of a potential peak to consider for local maximum detection (for Profile method)."></q-input>
:placeholder="suggested_peak_picking_half_window" v-model="peak_picking_half_window" hint="Number of data points to the left and right of a potential peak to consider for local maximum detection (for Profile method)." :readonly="is_processing"></q-input>
</div>
</div>
<div class="row q-col-gutter-sm q-mt-md">
<div class="col-6">
<q-input standout="custom-standout" label="Min Peak Prominence" type="number" step="0.01"
:placeholder="suggested_peak_picking_min_peak_prominence" v-model="peak_picking_min_peak_prominence" hint="Minimum required prominence of a peak, expressed as a fraction of its height."></q-input>
:placeholder="suggested_peak_picking_min_peak_prominence" v-model="peak_picking_min_peak_prominence" hint="Minimum required prominence of a peak, expressed as a fraction of its height." :readonly="is_processing"></q-input>
</div>
<div class="col-6">
<q-input standout="custom-standout" label="Merge Peaks Tolerance (m/z)" type="number" step="0.001"
:placeholder="suggested_peak_picking_merge_peaks_tolerance" v-model="peak_picking_merge_peaks_tolerance" hint="The m/z tolerance within which to merge adjacent peaks, keeping the more intense one."></q-input>
:placeholder="suggested_peak_picking_merge_peaks_tolerance" v-model="peak_picking_merge_peaks_tolerance" hint="The m/z tolerance within which to merge adjacent peaks, keeping the more intense one." :readonly="is_processing"></q-input>
</div>
</div>
<div class="row q-col-gutter-sm q-mt-md">
<div class="col-6">
<q-input standout="custom-standout" label="Min Peak Width (PPM)" type="number"
:placeholder="suggested_peak_picking_min_peak_width_ppm" v-model="peak_picking_min_peak_width_ppm" hint="Minimum acceptable peak width (FWHM) in ppm."></q-input>
:placeholder="suggested_peak_picking_min_peak_width_ppm" v-model="peak_picking_min_peak_width_ppm" hint="Minimum acceptable peak width (FWHM) in ppm." :readonly="is_processing"></q-input>
</div>
<div class="col-6">
<q-input standout="custom-standout" label="Max Peak Width (PPM)" type="number"
:placeholder="suggested_peak_picking_max_peak_width_ppm" v-model="peak_picking_max_peak_width_ppm" hint="Maximum acceptable peak width (FWHM) in ppm."></q-input>
:placeholder="suggested_peak_picking_max_peak_width_ppm" v-model="peak_picking_max_peak_width_ppm" hint="Maximum acceptable peak width (FWHM) in ppm." :readonly="is_processing"></q-input>
</div>
</div>
<q-input standout="custom-standout" label="Min Peak Shape R2" type="number" step="0.01" class="q-mt-md"
:placeholder="suggested_peak_picking_min_peak_shape_r2" v-model="peak_picking_min_peak_shape_r2" hint="Minimum R-squared value from a Gaussian fit to the peak, used as a quality measure for peak shape."></q-input>
:placeholder="suggested_peak_picking_min_peak_shape_r2" v-model="peak_picking_min_peak_shape_r2" hint="Minimum R-squared value from a Gaussian fit to the peak, used as a quality measure for peak shape." :readonly="is_processing"></q-input>
</q-card-section>
</q-card>
@ -333,33 +361,33 @@
<div class="row q-col-gutter-sm">
<div class="col-6">
<q-input standout="custom-standout" label="Min SNR" type="number" step="0.1"
:placeholder="suggested_peak_selection_min_snr" v-model="peak_selection_min_snr" hint="Minimum Signal-to-Noise Ratio for a peak to be kept."></q-input>
:placeholder="suggested_peak_selection_min_snr" v-model="peak_selection_min_snr" hint="Minimum Signal-to-Noise Ratio for a peak to be kept." :readonly="is_processing"></q-input>
</div>
<div class="col-6">
<q-input standout="custom-standout" label="Min FWHM (PPM)" type="number"
:placeholder="suggested_peak_selection_min_fwhm_ppm" v-model="peak_selection_min_fwhm_ppm" hint="Minimum Full Width at Half Maximum (FWHM) in ppm for a peak to be kept."></q-input>
:placeholder="suggested_peak_selection_min_fwhm_ppm" v-model="peak_selection_min_fwhm_ppm" hint="Minimum Full Width at Half Maximum (FWHM) in ppm for a peak to be kept." :readonly="is_processing"></q-input>
</div>
</div>
<div class="row q-col-gutter-sm q-mt-md">
<div class="col-6">
<q-input standout="custom-standout" label="Max FWHM (PPM)" type="number"
:placeholder="suggested_peak_selection_max_fwhm_ppm" v-model="peak_selection_max_fwhm_ppm" hint="Maximum Full Width at Half Maximum (FWHM) in ppm for a peak to be kept."></q-input>
:placeholder="suggested_peak_selection_max_fwhm_ppm" v-model="peak_selection_max_fwhm_ppm" hint="Maximum Full Width at Half Maximum (FWHM) in ppm for a peak to be kept." :readonly="is_processing"></q-input>
</div>
<div class="col-6">
<q-input standout="custom-standout" label="Min Peak Shape R2" type="number" step="0.01"
:placeholder="suggested_peak_selection_min_shape_r2" v-model="peak_selection_min_shape_r2" hint="Minimum R-squared value from a Gaussian fit, filtering for good peak shape."></q-input>
:placeholder="suggested_peak_selection_min_shape_r2" v-model="peak_selection_min_shape_r2" hint="Minimum R-squared value from a Gaussian fit, filtering for good peak shape." :readonly="is_processing"></q-input>
</div>
</div>
<div class="row q-col-gutter-sm q-mt-md">
<div class="col-6">
<q-input standout="custom-standout" label="Frequency Threshold" type="number" step="0.01"
:placeholder="suggested_peak_selection_frequency_threshold" v-model="peak_selection_frequency_threshold"
hint="The minimum fraction of spectra a peak must be present in to be kept (0.0 to 1.0)."></q-input>
hint="The minimum fraction of spectra a peak must be present in to be kept (0.0 to 1.0)." :readonly="is_processing"></q-input>
</div>
<div class="col-6">
<q-input standout="custom-standout" label="Correlation Threshold" type="number" step="0.01"
:placeholder="suggested_peak_selection_correlation_threshold" v-model="peak_selection_correlation_threshold"
hint="Minimum correlation with neighboring peaks (not yet implemented)."></q-input>
hint="Minimum correlation with neighboring peaks (not yet implemented)." :readonly="is_processing"></q-input>
</div>
</div>
</q-card-section>
@ -371,8 +399,8 @@
<div class="text-caption">The binning strategy.</div>
</q-card-section>
<q-card-section>
<q-radio v-model="binning_method" val="adaptive" label="ADAPTIVE" hint="Creates bins based on the density of detected peaks." /><br>
<q-radio v-model="binning_method" val="uniform" label="UNIFORM" hint="Creates a fixed number of equally spaced bins over the m/z range." /><br>
<q-radio v-model="binning_method" val="adaptive" label="ADAPTIVE" hint="Creates bins based on the density of detected peaks." :disable="is_processing" /><br>
<q-radio v-model="binning_method" val="uniform" label="UNIFORM" hint="Creates a fixed number of equally spaced bins over the m/z range." :disable="is_processing" /><br>
</q-card-section>
<q-card-section>
<div class="text-h6">Parameters</div>
@ -381,35 +409,35 @@
<div class="row q-col-gutter-sm">
<div class="col-6">
<q-input standout="custom-standout" label="Tolerance (for Adaptive)" type="number" step="0.001"
:placeholder="suggested_binning_tolerance" v-model="binning_tolerance" hint="Tolerance for grouping peaks into a bin in adaptive mode."></q-input>
:placeholder="suggested_binning_tolerance" v-model="binning_tolerance" hint="Tolerance for grouping peaks into a bin in adaptive mode." :readonly="is_processing"></q-input>
</div>
<div class="col-6">
<q-select standout="custom-standout" label="Tolerance Unit" v-model="binning_tolerance_unit"
:options="['mz', 'ppm']" hint="The unit for tolerance, either 'mz' (absolute) or 'ppm' (relative)."></q-select>
:options="['mz', 'ppm']" hint="The unit for tolerance, either 'mz' (absolute) or 'ppm' (relative)." :disable="is_processing"></q-select>
</div>
</div>
<div class="row q-col-gutter-sm q-mt-md">
<div class="col-6">
<q-input standout="custom-standout" label="Frequency Threshold" type="number" step="0.01"
:placeholder="suggested_binning_frequency_threshold" v-model="binning_frequency_threshold" hint="The minimum fraction of spectra a bin must contain a peak in to be kept (0.0 to 1.0)."></q-input>
:placeholder="suggested_binning_frequency_threshold" v-model="binning_frequency_threshold" hint="The minimum fraction of spectra a bin must contain a peak in to be kept (0.0 to 1.0)." :readonly="is_processing"></q-input>
</div>
<div class="col-6">
<q-input standout="custom-standout" label="Min Peaks Per Bin" type="number"
:placeholder="suggested_binning_min_peak_per_bin" v-model="binning_min_peak_per_bin" hint="The minimum number of individual peaks required to form a bin in adaptive mode."></q-input>
:placeholder="suggested_binning_min_peak_per_bin" v-model="binning_min_peak_per_bin" hint="The minimum number of individual peaks required to form a bin in adaptive mode." :readonly="is_processing"></q-input>
</div>
</div>
<div class="row q-col-gutter-sm q-mt-md">
<div class="col-6">
<q-input standout="custom-standout" label="Max Bin Width (PPM)" type="number"
:placeholder="suggested_binning_max_bin_width_ppm" v-model="binning_max_bin_width_ppm" hint="Maximum width of a bin in ppm for adaptive mode."></q-input>
:placeholder="suggested_binning_max_bin_width_ppm" v-model="binning_max_bin_width_ppm" hint="Maximum width of a bin in ppm for adaptive mode." :readonly="is_processing"></q-input>
</div>
<div class="col-6">
<q-input standout="custom-standout" label="Number of Uniform Bins" type="number"
:placeholder="suggested_binning_num_uniform_bins" v-model="binning_num_uniform_bins" hint="The number of bins to create for the uniform method."></q-input>
:placeholder="suggested_binning_num_uniform_bins" v-model="binning_num_uniform_bins" hint="The number of bins to create for the uniform method." :readonly="is_processing"></q-input>
</div>
</div>
<q-toggle v-model="binning_intensity_weighted_centers" v-on:click="binning_intensity_weighted_centers" label="Intensity Weighted Centers"
class="q-mt-md" hint="If enabled, calculates bin centers as an intensity-weighted average of the peaks within it."></q-toggle>
class="q-mt-md" hint="If enabled, calculates bin centers as an intensity-weighted average of the peaks within it." :disable="is_processing"></q-toggle>
</q-card-section>
</q-card>
@ -418,22 +446,10 @@
<!-- Pipeline Controls -->
<div class="row justify-end items-center q-mt-md">
<q-btn class="q-ma-sm" icon="save" v-on:click="export_params_btn=true" label="Export Params" outline />
<q-btn class="q-ma-sm" icon="upload_file" v-on:click="import_params_btn=true" label="Import Params" outline />
<q-btn :loading="progressPrep" class="q-ma-sm btn-style" icon="play_arrow"
v-on:click="run_full_pipeline=true" padding="lg" label="Run Pipeline" />
</div>
</q-tab-panel>
</q-expansion-item>
</q-list>
<!-- Pipeline Controls -->
<div class="row justify-end items-center q-mt-md">
<q-btn class="q-ma-sm" icon="save" v-on:click="export_params_btn=true" label="Export Params" outline />
<q-btn class="q-ma-sm" icon="upload_file" v-on:click="import_params_btn=true" label="Import Params" outline />
<q-btn :loading="progressPrep" class="q-ma-sm btn-style" icon="play_arrow"
v-on:click="run_full_pipeline=true" padding="lg" label="Run Pipeline" />
<q-btn class="q-ma-sm" icon="get_app" v-on:click="export_params_btn=true" label="Export Params" outline :disable="is_processing" />
<q-btn class="q-ma-sm" icon="upload_file" v-on:click="import_params_btn=true" label="Import Params" outline :disable="is_processing" />
<q-btn :loading="is_processing" class="q-ma-sm btn-style" icon="play_arrow"
v-on:click="run_full_pipeline=true" padding="lg" label="Run Pipeline" :disable="is_processing" />
</div>
</q-tab-panel>
<q-tab-panel name="generator">
@ -446,13 +462,13 @@
<div class="row items-center">
<q-input standout="custom-standout" class="q-ma-sm cursor-pointer col" v-model="full_route" readonly
:label="batch_file_count > 0 ? batch_file_count + ' file(s) in batch' : 'Select an imzMl / mzML file'"
v-on:click="btnSearch=true">
v-on:click="btnSearch=true" :disable="is_processing">
<template v-slot:append>
<q-icon name="search" v-on:click="btnSearch=true" class="cursor-pointer" />
<q-icon name="search" v-on:click="btnSearch=true" class="cursor-pointer" :disable="is_processing" />
</template>
</q-input>
<q-btn class="q-ma-sm" icon="add" v-on:click="btnAddBatch=true" label="Add"></q-btn>
<q-btn class="q-ma-sm" icon="clear" v-on:click="clear_batch_btn=true" :disable="batch_file_count === 0"
<q-btn class="q-ma-sm" icon="add" v-on:click="btnAddBatch=true" label="Add" :disable="is_processing"></q-btn>
<q-btn class="q-ma-sm" icon="clear" v-on:click="clear_batch_btn=true" :disable="is_processing || batch_file_count === 0"
label="Clear"></q-btn>
</div>
<q-list bordered separator v-if="selected_files.length > 0">
@ -461,7 +477,7 @@
{{ file }}
</q-item-section>
<q-item-section side>
<q-btn flat round icon="delete" size="sm" v-on:click="selected_files.splice(index, 1)"></q-btn>
<q-btn flat round icon="delete" size="sm" v-on:click="selected_files.splice(index, 1)" :disable="is_processing"></q-btn>
</q-item-section>
</q-item>
</q-list>
@ -473,18 +489,18 @@
label="Mass-to-charge ratio(s) of interest" type="text" :rules="[
val => !!val || '* Required',
val => val.split(',').every(m => !isNaN(parseFloat(m.trim())) && parseFloat(m.trim()) > 0) || 'Need comma-separated positive numbers'
]">
]" :readonly="is_processing">
</q-input>
</div>
<div class="st-col col-4 col-sm q-ma-sm">
<q-input standout="custom-standout" id="textTol" step="0.005" v-model="Tol"
label="Mass-to-charge ratio tolerance" type="number"
:rules="[val => !!val || '* Required', val => val >= 0.0 &amp;&amp; val <= 1.0 || 'Needs to be in range between 0 and 1']"></q-input>
:rules="[val => !!val || '* Required', val => val >= 0.0 &amp;&amp; val <= 1.0 || 'Needs to be in range between 0 and 1']" :readonly="is_processing"></q-input>
</div>
<div class="st-col col-4 col-sm q-ma-sm">
<q-input standout="custom-standout" id="textcolorLevel" step="1" v-model="colorLevel" label="Color levels"
type="number"
:rules="[ val => !!val || '* Required', val => val >= 2 &amp;&amp; val <= 256 || 'Needs to be in range between 2 and 256']"></q-input>
:rules="[ val => !!val || '* Required', val => val >= 2 &amp;&amp; val <= 256 || 'Needs to be in range between 2 and 256']" :readonly="is_processing"></q-input>
</div>
</div>
<div class="row">
@ -492,25 +508,25 @@
<div class="col-6">
<div class="st-col col-6 col-sm q-ma-sm">
<q-toggle id="btnEnableMFilter" v-on:click="MFilterEnabled" v-model="MFilterEnabled" color="green"
label="Add Median Filter"></q-toggle>
label="Add Median Filter" :disable="is_processing"></q-toggle>
<q-toggle id="btnEnableTriq" v-on:click="triqEnabled" v-model="triqEnabled" color="blue"
label="Add Threshold Intensity Quantization (TrIQ)"></q-toggle>
label="Add Threshold Intensity Quantization (TrIQ)" :disable="is_processing"></q-toggle>
<q-toggle id="btnEnableMask" v-on:click="maskEnabled" v-model="maskEnabled" color="black"
label="Use Mask To Filter Data"></q-toggle>
label="Use Mask To Filter Data" :disable="is_processing"></q-toggle>
</div>
<div class="row">
<div class="st-col col-4 col-sm-4 q-ma-sm">
<q-input standout="custom-standout" id="textTriqProb" step="0.01" v-model="triqProb"
label="TrIQ probability" type="number" :rules="[
val => triqEnabled ? ( '* Required', val >= 0.8 &amp;&amp; val <= 1 || 'Needs to be in range between 0.8 and 1') : true
]" :readonly="!triqEnabled" :disable="!triqEnabled"></q-input>
]" :readonly="is_processing || !triqEnabled" :disable="is_processing || !triqEnabled"></q-input>
</div>
</div>
</div>
<!-- Spectra Plot Manipulation -->
<div class="col-6">
<div class="st-col col-6 col-sm">
<q-btn-dropdown class="q-ma-sm btn-style" :loading="progressSpectraPlot" :disable="btnSpectraDisable"
<q-btn-dropdown class="q-ma-sm btn-style" :loading="is_processing" :disable="is_processing"
label="Generate Spectra" icon="play_arrow">
<template v-slot:loading>
<q-spinner-hourglass class="on-left" />
@ -544,23 +560,23 @@
<div class="row col-6">
<div class="st-col col-4 col-sm-4 q-ma-sm">
<q-input standout="custom-standout" step="1" v-model="idSpectrum" label="Spectrum ID" type="number"
hint="Not for Mean/Sum plots."></q-input>
hint="Not for Mean/Sum plots." :readonly="is_processing"></q-input>
</div>
<div class="st-col col-4 col-sm-4 q-ma-sm">
<q-input standout="custom-standout" step="1" v-model="xCoord" label="X coord" type="number" :rules="[
val => SpectraEnabled ? ( '* Required', val >= 0|| 'Needs to be bigger than 0') : true
]"></q-input>
]" :readonly="is_processing"></q-input>
</div>
<div class="st-col col-4 col-sm-4 q-ma-sm">
<q-input standout="custom-standout" step="1" v-model="yCoord" label="Y coord" type="number" :rules="[
val => SpectraEnabled ? ( '* Required', val <= 0|| 'Needs to be lower than 0') : true
]"></q-input>
]" :readonly="is_processing"></q-input>
</div>
</div>
</div>
</div>
<div class="row">
<q-btn :loading="progress" class="q-ma-sm btn-style" :disabled="btnStartDisable" icon="play_arrow"
<q-btn :loading="is_processing" class="q-ma-sm btn-style" :disable="is_processing" icon="play_arrow"
v-on:click="mainProcess=true" padding="lg" label="Generate Slice">
<template v-slot:loading>
<q-spinner-hourglass class="on-left" />
@ -568,18 +584,18 @@
</template>
</q-btn>
<q-btn icon="zoom_out_map" class="q-ma-sm on-right btn-style" v-on:click="compareBtn=true" padding="sm"
label="Compare"></q-btn>
<q-btn class="q-ma-sm btn-style" icon="edit" label="Mask Editor" href="/mask"></q-btn>
label="Compare" :disable="is_processing"></q-btn>
<q-btn class="q-ma-sm btn-style" icon="edit" label="Mask Editor" href="/mask" :disable="is_processing"></q-btn>
<q-btn class="q-ma-sm btn-style" icon="dashboard" v-on:click="showMetadataBtn=true"
label="Show Metadata"></q-btn>
<div class="q-pa-md row items-center" v-show="progress">
label="Show Metadata" :disable="is_processing"></q-btn>
<div class="q-pa-md row items-center" v-show="is_processing">
<q-spinner color="primary" size="2em" class="q-mr-sm"></q-spinner>
<div class="text-caption">{{ progress_message }}</div>
</div>
</div>
<p>{{msg}}</p>
<div class="row st-col col-12">
<q-btn-dropdown class="q-ma-sm btn-style" :loading="progressPlot" :disable="btnPlotDisable"
<q-btn-dropdown class="q-ma-sm btn-style" :loading="is_processing" :disable="is_processing"
label="Generate Plots" icon="play_arrow">
<template v-slot:loading>
<q-spinner-hourglass class="on-left" />
@ -612,7 +628,7 @@
</q-item>
</q-list>
</q-btn-dropdown>
<q-btn-dropdown icon="search" class="q-ma-sm btn-style" :disable="btnOpticalDisable"
<q-btn-dropdown icon="search" class="q-ma-sm btn-style" :disable="is_processing"
label="Load your optical image">
<q-item clickable v-close-popup v-on:click="btnOptical=true">
<q-item-section>
@ -626,7 +642,7 @@
</q-item>
</q-btn-dropdown>
<div class="q-mx-sm">
<q-slider color="black" v-model="imgTrans" :min="0.0" :max="1" :step="0.1" :disable="btnOpticalDisable" />
<q-slider color="black" v-model="imgTrans" :min="0.0" :max="1" :step="0.1" :disable="is_processing" />
<q-badge style="background-color: #009f90;"> Transparency: {{ imgTrans }}</q-badge>
</div>
</div>
@ -636,20 +652,20 @@
<p>Select the .mzML file and the corresponding .txt synchronization file to convert them into an .imzML/.ibd
pair.</p>
<q-input standout="custom-standout" class="q-ma-sm cursor-pointer" v-model="mzml_full_route" readonly
label="Select your .mzML file" v-on:click="btnSearchMzml=true">
label="Select your .mzML file" v-on:click="btnSearchMzml=true" :disable="is_processing">
<template v-slot:append>
<q-icon name="search" v-on:click="btnSearchMzml=true" class="cursor-pointer" />
<q-icon name="search" v-on:click="btnSearchMzml=true" class="cursor-pointer" :disable="is_processing" />
</template>
</q-input>
<q-input standout="custom-standout" class="q-ma-sm cursor-pointer" v-model="sync_full_route" readonly
label="Select your .txt sync file" v-on:click="btnSearchSync=true">
label="Select your .txt sync file" v-on:click="btnSearchSync=true" :disable="is_processing">
<template v-slot:append>
<q-icon name="search" v-on:click="btnSearchSync=true" class="cursor-pointer" />
<q-icon name="search" v-on:click="btnSearchSync=true" class="cursor-pointer" :disable="is_processing" />
</template>
</q-input>
<q-btn :loading="progress_conversion" class="q-ma-sm btn-style" :disabled="btnConvertDisable"
<q-btn :loading="is_processing" class="q-ma-sm btn-style" :disable="is_processing || btnConvertDisable"
icon="swap_horiz" v-on:click="convert_process=true" padding="lg" label="Convert File">
<template v-slot:loading>
<q-spinner-hourglass class="on-left" />
@ -692,10 +708,10 @@
<h6>Image visualizer</h6>
<div class="row items-center">
<q-select v-model="selected_folder_main" :options="image_available_folders" label="Select Dataset"
class="q-ma-sm" style="min-width: 200px;" v-on:focus="refetch_folders = true"></q-select>
class="q-ma-sm" style="min-width: 200px;" v-on:focus="refetch_folders = true" :disable="is_processing"></q-select>
<q-space></q-space>
<q-btn icon="arrow_back" class="q-my-sm btn-style" v-on:click="imgMinus=true"></q-btn>
<q-btn icon="arrow_forward" class="q-my-sm on-right btn-style" v-on:click="imgPlus=true"></q-btn>
<q-btn icon="arrow_back" class="q-my-sm btn-style" v-on:click="imgMinus=true" :disable="is_processing"></q-btn>
<q-btn icon="arrow_forward" class="q-my-sm on-right btn-style" v-on:click="imgPlus=true" :disable="is_processing"></q-btn>
</div>
<!-- Image manager -->
<div id="image-container-normal" class="row st-col col-12">
@ -715,10 +731,10 @@
<h6>TrIQ visualizer</h6>
<div class="row items-center">
<q-select v-model="selected_folder_main" :options="image_available_folders" label="Select Dataset"
class="q-ma-sm" style="min-width: 200px;" v-on:focus="refetch_folders = true"></q-select>
class="q-ma-sm" style="min-width: 200px;" v-on:focus="refetch_folders = true" :disable="is_processing"></q-select>
<q-space></q-space>
<q-btn icon="arrow_back" class="q-my-sm btn-style" v-on:click="imgMinusT=true"></q-btn>
<q-btn icon="arrow_forward" class="q-my-sm on-right btn-style" v-on:click="imgPlusT=true"></q-btn>
<q-btn icon="arrow_back" class="q-my-sm btn-style" v-on:click="imgMinusT=true" :disable="is_processing"></q-btn>
<q-btn icon="arrow_forward" class="q-my-sm on-right btn-style" v-on:click="imgPlusT=true" :disable="is_processing"></q-btn>
</div>
<!-- Triq Image manager -->
<div id="image-container-triq" class="row st-col col-12">
@ -736,8 +752,8 @@
<q-tab-panel name="tab2">
<div class="row items-center">
<q-select v-model="selected_folder_main" :options="available_folders" label="Select Dataset"
class="q-ma-sm" style="min-width: 200px;" v-on:focus="refetch_folders = true"></q-select>
<q-btn-dropdown class="q-ma-sm btn-style" :loading="progressSpectraPlot" :disable="btnSpectraDisable"
class="q-ma-sm" style="min-width: 200px;" v-on:focus="refetch_folders = true" :disable="is_processing"></q-select>
<q-btn-dropdown class="q-ma-sm btn-style" :loading="is_processing" :disable="is_processing"
label="Generate Spectra" icon="play_arrow">
<template v-slot:loading>
<q-spinner-hourglass class="on-left" />
@ -806,11 +822,11 @@
<q-card-section class="row items-center">
<div class="text-h6 q-ma-sm">Compare two different images or plots</div>
<div class="q-mx-sm">
<q-slider color="black" v-model="imgTrans" :min="0.0" :max="1" :step="0.1" :disable="btnOpticalDisable" />
<q-slider color="black" v-model="imgTrans" :min="0.0" :max="1" :step="0.1" :disable="is_processing" />
<q-badge style="background-color: #009f90;"> Transparency: {{ imgTrans }}</q-badge>
</div>
<q-toggle id="btnOpticalOver" v-on:click="opticalOverTriq" v-model="opticalOverTriq" color="black"
label="Optical over TrIQ"></q-toggle>
label="Optical over TrIQ" :disable="is_processing"></q-toggle>
</q-card-section>
<q-card-section class="q-pt-none col-12">
@ -819,7 +835,7 @@
<div class="row items-center">
<q-select v-model="selected_folder_compare_left" :options="image_available_folders"
label="Select Left Dataset" class="q-ma-sm" style="min-width: 200px;"
v-on:focus="refetch_folders = true"></q-select>
v-on:focus="refetch_folders = true" :disable="is_processing"></q-select>
<q-space></q-space>
<st-tabs id="tabHeaderCompareLeft" :ids="CompTabIDsLeft" :labels="CompTabLabelsLeft"
v-model="CompSelectedTabLeft"></st-tabs>
@ -829,9 +845,9 @@
<!-- Content for Tab 0 -->
<!-- Btn image changer -->
<div>
<q-btn icon="arrow_back" class="q-my-sm btn-style" v-on:click="imgMinusCompLeft=true"></q-btn>
<q-btn icon="arrow_back" class="q-my-sm btn-style" v-on:click="imgMinusCompLeft=true" :disable="is_processing"></q-btn>
<q-btn icon="arrow_forward" class="q-my-sm on-right btn-style"
v-on:click="imgPlusCompLeft=true"></q-btn>
v-on:click="imgPlusCompLeft=true" :disable="is_processing"></q-btn>
</div>
<!-- Image manager -->
<div id="image-container-compare-left-normal" class="row st-col col-12">
@ -851,9 +867,9 @@
<!-- Content for Tab 1 -->
<!-- Triq Btn image changer -->
<div>
<q-btn icon="arrow_back" class="q-my-sm btn-style" v-on:click="imgMinusTCompLeft=true"></q-btn>
<q-btn icon="arrow_back" class="q-my-sm btn-style" v-on:click="imgMinusTCompLeft=true" :disable="is_processing"></q-btn>
<q-btn icon="arrow_forward" class="q-my-sm on-right btn-style"
v-on:click="imgPlusTCompLeft=true"></q-btn>
v-on:click="imgPlusTCompLeft=true" :disable="is_processing"></q-btn>
</div>
<!-- Triq Image manager -->
<div id="image-container-compare-left-triq" class="row st-col col-12">
@ -889,7 +905,7 @@
<div class="row items-center">
<q-select v-model="selected_folder_compare_right" :options="image_available_folders"
label="Select Right Dataset" class="q-ma-sm" style="min-width: 200px;"
v-on:focus="refetch_folders = true"></q-select>
v-on:focus="refetch_folders = true" :disable="is_processing"></q-select>
<q-space></q-space>
<st-tabs id="tabHeaderCompareRight" :ids="CompTabIDsRight" :labels="CompTabLabelsRight"
v-model="CompSelectedTabRight"></st-tabs>
@ -899,9 +915,9 @@
<!-- Content for Tab 0 -->
<!-- Btn image changer -->
<div>
<q-btn icon="arrow_back" class="q-my-sm btn-style" v-on:click="imgMinusCompRight=true"></q-btn>
<q-btn icon="arrow_back" class="q-my-sm btn-style" v-on:click="imgMinusCompRight=true" :disable="is_processing"></q-btn>
<q-btn icon="arrow_forward" class="q-my-sm on-right btn-style"
v-on:click="imgPlusCompRight=true"></q-btn>
v-on:click="imgPlusCompRight=true" :disable="is_processing"></q-btn>
</div>
<!-- Image manager -->
<div id="image-container-compare-right-normal" class="row st-col col-12">
@ -921,9 +937,9 @@
<!-- Content for Tab 1 -->
<!-- Triq Btn image changer -->
<div>
<q-btn icon="arrow_back" class="q-my-sm btn-style" v-on:click="imgMinusTCompRight=true"></q-btn>
<q-btn icon="arrow_back" class="q-my-sm btn-style" v-on:click="imgMinusTCompRight=true" :disable="is_processing"></q-btn>
<q-btn icon="arrow_forward" class="q-my-sm on-right btn-style"
v-on:click="imgPlusTCompRight=true"></q-btn>
v-on:click="imgPlusTCompRight=true" :disable="is_processing"></q-btn>
</div>
<!-- Triq Image manager -->
<div id="image-container-compare-right-triq" class="row st-col col-12">
@ -986,7 +1002,7 @@
<div class="text-h6">Dataset Summary</div>
<q-space />
<q-select v-model="selected_folder_metadata" :options="available_folders" label="Select Dataset" class="q-ma-sm"
style="min-width: 250px;" standout="custom-standout" v-on:focus="refetch_folders = true"></q-select>
style="min-width: 250px;" standout="custom-standout" v-on:focus="refetch_folders = true" :disable="is_processing"></q-select>
</q-card-section>
<q-card-section class="q-pt-none">

View File

@ -1,2 +1,2 @@
ENV["GENIE_ENV"] = "dev"
#ENV["GENIE_ENV"] = "prod"
#ENV["GENIE_ENV"] = "dev"
ENV["GENIE_ENV"] = "prod"

6
config/env/prod.jl vendored Normal file
View File

@ -0,0 +1,6 @@
# config/env/prod.jl
# This file is loaded when GENIE_ENV is set to "prod"
# Define PLUGINS_WITH_ASSETS to prevent UndefVarError in production mode
# It's typically an empty vector if no specific plugins with assets are tracked.
const PLUGINS_WITH_ASSETS = []

109
mask.jl
View File

@ -150,6 +150,7 @@ end
@in selected_folder_main = ""
@out available_folders = String[]
@out image_available_folders = String[]
@out registry_path = abspath(joinpath(@__DIR__, "public", "registry.json"))
@private registry_init_done = false
@in refetch_folders = false
@ -190,6 +191,7 @@ end
@in btn_flip_mask = false
@in btn_save_final_mask = false
@in btn_move_mask = false
@in btn_upload_premade_mask = false
# --- Manual Editor State ---
@in brush_size = 10
@ -271,6 +273,33 @@ end
msgimg = "No MSI images found in this dataset."
show_verification_plot = false
end
# --- Check for mask in registry and update message ---
reg_path = abspath(joinpath(@__DIR__, "public", "registry.json"))
if isfile(reg_path)
registry = JSON.parsefile(reg_path) # Assuming JSON.jl is loaded
if haskey(registry, selected_folder_main)
dataset_entry = registry[selected_folder_main]
if get(dataset_entry, "has_mask", false) && haskey(dataset_entry, "mask_path")
mask_filepath = dataset_entry["mask_path"]
mask_filename = basename(mask_filepath)
mask_editor_message = "Dataset has an existing mask: $(mask_filename)"
# Optionally, load this mask if the user is currently editing
if is_editing_mask && isempty(smoothed_mask_path)
# Only auto-load if not already editing a mask and smoothed_mask_path is empty
smoothed_mask_path = get_timestamped_path("/css/masks/$(mask_filename)")
plotdata_verify, plotlayout_verify, show_verification_plot = update_main_plot(imgInt, smoothed_mask_path, imgTrans)
mask_editor_message *= " (loaded for editing)"
end
else
mask_editor_message = "No existing mask found for this dataset."
end
else
mask_editor_message = "Dataset entry not found in registry."
end
else
mask_editor_message = "Registry file (registry.json) not found."
end
end
end
@ -345,6 +374,86 @@ end
end
end
@onbutton btn_upload_premade_mask begin
picked_path = pick_file(; filterlist="png,bmp,jpg,jpeg")
if !isempty(picked_path)
target_dir = joinpath("public", "css", "masks")
mkpath(target_dir)
uploaded_filename = "premade_mask.png"
destination_path = joinpath(target_dir, uploaded_filename)
local_uploaded_path = "" # Define here for finally block cleanup
try
cp(picked_path, destination_path; force=true)
local_uploaded_path = destination_path # Full path to the copied image
# --- Binary Check ---
img = load(local_uploaded_path)
gray_img = ensure_grayscale(img)
# Check if image is effectively binary (only two distinct values, or close enough)
# Convert to raw pixel values for robust checking
pixel_values = Float64.(collect(Iterators.flatten(channelview(gray_img))))
unique_pixel_values = unique(pixel_values)
# Heuristic: if more than 2 distinct values exist, it's not truly binary
# Allow for floating point inaccuracies
if length(unique_pixel_values) > 2
# Find min and max for range check
min_val, max_val = extrema(unique_pixel_values)
# If values are not clustered at 0 and 1, it's likely not binary
if !(min_val < 0.1 && max_val > 0.9 && all(v -> v < 0.1 || v > 0.9, unique_pixel_values))
mask_editor_message = "Warning: Uploaded image is not purely binary (found $(length(unique_pixel_values)) distinct pixel values). Please use 'Upload to Create Mask' for processing or ensure your image is strictly black and white."
mask_editor_warning = true
rm(local_uploaded_path; force=true) # Clean up non-binary file
return
end
end
# If it has 2 values, or only one value, ensure it's a true BitMatrix
# This handles cases like 0-255 images being converted to 0.0-1.0 and then to true/false
binary_img = gray_img .>= 0.5 # Ensure pure binary (true/false)
save(local_uploaded_path, binary_img)
# --- Resizing to Slice (if imgInt is present) ---
slice_path_cleaned = replace(imgInt, r"\?.*" => "")
slice_full_path = joinpath("public", lstrip(slice_path_cleaned, '/'))
if !isempty(imgInt) && isfile(slice_full_path) # Only resize if a slice is present
slice_img = load(slice_full_path)
mask_img = load(local_uploaded_path) # Reload potentially re-binarized image to get correct type/size
if size(slice_img) != size(mask_img)
@info "Resizing pre-made mask to match slice dimensions."
resized_mask = imresize(mask_img, size(slice_img))
save(local_uploaded_path, resized_mask)
end
end
is_browsing_slices = false
is_editing_mask = true
# Update smoothed_mask_path to the new file, with timestamp for cache busting
relative_path_for_web = "/css/masks/$(uploaded_filename)"
smoothed_mask_path = get_timestamped_path(relative_path_for_web)
mask_editor_message = "Pre-made mask uploaded and loaded successfully!"
mask_editor_warning = false
# Trigger plot update
plotdata_verify, plotlayout_verify, show_verification_plot = update_main_plot(imgInt, smoothed_mask_path, imgTrans)
catch e
@error "Failed to upload pre-made mask" exception=(e, catch_backtrace())
mask_editor_message = "Error uploading pre-made mask: $(sprint(showerror, e))"
mask_editor_warning = true
if !isempty(local_uploaded_path) && isfile(local_uploaded_path) rm(local_uploaded_path; force=true) end # Clean up
end
else
mask_editor_message = "No file selected for upload."
mask_editor_warning = true
end
end
@onbutton btn_change_slice begin
is_browsing_slices = true
is_editing_mask = false

View File

@ -26,6 +26,8 @@
:disable="!is_browsing_slices || !imgInt"></q-btn>
<q-btn class="q-ma-sm btn-style" v-on:click="btn_upload_mask = true" label="Upload to Create Mask"
:disable="!is_browsing_slices || !imgInt"></q-btn>
<q-btn class="q-ma-sm btn-style" v-on:click="btn_upload_premade_mask = true" label="Upload Pre-made Mask"
:disable="!is_browsing_slices"></q-btn>
<q-btn class="q-ma-sm btn-style" v-on:click="btn_change_slice = true" label="Change Mask Blueprint"
:disable="!is_editing_mask"></q-btn>
</div>

View File

@ -1,13 +1,23 @@
using Pkg
sTime=time()
Pkg.activate(".")
#ENV["GENIE_ENV"] = "dev"
ENV["GENIE_ENV"] = "prod"
manifest_path = joinpath(@__DIR__, "Manifest.toml")
# Only instantiate in development mode
if get(ENV, "GENIE_ENV", "dev") != "prod"
if get(ENV, "GENIE_ENV", "dev") != "prod" || !isfile(manifest_path)
@info "Development environment detected. Instantiating packages..."
if !isfile(manifest_path)
@info "Manifest.toml not found. Generating it based on Project.toml..."
end
Pkg.resolve()
Pkg.instantiate()
Pkg.gc()
end
Pkg.gc()
using Genie