Added plot interaction to the UI, improved boot loading, modified UI to accomodate for these changes

This commit is contained in:
Pixelguy14 2025-01-22 23:58:06 -06:00
parent bf50d0cb0c
commit 09e4a015e0
6 changed files with 641 additions and 445 deletions

View File

@ -242,9 +242,9 @@ version = "0.4.1"
[[deps.ColorSchemes]] [[deps.ColorSchemes]]
deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"]
git-tree-sha1 = "c785dfb1b3bfddd1da557e861b919819b82bbe5b" git-tree-sha1 = "26ec26c98ae1453c692efded2b17e15125a5bea1"
uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
version = "3.27.1" version = "3.28.0"
[[deps.ColorTypes]] [[deps.ColorTypes]]
deps = ["FixedPointNumbers", "Random"] deps = ["FixedPointNumbers", "Random"]
@ -525,9 +525,9 @@ version = "0.3.2"
[[deps.FFTW]] [[deps.FFTW]]
deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"]
git-tree-sha1 = "4820348781ae578893311153d69049a93d05f39d" git-tree-sha1 = "7de7c78d681078f027389e067864a8d53bd7c3c9"
uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
version = "1.8.0" version = "1.8.1"
[[deps.FFTW_jll]] [[deps.FFTW_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
@ -708,15 +708,15 @@ uuid = "5c4fdc26-39e3-47cf-9034-e533e09961c2"
version = "1.1.0" version = "1.1.0"
[[deps.GeoFormatTypes]] [[deps.GeoFormatTypes]]
git-tree-sha1 = "ce573eab15760315756de2c82df7406c870c7187" git-tree-sha1 = "8e233d5167e63d708d41f87597433f59a0f213fe"
uuid = "68eda718-8dee-11e9-39e7-89f7f65f511f" uuid = "68eda718-8dee-11e9-39e7-89f7f65f511f"
version = "0.4.3" version = "0.4.4"
[[deps.GeoInterface]] [[deps.GeoInterface]]
deps = ["DataAPI", "Extents", "GeoFormatTypes"] deps = ["DataAPI", "Extents", "GeoFormatTypes"]
git-tree-sha1 = "f4ee66b6b1872a4ca53303fbb51d158af1bf88d4" git-tree-sha1 = "294e99f19869d0b0cb71aef92f19d03649d028d5"
uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f"
version = "1.4.0" version = "1.4.1"
[[deps.GeometryBasics]] [[deps.GeometryBasics]]
deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "PrecompileTools", "Random", "StaticArrays"] deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "PrecompileTools", "Random", "StaticArrays"]
@ -814,9 +814,9 @@ version = "0.5.0"
[[deps.HypergeometricFunctions]] [[deps.HypergeometricFunctions]]
deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"]
git-tree-sha1 = "b1c2585431c382e3fe5805874bda6aea90a95de9" git-tree-sha1 = "2bd56245074fab4015b9174f24ceba8293209053"
uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a"
version = "0.3.25" version = "0.3.27"
[[deps.HypertextLiteral]] [[deps.HypertextLiteral]]
deps = ["Tricks"] deps = ["Tricks"]
@ -933,9 +933,9 @@ version = "0.10.1"
[[deps.Images]] [[deps.Images]]
deps = ["Base64", "FileIO", "Graphics", "ImageAxes", "ImageBase", "ImageBinarization", "ImageContrastAdjustment", "ImageCore", "ImageCorners", "ImageDistances", "ImageFiltering", "ImageIO", "ImageMagick", "ImageMetadata", "ImageMorphology", "ImageQualityIndexes", "ImageSegmentation", "ImageShow", "ImageTransformations", "IndirectArrays", "IntegralArrays", "Random", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "StatsBase", "TiledIteration"] deps = ["Base64", "FileIO", "Graphics", "ImageAxes", "ImageBase", "ImageBinarization", "ImageContrastAdjustment", "ImageCore", "ImageCorners", "ImageDistances", "ImageFiltering", "ImageIO", "ImageMagick", "ImageMetadata", "ImageMorphology", "ImageQualityIndexes", "ImageSegmentation", "ImageShow", "ImageTransformations", "IndirectArrays", "IntegralArrays", "Random", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "StatsBase", "TiledIteration"]
git-tree-sha1 = "12fdd617c7fe25dc4a6cc804d657cc4b2230302b" git-tree-sha1 = "a49b96fd4a8d1a9a718dfd9cde34c154fc84fcd5"
uuid = "916415d5-f1e6-5110-898d-aaa5f9f070e0" uuid = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
version = "0.26.1" version = "0.26.2"
[[deps.Imath_jll]] [[deps.Imath_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"] deps = ["Artifacts", "JLLWrappers", "Libdl"]
@ -980,9 +980,9 @@ version = "0.1.6"
[[deps.IntelOpenMP_jll]] [[deps.IntelOpenMP_jll]]
deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"]
git-tree-sha1 = "10bd689145d2c3b2a9844005d01087cc1194e79e" git-tree-sha1 = "0f14a5456bdc6b9731a5682f439a672750a09e48"
uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0"
version = "2024.2.1+0" version = "2025.0.4+0"
[[deps.InteractiveUtils]] [[deps.InteractiveUtils]]
deps = ["Markdown"] deps = ["Markdown"]
@ -1350,9 +1350,9 @@ version = "0.1.4"
[[deps.MKL_jll]] [[deps.MKL_jll]]
deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"]
git-tree-sha1 = "f046ccd0c6db2832a9f639e2c669c6fe867e5f4f" git-tree-sha1 = "5de60bc6cb3899cd318d80d627560fae2e2d99ae"
uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7"
version = "2024.2.0+0" version = "2025.0.1+1"
[[deps.MacroTools]] [[deps.MacroTools]]
git-tree-sha1 = "72aebe0b5051e5143a079a4685a46da330a40472" git-tree-sha1 = "72aebe0b5051e5143a079a4685a46da330a40472"
@ -1459,9 +1459,9 @@ version = "1.2.1"
[[deps.NaNMath]] [[deps.NaNMath]]
deps = ["OpenLibm_jll"] deps = ["OpenLibm_jll"]
git-tree-sha1 = "030ea22804ef91648f29b7ad3fc15fa49d0e6e71" git-tree-sha1 = "fe891aea7ccd23897520db7f16931212454e277e"
uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
version = "1.0.3" version = "1.1.1"
[[deps.NativeFileDialog]] [[deps.NativeFileDialog]]
deps = ["FilePathsBase", "NativeFileDialog_jll"] deps = ["FilePathsBase", "NativeFileDialog_jll"]
@ -1921,9 +1921,9 @@ version = "1.3.0"
[[deps.Revise]] [[deps.Revise]]
deps = ["CodeTracking", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "REPL", "Requires", "UUIDs", "Unicode"] deps = ["CodeTracking", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "REPL", "Requires", "UUIDs", "Unicode"]
git-tree-sha1 = "b5e7c125687aa818de948ef8a0b9dc59f043342c" git-tree-sha1 = "9bb80533cb9769933954ea4ffbecb3025a783198"
uuid = "295af30f-e4ad-537b-8983-00126c2a3abe" uuid = "295af30f-e4ad-537b-8983-00126c2a3abe"
version = "3.7.1" version = "3.7.2"
weakdeps = ["Distributed"] weakdeps = ["Distributed"]
[deps.Revise.extensions] [deps.Revise.extensions]

View File

@ -9,20 +9,16 @@ A Graphical User Interface for IMS in Julia: https://github.com/CINVESTAV-LABI/j
unzip the file in your desired location<br> unzip the file in your desired location<br>
## Load User Interface ## Load User Interface
1. Launch Julia in your terminal using: 1. Set working directory to Julia_msi_GUI (this repository) in your terminal using:
``` ```
julia cd PathToRepository/Julia_msi_GUI-main
``` ```
2. Set working directory to Julia_msi_GUI (this repository) code using: 2. Launch the Julia project in your terminal using:
``` ```
cd("PathToRepository/Julia_msi_GUI-main") julia --project=. start_MSI_GUI.jl
``` ```
3. With the active directory being Julia_msi_GUI run the next script: 3. Alternatively, you can open a terminal in the path of the repository and run the command and skip the next step:
``` ```
include("start_MSI_GUI.jl") julia --project=. start_MSI_GUI.jl
``` ```
4. Alternatively, you can open a terminal in the path of the repository and run the command and skip the next step: 4. After the script has finished loading, it should open a page (http://127.0.0.1:1481/) in your browser with the web app running.
```
julia start_MSI_GUI.jl
```
5. After the script has finished loading, it should open a page in your browser with the web app running.

344
app.jl
View File

@ -1,5 +1,5 @@
module App module App
# == Packages == # ==Packages ==
using GenieFramework # Set up Genie development environment. using GenieFramework # Set up Genie development environment.
using Pkg using Pkg
using Libz using Libz
@ -15,18 +15,18 @@ using NativeFileDialog # Opens the file explorer depending on the OS
using StipplePlotly using StipplePlotly
@genietools @genietools
# == Code import == # ==Code import ==
# add your data analysis code here or in the lib folder. Code in lib/ will be # add your data analysis code here or in the lib folder. Code in lib/ will be
# automatically loaded # automatically loaded
rgb_ViridisPalette=reinterpret(ColorTypes.RGB24, ViridisPalette) rgb_ViridisPalette=reinterpret(ColorTypes.RGB24, ViridisPalette)
# == Search functions == # ==Search functions ==
function increment_image(current_image, image_list) function increment_image(current_image, image_list)
if isempty(image_list) if isempty(image_list)
return nothing return nothing
end end
current_index=findfirst(isequal(current_image), image_list) current_index=findfirst(isequal(current_image), image_list)
if current_index == nothing || current_index == length(image_list) || current_image === "" if current_index ==nothing || current_index ==length(image_list) || current_image ===""
return image_list[length(image_list)] # Return the current image if it's the last one or not found return image_list[length(image_list)] # Return the current image if it's the last one or not found
else else
return image_list[current_index + 1] # Move to the next image return image_list[current_index + 1] # Move to the next image
@ -38,31 +38,39 @@ function decrement_image(current_image, image_list)
return nothing return nothing
end end
current_index=findfirst(isequal(current_image), image_list) current_index=findfirst(isequal(current_image), image_list)
if current_index == nothing || current_index == 1 || current_image === "" if current_index ==nothing || current_index ==1 || current_image ===""
return image_list[1] # Return the current image if it's the first one or not found return image_list[1] # Return the current image if it's the first one or not found
else else
return image_list[current_index - 1] # Move to the previous image return image_list[current_index - 1] # Move to the previous image
end end
end end
# == Reactive code == # ==Reactive code ==
# reactive code to make the UI interactive # reactive code to make the UI interactive
@app begin @app begin
# == Reactive variables == # ==Reactive variables ==
# reactive variables exist in both the Julia backend and the browser with two-way synchronization # reactive variables exist in both the Julia backend and the browser with two-way synchronization
# @out variables can only be modified by the backend # @out variables can only be modified by the backend
# @in variables can be modified by both the backend and the browser # @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 # variables must be initialized with constant values, or variables defined outside of the @app block
#@out test="/test.bmp" #slash means it's getting the info from 'public' folder #@out test="/test.bmp" #slash means it's getting the info from 'public' folder
# Interface non Variables ## Interface non Variables
@out warning_fr=""
@out btnStartDisable=true @out btnStartDisable=true
@out btnPlotDisable=false @out btnPlotDisable=false
@out btnSpectraDisable=true
# Loading animations
@in progress=false
@in progressPlot=false
@in progressSpectraPlot=false
# Text field validations
@in triqEnabled=false
@in SpectraEnabled=false
# Dialogs
@in warning_msg=false @in warning_msg=false
@in CompareDialog=false @in CompareDialog=false
# Interface Variables ## Interface Variables
@in file_route="" @in file_route=""
@in file_name="" @in file_name=""
@in Nmass=0.0 @in Nmass=0.0
@ -70,38 +78,39 @@ end
@in triqProb=0.98 @in triqProb=0.98
@in triqColor=256 @in triqColor=256
# Interface Buttons and Validations ## Interface Buttons
@in btnSearch=false # To search for files in your device @in btnSearch=false # To search for files in your device
@in mainProcess=false # To generate images @in mainProcess=false # To generate images
@in compareBtn=false # To open dialog @in compareBtn=false # To open dialog
@in createSumPlot=false # To generate sum spectrum plot @in createSumPlot=false # To generate sum spectrum plot
@in createXYPlot=false # To generate an spectrum plot according to the xy values inputed
@in image3dPlot=false # To generate 3d plot based on current image @in image3dPlot=false # To generate 3d plot based on current image
@in triq3dPlot=false # To generate 3d plot based on current triq image @in triq3dPlot=false # To generate 3d plot based on current triq image
@in imageCPlot=false # To generate contour plots of current image @in imageCPlot=false # To generate contour plots of current image
@in triqCPlot=false # To generate contour plots of current triq image @in triqCPlot=false # To generate contour plots of current triq image
@in progress=false # Image change buttons
@in progressPlot=false
@in triqEnabled=false
@in imgPlus=false @in imgPlus=false
@in imgMinus=false @in imgMinus=false
@in imgPlusT=false @in imgPlusT=false
@in imgMinusT=false @in imgMinusT=false
# TAB variables ## Tabulation variables
@out tabIDs=["tab0","tab1","tab2","tab3","tab4"] @out tabIDs=["tab0","tab1","tab2","tab3","tab4"]
@out tabLabels=["Image", "TrIQ", "Spectrum Plot", "Topology Plot","Surface Plot"] @out tabLabels=["Image", "TrIQ", "Spectrum Plot", "Topology Plot","Surface Plot"]
@in selectedTab= "tab0" @in selectedTab="tab0"
@out CompTabIDs=["tab0","tab1","tab2","tab3","tab4"] @out CompTabIDs=["tab0","tab1","tab2","tab3","tab4"]
@out CompTabLabels=["Image", "TrIQ", "Spectrum Plot", "Topology Plot","Surface Plot"] @out CompTabLabels=["Image", "TrIQ", "Spectrum Plot", "Topology Plot","Surface Plot"]
@in CompSelectedTab= "tab0" @in CompSelectedTab="tab0"
# Interface Images # Interface Images
@out imgInt="/.bmp" # image Interface @out imgInt="/.bmp" # image Interface
@out imgIntT="/.bmp" # image Interface TrIQ @out imgIntT="/.bmp" # image Interface TrIQ
@out colorbar="/.png" @out colorbar="/.png"
@out colorbarT="/.png" @out colorbarT="/.png"
@out img_width=0
@out img_height=0
# Messages to interface Variables # Messages to interface variables
@out msg="" @out msg=""
@out msgimg="" @out msgimg=""
@out msgtriq="" @out msgtriq=""
@ -126,11 +135,12 @@ end
@out current_triq="" @out current_triq=""
@out current_col_triq="" @out current_col_triq=""
# Starting and finishing times to measure how long it takes for a function to finish in elapse time ## Time measurement variables
@out sTime=time() @out sTime=time()
@out fTime=time() @out fTime=time()
@out eTime=time() @out eTime=time()
## Plots
# Interface Plot Spectrum # Interface Plot Spectrum
layoutSpectra=PlotlyBase.Layout( layoutSpectra=PlotlyBase.Layout(
title="SUM Spectrum plot", title="SUM Spectrum plot",
@ -148,10 +158,14 @@ end
# Create conection to frontend # Create conection to frontend
@out plotdata=[traceSpectra] @out plotdata=[traceSpectra]
@out plotlayout=layoutSpectra @out plotlayout=layoutSpectra
@in xCoord=0
@in yCoord=0
@out xSpectraMz=Float64[]
@out ySpectraMz=Float64[]
# Interactive plot reactions # Interactive plot reactions
@in data_click = Dict{String,Any}() @in data_click=Dict{String,Any}()
#@in data_selected = Dict{String,Any}() # Selected is for areas, this can work for the masks #@in data_selected=Dict{String,Any}() # Selected is for areas, this can work for the masks
#<plotly id="plotStyle" :data="plotdata" :layout="plotlayout" @click="data_selected" class="q-pa-none q-ma-none sync_data"></plotly> #<plotly id="plotStyle" :data="plotdata" :layout="plotlayout" @click="data_selected" class="q-pa-none q-ma-none sync_data"></plotly>
# Interface Plot Surface # Interface Plot Surface
@ -159,13 +173,12 @@ end
title="2D Topographic Map", title="2D Topographic Map",
xaxis=PlotlyBase.attr( xaxis=PlotlyBase.attr(
title="X", title="X",
showgrid=true scaleanchor="y"
), ),
yaxis=PlotlyBase.attr( yaxis=PlotlyBase.attr(
title="Y", title="Y"
showgrid=true ),
) )
)
# Dummy 2D surface plot # Dummy 2D surface plot
traceContour=PlotlyBase.scatter(x=[], y=[], mode="lines") traceContour=PlotlyBase.scatter(x=[], y=[], mode="lines")
# Create conection to frontend # Create conection to frontend
@ -203,7 +216,7 @@ end
@out plotdata3d=[trace3D] @out plotdata3d=[trace3D]
@out plotlayout3d=layout3D @out plotlayout3d=layout3D
# == Reactive handlers == # ==Reactive handlers ==
# Reactive handlers watch a variable and execute a block of code when its value changes # 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 # The onbutton handler will set the variable to false after the block is executed
@ -218,10 +231,12 @@ end
#println("Selected file path: ", full_route) #println("Selected file path: ", full_route)
btnStartDisable=false btnStartDisable=false
btnPlotDisable=false btnPlotDisable=false
msi_bmp=sort(filter(filename -> startswith(filename, "MSI_") && endswith(filename, ".bmp"), readdir("public")),lt=natural) full_routeMz=split( full_route, "." )[1] * ".mzML" # Splitting the route from imzml to mzml so the plotting can work
col_msi_png=sort(filter(filename -> startswith(filename, "colorbar_MSI_") && endswith(filename, ".png"), readdir("public")),lt=natural) if isfile(full_routeMz)
triq_bmp=sort(filter(filename -> startswith(filename, "TrIQ_") && endswith(filename, ".bmp"), readdir("public")),lt=natural) # We enable coord search and spectra plot creation
col_triq_png=sort(filter(filename -> startswith(filename, "colorbar_TrIQ_") && endswith(filename, ".png"), readdir("public")),lt=natural) btnSpectraDisable=false
SpectraEnabled=true
end
end end
end end
@ -229,10 +244,11 @@ end
progress=true # Start progress button animation progress=true # Start progress button animation
btnStartDisable=true # We disable the button to avoid multiple requests btnStartDisable=true # We disable the button to avoid multiple requests
btnPlotDisable=true btnPlotDisable=true
btnSpectraDisable=true
text_nmass=replace(string(Nmass), "." => "_") text_nmass=replace(string(Nmass), "." => "_")
sTime=time() sTime=time()
#full_route=joinpath(file_route, file_name) #full_route=joinpath(file_route, file_name)
if isfile(full_route) && Nmass > 0 && Tol > 0 && Tol <= 1 if isfile(full_route) && Nmass > 0 && Tol > 0 && Tol <=1
msg="File exists, Nmass=$(Nmass) Tol=$(Tol). Loading file will begin, please be patient." msg="File exists, Nmass=$(Nmass) Tol=$(Tol). Loading file will begin, please be patient."
try try
spectra=LoadImzml(full_route) spectra=LoadImzml(full_route)
@ -254,6 +270,8 @@ end
img=reverse(permutedims(img, (2, 1)), dims=1) img=reverse(permutedims(img, (2, 1)), dims=1)
end end
flipped_img=reverse(img, dims=1) flipped_img=reverse(img, dims=1)
img_width=size(flipped_img, 2)
img_height=size(flipped_img, 1)
save(image_path, flipped_img) save(image_path, flipped_img)
# Use timestamp to refresh image interface container # Use timestamp to refresh image interface container
imgIntT="/TrIQ_$(text_nmass).bmp?t=$(timestamp)" imgIntT="/TrIQ_$(text_nmass).bmp?t=$(timestamp)"
@ -275,7 +293,7 @@ end
msg="The file has been created in $(eTime) seconds successfully inside the 'public' folder of the app" msg="The file has been created in $(eTime) seconds successfully inside the 'public' folder of the app"
selectedTab="tab1" selectedTab="tab1"
#println("all msi in folder=",triq_bmp) #println("all msi in folder=",triq_bmp)
#println("all col msi in folder= ",col_triq_png) #println("all col msi in folder=",col_triq_png)
end end
else # If we don't use TrIQ else # If we don't use TrIQ
image_path=joinpath("./public", "MSI_$(text_nmass).bmp") image_path=joinpath("./public", "MSI_$(text_nmass).bmp")
@ -286,6 +304,8 @@ end
img=reverse(permutedims(img, (2, 1)), dims=1) img=reverse(permutedims(img, (2, 1)), dims=1)
end end
flipped_img=reverse(img, dims=1) flipped_img=reverse(img, dims=1)
img_width=size(flipped_img, 2)
img_height=size(flipped_img, 1)
save(image_path, flipped_img) save(image_path, flipped_img)
# Use timestamp to refresh image interface container # Use timestamp to refresh image interface container
imgInt="/MSI_$(text_nmass).bmp?t=$(timestamp)" imgInt="/MSI_$(text_nmass).bmp?t=$(timestamp)"
@ -307,7 +327,7 @@ end
eTime=round(fTime-sTime,digits=3) eTime=round(fTime-sTime,digits=3)
msg="The file has been created in $(eTime) seconds successfully inside the 'public' folder of the app" msg="The file has been created in $(eTime) seconds successfully inside the 'public' folder of the app"
#println("all msi in folder=",msi_bmp) #println("all msi in folder=",msi_bmp)
#println("all col msi in folder= ",col_msi_png) #println("all col msi in folder=",col_msi_png)
end end
catch e catch e
msg="There was an error loading the ImzML file, please verify the file accordingly and try again. $(e)" msg="There was an error loading the ImzML file, please verify the file accordingly and try again. $(e)"
@ -325,6 +345,11 @@ end
end end
btnStartDisable=false btnStartDisable=false
btnPlotDisable=false btnPlotDisable=false
if isfile(full_routeMz)
# We enable coord search and spectra plot creation
btnSpectraDisable=false
SpectraEnabled=true
end
progress=false progress=false
end end
@ -332,55 +357,101 @@ end
msg="Sum spectrum plot selected" msg="Sum spectrum plot selected"
sTime=time() sTime=time()
#full_route=joinpath( file_route, file_name ) #full_route=joinpath( file_route, file_name )
if isfile(full_route) # Check if the file exists if isfile(full_routeMz) # Check if the file exists
btnPlotDisable=false progressSpectraPlot=true
btnStartDisable=false btnPlotDisable=true
full_routeMz=split( full_route, "." )[1] * ".mzML" # Splitting the route from imzml to mzml so the plotting can work btnStartDisable=true
if isfile(full_routeMz) && (full_routeMz2 == "" || full_routeMz2 != full_routeMz) # Check if the mzml exists msg="Loading plot..."
progressPlot=true spectraMz=LoadMzml(full_routeMz)
btnPlotDisable=true layoutSpectra=PlotlyBase.Layout(
btnStartDisable=true title="SUM Spectrum plot",
msg="Loading plot..." xaxis=PlotlyBase.attr(
spectraMz=LoadMzml(full_routeMz) title="<i>m/z</i>",
layoutSpectra=PlotlyBase.Layout( showgrid=true
title="SUM Spectrum plot", ),
xaxis=PlotlyBase.attr( yaxis=PlotlyBase.attr(
title="<i>m/z</i>", title="Intensity",
showgrid=true showgrid=true
),
), autosize=false
yaxis=PlotlyBase.attr( )
title="Intensity", # dims=size(spectraMz)
showgrid=true # scansMax=dims[2] # we get the total of scansMax
) xSpectraMz=mean(spectraMz[1,:])
) ySpectraMz=mean(spectraMz[2,:])
# dims=size(spectraMz) traceSpectra=PlotlyBase.scatter(x=xSpectraMz, y=ySpectraMz, mode="lines")
# scansMax=dims[2] # we get the total of scansMax plotdata=[traceSpectra] # We add the data from spectra to the plot
# traceSpectra=PlotlyBase.scatter(x=spectraMz[1, 1], y=spectraMz[2, 1], mode="lines") plotlayout=layoutSpectra
traceSpectra=PlotlyBase.scatter(x=mean(spectraMz[1,:]), y=mean(spectraMz[2,:]), mode="lines") GC.gc() # Trigger garbage collection
plotdata=[traceSpectra] # We add the data from spectra to the plot if Sys.islinux()
plotlayout=layoutSpectra ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure julia returns the freed memory to OS
spectraMz=nothing # Important for memory cleaning
GC.gc() # Trigger garbage collection
if Sys.islinux()
ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure julia returns the freed memory to OS
end
selectedTab="tab2"
fTime=time()
eTime=round(fTime-sTime,digits=3)
msg="Plot loaded in $(eTime) seconds"
full_routeMz2=full_routeMz # To avoid creating the plot if its the same file read as before
else
msg="the mzML file was not found or you're trying to load the same mzML"
warning_msg=true
end end
selectedTab="tab2"
fTime=time()
eTime=round(fTime-sTime,digits=3)
msg="Plot loaded in $(eTime) seconds"
else else
msg="is not an imzML file" msg="there was an error with the mzML, please try again"
warning_msg=true warning_msg=true
end end
progressPlot=false progressSpectraPlot=false
btnPlotDisable=false btnPlotDisable=false
btnStartDisable=false btnStartDisable=false
if isfile(full_routeMz)
# We enable coord search and spectra plot creation
btnSpectraDisable=false
SpectraEnabled=true
end
end
@onbutton createXYPlot begin
msg="Sum spectrum plot selected"
sTime=time()
#full_route=joinpath( file_route, file_name )
if isfile(full_routeMz) # Check if the file exists
progressSpectraPlot=true
btnStartDisable=true
btnPlotDisable=true
btnSpectraDisable=true
msg="Loading plot..."
spectraMz=LoadMzml(full_routeMz)
layoutSpectra=PlotlyBase.Layout(
title="($xCoord, $yCoord) Specific spectrum plot",
xaxis=PlotlyBase.attr(
title="<i>m/z</i>",
showgrid=true
),
yaxis=PlotlyBase.attr(
title="Intensity",
showgrid=true
),
autosize=false
)
xSpectraMz=spectraMz[1,abs(xCoord)]
ySpectraMz=spectraMz[2,abs(yCoord)]
traceSpectra=PlotlyBase.scatter(x=xSpectraMz, y=ySpectraMz, mode="lines")
plotdata=[traceSpectra] # We add the data from spectra to the plot
plotlayout=layoutSpectra
GC.gc() # Trigger garbage collection
if Sys.islinux()
ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure julia returns the freed memory to OS
end
selectedTab="tab2"
fTime=time()
eTime=round(fTime-sTime,digits=3)
msg="Plot loaded in $(eTime) seconds"
else
msg="there was an error with the mzML or the coordenates, please try again"
warning_msg=true
end
progressSpectraPlot=false
btnPlotDisable=false
btnStartDisable=false
if isfile(full_routeMz)
# We enable coord search and spectra plot creation
btnSpectraDisable=false
SpectraEnabled=true
end
end end
# Image loaders based on the position of the current image (increment and decrement for both normal and filter) # Image loaders based on the position of the current image (increment and decrement for both normal and filter)
@ -389,8 +460,8 @@ end
# Append a query string to force the image to refresh # Append a query string to force the image to refresh
timestamp=string(time_ns()) timestamp=string(time_ns())
# Update the array of images listed in the public folder # Update the array of images listed in the public folder
msi_bmp=sort(filter(filename -> startswith(filename, "MSI_") && endswith(filename, ".bmp"), readdir("public")),lt=natural) msi_bmp=sort(filter(filename -> startswith(filename, "MSI_") && endswith(filename, ".bmp"), readdir("public")),lt=natural)
col_msi_png=sort(filter(filename -> startswith(filename, "colorbar_MSI_") && endswith(filename, ".png"), readdir("public")),lt=natural) col_msi_png=sort(filter(filename -> startswith(filename, "colorbar_MSI_") && endswith(filename, ".png"), readdir("public")),lt=natural)
new_msi=decrement_image(current_msi, msi_bmp) new_msi=decrement_image(current_msi, msi_bmp)
new_col_msi=decrement_image(current_col_msi, col_msi_png) new_col_msi=decrement_image(current_col_msi, col_msi_png)
@ -408,8 +479,8 @@ end
# Append a query string to force the image to refresh # Append a query string to force the image to refresh
timestamp=string(time_ns()) timestamp=string(time_ns())
# Update the array of images listed in the public folder # Update the array of images listed in the public folder
msi_bmp=sort(filter(filename -> startswith(filename, "MSI_") && endswith(filename, ".bmp"), readdir("public")),lt=natural) msi_bmp=sort(filter(filename -> startswith(filename, "MSI_") && endswith(filename, ".bmp"), readdir("public")),lt=natural)
col_msi_png=sort(filter(filename -> startswith(filename, "colorbar_MSI_") && endswith(filename, ".png"), readdir("public")),lt=natural) col_msi_png=sort(filter(filename -> startswith(filename, "colorbar_MSI_") && endswith(filename, ".png"), readdir("public")),lt=natural)
new_msi=increment_image(current_msi, msi_bmp) new_msi=increment_image(current_msi, msi_bmp)
new_col_msi=increment_image(current_col_msi, col_msi_png) new_col_msi=increment_image(current_col_msi, col_msi_png)
@ -454,8 +525,8 @@ end
current_triq=new_msi current_triq=new_msi
current_col_triq=new_col_msi current_col_triq=new_col_msi
imgIntT="/$(current_triq)" imgIntT="/$(current_triq)?t=$(timestamp)"
colorbarT="/$(current_col_triq)" colorbarT="/$(current_col_triq)?t=$(timestamp)"
text_nmass=replace(current_triq, "TrIQ_" => "") text_nmass=replace(current_triq, "TrIQ_" => "")
text_nmass=replace(text_nmass, ".bmp" => "") text_nmass=replace(text_nmass, ".bmp" => "")
@ -474,6 +545,7 @@ end
progressPlot=true progressPlot=true
btnPlotDisable=true btnPlotDisable=true
btnStartDisable=true btnStartDisable=true
btnSpectraDisable=true
try try
img=load(var) img=load(var)
#println("Image type:", typeof(img)) #println("Image type:", typeof(img))
@ -528,7 +600,6 @@ end
), colorscale="Viridis") ), colorscale="Viridis")
plotdata3d=[trace3D] # We add the data from the image to the plot plotdata3d=[trace3D] # We add the data from the image to the plot
plotlayout3d=layout3D # we update the style of the plot to fit the image. plotlayout3d=layout3D # we update the style of the plot to fit the image.
spectraMz=nothing # Important for memory cleaning
GC.gc() # Trigger garbage collection GC.gc() # Trigger garbage collection
if Sys.islinux() if Sys.islinux()
ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure julia returns the freed memory to OS ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure julia returns the freed memory to OS
@ -549,6 +620,11 @@ end
progressPlot=false progressPlot=false
btnPlotDisable=false btnPlotDisable=false
btnStartDisable=false btnStartDisable=false
if isfile(full_routeMz)
# We enable coord search and spectra plot creation
btnSpectraDisable=false
SpectraEnabled=true
end
end end
# 3d plot for TrIQ # 3d plot for TrIQ
@onbutton triq3dPlot begin @onbutton triq3dPlot begin
@ -562,6 +638,7 @@ end
progressPlot=true progressPlot=true
btnPlotDisable=true btnPlotDisable=true
btnStartDisable=true btnStartDisable=true
btnSpectraDisable=true
try try
img=load(var) img=load(var)
img_gray=Gray.(img) # Convert to grayscale img_gray=Gray.(img) # Convert to grayscale
@ -610,7 +687,6 @@ end
), colorscale="Viridis") ), colorscale="Viridis")
plotdata3d=[trace3D] # We add the data from the image to the plot plotdata3d=[trace3D] # We add the data from the image to the plot
plotlayout3d=layout3D # we update the style of the plot to fit the image. plotlayout3d=layout3D # we update the style of the plot to fit the image.
spectraMz=nothing # Important for memory cleaning
GC.gc() # Trigger garbage collection GC.gc() # Trigger garbage collection
if Sys.islinux() if Sys.islinux()
ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure julia returns the freed memory to OS ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure julia returns the freed memory to OS
@ -631,6 +707,11 @@ end
progressPlot=false progressPlot=false
btnPlotDisable=false btnPlotDisable=false
btnStartDisable=false btnStartDisable=false
if isfile(full_routeMz)
# We enable coord search and spectra plot creation
btnSpectraDisable=false
SpectraEnabled=true
end
end end
# Contour 2d plot # Contour 2d plot
@ -645,6 +726,7 @@ end
progressPlot=true progressPlot=true
btnPlotDisable=true btnPlotDisable=true
btnStartDisable=true btnStartDisable=true
btnSpectraDisable=true
try try
img=load(var) img=load(var)
# Convert to grayscale # Convert to grayscale
@ -665,8 +747,13 @@ end
layoutContour=PlotlyBase.Layout( layoutContour=PlotlyBase.Layout(
title="2D Topographic Map", title="2D Topographic Map",
xaxis_title="X", xaxis=PlotlyBase.attr(
yaxis_title="Y" title="X",
scaleanchor="y"
),
yaxis=PlotlyBase.attr(
title="Y"
),
) )
traceContour=PlotlyBase.contour( traceContour=PlotlyBase.contour(
z=elevation_smoothed, z=elevation_smoothed,
@ -677,8 +764,6 @@ end
) )
plotdataC=[traceContour] plotdataC=[traceContour]
plotlayoutC=layoutContour plotlayoutC=layoutContour
spectraMz=nothing # Important for memory cleaning
GC.gc() # Trigger garbage collection GC.gc() # Trigger garbage collection
if Sys.islinux() if Sys.islinux()
ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure Julia returns the freed memory to OS ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure Julia returns the freed memory to OS
@ -699,6 +784,11 @@ end
progressPlot=false progressPlot=false
btnPlotDisable=false btnPlotDisable=false
btnStartDisable=false btnStartDisable=false
if isfile(full_routeMz)
# We enable coord search and spectra plot creation
btnSpectraDisable=false
SpectraEnabled=true
end
end end
# Contour 2d plot for TrIQ # Contour 2d plot for TrIQ
@onbutton triqCPlot begin @onbutton triqCPlot begin
@ -712,6 +802,7 @@ end
progressPlot=true progressPlot=true
btnPlotDisable=true btnPlotDisable=true
btnStartDisable=true btnStartDisable=true
btnSpectraDisable=true
try try
img=load(var) img=load(var)
# Convert to grayscale # Convert to grayscale
@ -732,8 +823,13 @@ end
layoutContour=PlotlyBase.Layout( layoutContour=PlotlyBase.Layout(
title="2D Topographic Map", title="2D Topographic Map",
xaxis_title="X", xaxis=PlotlyBase.attr(
yaxis_title="Y" title="X",
scaleanchor="y"
),
yaxis=PlotlyBase.attr(
title="Y"
),
) )
traceContour=PlotlyBase.contour( traceContour=PlotlyBase.contour(
z=elevation_smoothed, z=elevation_smoothed,
@ -744,8 +840,6 @@ end
) )
plotdataC=[traceContour] plotdataC=[traceContour]
plotlayoutC=layoutContour plotlayoutC=layoutContour
spectraMz=nothing # Important for memory cleaning
GC.gc() # Trigger garbage collection GC.gc() # Trigger garbage collection
if Sys.islinux() if Sys.islinux()
ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure Julia returns the freed memory to OS ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure Julia returns the freed memory to OS
@ -766,19 +860,67 @@ end
progressPlot=false progressPlot=false
btnPlotDisable=false btnPlotDisable=false
btnStartDisable=false btnStartDisable=false
if isfile(full_routeMz)
# We enable coord search and spectra plot creation
btnSpectraDisable=false
SpectraEnabled=true
end
end end
@onbutton compareBtn begin @onbutton compareBtn begin
CompareDialog=true CompareDialog=true
# We remove the red lines
traceSpectra=PlotlyBase.scatter(x=xSpectraMz, y=ySpectraMz, mode="lines",name="Spectra",showlegend=false)
plotdata=[traceSpectra]
end end
# Event detection for clicking on the spectrum plot # Event detection for clicking on the spectrum plot
@onchange data_click begin @onchange data_click begin
println("Clicked data on sum spectrum plot : ", data_click) if !isempty(xSpectraMz)
# Now it needs to compare if there is a value from the spectrum close (to make sure it does not select invalid m/z) #println("Clicked data on sum spectrum plot : ", data_click)
# and then, add it to the mass-to-charge ratio of interest input to the frontend to ease with inputs spectracoords=reshape(plotdata, 1, length(plotdata))
# optional: red line signaling which m/z got selected in the spectrum plot #println("Spectra: $(ndims(spectracoords))")
# Extract x and y values from data_click
cursor_data=data_click["cursor"]
x_value = cursor_data["x"]
y_value = cursor_data["y"] # Get the x and y values from the click of the cursor
closest_distance = Inf
for val in spectracoords
# Find the index where x is within a range
start_idx = findfirst(x -> x >= x_value - 10, val[:x])
end_idx = findlast(x -> x <= x_value + 10, val[:x])
# Ensure the index are valid and within range
if start_idx !== nothing && end_idx !== nothing
for i in start_idx:end_idx
spectra_x = val[:x][i]
spectra_y = val[:y][i]
distance = sqrt((spectra_x - x_value)^2 + (spectra_y - y_value)^2) # Calculate distance
if distance < closest_distance
closest_distance = distance
Nmass = round(spectra_x, digits=2)
end
end
end
end
layoutSpectra=PlotlyBase.Layout(
title="SUM Spectrum plot",
xaxis=PlotlyBase.attr(
title="<i>m/z</i>",
showgrid=true
),
yaxis=PlotlyBase.attr(
title="Intensity",
showgrid=true
),
autosize=false
)
traceSpectra=PlotlyBase.scatter(x=xSpectraMz, y=ySpectraMz, mode="lines",name="Spectra",showlegend=false)
trace2=PlotlyBase.scatter(x=[Nmass, Nmass],y=[0, maximum(ySpectraMz)],mode="lines",line=attr(color="red", width=0.5),name="<i>m/z</i> selected",showlegend=false)
plotdata=[traceSpectra,trace2] # We add the data from spectra and the red line to the plot
plotlayout=layoutSpectra
end
end end
# WIP add an x and y input and a plot to select pixels in an image and then calculate a plot (not the sum of plots) # WIP add an x and y input and a plot to select pixels in an image and then calculate a plot (not the sum of plots)
@ -791,12 +933,12 @@ end
ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure julia returns the freed memory to OS ccall(:malloc_trim, Int32, (Int32,), 0) # Ensure julia returns the freed memory to OS
end end
end end
# == Pages == # ==Pages ==
# Register a new route and the page that will be loaded on access # Register a new route and the page that will be loaded on access
@page("/", "app.jl.html") @page("/", "app.jl.html")
end end
# == Advanced features == # ==Advanced features ==
#= #=
- The @private macro defines a reactive variable that is not sent to the browser. - The @private macro defines a reactive variable that is not sent to the browser.
This is useful for storing data that is unique to each user session but is not needed This is useful for storing data that is unique to each user session but is not needed

