diff --git a/.gitignore b/.gitignore index 0bb3977..0bec6dd 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ log/* R_original_scripts/ test/results/ test/binarization_results/ +Manifest.toml \ No newline at end of file diff --git a/Manifest.toml b/Manifest.toml index d9db884..adde889 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -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"] diff --git a/README.md b/README.md index 489bd0f..f85afc9 100644 --- a/README.md +++ b/README.md @@ -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.
diff --git a/app.jl b/app.jl index fda643e..224aeb4 100644 --- a/app.jl +++ b/app.jl @@ -91,6 +91,72 @@ function is_step_enabled(step_name::String, pipeline_order::Vector{Dict{String, return false # Default to disabled if step not found end +function get_processed_mean_spectrum(spectra::Vector{MutableSpectrum}; num_bins=2000) + # 1. Find global m/z range from all spectra + min_mz, max_mz = Inf, -Inf + for s in spectra + if !isempty(s.mz) + min_mz = min(min_mz, minimum(s.mz)) + max_mz = max(max_mz, maximum(s.mz)) + end + end + + if !isfinite(min_mz) + return Float64[], Float64[] + end + + # 2. Create bins + mz_bins = range(min_mz, stop=max_mz, length=num_bins) + intensity_sum = zeros(Float64, num_bins) + bin_step = step(mz_bins) + inv_bin_step = 1.0 / bin_step + + # 3. Bin intensities + for s in spectra + for i in eachindex(s.mz) + bin_index = trunc(Int, (s.mz[i] - min_mz) * inv_bin_step + 1.0) + final_index = clamp(bin_index, 1, num_bins) + intensity_sum[final_index] += s.intensity[i] + end + end + + # 4. Average and return + if isempty(spectra) + return collect(mz_bins), intensity_sum + end + average_intensity = intensity_sum ./ length(spectra) + return collect(mz_bins), average_intensity +end + +function get_processed_sum_spectrum(spectra::Vector{MutableSpectrum}; num_bins=2000) + min_mz, max_mz = Inf, -Inf + for s in spectra + if !isempty(s.mz) + min_mz = min(min_mz, minimum(s.mz)) + max_mz = max(max_mz, maximum(s.mz)) + end + end + + if !isfinite(min_mz) + return Float64[], Float64[] + end + + mz_bins = range(min_mz, stop=max_mz, length=num_bins) + intensity_sum = zeros(Float64, num_bins) + bin_step = step(mz_bins) + inv_bin_step = 1.0 / bin_step + + for s in spectra + for i in eachindex(s.mz) + bin_index = trunc(Int, (s.mz[i] - min_mz) * inv_bin_step + 1.0) + final_index = clamp(bin_index, 1, num_bins) + intensity_sum[final_index] += s.intensity[i] + end + end + + return collect(mz_bins), intensity_sum +end + @genietools # == Reactive code == @@ -99,145 +165,114 @@ end # == Loading Screen Variables == @in is_initializing = true @in initialization_message = "Initializing..." + # Loading animations and readonly / disable elements are all handled by this variable. + @in is_processing = false - # == Reactive variables == - # reactive variables exist in both the Julia backend and the browser with two-way synchronization - # @out variables can only be modified by the backend - # @in variables can be modified by both the backend and the browser - # variables must be initialized with constant values, or variables defined outside of the @app block - - ## Interface non Variables - @out btnStartDisable=true - @out btnPlotDisable=false - @out btnSpectraDisable=false - # Loading animations - @in progress=false - @in progressPlot=false - @in progressSpectraPlot=false - # Text field validations - @in triqEnabled=false - @in SpectraEnabled=false - @in MFilterEnabled=false - @in maskEnabled=false - # Dialogs - @in warning_msg=false - @in CompareDialog=false - - ## Interface Variables + # == SLICE GENERATOR TAB VARIABLES == + # File selection and batch processing @in file_route="" @in file_name="" - @in Nmass="0.0" - @in Tol=0.1 - @in triqProb=0.98 - @in colorLevel=20 - - ## Interface Buttons @in btnSearch=false # To search for files in your device @in btnAddBatch = false @in clear_batch_btn = false @out batch_file_count = 0 - @in mainProcess=false # To generate images - @in compareBtn=false # To open dialog + @in selected_files = String[] + @out full_route="" # Saves the route where imzML and mzML files are located + + # Mass-to-charge parameters + @in Nmass="0.0" # Mass-to-charge ratio(s) of interest + @in Tol=0.1 # Mass-to-charge ratio tolerance + @in colorLevel=20 # Color levels for visualization + + # Processing toggles + @in triqEnabled=false # Threshold Intensity Quantization + @in MFilterEnabled=false # Median Filter + @in maskEnabled=false # Use Mask To Filter Data + @in triqProb=0.98 # TrIQ probability parameter + + # Spectrum selection and coordinates + @in idSpectrum=0 # Spectrum ID for ID-based plots + @in xCoord=0 # X coordinate for coordinate-based plots + @in yCoord=0 # Y coordinate for coordinate-based plots + @in SpectraEnabled=false # Enables xCoord and yCoord inputs when spectral data is loaded + + # Plot generation triggers + @in mainProcess=false # To generate images/slices @in createMeanPlot=false # To generate mean spectrum plot - @in createXYPlot=false # To generate an spectrum plot according to the xy values inputed - @in createNSpectrumPlot=false # To generate an spectrum plot according to spectrum order - @in createSumPlot=false # To generate a sum of all the spectrum plots + @in createXYPlot=false # To generate spectrum plot according to xy values + @in createNSpectrumPlot=false # To generate spectrum plot according to spectrum order + @in createSumPlot=false # To generate sum of all spectrum plots @in image3dPlot=false # To generate 3d plot based on current image @in triq3dPlot=false # To generate 3d plot based on current triq image @in imageCPlot=false # To generate contour plots of current image @in triqCPlot=false # To generate contour plots of current triq image - # Image change buttons - @in imgPlus=false - @in imgMinus=false - @in imgPlusT=false - @in imgMinusT=false - # Image change comparative buttons - @in imgPlusCompLeft=false - @in imgMinusCompLeft=false - @in imgPlusTCompLeft=false - @in imgMinusTCompLeft=false - @in imgPlusCompRight=false - @in imgMinusCompRight=false - @in imgPlusTCompRight=false - @in imgMinusTCompRight=false - ## Tabulation variables - @out tabIDs=["tab0","tab1","tab2","tab3","tab4"] - @out tabLabels=["Image", "TrIQ", "Spectrum Plot", "Topography Plot","Surface Plot"] - @in selectedTab="tab0" - @out CompTabIDsLeft=["tab0","tab1","tab2","tab3","tab4"] - @out CompTabLabelsLeft=["Image", "TrIQ", "Spectrum Plot", "Topography Plot","Surface Plot"] - @in CompSelectedTabLeft="tab0" - @out CompTabIDsRight=["tab0","tab1","tab2","tab3","tab4"] - @out CompTabLabelsRight=["Image", "TrIQ", "Spectrum Plot", "Topography Plot","Surface Plot"] - @in CompSelectedTabRight="tab0" + # Image navigation controls + @in imgPlus=false # Next image in normal mode + @in imgMinus=false # Previous image in normal mode + @in imgPlusT=false # Next image in TrIQ mode + @in imgMinusT=false # Previous image in TrIQ mode - # Interface Images - @out imgInt="/.bmp" # image Interface - @out imgIntT="/.bmp" # image Interface TrIQ - @out colorbar="/.png" - @out colorbarT="/.png" - # Interface controlling for the comparative view - @out imgIntCompLeft="/.bmp" - @out imgIntTCompLeft="/.bmp" - @out colorbarCompLeft="/.png" - @out colorbarTCompLeft="/.png" - @out imgIntCompRight="/.bmp" - @out imgIntTCompRight="/.bmp" - @out colorbarCompRight="/.png" - @out colorbarTCompRight="/.png" - @out imgWidth=0 - @out imgHeight=0 + # Optical image overlay + @in imgTrans=1.0 # Transparency level for optical overlay + @in btnOptical=false # Load optical image over normal image + @in btnOpticalT=false # Load optical image over TrIQ image + @in opticalOverTriq=false # Toggle optical overlay mode - # Optical Image Overlay & Transparency - @in imgTrans=1.0 - @in progressOptical=false - @out btnOpticalDisable=true - @in btnOptical=false - @in btnOpticalT=false - @in opticalOverTriq=false - @out imgRoute="" + # Messages and status + @out msg="" # Main status message + @out msgimg="" # Image status message + @out msgtriq="" # TrIQ status message - # Messages to interface variables - @out msg="" - @out msgimg="" - @out msgtriq="" - # Reiteration of the messages under the image to know which spectra is being visualized - @out msgimgCompLeft="" - @out msgtriqCompLeft="" - @out msgimgCompRight="" - @out msgtriqCompRight="" + # == CONVERTER TAB VARIABLES == + @in left_tab = "generator" # Active left tab (generator, converter, pre_treatment) + @out mzml_full_route = "" # Path to .mzML file + @out sync_full_route = "" # Path to .txt synchronization file + @in btnSearchMzml = false # Trigger mzML file search + @in btnSearchSync = false # Trigger sync file search + @in convert_process = false # Start conversion process + @out progress_conversion = false # Conversion progress indicator + @out msg_conversion = "" # Conversion status message + @out btnConvertDisable = true # Disable convert button when files not selected - # Centralized MSIData object - @out msi_data::Union{MSIData, Nothing} = nothing + # == PRE-TREATMENT TAB VARIABLES == + # File selection and batch + @in pre_tab = "stabilization" # Active preprocessing subtab - # Metadata table variables - @in showMetadataDialog = false - @in showMetadataBtn = false - @out metadata_columns = [] - @out metadata_rows = [] - @out btnMetadataDisable = false - @in selected_folder_metadata = "" + # Subset processing + @in enable_subset_processing = false # Enable processing only first N spectra + @in spectra_subset_size = 100 # Number of spectra for subset processing - # Saves the route where imzML and mzML files are located - @out full_route="" + # Internal standards management + @in enable_standards = true # Use internal standards for calibration + @in reference_peaks_list = [ + Dict("mz" => 137.0244, "label" => "DHB_fragment"), + Dict("mz" => 155.0349, "label" => "DHB_M+H"), + ] + @in addReferencePeak = false # Add new reference peak + @in remove_peak_trigger = false # Remove reference peak + @in export_standards_btn = false # Export standards to JSON + @in import_standards_btn = false # Import standards from JSON - # == Converter Tab Variables == - @in left_tab = "generator" - @out mzml_full_route = "" - @out sync_full_route = "" - @in btnSearchMzml = false - @in btnSearchSync = false - @in convert_process = false - @out progress_conversion = false - @out msg_conversion = "" - @out btnConvertDisable = true + # Pipeline step management + @in pipeline_step_order = [ + Dict("name" => "stabilization", "label" => "Stabilization", "enabled" => true), + Dict("name" => "smoothing", "label" => "Smoothing", "enabled" => true), + Dict("name" => "baseline_correction", "label" => "Baseline Correction", "enabled" => true), + Dict("name" => "peak_picking", "label" => "Peak Picking", "enabled" => true), + Dict("name" => "peak_selection", "label" => "Peak Selection", "enabled" => true), + Dict("name" => "calibration", "label" => "Calibration", "enabled" => true), + Dict("name" => "peak_alignment", "label" => "Peak Alignment", "enabled" => true), + Dict("name" => "normalization", "label" => "Normalization", "enabled" => true), + Dict("name" => "peak_binning", "label" => "Peak Binning", "enabled" => true) + ] + @in action_index = -1 # Index for step operations + @in move_step_up_trigger = false # Move step up in pipeline + @in move_step_down_trigger = false # Move step down in pipeline + @in toggle_step_trigger = false # Toggle step enabled/disabled + @out current_pipeline_step = "" # Current running step in full pipeline - # == Pre Processing Variables == - @in pre_tab = "stabilization" - - ## Preprocessing Parameters - @in progressPrep=false + # Preprocessing method parameters @in stabilization_method="sqrt" @in smoothing_method="sg" @in smoothing_window = "" @@ -277,48 +312,7 @@ end @in peak_selection_frequency_threshold = "" @in peak_selection_correlation_threshold = "" - # == Pipeline Step Order and Mask Route Variables == - @in pipeline_step_order = [ - Dict("name" => "stabilization", "label" => "Stabilization", "enabled" => true), - Dict("name" => "smoothing", "label" => "Smoothing", "enabled" => true), - Dict("name" => "baseline_correction", "label" => "Baseline Correction", "enabled" => true), - Dict("name" => "peak_picking", "label" => "Peak Picking", "enabled" => true), - Dict("name" => "peak_selection", "label" => "Peak Selection", "enabled" => true), - Dict("name" => "calibration", "label" => "Calibration", "enabled" => true), - Dict("name" => "peak_alignment", "label" => "Peak Alignment", "enabled" => true), - Dict("name" => "normalization", "label" => "Normalization", "enabled" => true), - Dict("name" => "peak_binning", "label" => "Peak Binning", "enabled" => true) - ] - @in selected_spectrum_id_for_plot = 1 - @in feature_matrix_result = nothing - @in bin_info_result = nothing - - @in reference_peaks_list = [ - Dict("mz" => 137.0244, "label" => "DHB_fragment"), - Dict("mz" => 155.0349, "label" => "DHB_M+H"), - ] - - @in save_feature_matrix_btn = false - @in recalculate_suggestions_btn = false - @in addReferencePeak = false - @in removeReferencePeak = false - @in moveStepUp = false - @in moveStepDown = false - - # Trigger for running the full pipeline - @in run_full_pipeline = false - @in enable_standards = true - @in action_index = -1 - @in remove_peak_trigger = false - @in move_step_up_trigger = false - @in move_step_down_trigger = false - @in toggle_step_trigger = false - @out current_pipeline_step = "" # To indicate which step is currently running in the full pipeline - - @in export_params_btn = false - @in import_params_btn = false - @in imported_params_file = nothing - + # Suggested parameter values @in suggested_smoothing_window = "" @in suggested_smoothing_order = "" @in suggested_baseline_iterations = "" @@ -348,42 +342,114 @@ end @in suggested_peak_selection_frequency_threshold = "" @in suggested_peak_selection_correlation_threshold = "" - # == Batch Summary Dialog == - @in showBatchSummary = false - @out batch_summary = "" + # Pipeline control triggers + @in run_full_pipeline = false # Trigger full pipeline execution + @in recalculate_suggestions_btn = false # Recalculate parameter suggestions + @in export_params_btn = false # Export parameters to file + @in import_params_btn = false # Import parameters from file + @in save_feature_matrix_btn = false # Save feature matrix results - # == Batch Processing & Registry Variables == + # Preprocessing results + @in selected_spectrum_id_for_plot = 1 + @in last_plot_type = "single" + @in feature_matrix_result::Union{Nothing, Matrix{Float64}} = nothing + @in bin_info_result::Union{Nothing, Vector} = nothing + + # == RIGHT PANEL VARIABLES (intDivStyle-right) == + # Tab management + @out tabIDs=["tab0","tab1","tab2","tab3","tab4"] + @out tabLabels=["Image", "TrIQ", "Spectrum Plot", "Topography Plot","Surface Plot"] + @in selectedTab="tab0" + + # Compare dialog tabs + @out CompTabIDsLeft=["tab0","tab1","tab2","tab3","tab4"] + @out CompTabLabelsLeft=["Image", "TrIQ", "Spectrum Plot", "Topography Plot","Surface Plot"] + @in CompSelectedTabLeft="tab0" + @out CompTabIDsRight=["tab0","tab1","tab2","tab3","tab4"] + @out CompTabLabelsRight=["Image", "TrIQ", "Spectrum Plot", "Topography Plot","Surface Plot"] + @in CompSelectedTabRight="tab0" + + # Compare dialog controls + @in CompareDialog=false + @in compareBtn=false # Open compare dialog + @in imgPlusCompLeft=false # Next image in compare left panel + @in imgMinusCompLeft=false # Previous image in compare left panel + @in imgPlusTCompLeft=false # Next TrIQ image in compare left panel + @in imgMinusTCompLeft=false # Previous TrIQ image in compare left panel + @in imgPlusCompRight=false # Next image in compare right panel + @in imgMinusCompRight=false # Previous image in compare right panel + @in imgPlusTCompRight=false # Next TrIQ image in compare right panel + @in imgMinusTCompRight=false # Previous TrIQ image in compare right panel + + # Image display variables + @out imgInt="/.bmp" # Normal image interface + @out imgIntT="/.bmp" # TrIQ image interface + @out colorbar="/.png" # Normal colorbar + @out colorbarT="/.png" # TrIQ colorbar + + # Compare dialog images + @out imgIntCompLeft="/.bmp" # Left compare normal image + @out imgIntTCompLeft="/.bmp" # Left compare TrIQ image + @out colorbarCompLeft="/.png" # Left compare normal colorbar + @out colorbarTCompLeft="/.png" # Left compare TrIQ colorbar + @out imgIntCompRight="/.bmp" # Right compare normal image + @out imgIntTCompRight="/.bmp" # Right compare TrIQ image + @out colorbarCompRight="/.png" # Right compare normal colorbar + @out colorbarTCompRight="/.png" # Right compare TrIQ colorbar + + @out imgWidth=0 + @out imgHeight=0 + + # Compare dialog messages + @out msgimgCompLeft="" + @out msgtriqCompLeft="" + @out msgimgCompRight="" + @out msgtriqCompRight="" + + # == BATCH PROCESSING & REGISTRY VARIABLES == @private registry_init_done = false @in refetch_folders = false - @in selected_files = String[] @in available_folders = String[] @in image_available_folders = String[] @out registry_path = abspath(joinpath(@__DIR__, "public", "registry.json")) - # Progress reporting - @out overall_progress = 0.0 - @out progress_message = "" - # == Folder-based UI State == + # Folder selection state @in selected_folder_main = "" @in selected_folder_compare_left = "" @in selected_folder_compare_right = "" + # Progress reporting + @out overall_progress = 0.0 + @out progress_message = "" - # For the creation of images with a more specific mass charge - @out text_nmass="" + # Batch summary + @in showBatchSummary = false + @out batch_summary = "" - # For image search image lists we apply a filter that searches specific type of images into our public folder, then we sort it in a "numerical" order + # == METADATA VARIABLES == + @in showMetadataDialog = false + @in showMetadataBtn = false + @out metadata_columns = [] + @out metadata_rows = [] + @out btnMetadataDisable = false + @in selected_folder_metadata = "" + + # == DATA MANAGEMENT VARIABLES == + # Centralized MSIData object + @out msi_data::Union{MSIData, Nothing} = nothing + + # Image file management + @out text_nmass="" # For specific mass charge image creation @in msi_bmp=sort(filter(filename -> startswith(filename, "MSI_") && endswith(filename, ".bmp"), readdir("public")),lt=natural) @in col_msi_png=sort(filter(filename -> startswith(filename, "colorbar_MSI_") && endswith(filename, ".png"), readdir("public")),lt=natural) @in triq_bmp=sort(filter(filename -> startswith(filename, "TrIQ_") && endswith(filename, ".bmp"), readdir("public")),lt=natural) @in col_triq_png=sort(filter(filename -> startswith(filename, "colorbar_TrIQ_") && endswith(filename, ".png"), readdir("public")),lt=natural) - - # Set current image for the list to display + + # Current image display @out current_msi="" @out current_col_msi="" @out current_triq="" @out current_col_triq="" - # We reiterate the process to display in the comparative view @out current_msiCompLeft="" @out current_col_msiCompLeft="" @out current_triqCompLeft="" @@ -393,13 +459,11 @@ end @out current_triqCompRight="" @out current_col_triqCompRight="" - ## Time measurement variables - @out sTime=time() - @out fTime=time() - @out eTime=time() + # Optical image + @out imgRoute="" - ## Plots - # Local image to plot + # == PLOTTING VARIABLES == + # Image plots layoutImg=PlotlyBase.Layout( title=PlotlyBase.attr( text="", @@ -423,21 +487,20 @@ end traceImg=PlotlyBase.heatmap(x=Vector{Float64}(), y=Vector{Float64}()) @out plotdataImg=[traceImg] @out plotlayoutImg=layoutImg - # For the image in the comparative view @out plotdataImgCompLeft=[traceImg] @out plotlayoutImgCompLeft=layoutImg @out plotdataImgCompRight=[traceImg] @out plotlayoutImgCompRight=layoutImg - # For triq image + # TrIQ image plots @out plotdataImgT=[traceImg] @out plotlayoutImgT=layoutImg - # For the triq image in the comparative view @out plotdataImgTCompLeft=[traceImg] @out plotlayoutImgTCompLeft=layoutImg @out plotdataImgTCompRight=[traceImg] @out plotlayoutImgTCompRight=layoutImg - # Interface Plot Spectrum + + # Spectrum plots layoutSpectra=PlotlyBase.Layout( title=PlotlyBase.attr( text="Spectrum plot", @@ -465,30 +528,21 @@ end yanchor="top" ) ) - # Dummy 2D scatter plot traceSpectra=PlotlyBase.scatter(x=Vector{Float64}(), y=Vector{Float64}(), mode="lines", marker=attr(size=1, color="blue", opacity=0.1)) - # Create conection to frontend @out plotdata=[traceSpectra] @out plotlayout=layoutSpectra - @in idSpectrum=0 - @in xCoord=0 - @in yCoord=0 - @out xSpectraMz = Vector{Float64}() - @out ySpectraMz = Vector{Float64}() - - # UI plot data for Preprocessing + # Preprocessing spectrum plots @out plotdata_before = [traceSpectra] @out plotlayout_before = layoutSpectra @out plotdata_after = [traceSpectra] @out plotlayout_after = layoutSpectra - # Interactive plot reactions - @in data_click=Dict{String,Any}() - #@in data_selected=Dict{String,Any}() # Selected is for areas, this can work for the masks - # + # Spectrum data + @out xSpectraMz = Vector{Float64}() + @out ySpectraMz = Vector{Float64}() - # Interface Plot Surface + # Contour plots layoutContour=PlotlyBase.Layout( title=PlotlyBase.attr( text="2D Topographic map", @@ -507,14 +561,11 @@ end ), margin=attr(l=0,r=0,t=100,b=0,pad=0) ) - # Dummy 2D surface plot traceContour=PlotlyBase.contour(x=Vector{Float64}(), y=Vector{Float64}(), mode="lines") - # Create conection to frontend @out plotdataC=[traceContour] @out plotlayoutC=layoutContour - # Interface Plot 3d - # Define the layout for the 3D plot + # 3D surface plots layout3D=PlotlyBase.Layout( title=PlotlyBase.attr( text="3D Surface plot", @@ -536,8 +587,6 @@ end ), margin=attr(l=0,r=0,t=120,b=0,pad=0) ) - - # Dummy 3D surface plot x=1:10 y=1:10 z=[sin(i * j / 10) for i in x, j in y] @@ -548,10 +597,20 @@ end highlightcolor="limegreen", project_z=true ), colorscale="Viridis") - # Create conection to frontend @out plotdata3d=[trace3D] @out plotlayout3d=layout3D + # Interactive plot reactions + @in data_click=Dict{String,Any}() + + # == TIME MEASUREMENT VARIABLES == + @out sTime=time() + @out fTime=time() + @out eTime=time() + + # == DIALOGS AND MESSAGES == + @in warning_msg=false + # == Reactive handlers == # Reactive handlers watch a variable and execute a block of code when its value changes # The onbutton handler will set the variable to false after the block is executed @@ -559,12 +618,13 @@ end # This handler correctly uses pick_file and loads the selected file # as the active dataset for the UI. @onbutton btnSearch begin + is_processing = true picked_route = pick_file(; filterlist="imzML,imzml,mzML,mzml") if isempty(picked_route) + is_processing = false return end - progress = true msg = "Opening file: $(basename(picked_route))..." try @@ -588,9 +648,6 @@ end msi_data = nothing # Ensure data is not held in memory log_memory_usage("Fast Load (msi_data cleared)", msi_data) btnMetadataDisable = false - btnStartDisable = false - btnPlotDisable = false - btnSpectraDisable = false SpectraEnabled = true selected_folder_main = dataset_name @@ -601,12 +658,12 @@ end image_available_folders = deepcopy(img_folders) msg = "Successfully loaded pre-processed dataset: $(dataset_name)" - progress = false - return + end + # --- Full Load Path --- - msg = "Performing first-time analysis for: $(basename(picked_route))..." + local local_full_route if endswith(picked_route, r"imzml"i) local_full_route = replace(picked_route, r"\.imzml$"i => ".imzML") @@ -621,14 +678,18 @@ end sTime = time() loaded_data = OpenMSIData(local_full_route) is_imzML = loaded_data.source isa ImzMLSource - - precompute_analytics(loaded_data) + + if isempty(get(existing_entry, "metadata", Dict())) + msg = "Performing first-time metadata analysis for: $(basename(picked_route))..." + precompute_analytics(loaded_data) + end # Auto-suggest parameters try println("Calling main_precalculation to get recommended parameters...") recommended_params = main_precalculation(loaded_data) + for (step_name, params) in recommended_params for (param_key, value) in params # Convert value to appropriate type before assignment @@ -833,17 +894,12 @@ end eTime = round(time() - sTime, digits=3) msg = "Active file loaded in $(eTime) seconds. Dataset '$(dataset_name)' is ready for analysis." - btnStartDisable = false - btnPlotDisable = false - btnSpectraDisable = false SpectraEnabled = true catch e msi_data = nothing msg = "Error loading active file: $e" warning_msg = true - btnStartDisable = true - btnSpectraDisable = true SpectraEnabled = false btnMetadataDisable = true @error "File loading failed" exception=(e, catch_backtrace()) @@ -852,12 +908,12 @@ end if Sys.islinux() ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure Julia returns the freed memory to OS end - progress = false - progressSpectraPlot = false + is_processing = false end end @onbutton export_params_btn begin + is_processing = true params_to_export = Dict( "pipeline_step_order" => pipeline_step_order, "enable_standards" => enable_standards, # Export global flag @@ -901,52 +957,135 @@ end "peak_selection_correlation_threshold" => peak_selection_correlation_threshold, "reference_peaks_list" => reference_peaks_list ) + + # 1. Generate the JSON string json_string = JSON.json(params_to_export) + + # 2. ESCAPING (Crucial for stability) + # We must escape backslashes (for Windows paths) and single quotes + # so they don't break the JavaScript string literal. + safe_json = replace(json_string, "\\" => "\\\\") + safe_json = replace(safe_json, "'" => "\\'") + + # 3. Create the JavaScript payload + # We inject 'safe_json' into the JS 'encodeURIComponent' js_script = """ var element = document.createElement('a'); - element.setAttribute('href', 'data:text/json;charset=utf-8,' + encodeURIComponent(`$json_string`)); + element.setAttribute('href', 'data:text/json;charset=utf-8,' + encodeURIComponent('$safe_json')); element.setAttribute('download', 'preprocessing_params.json'); element.style.display = 'none'; document.body.appendChild(element); element.click(); document.body.removeChild(element); """ - run_js(js_script) + + # 4. Execute on the client + run(__model__, js_script) + is_processing = false msg = "Parameters exported." end - @onchange import_params_btn begin - if import_params_btn - try - json_string = String(imported_params_file.data) - params = JSON.parse(json_string) - - for (key, value) in params - if key == "reference_peaks_list" - reference_peaks_list = value - elseif key == "pipeline_step_order" - pipeline_step_order = value - elseif key == "enable_standards" # Import global flag - enable_standards = value - else - # Use getfield and setproperty! to update reactive variables by name - if hasfield(typeof(@__MODULE__), Symbol(key)) - getfield(@__MODULE__, Symbol(key))[] = value - end - end - end - msg = "Parameters imported successfully." - catch e - msg = "Failed to import parameters: $e" - warning_msg = true - finally - import_params_btn = false # Reset button state - end + @onbutton import_params_btn begin + is_processing = true + picked_file = pick_file(filterlist="json") + if isempty(picked_file) + is_processing = false + return end + + try + json_string = read(picked_file, String) + params = JSON.parse(json_string) + + # This is a list of all known reactive variables that can be imported. + # This prevents arbitrary variable assignment. + known_params = [ + "stabilization_method", "smoothing_method", "smoothing_window", "smoothing_order", + "baseline_method", "baseline_iterations", "baseline_window", "normalization_method", + "alignment_method", "alignment_span", "alignment_tolerance", "alignment_tolerance_unit", + "alignment_max_shift_ppm", "alignment_min_matched_peaks", "peak_picking_method", + "peak_picking_snr_threshold", "peak_picking_half_window", "peak_picking_min_peak_prominence", + "peak_picking_merge_peaks_tolerance", "peak_picking_min_peak_width_ppm", + "peak_picking_max_peak_width_ppm", "peak_picking_min_peak_shape_r2", "binning_method", + "binning_tolerance", "binning_tolerance_unit", "binning_frequency_threshold", + "binning_min_peak_per_bin", "binning_max_bin_width_ppm", "binning_intensity_weighted_centers", + "binning_num_uniform_bins", "calibration_fit_order", "calibration_ppm_tolerance", + "peak_selection_min_snr", "peak_selection_min_fwhm_ppm", "peak_selection_max_fwhm_ppm", + "peak_selection_min_shape_r2", "peak_selection_frequency_threshold", "peak_selection_correlation_threshold" + ] + + for (key, value) in params + if key == "reference_peaks_list" + reference_peaks_list = value + elseif key == "pipeline_step_order" + pipeline_step_order = value + elseif key == "enable_standards" + enable_standards = value + elseif key in known_params + # Use getfield and setproperty! to update reactive variables by name + if hasfield(typeof(@__MODULE__), Symbol(key)) + getfield(@__MODULE__, Symbol(key))[] = value + end + else + @warn "Unknown parameter '$key' found in JSON file. Skipping." + end + end + msg = "Parameters imported successfully from $(basename(picked_file))." + catch e + msg = "Failed to import parameters: $e" + warning_msg = true + @error "Parameter import failed" exception=(e, catch_backtrace()) + end + is_processing = false + end + + @onbutton export_standards_btn begin + is_processing = true + json_string = JSON.json(reference_peaks_list) + safe_json = replace(json_string, "\\" => "\\\\") + safe_json = replace(safe_json, "'" => "\\'") + js_script = """ + var element = document.createElement('a'); + element.setAttribute('href', 'data:text/json;charset=utf-8,' + encodeURIComponent('$safe_json')); + element.setAttribute('download', 'internal_standards.json'); + element.style.display = 'none'; + document.body.appendChild(element); + element.click(); + document.body.removeChild(element); + """ + run(__model__, js_script) + is_processing = false + msg = "Internal standards exported." + end + + @onbutton import_standards_btn begin + is_processing = true + picked_file = pick_file(filterlist="json") + if isempty(picked_file) + return + end + + try + json_string = read(picked_file, String) + new_standards = JSON.parse(json_string) + # Basic validation + if new_standards isa Vector && all(p -> p isa Dict && haskey(p, "mz") && haskey(p, "label"), new_standards) + reference_peaks_list = new_standards + msg = "Internal standards imported successfully from $(basename(picked_file))." + else + msg = "Invalid format for internal standards file." + warning_msg = true + end + catch e + msg = "Failed to import internal standards: $e" + warning_msg = true + @error "Standards import failed" exception=(e, catch_backtrace()) + end + is_processing = false end @onbutton run_full_pipeline begin - progressPrep = true + is_processing = true current_pipeline_step = "Initializing..." println("DEBUG: run_full_pipeline started.") # println("DEBUG: Current pipeline_step_order configuration: $pipeline_step_order") @@ -958,6 +1097,7 @@ end msg = "No dataset loaded. Please load a file using 'Select an imzMl / mzML file'." warning_msg = true println("DEBUG: $msg") + is_processing = false return end @@ -1028,6 +1168,14 @@ end println("DEBUG: No mask applied. Processing all $(length(msi_data.spectra_metadata)) spectra.") end + # Apply subset processing if enabled + if enable_subset_processing && spectra_subset_size > 0 + n_total = length(spectrum_indices_to_process) + n_to_process = min(spectra_subset_size, n_total) + spectrum_indices_to_process = spectrum_indices_to_process[1:n_to_process] + println("DEBUG: Subset processing enabled. Processing first $(length(spectrum_indices_to_process)) of $n_total spectra.") + end + # Initialize spectra data structure current_pipeline_step = "Loading spectra..." println("DEBUG: Loading $(length(spectrum_indices_to_process)) spectra into MutableSpectrum objects...") @@ -1036,7 +1184,7 @@ end Threads.@threads for i in 1:length(spectrum_indices_to_process) original_idx = spectrum_indices_to_process[i] mz, intensity = GetSpectrum(msi_data, original_idx) # Fetch mz and intensity for the current spectrum - current_spectra[i] = MutableSpectrum(original_idx, Float64.(mz), Float64.(intensity), NamedTuple{(:mz, :intensity, :fwhm, :shape_r2, :snr, :prominence), NTuple{6, Float64}}[]) + current_spectra[i] = MutableSpectrum(original_idx, copy(Float64.(mz)), copy(Float64.(intensity)), NamedTuple{(:mz, :intensity, :fwhm, :shape_r2, :snr, :prominence), NTuple{6, Float64}}[]) end println("DEBUG: All spectra loaded into temporary structure for processing.") @@ -1273,47 +1421,65 @@ end # 4. Update Results Display current_pipeline_step = "Updating results..." - println("DEBUG: Updating results display after pipeline completion.") - - # Find the spectrum to display in "after" plot - display_spectrum_idx = findfirst(s -> s.id == selected_spectrum_id_for_plot, current_spectra) - if display_spectrum_idx !== nothing - processed_spectrum = current_spectra[display_spectrum_idx] - println("DEBUG: Displaying spectrum $(selected_spectrum_id_for_plot) after processing.") - - after_trace = PlotlyBase.scatter( - x=processed_spectrum.mz, - y=processed_spectrum.intensity, - mode="lines", - name="Processed Spectrum" - ) - - traces_after = [after_trace] + subset_label = enable_subset_processing ? " (from subset of $(length(current_spectra)) spectra)" : "" + println("DEBUG: Updating results display after pipeline completion for plot type: $(last_plot_type)") - if !isempty(processed_spectrum.peaks) - peak_mzs = [p.mz for p in processed_spectrum.peaks] - peak_intensities = [p.intensity for p in processed_spectrum.peaks] - peak_trace = PlotlyBase.scatter( - x=peak_mzs, - y=peak_intensities, - mode="markers", - name="Picked Peaks", - marker=attr(color="red", size=8) + if last_plot_type == "single" + display_spectrum_idx = findfirst(s -> s.id == selected_spectrum_id_for_plot, current_spectra) + if display_spectrum_idx !== nothing + processed_spectrum = current_spectra[display_spectrum_idx] + println("DEBUG: Displaying spectrum $(selected_spectrum_id_for_plot) after processing.") + + after_trace = PlotlyBase.scatter( + x=processed_spectrum.mz, + y=processed_spectrum.intensity, + mode="lines", + name="Processed Spectrum" + ) + + traces_after = [after_trace] + + if !isempty(processed_spectrum.peaks) + peak_mzs = [p.mz for p in processed_spectrum.peaks] + peak_intensities = [p.intensity for p in processed_spectrum.peaks] + peak_trace = PlotlyBase.scatter( + x=peak_mzs, + y=peak_intensities, + mode="markers", + name="Picked Peaks", + marker=attr(color="red", size=8) + ) + push!(traces_after, peak_trace) + end + + plotdata_after = traces_after + plotlayout_after = PlotlyBase.Layout( + title="After Preprocessing (Spectrum $(selected_spectrum_id_for_plot))$(subset_label)", + xaxis_title="m/z", + yaxis_title="Intensity", + legend=attr(x=0.98, y=0.98, xanchor="right", yanchor="top") ) - push!(traces_after, peak_trace) - println("DEBUG: $(length(processed_spectrum.peaks)) peaks picked for spectrum $(selected_spectrum_id_for_plot).") else - println("DEBUG: No peaks picked for spectrum $(selected_spectrum_id_for_plot).") + println("DEBUG: Selected spectrum for display ($(selected_spectrum_id_for_plot)) not found in processed spectra.") end - - plotdata_after = traces_after + elseif last_plot_type == "mean" + mz, intensity = get_processed_mean_spectrum(current_spectra) + plotdata_after = [PlotlyBase.scatter(x=mz, y=intensity, mode="lines", name="Processed Mean Spectrum")] plotlayout_after = PlotlyBase.Layout( - title="After Preprocessing (Spectrum $(selected_spectrum_id_for_plot))", + title="After Preprocessing (Mean Spectrum)$(subset_label)", xaxis_title="m/z", - yaxis_title="Intensity" + yaxis_title="Average Intensity", + legend=attr(x=0.98, y=0.98, xanchor="right", yanchor="top") + ) + elseif last_plot_type == "sum" + mz, intensity = get_processed_sum_spectrum(current_spectra) + plotdata_after = [PlotlyBase.scatter(x=mz, y=intensity, mode="lines", name="Processed Sum Spectrum")] + plotlayout_after = PlotlyBase.Layout( + title="After Preprocessing (Sum Spectrum)$(subset_label)", + xaxis_title="m/z", + yaxis_title="Total Intensity", + legend=attr(x=0.98, y=0.98, xanchor="right", yanchor="top") ) - else - println("DEBUG: Selected spectrum for display ($(selected_spectrum_id_for_plot)) not found in processed spectra.") end # Save feature matrix if binning was performed @@ -1334,7 +1500,7 @@ end @error "Pipeline failed" exception=(e, catch_backtrace()) println("DEBUG: Pipeline caught an exception: $e") finally - progressPrep = false + is_processing = false current_pipeline_step = "" println("DEBUG: run_full_pipeline finished (finally block).") GC.gc() # Trigger garbage collection @@ -1345,6 +1511,7 @@ end end @onbutton recalculate_suggestions_btn begin + is_processing = true if msi_data === nothing msg = "Please load a file first." warning_msg = true @@ -1353,10 +1520,10 @@ end try msg = "Recalculating suggestions..." - progressPrep = true ref_peaks = Dict(p["mz"] => p["label"] for p in reference_peaks_list) recommended_params = main_precalculation(msi_data, reference_peaks=ref_peaks) + for (step_name, params) in recommended_params for (param_key, value) in params @@ -1511,17 +1678,20 @@ end warning_msg = true @error "Recalculation failed" exception=(e, catch_backtrace()) finally - progressPrep = false + is_processing = false end end @onbutton addReferencePeak begin + is_processing = true new_list = deepcopy(reference_peaks_list) push!(new_list, Dict("mz" => 0.0, "label" => "")) reference_peaks_list = new_list # Assign new list to trigger reactivity + is_processing = false end @onbutton remove_peak_trigger begin + is_processing = true if action_index > -1 julia_index = action_index + 1 new_list = deepcopy(reference_peaks_list) @@ -1531,9 +1701,11 @@ end end action_index = -1 # Reset end + is_processing = false end @onbutton move_step_up_trigger begin + is_processing = true if action_index > -1 julia_index = action_index + 1 if julia_index > 1 @@ -1545,9 +1717,11 @@ end end action_index = -1 # Reset end + is_processing = false end @onbutton move_step_down_trigger begin + is_processing = true if action_index > -1 julia_index = action_index + 1 if julia_index < length(pipeline_step_order) @@ -1559,9 +1733,11 @@ end end action_index = -1 # Reset end + is_processing = false end @onbutton toggle_step_trigger begin + is_processing = true if action_index > -1 julia_index = action_index + 1 if 1 <= julia_index <= length(pipeline_step_order) @@ -1571,10 +1747,12 @@ end end action_index = -1 # Reset end + is_processing = false end # This new handler correctly adds the file from full_route to the batch list. @onbutton btnAddBatch begin + is_processing = true if isempty(full_route) || full_route == "unknown (manually added)" msg = "No active file selected to add to batch." warning_msg = true @@ -1590,12 +1768,15 @@ end msg = "File is already in the batch list." warning_msg = true end + is_processing = false end @onbutton clear_batch_btn begin + is_processing = true selected_files = String[] batch_file_count = 0 msg = "Batch cleared" + is_processing = false end @onchange selected_files begin @@ -1642,6 +1823,7 @@ end end @onchange btnSearchMzml, btnSearchSync begin + is_processing = true if btnSearchMzml picked_route = pick_file(; filterlist="mzML,mzml") if !isempty(picked_route) @@ -1660,17 +1842,17 @@ end # Enable button only if both files are selected btnConvertDisable = isempty(mzml_full_route) || isempty(sync_full_route) + is_processing = false end @onbutton convert_process begin + is_processing = true if isempty(mzml_full_route) || isempty(sync_full_route) msg_conversion = "Please select both an .mzML file and a .txt sync file." warning_msg = true return end - progress_conversion = true - btnConvertDisable = true msg_conversion = "Starting conversion process..." try @@ -1696,7 +1878,7 @@ end warning_msg = true @error "Conversion failed" exception=(e, catch_backtrace()) finally - progress_conversion = false + is_processing = false # Re-enable button if files are still selected btnConvertDisable = isempty(mzml_full_route) || isempty(sync_full_route) end @@ -1704,10 +1886,6 @@ end @onbutton mainProcess @time begin # --- UI State Update --- - progress = true - btnStartDisable = true - btnPlotDisable = true - btnSpectraDisable = true overall_progress = 0.0 progress_message = "Preparing batch process..." @@ -1732,6 +1910,7 @@ end println(progress_message) return end + is_processing = true masses = Float64[] try @@ -1877,14 +2056,10 @@ end @error "Main process failed" exception=(e, catch_backtrace()) finally # --- UI State Reset --- - progress = false - btnStartDisable = false - btnPlotDisable = false - btnOpticalDisable = false - btnSpectraDisable = false + is_processing = false SpectraEnabled = true overall_progress = 0.0 - println("Done") + #println("Done") GC.gc() # Trigger garbage collection if Sys.islinux() ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure Julia returns the freed memory to OS @@ -1899,10 +2074,7 @@ end return end - progressSpectraPlot = true - btnPlotDisable = true - btnStartDisable = true - msg = "Loading plot for $(selected_folder_main)..." + is_processing = true try sTime = time() @@ -1946,21 +2118,19 @@ end plotdata, plotlayout, xSpectraMz, ySpectraMz = meanSpectrumPlot(msi_data, selected_folder_main, mask_path=mask_path_for_plot) plotdata_before = plotdata plotlayout_before = plotlayout + last_plot_type = "mean" selectedTab = "tab2" fTime = time() eTime = round(fTime - sTime, digits=3) msg = "Plot loaded in $(eTime) seconds" log_memory_usage("Mean Plot Generated", msi_data) catch e - msg = "Could not generate mean spectrum plot: $e" - warning_msg = true - @error "Mean spectrum plotting failed" exception=(e, catch_backtrace()) - finally - progressSpectraPlot = false - btnPlotDisable = false - btnSpectraDisable = false - btnStartDisable = false - GC.gc() # Trigger garbage collection + msg = "Could not generate mean spectrum plot: $e" + warning_msg = true + @error "Mean spectrum plotting failed" exception=(e, catch_backtrace()) + finally + is_processing = false + GC.gc() # Trigger garbage collection if Sys.islinux() ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure Julia returns the freed memory to OS end @@ -1974,9 +2144,7 @@ end return end - progressSpectraPlot = true - btnPlotDisable = true - btnStartDisable = true + is_processing = true msg = "Loading total spectrum plot for $(selected_folder_main)..." try @@ -2020,6 +2188,7 @@ end plotdata, plotlayout, xSpectraMz, ySpectraMz = sumSpectrumPlot(msi_data, selected_folder_main, mask_path=mask_path_for_plot) plotdata_before = plotdata plotlayout_before = plotlayout + last_plot_type = "sum" selectedTab = "tab2" fTime = time() eTime = round(fTime - sTime, digits=3) @@ -2030,10 +2199,7 @@ end warning_msg = true @error "Total spectrum plotting failed" exception=(e, catch_backtrace()) finally - progressSpectraPlot = false - btnPlotDisable = false - btnSpectraDisable = false - btnStartDisable = false + is_processing = false GC.gc() # Trigger garbage collection if Sys.islinux() ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure Julia returns the freed memory to OS @@ -2048,10 +2214,7 @@ end return end - progressSpectraPlot = true - btnStartDisable = true - btnPlotDisable = true - btnSpectraDisable = true + is_processing = true msg = "Loading plot for $(selected_folder_main)..." try @@ -2106,6 +2269,7 @@ end plotdata, plotlayout, xSpectraMz, ySpectraMz, spectrum_id = xySpectrumPlot(msi_data, xCoord, y_positive, imgWidth, imgHeight, selected_folder_main, mask_path=mask_path_for_plot) plotdata_before = plotdata plotlayout_before = plotlayout + last_plot_type = "single" selected_spectrum_id_for_plot = spectrum_id idSpectrum = spectrum_id # we set the same obtained spectrum id to the UI @@ -2149,10 +2313,7 @@ end warning_msg = true @error "Spectrum plotting failed" exception=(e, catch_backtrace()) finally - progressSpectraPlot = false - btnPlotDisable = false - btnSpectraDisable = false - btnStartDisable = false + is_processing = false GC.gc() # Trigger garbage collection if Sys.islinux() ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure Julia returns the freed memory to OS @@ -2167,10 +2328,7 @@ end return end - progressSpectraPlot = true - btnStartDisable = true - btnPlotDisable = true - btnSpectraDisable = true + is_processing = true msg = "Loading plot for $(selected_folder_main)..." try @@ -2224,6 +2382,7 @@ end plotdata, plotlayout, xSpectraMz, ySpectraMz, spectrum_id = nSpectrumPlot(msi_data, idSpectrum, selected_folder_main, mask_path=mask_path_for_plot) plotdata_before = plotdata plotlayout_before = plotlayout + last_plot_type = "single" selected_spectrum_id_for_plot = spectrum_id selectedTab = "tab2" @@ -2236,10 +2395,7 @@ end warning_msg = true @error "nSpectrum plotting failed" exception=(e, catch_backtrace()) finally - progressSpectraPlot = false - btnPlotDisable = false - btnSpectraDisable = false - btnStartDisable = false + is_processing = false GC.gc() # Trigger garbage collection if Sys.islinux() ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure Julia returns the freed memory to OS @@ -2268,7 +2424,6 @@ end text_nmass = replace(current_msi, r"MSI_|.bmp" => "") msgimg = "m/z: $(replace(text_nmass, "_" => "."))" plotdataImg, plotlayoutImg, _, _ = loadImgPlot(imgInt) - btnOpticalDisable = false end end @onbutton imgPlus begin @@ -2290,7 +2445,6 @@ end text_nmass = replace(current_msi, r"MSI_|.bmp" => "") msgimg = "m/z: $(replace(text_nmass, "_" => "."))" plotdataImg, plotlayoutImg, _, _ = loadImgPlot(imgInt) - btnOpticalDisable = false end end @@ -2313,7 +2467,6 @@ end text_nmass = replace(current_triq, r"TrIQ_|.bmp" => "") msgtriq = "TrIQ m/z: $(replace(text_nmass, "_" => "."))" plotdataImgT, plotlayoutImgT, _, _ = loadImgPlot(imgIntT) - btnOpticalDisable = false end end @onbutton imgPlusT begin @@ -2335,7 +2488,6 @@ end text_nmass = replace(current_triq, r"TrIQ_|.bmp" => "") msgtriq = "TrIQ m/z: $(replace(text_nmass, "_" => "."))" plotdataImgT, plotlayoutImgT, _, _ = loadImgPlot(imgIntT) - btnOpticalDisable = false end end @@ -2726,11 +2878,7 @@ end warning_msg = true return end - - progressPlot = true - btnPlotDisable = true - btnStartDisable = true - btnSpectraDisable = true + is_processing = true try # --- Get Mask Path --- @@ -2766,10 +2914,7 @@ end warning_msg = true @error "3D plot generation failed" exception=(e, catch_backtrace()) finally - progressPlot=false - btnPlotDisable=false - btnStartDisable=false - btnSpectraDisable=false + is_processing = true SpectraEnabled=true GC.gc() # Trigger garbage collection if Sys.islinux() @@ -2790,10 +2935,7 @@ end return end - progressPlot = true - btnPlotDisable = true - btnStartDisable = true - btnSpectraDisable = true + is_processing = true try # --- Get Mask Path --- @@ -2829,10 +2971,7 @@ end warning_msg = true @error "3D TrIQ plot generation failed" exception=(e, catch_backtrace()) finally - progressPlot=false - btnPlotDisable=false - btnStartDisable=false - btnSpectraDisable=false + is_processing = true SpectraEnabled=true GC.gc() # Trigger garbage collection if Sys.islinux() @@ -2854,10 +2993,7 @@ end return end - progressPlot=true - btnPlotDisable=true - btnStartDisable=true - btnSpectraDisable=true + is_processing = true try sTime=time() @@ -2874,10 +3010,7 @@ end msg="Failed to load and process image: $e" warning_msg=true finally - progressPlot=false - btnPlotDisable=false - btnStartDisable=false - btnSpectraDisable=false + is_processing = true SpectraEnabled=true GC.gc() if Sys.islinux() @@ -2898,10 +3031,7 @@ end return end - progressPlot=true - btnPlotDisable=true - btnStartDisable=true - btnSpectraDisable=true + is_processing = true try sTime=time() @@ -2918,10 +3048,7 @@ end msg="Failed to load and process image: $e" warning_msg=true finally - progressPlot=false - btnPlotDisable=false - btnStartDisable=false - btnSpectraDisable=false + is_processing = true SpectraEnabled=true GC.gc() if Sys.islinux() @@ -3040,6 +3167,7 @@ end end @onbutton btnOptical begin + is_processing = true imgRoute=pick_file(; filterlist="png,bmp,jpg,jpeg") if imgRoute=="" msg="No optical image selected" @@ -3050,10 +3178,11 @@ end save("./public/css/imgOver.png",img) plotdataImg, plotlayoutImg, imgWidth, imgHeight=loadImgPlot(imgInt,"/css/imgOver.png",imgTrans) end - + is_processing = false end @onbutton btnOpticalT begin + is_processing = true imgRoute=pick_file(; filterlist="png,bmp,jpg,jpeg") if imgRoute=="" msg="No optical image selected" @@ -3065,6 +3194,7 @@ end plotdataImgT, plotlayoutImgT, imgWidth, imgHeight=loadImgPlot(imgIntT,"/css/imgOver.png",imgTrans) opticalOverTriq=true end + is_processing = false end @onchange imgTrans begin @@ -3088,6 +3218,7 @@ end end @onbutton refetch_folders begin + is_processing = true # Re-load registry and update folder lists registry = load_registry(registry_path) all_folders = sort(collect(keys(registry)), lt=natural) @@ -3116,11 +3247,13 @@ end selected_folder_metadata = first(available_folders) end end + is_processing = false end @mounted watchplots() @onchange isready @time begin + # is_processing = true if isready && !registry_init_done initialization_message = "Pre-compiling functions at startup..." warmup_init() @@ -3180,7 +3313,7 @@ end initialization_message = "Done." log_memory_usage("App Ready", msi_data) end - + # is_processing = false GC.gc() # Trigger garbage collection if Sys.islinux() ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure julia returns the freed memory to OS diff --git a/app.jl.html b/app.jl.html index 910ae13..38fcd8a 100644 --- a/app.jl.html +++ b/app.jl.html @@ -32,25 +32,48 @@
+ v-on:click="!is_processing && (btnSearch=true)" :disable="is_processing"> - - +
- +
+ + + +
+
+
Quick Test (Subset Processing)
+
Process only the first N spectra to quickly test parameters.
+
+
+ +
+
+
+ + + +
+
+
+

{{msg}}

+
Preview Spectrum:
- @@ -72,73 +95,78 @@
+ hint="Not for Mean/Sum plots." :readonly="is_processing">
+ val => !SpectraEnabled ? ( val >= 0 || 'Needs to be bigger than 0') : true + ]" :readonly="is_processing">
+ val => !SpectraEnabled ? ( val >= 0 || 'Needs to be bigger than 0') : true + ]" :readonly="is_processing">
- - - -
Internal Standards
-
Reference peaks for calibration, alignment and precise suggestion calculations
-
- - - - - - - - - -
-
- -
-
- -
-
-
-
- - - - - -
-
- + + + + + + + + + + + + +
+
+
- - +
+ +
+
+
+
+ + + + + +
+
+ + + +
+
+
+
Preprocessing Pipeline
- + + :class="step.enabled ? '' : 'text-grey'" :disable="is_processing"> - - - - - + + + + + - - + +
- +
- +
@@ -183,9 +211,9 @@
The algorithm to use for baseline correction.
-
-
-
+
+
+
Parameters
@@ -194,11 +222,11 @@
+ :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">
+ :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">
@@ -210,10 +238,10 @@
The normalization method to apply.
-
-
-
-
+
+
+
+
@@ -223,9 +251,9 @@
The alignment algorithm.
-
-
-
+
+
+
Parameters
@@ -234,23 +262,23 @@
+ :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">
+ :placeholder="suggested_alignment_tolerance" v-model="alignment_tolerance" hint="The tolerance for matching peaks between the target and reference spectrum." :readonly="is_processing">
+ :options="['mz', 'ppm']" class="q-mt-md" hint="The unit for tolerance, either 'mz' (absolute) or 'ppm' (relative)." :disable="is_processing">
+ :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">
+ :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">
@@ -265,12 +293,12 @@
+ hint="Polynomial order for the calibration curve (e.g., 1 or 2)." :readonly="is_processing">
+ hint="PPM tolerance for matching reference peaks to internal standards." :readonly="is_processing">
@@ -282,9 +310,9 @@
The peak detection algorithm.
-
-
-
+
+
+
Parameters
@@ -293,35 +321,35 @@
+ :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">
+ :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">
+ :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">
+ :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">
+ :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">
+ :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">
+ :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">
@@ -333,33 +361,33 @@
+ :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">
+ :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">
+ :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">
+ :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">
+ hint="The minimum fraction of spectra a peak must be present in to be kept (0.0 to 1.0)." :readonly="is_processing">
+ hint="Minimum correlation with neighboring peaks (not yet implemented)." :readonly="is_processing">
@@ -371,8 +399,8 @@
The binning strategy.
-
-
+
+
Parameters
@@ -381,35 +409,35 @@
+ :placeholder="suggested_binning_tolerance" v-model="binning_tolerance" hint="Tolerance for grouping peaks into a bin in adaptive mode." :readonly="is_processing">
+ :options="['mz', 'ppm']" hint="The unit for tolerance, either 'mz' (absolute) or 'ppm' (relative)." :disable="is_processing">
+ :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">
+ :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">
+ :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">
+ :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">
+ class="q-mt-md" hint="If enabled, calculates bin centers as an intensity-weighted average of the peaks within it." :disable="is_processing">
@@ -418,22 +446,10 @@
- - - -
- - - - - - -
- - - + + +
@@ -446,13 +462,13 @@
+ v-on:click="btnSearch=true" :disable="is_processing"> - - +
@@ -461,7 +477,7 @@ {{ file }} - + @@ -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">
+ :rules="[val => !!val || '* Required', val => val >= 0.0 && val <= 1.0 || 'Needs to be in range between 0 and 1']" :readonly="is_processing">
+ :rules="[ val => !!val || '* Required', val => val >= 2 && val <= 256 || 'Needs to be in range between 2 and 256']" :readonly="is_processing">
@@ -492,25 +508,25 @@
+ label="Add Median Filter" :disable="is_processing"> + label="Add Threshold Intensity Quantization (TrIQ)" :disable="is_processing"> + label="Use Mask To Filter Data" :disable="is_processing">
+ ]" :readonly="is_processing || !triqEnabled" :disable="is_processing || !triqEnabled">
-