View File

@ -1,311 +1,354 @@
<template> <template>
<header id="header"> <header id="header">
<img src="/css/LABI_logo.jpeg" alt="Labi Logo Icon" id="imgLogo"> <img src="/css/LABI_logo.jpeg" alt="Labi Logo Icon" id="imgLogo">
<div> <div>
<h4>Julia mzML imzML analysis GUI&nbsp;</h4> <h4>Julia mzML imzML analysis GUI&nbsp;</h4>
<h6>Please make sure the ibd, the mzML and the imzML files are located in the same directory and have the same name.</h6> <h6>Please make sure the ibd, the mzML and the imzML files are located in the same directory and have the same
<h6>It may take a while to generate the image and the plot, please be patient.</h6> name.</h6>
<h6>To generate the contour or surface plots, you have to select the desired image first using the interface.</h6> <h6>It may take a while to generate the image and the plot, please be patient.</h6>
<h6>To generate the contour or surface plots, you have to select the desired image first using the interface.</h6>
</div>
</header>
<div id="extDivStyle" class="row col-12 q-pa-xl">
<div class="row col-6">
<!-- Left DIV -->
<div id="intDivStyle" class="st-col col-12 st-module">
<!--<q-input id="textRoute" standout="custom-standout" v-model="file_route" label="Insert the route to your imzML file"></q-input>-->
<h6>Search for your imzML file in your device</h6>
<q-btn id="btnStyle" icon="search" class="q-ma-sm" v-on:click="btnSearch=true"
label="Search in your device for the imzML file"></q-btn>
<!--<p>{{full_route}}</p>-->
<div class="row st-col col-12">
<!--<q-input id="textName" class="col-9" standout="custom-standout" v-model="file_name" label="Insert the name of your imzML file"></q-input>-->
<q-btn-dropdown id="btnStyle" class="q-ma-sm" :loading="progressPlot" :disable="btnPlotDisable"
label="Generate Plots" icon="play_arrow">
<template v-slot:loading>
<q-spinner-hourglass class="on-left" />
Loading Plot
</template>
<q-list>
<q-item clickable v-close-popup v-on:click="imageCPlot=true">
<q-item-section>
<q-item-label>Image Contour Plot</q-item-label>
</q-item-section>
</q-item>
<q-item clickable v-close-popup v-on:click="triqCPlot=true">
<q-item-section>
<q-item-label>TrIQ Contour Plot</q-item-label>
</q-item-section>
</q-item>
<q-item clickable v-close-popup v-on:click="image3dPlot=true">
<q-item-section>
<q-item-label>Image 3D Plot</q-item-label>
</q-item-section>
</q-item>
<q-item clickable v-close-popup v-on:click="triq3dPlot=true">
<q-item-section>
<q-item-label>TrIQ 3D Plot</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</div> </div>
</header> <p id="lblFullRoute">full route: {{full_route}}</p>
<div id="extDivStyle" class="row col-12 q-pa-xl"> <!-- Variable Manipulation -->
<div class="row col-7"> <div class="row">
<!-- Left DIV --> <div class="st-col col-12 col-sm q-ma-sm">
<div id="intDivStyle" class="st-col col-12 st-module"> <q-input standout="custom-standout" id="textNmass" step="0.01" v-model="Nmass"
<!--<q-file v-model="file_route" filled="" label="Select your imzML file" accept=".imzML"></q-file>--> label="Mass-to-charge ratio of interest" type="number"
<!--<q-input id="textRoute" standout="custom-standout" v-model="file_route" label="Insert the route to your imzML file"></q-input>--> :rules="[ val => !!val || '* Required', val => val >= 0.0 &amp;&amp; val <= 2000.0 || 'Need positive mass values',]"></q-input>
<h6>Search for your imzML file in your device</h6> </div>
<q-btn id="btnStyle" icon="search" class="q-ma-sm" v-on:click="btnSearch=true" label="Search in your device for the imzML file"></q-btn> <div class="st-col col-12 col-sm q-ma-sm">
<!--<p>{{full_route}}</p>--> <q-input standout="custom-standout" id="textTol" step="0.01" v-model="Tol"
<div class="row st-col col-12"> label="Mass-to-charge ratio tolerance" type="number"
<!--<q-input id="textName" class="col-9" standout="custom-standout" v-model="file_name" label="Insert the name of your imzML file"></q-input>--> :rules="[val => !!val || '* Required', val => val >= 0.0 &amp;&amp; val <= 1.0 || 'Needs to be in range between 0 and 1',]"></q-input>
<q-btn-dropdown </div>
id="btnStyle"
class="q-ma-sm"
:loading="progressPlot"
:disable="btnPlotDisable"
label="Generate Plots"
icon="play_arrow"
>
<template v-slot:loading>
<q-spinner-hourglass class="on-left" />
Loading Plot
</template>
<q-list>
<q-item clickable v-close-popup v-on:click="createSumPlot=true">
<q-item-section>
<q-item-label>Sum Spectrum Plot</q-item-label>
</q-item-section>
</q-item>
<q-item clickable v-close-popup v-on:click="imageCPlot=true">
<q-item-section>
<q-item-label>Image Contour Plot</q-item-label>
</q-item-section>
</q-item>
<q-item clickable v-close-popup v-on:click="triqCPlot=true">
<q-item-section>
<q-item-label>TrIQ Contour Plot</q-item-label>
</q-item-section>
</q-item>
<q-item clickable v-close-popup v-on:click="image3dPlot=true">
<q-item-section>
<q-item-label>Image 3D Plot</q-item-label>
</q-item-section>
</q-item>
<q-item clickable v-close-popup v-on:click="triq3dPlot=true">
<q-item-section>
<q-item-label>TrIQ 3D Plot</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</div>
<p id="lblFullRoute">full route: {{full_route}} {{warning_fr}}</p>
<!-- Variable Manipulation -->
<div class="row">
<div class="st-col col-12 col-sm">
<q-input standout="custom-standout" id="textNmass" step="0.01" v-model="Nmass" label="Mass-to-charge ratio of interest" type="number" :rules="[ val => !!val || '* Required', val => val >= 0.0 &amp;&amp; val <= 2000.0 || 'Need positive mass values',]"></q-input>
</div>
<div class="st-col col-12 col-sm">
<q-input standout="custom-standout" id="textTol" step="0.01" 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>
</div>
</div>
<div class="row">
<div class="st-col col-12 col-sm">
<q-toggle id="btnEnableTriq" v-on:click="triqEnabled" v-model="triqEnabled" color="blue" label="Add Threshold Intensity Quantization (TrIQ)!"></q-toggle>
</div>
</div>
<!-- Triq Variable Manipulation -->
<div class="row">
<div class="st-col col-12 col-sm-8">
<q-input standout="custom-standout" id="textTriqProb" step="0.01" v-model="triqProb" label="TrIQ probability" type="number" :rules="[
val => triqEnabled ? ( '* Required', val >= 0 &amp;&amp; val <= 1 || 'Needs to be in range between 0 and 1') : true
]" :readonly="!triqEnabled" :disable="!triqEnabled"></q-input>
</div>
<div class="st-col col-12 col-sm-4">
<q-input standout="custom-standout" id="textTriqColor" step="1" v-model="triqColor" label="TrIQ color levels" type="number" :rules="[
val => triqEnabled ? ( '* Required', val >= 0 &amp;&amp; val <= 256 || 'Needs to be in range between 1 and 256') : true
]" :readonly="!triqEnabled" :disable="!triqEnabled"></q-input>
</div>
</div>
<div class="row">
<q-btn id="btnStyle" :loading="progress" class="q-ma-sm" :disabled="btnStartDisable" icon="play_arrow" v-on:click="mainProcess=true" padding="lg" label="Main process">
<template v-slot:loading>
<q-spinner-hourglass class="on-left" />
Loading...
</template>
</q-btn>
<q-btn id="btnStyle" icon="zoom_out_map" class="q-ma-sm on-right" v-on:click="compareBtn=true" padding="sm" label="Compare"></q-btn>
</div>
<p>{{msg}}</p>
</div>
</div>
<div class="row col-5">
<!-- Right DIV -->
<div id="intDivStyle" class="st-col col-12 col-sm st-module">
<st-tabs id="tabHeader":ids="tabIDs" :labels="tabLabels" v-model="selectedTab" no-arrows></st-tabs>
<q-tab-panels v-model="selectedTab">
<q-tab-panel name="tab0">
<!-- Content for Tab 0 -->
<!-- Btn image changer -->
<h6>Image Visualizer</h6>
<div>
<q-btn id="btnStyle" icon="arrow_back" class="q-my-sm" v-on:click="imgMinus=true"></q-btn>
<q-btn id="btnStyle" icon="arrow_forward" class="q-my-sm on-right" v-on:click="imgPlus=true"></q-btn>
</div>
<!-- Image manager -->
<div id="image-container" class="row st-col col-12 items-center">
<div class="st-col col-10">
<q-img id="imgInt" class="q-ma-none q-pa-none" :src="imgInt" fit="scale-down"></q-img>
</div>
<div class="st-col col-2">
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbar"></q-img>
</div>
</div>
<p>{{msgimg}}</p>
</q-tab-panel>
<q-tab-panel name="tab1">
<!-- Content for Tab 1 -->
<!-- Triq Btn image changer -->
<h6>TrIQ Visualizer</h6>
<div>
<q-btn id="btnStyle" icon="arrow_back" class="q-my-sm" v-on:click="imgMinusT=true"></q-btn>
<q-btn id="btnStyle" icon="arrow_forward" class="q-my-sm on-right" v-on:click="imgPlusT=true"></q-btn>
</div>
<!-- Triq Image manager -->
<div id="image-container" class="row st-col col-12 items-center">
<div class="col-10">
<q-img id="imgInt" class="q-ma-none q-pa-none" :src="imgIntT" fit="scale-down"></q-img>
</div>
<div class="col-2">
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbarT"></q-img>
</div>
</div>
<p>{{msgtriq}}</p>
</q-tab-panel>
<q-tab-panel name="tab2">
<!-- Content for Tab 2 -->
<!--<plotly id="plotStyle" :data="plotdata" :layout="plotlayout" class="q-pa-none q-ma-none"></plotly>-->
<plotly id="plotStyle" :data="plotdata" :layout="plotlayout" @click="data_click" class="q-pa-none q-ma-none sync_data"></plotly>
</q-tab-panel>
<q-tab-panel name="tab3">
<!-- Content for Tab 3 -->
<plotly id="plotStyle" :data="plotdataC" :layout="plotlayoutC" class="q-pa-none q-ma-none"></plotly>
</q-tab-panel>
<q-tab-panel name="tab4">
<!-- Content for Tab 4 -->
<plotly id="plotStyle3d" :data="plotdata3d" :layout="plotlayout3d" class="q-pa-none q-ma-none"></plotly>
</q-tab-panel>
</q-tab-panels>
</div>
</div>
</div> </div>
<div class="row">
<q-dialog v-model="warning_msg"> <!-- Triq Variable Manipulation -->
<q-card> <div class="col-6">
<q-card-section> <div class="st-col col-6 col-sm q-ma-sm">
<div class="text-h6">Warning</div> <q-toggle id="btnEnableTriq" v-on:click="triqEnabled" v-model="triqEnabled" color="blue"
</q-card-section> label="Add Threshold Intensity Quantization (TrIQ)!"></q-toggle>
</div>
<q-card-section class="q-pt-none">
{{msg}}
</q-card-section>
<q-card-actions align="right">
<q-btn flat label="Ok" style="color:#009f90" v-close-popup />
</q-card-actions>
</q-card>
</q-dialog>
<q-dialog v-model="CompareDialog" full-width>
<q-card>
<q-card-section>
<div class="text-h6">Compare two diferent images or plots in a larger screen</div>
</q-card-section>
<q-card-section class="q-pt-none col-12">
<div class="row"> <div class="row">
<div class="col-6"> <div class="st-col col-4 col-sm-4 q-ma-sm">
<st-tabs id="tabHeader":ids="tabIDs" :labels="tabLabels" v-model="selectedTab"></st-tabs> <q-input standout="custom-standout" id="textTriqProb" step="0.01" v-model="triqProb"
<q-tab-panels v-model="selectedTab"> label="TrIQ probability" type="number" :rules="[
<q-tab-panel name="tab0"> val => triqEnabled ? ( '* Required', val >= 0 &amp;&amp; val <= 1 || 'Needs to be in range between 0 and 1') : true
<!-- Content for Tab 0 --> ]" :readonly="!triqEnabled" :disable="!triqEnabled"></q-input>
<!-- Btn image changer --> </div>
<div> <div class="st-col col-4 col-sm-4 q-ma-sm">
<q-btn id="btnStyle" icon="arrow_back" class="q-my-sm" v-on:click="imgMinus=true"></q-btn> <q-input standout="custom-standout" id="textTriqColor" step="1" v-model="triqColor"
<q-btn id="btnStyle" icon="arrow_forward" class="q-my-sm on-right" v-on:click="imgPlus=true"></q-btn> label="TrIQ color levels" type="number" :rules="[
</div> val => triqEnabled ? ( '* Required', val >= 0 &amp;&amp; val <= 256 || 'Needs to be in range between 1 and 256') : true
<!-- Image manager --> ]" :readonly="!triqEnabled" :disable="!triqEnabled"></q-input>
<div id="image-container" class="row st-col col-12 items-center"> </div>
<div class="st-col col-10">
<q-img id="imgInt" class="q-ma-none q-pa-none" :src="imgInt" fit="scale-down"></q-img>
</div>
<div class="st-col col-2">
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbar"></q-img>
</div>
</div>
<p>{{msgimg}}</p>
</q-tab-panel>
<q-tab-panel name="tab1">
<!-- Content for Tab 1 -->
<!-- Triq Btn image changer -->
<div>
<q-btn id="btnStyle" icon="arrow_back" class="q-my-sm" v-on:click="imgMinusT=true"></q-btn>
<q-btn id="btnStyle" icon="arrow_forward" class="q-my-sm on-right" v-on:click="imgPlusT=true"></q-btn>
</div>
<!-- Triq Image manager -->
<div id="image-container" class="row st-col col-12 items-center">
<div class="col-10">
<q-img id="imgInt" class="q-ma-none q-pa-none" :src="imgIntT" fit="scale-down"></q-img>
</div>
<div class="col-2">
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbarT"></q-img>
</div>
</div>
<p>{{msgtriq}}</p>
</q-tab-panel>
<q-tab-panel name="tab2">
<!-- Content for Tab 2 -->
<plotly id="plotStyle" :data="plotdata" :layout="plotlayout" class="q-pa-none q-ma-none"></plotly>
</q-tab-panel>
<q-tab-panel name="tab3">
<!-- Content for Tab 3 -->
<plotly id="plotStyle" :data="plotdataC" :layout="plotlayoutC" class="q-pa-none q-ma-none"></plotly>
</q-tab-panel>
<q-tab-panel name="tab4">
<!-- Content for Tab 4 -->
<plotly id="plotStyle3d" :data="plotdata3d" :layout="plotlayout3d" class="q-pa-none q-ma-none"></plotly>
</q-tab-panel>
</q-tab-panels>
</div>
<div class="col-6">
<st-tabs id="tabHeader" :ids="CompTabIDs" :labels="CompTabLabels" v-model="CompSelectedTab" outside-arrows mobile-arrows></st-tabs>
<q-tab-panels v-model="CompSelectedTab">
<q-tab-panel name="tab0">
<!-- Content for Tab 0 -->
<!-- Btn image changer -->
<div>
<q-btn id="btnStyle" icon="arrow_back" class="q-my-sm" v-on:click="imgMinus=true"></q-btn>
<q-btn id="btnStyle" icon="arrow_forward" class="q-my-sm on-right" v-on:click="imgPlus=true"></q-btn>
</div>
<!-- Image manager -->
<div id="image-container" class="row st-col col-12 items-center">
<div class="st-col col-10">
<q-img id="imgInt" class="q-ma-none q-pa-none" :src="imgInt" fit="scale-down"></q-img>
</div>
<div class="st-col col-2">
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbar"></q-img>
</div>
</div>
<p>{{msgimg}}</p>
</q-tab-panel>
<q-tab-panel name="tab1">
<!-- Content for Tab 1 -->
<!-- Triq Btn image changer -->
<div>
<q-btn id="btnStyle" icon="arrow_back" class="q-my-sm" v-on:click="imgMinusT=true"></q-btn>
<q-btn id="btnStyle" icon="arrow_forward" class="q-my-sm on-right" v-on:click="imgPlusT=true"></q-btn>
</div>
<!-- Triq Image manager -->
<div id="image-container" class="row st-col col-12 items-center">
<div class="col-10">
<q-img id="imgInt" class="q-ma-none q-pa-none" :src="imgIntT" fit="scale-down"></q-img>
</div>
<div class="col-2">
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbarT"></q-img>
</div>
</div>
<p>{{msgtriq}}</p>
</q-tab-panel>
<q-tab-panel name="tab2">
<!-- Content for Tab 2 -->
<plotly id="plotStyle" :data="plotdata" :layout="plotlayout" class="q-pa-none q-ma-none"></plotly>
</q-tab-panel>
<q-tab-panel name="tab3">
<!-- Content for Tab 3 -->
<plotly id="plotStyle" :data="plotdataC" :layout="plotlayoutC" class="q-pa-none q-ma-none"></plotly>
</q-tab-panel>
<q-tab-panel name="tab4">
<!-- Content for Tab 4 -->
<plotly id="plotStyle3d" :data="plotdata3d" :layout="plotlayout3d" class="q-pa-none q-ma-none"></plotly>
</q-tab-panel>
</q-tab-panels>
</div>
</div> </div>
</q-card-section> </div>
<!-- Spectra Plot Manipulation -->
<div class="col-6">
<div class="st-col col-6 col-sm">
<q-btn-dropdown id="btnStyle" class="q-ma-sm" :loading="progressSpectraPlot" :disable="btnSpectraDisable"
label="Generate Spectra" icon="play_arrow">
<template v-slot:loading>
<q-spinner-hourglass class="on-left" />
Loading Plot
</template>
<q-card-actions align="right"> <q-list>
<q-btn flat label="Done" style="color:#009f90" v-close-popup /> <q-item clickable v-close-popup v-on:click="createSumPlot=true">
</q-card-actions> <q-item-section>
</q-card> <q-item-label>Sum Spectrum Plot</q-item-label>
</q-dialog> </q-item-section>
</q-item>
<q-item clickable v-close-popup v-on:click="createXYPlot=true">
<q-item-section>
<q-item-label>Spectrum Plot (X,Y)</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</div>
<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="xCoord" label="X coord"
type="number" :rules="[
val => SpectraEnabled ? ( '* Required', val >= 0|| 'Needs to be bigger than 0') : true
]" :readonly="!SpectraEnabled" :disable="!SpectraEnabled"></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
]" :readonly="!SpectraEnabled" :disable="!SpectraEnabled"></q-input>
</div>
</div>
</div>
</div>
<div class="row">
<q-btn id="btnStyle" :loading="progress" class="q-ma-sm" :disabled="btnStartDisable" icon="play_arrow"
v-on:click="mainProcess=true" padding="lg" label="Main process">
<template v-slot:loading>
<q-spinner-hourglass class="on-left" />
Loading...
</template>
</q-btn>
<q-btn id="btnStyle" icon="zoom_out_map" class="q-ma-sm on-right" v-on:click="compareBtn=true" padding="sm"
label="Compare"></q-btn>
</div>
<p>{{msg}}</p>
</div>
</div>
<div class="row col-6">
<!-- Right DIV -->
<div id="intDivStyle" class="st-col col-12 col-sm st-module">
<st-tabs id="tabHeader" :ids="tabIDs" :labels="tabLabels" v-model="selectedTab" no-arrows></st-tabs>
<q-tab-panels v-model="selectedTab">
<q-tab-panel name="tab0">
<!-- Content for Tab 0 -->
<!-- Btn image changer -->
<h6>Image Visualizer</h6>
<div>
<q-btn id="btnStyle" icon="arrow_back" class="q-my-sm" v-on:click="imgMinus=true"></q-btn>
<q-btn id="btnStyle" icon="arrow_forward" class="q-my-sm on-right" v-on:click="imgPlus=true"></q-btn>
</div>
<!-- Image manager -->
<div id="image-container" class="row st-col col-12">
<div class="col-10">
<q-img id="imgInt" class="q-ma-none q-pa-none" :src="imgInt" width="80%"></q-img>
</div>
<div class="col-2">
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbar"></q-img>
</div>
</div>
<p>{{msgimg}}</p>
</q-tab-panel>
</template> <q-tab-panel name="tab1">
<!-- Content for Tab 1 -->
<!-- Triq Btn image changer -->
<h6>TrIQ Visualizer</h6>
<div>
<q-btn id="btnStyle" icon="arrow_back" class="q-my-sm" v-on:click="imgMinusT=true"></q-btn>
<q-btn id="btnStyle" icon="arrow_forward" class="q-my-sm on-right" v-on:click="imgPlusT=true"></q-btn>
</div>
<!-- Triq Image manager -->
<div id="image-container" class="row st-col col-12">
<div class="col-10">
<q-img id="imgInt" class="q-ma-none q-pa-none" :src="imgIntT" width="80%"></q-img>
</div>
<div class="col-2">
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbarT"></q-img>
</div>
</div>
<p>{{msgtriq}}</p>
</q-tab-panel>
<q-tab-panel name="tab2">
<!-- Content for Tab 2 -->
<!--<plotly id="plotStyle" :data="plotdata" :layout="plotlayout" class="q-pa-none q-ma-none"></plotly>-->
<plotly id="plotStyle" :data="plotdata" :layout="plotlayout" @click="data_click"
class="q-pa-none q-ma-none sync_data"></plotly>
</q-tab-panel>
<q-tab-panel name="tab3">
<!-- Content for Tab 3 -->
<plotly id="plotStyle" :data="plotdataC" :layout="plotlayoutC" class="q-pa-none q-ma-none"></plotly>
</q-tab-panel>
<q-tab-panel name="tab4">
<!-- Content for Tab 4 -->
<plotly id="plotStyle3d" :data="plotdata3d" :layout="plotlayout3d" class="q-pa-none q-ma-none"></plotly>
</q-tab-panel>
</q-tab-panels>
</div>
</div>
</div>
<q-dialog v-model="warning_msg">
<q-card>
<q-card-section>
<div class="text-h6">Warning</div>
</q-card-section>
<q-card-section class="q-pt-none">
{{msg}}
</q-card-section>
<q-card-actions align="right">
<q-btn flat label="Ok" style="color:#009f90" v-close-popup />
</q-card-actions>
</q-card>
</q-dialog>
<q-dialog v-model="CompareDialog" full-width>
<q-card>
<q-card-section>
<div class="text-h6">Compare two diferent images or plots in a larger screen</div>
</q-card-section>
<q-card-section class="q-pt-none col-12">
<div class="row">
<div class="col-6">
<st-tabs id="tabHeader" :ids="tabIDs" :labels="tabLabels" v-model="selectedTab"></st-tabs>
<q-tab-panels v-model="selectedTab">
<q-tab-panel name="tab0">
<!-- Content for Tab 0 -->
<!-- Btn image changer -->
<div>
<q-btn id="btnStyle" icon="arrow_back" class="q-my-sm" v-on:click="imgMinus=true"></q-btn>
<q-btn id="btnStyle" icon="arrow_forward" class="q-my-sm on-right" v-on:click="imgPlus=true"></q-btn>
</div>
<!-- Image manager -->
<div id="image-container" class="row st-col col-12">
<div class="st-col col-10">
<q-img id="imgInt" class="q-ma-none q-pa-none" :src="imgInt" width="80%"></q-img>
</div>
<div class="st-col col-2">
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbar"></q-img>
</div>
</div>
<p>{{msgimg}}</p>
</q-tab-panel>
<q-tab-panel name="tab1">
<!-- Content for Tab 1 -->
<!-- Triq Btn image changer -->
<div>
<q-btn id="btnStyle" icon="arrow_back" class="q-my-sm" v-on:click="imgMinusT=true"></q-btn>
<q-btn id="btnStyle" icon="arrow_forward" class="q-my-sm on-right" v-on:click="imgPlusT=true"></q-btn>
</div>
<!-- Triq Image manager -->
<div id="image-container" class="row st-col col-12">
<div class="col-10">
<q-img id="imgInt" class="q-ma-none q-pa-none" :src="imgIntT" width="80%"></q-img>
</div>
<div class="col-2">
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbarT"></q-img>
</div>
</div>
<p>{{msgtriq}}</p>
</q-tab-panel>
<q-tab-panel name="tab2">
<!-- Content for Tab 2 -->
<plotly id="plotStyle" :data="plotdata" :layout="plotlayout" class="q-pa-none q-ma-none"></plotly>
</q-tab-panel>
<q-tab-panel name="tab3">
<!-- Content for Tab 3 -->
<plotly id="plotStyle" :data="plotdataC" :layout="plotlayoutC" class="q-pa-none q-ma-none"></plotly>
</q-tab-panel>
<q-tab-panel name="tab4">
<!-- Content for Tab 4 -->
<plotly id="plotStyle3d" :data="plotdata3d" :layout="plotlayout3d" class="q-pa-none q-ma-none"></plotly>
</q-tab-panel>
</q-tab-panels>
</div>
<div class="col-6">
<st-tabs id="tabHeader" :ids="CompTabIDs" :labels="CompTabLabels" v-model="CompSelectedTab" outside-arrows
mobile-arrows></st-tabs>
<q-tab-panels v-model="CompSelectedTab">
<q-tab-panel name="tab0">
<!-- Content for Tab 0 -->
<!-- Btn image changer -->
<div>
<q-btn id="btnStyle" icon="arrow_back" class="q-my-sm" v-on:click="imgMinus=true"></q-btn>
<q-btn id="btnStyle" icon="arrow_forward" class="q-my-sm on-right" v-on:click="imgPlus=true"></q-btn>
</div>
<!-- Image manager -->
<div id="image-container" class="row st-col col-12">
<div class="st-col col-10">
<q-img id="imgInt" class="q-ma-none q-pa-none" :src="imgInt" width="80%"></q-img>
</div>
<div class="st-col col-2">
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbar"></q-img>
</div>
</div>
<p>{{msgimg}}</p>
</q-tab-panel>
<q-tab-panel name="tab1">
<!-- Content for Tab 1 -->
<!-- Triq Btn image changer -->
<div>
<q-btn id="btnStyle" icon="arrow_back" class="q-my-sm" v-on:click="imgMinusT=true"></q-btn>
<q-btn id="btnStyle" icon="arrow_forward" class="q-my-sm on-right" v-on:click="imgPlusT=true"></q-btn>
</div>
<!-- Triq Image manager -->
<div id="image-container" class="row st-col col-12">
<div class="col-10">
<q-img id="imgInt" class="q-ma-none q-pa-none" :src="imgIntT" width="80%"></q-img>
</div>
<div class="col-2">
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbarT"></q-img>
</div>
</div>
<p>{{msgtriq}}</p>
</q-tab-panel>
<q-tab-panel name="tab2">
<!-- Content for Tab 2 -->
<plotly id="plotStyle" :data="plotdata" :layout="plotlayout" class="q-pa-none q-ma-none"></plotly>
</q-tab-panel>
<q-tab-panel name="tab3">
<!-- Content for Tab 3 -->
<plotly id="plotStyle" :data="plotdataC" :layout="plotlayoutC" class="q-pa-none q-ma-none"></plotly>
</q-tab-panel>
<q-tab-panel name="tab4">
<!-- Content for Tab 4 -->
<plotly id="plotStyle3d" :data="plotdata3d" :layout="plotlayout3d" class="q-pa-none q-ma-none"></plotly>
</q-tab-panel>
</q-tab-panels>
</div>
</div>
</q-card-section>
<q-card-actions align="right">
<q-btn flat label="Done" style="color:#009f90" v-close-popup />
</q-card-actions>
</q-card>
</q-dialog>
</template>

View File

@ -4,8 +4,7 @@ PENDING
Create function that makes the imzML from mzML files ? Create function that makes the imzML from mzML files ?
Possibility to add multiple imzML to process at once ? Possibility to add multiple imzML to process at once ?
Per pixel of image plot creation for spectra Per pixel of image plot creation for spectra
Multiple spectra plot types Add comparison image (rotate, transform, translate, transparency) CURRENTLY ONGOING
Even faster initial boot and subsectuential boot
DONE DONE
Quicker start for julia GUI Quicker start for julia GUI
@ -19,8 +18,10 @@ DONE
3d topology plots for images 3d topology plots for images
2d contour plots for images 2d contour plots for images
Image flip upside down Image flip upside down
Tag for time it takes in creating image and creating plots Measure for the time it takes creating image or plot
Rotate vertical images Rotate vertical images
Easier input for files Easier input for files
TrIQ default values TrIQ default values
Comparative for two views Comparative for two views
Even faster initial boot and subsectuential boot
Multiple spectra plot types

View File

@ -1,13 +1,25 @@
using Pkg using Pkg
Pkg.activate(".") Pkg.activate(".")
Pkg.instantiate() Pkg.instantiate()
Pkg.update()
Pkg.gc() Pkg.gc()
Pkg.add("Libz") ; Pkg.add("PlotlyBase") ; Pkg.add("CairoMakie") ; Pkg.add("Colors") ; Pkg.add("Statistics") ; Pkg.add("NaturalSort") ; Pkg.add("GenieFramework") ;Pkg.add("Genie")
Pkg.add(url="https://github.com/CINVESTAV-LABI/julia_mzML_imzML") # With this we ensure it uses the latest library iteration packages = [
Pkg.add("Images") ; Pkg.add("LinearAlgebra") "GenieFramework", "Libz", "PlotlyBase", "CairoMakie", "Colors",
Pkg.add("NativeFileDialog") "Statistics", "NaturalSort", "Genie",
Pkg.add("StipplePlotly") "Images", "LinearAlgebra", "NativeFileDialog", "StipplePlotly"
]
# Check for missing packages
for pkg in packages
if !(pkg in keys(Pkg.dependencies()))
Pkg.add(pkg)
end
end
# Add library for mzML imzML from GitHub if missing
if !("julia_mzML_imzML" in keys(Pkg.dependencies()))
Pkg.add(url="https://github.com/CINVESTAV-LABI/julia_mzML_imzML")
end
using Genie using Genie
@ -27,3 +39,5 @@ Genie.loadapp()
@async run(`start $url`) # For Windows @async run(`start $url`) # For Windows
end end
end end
wait()