Better image search, 3d images ongoing

This commit is contained in:
Pixelguy14 2025-01-13 00:56:12 -06:00
parent 04f7a107da
commit e5b796fce0
4 changed files with 313 additions and 123 deletions

View File

@ -539,9 +539,9 @@ version = "18.1.7+0"
[[deps.LZO_jll]] [[deps.LZO_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"] deps = ["Artifacts", "JLLWrappers", "Libdl"]
git-tree-sha1 = "854a9c268c43b77b0a27f22d7fab8d33cdb3a731" git-tree-sha1 = "1c602b1127f4751facb671441ca72715cc95938a"
uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac"
version = "2.10.2+3" version = "2.10.3+0"
[[deps.LaTeXStrings]] [[deps.LaTeXStrings]]
git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c"
@ -630,9 +630,9 @@ version = "1.17.0+1"
[[deps.Libmount_jll]] [[deps.Libmount_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"] deps = ["Artifacts", "JLLWrappers", "Libdl"]
git-tree-sha1 = "84eef7acd508ee5b3e956a2ae51b05024181dee0" git-tree-sha1 = "89211ea35d9df5831fca5d33552c02bd33878419"
uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9"
version = "2.40.2+2" version = "2.40.3+0"
[[deps.Libtiff_jll]] [[deps.Libtiff_jll]]
deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"]
@ -642,9 +642,9 @@ version = "4.5.1+1"
[[deps.Libuuid_jll]] [[deps.Libuuid_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"] deps = ["Artifacts", "JLLWrappers", "Libdl"]
git-tree-sha1 = "edbf5309f9ddf1cab25afc344b1e8150b7c832f9" git-tree-sha1 = "e888ad02ce716b319e6bdb985d2ef300e7089889"
uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700"
version = "2.40.2+2" version = "2.40.3+0"
[[deps.Libz]] [[deps.Libz]]
deps = ["BufferedStreams", "Random", "Test"] deps = ["BufferedStreams", "Random", "Test"]
@ -771,9 +771,9 @@ version = "1.0.0"
[[deps.Nettle_jll]] [[deps.Nettle_jll]]
deps = ["Artifacts", "GMP_jll", "JLLWrappers", "Libdl"] deps = ["Artifacts", "GMP_jll", "JLLWrappers", "Libdl"]
git-tree-sha1 = "19961ade0a39b98575505bed6f842e8a0ec35af9" git-tree-sha1 = "fd4678a4bd1f7156c98691200fab47c76b376360"
uuid = "4c82536e-c426-54e4-b420-14f461c4ed8b" uuid = "4c82536e-c426-54e4-b420-14f461c4ed8b"
version = "3.10.0+2" version = "3.10.1+0"
[[deps.NetworkOptions]] [[deps.NetworkOptions]]
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
@ -1366,9 +1366,9 @@ version = "1.8.6+3"
[[deps.Xorg_libXau_jll]] [[deps.Xorg_libXau_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"] deps = ["Artifacts", "JLLWrappers", "Libdl"]
git-tree-sha1 = "2b0e27d52ec9d8d483e2ca0b72b3cb1a8df5c27a" git-tree-sha1 = "e9216fdcd8514b7072b43653874fd688e4c6c003"
uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec"
version = "1.0.11+3" version = "1.0.12+0"
[[deps.Xorg_libXcursor_jll]] [[deps.Xorg_libXcursor_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"]
@ -1378,9 +1378,9 @@ version = "1.2.3+0"
[[deps.Xorg_libXdmcp_jll]] [[deps.Xorg_libXdmcp_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"] deps = ["Artifacts", "JLLWrappers", "Libdl"]
git-tree-sha1 = "02054ee01980c90297412e4c809c8694d7323af3" git-tree-sha1 = "89799ae67c17caa5b3b5a19b8469eeee474377db"
uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05"
version = "1.1.4+3" version = "1.1.5+0"
[[deps.Xorg_libXext_jll]] [[deps.Xorg_libXext_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"]
@ -1420,9 +1420,9 @@ version = "0.9.11+1"
[[deps.Xorg_libpthread_stubs_jll]] [[deps.Xorg_libpthread_stubs_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"] deps = ["Artifacts", "JLLWrappers", "Libdl"]
git-tree-sha1 = "fee57a273563e273f0f53275101cd41a8153517a" git-tree-sha1 = "c57201109a9e4c0585b208bb408bc41d205ac4e9"
uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74"
version = "0.1.1+3" version = "0.1.2+0"
[[deps.Xorg_libxcb_jll]] [[deps.Xorg_libxcb_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"]
@ -1486,9 +1486,9 @@ version = "2.39.0+0"
[[deps.Xorg_xtrans_jll]] [[deps.Xorg_xtrans_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"] deps = ["Artifacts", "JLLWrappers", "Libdl"]
git-tree-sha1 = "b9ead2d2bdb27330545eb14234a2e300da61232e" git-tree-sha1 = "6dba04dbfb72ae3ebe5418ba33d087ba8aa8cb00"
uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10"
version = "1.5.0+3" version = "1.5.1+0"
[[deps.YAML]] [[deps.YAML]]
deps = ["Base64", "Dates", "Printf", "StringEncodings"] deps = ["Base64", "Dates", "Printf", "StringEncodings"]

317
app.jl
View File

@ -8,6 +8,8 @@ using CairoMakie
using Colors using Colors
using julia_mzML_imzML using julia_mzML_imzML
using Statistics using Statistics
using NaturalSort
# using ImageMagick
@genietools @genietools
# == Code import == # == Code import ==
@ -15,6 +17,25 @@ using Statistics
# automatically loaded # automatically loaded
rgb_ViridisPalette = reinterpret(ColorTypes.RGB24, ViridisPalette) rgb_ViridisPalette = reinterpret(ColorTypes.RGB24, ViridisPalette)
# == Search functions ==
function increment_image(current_image, image_list)
current_index = findfirst(isequal(current_image), image_list)
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
else
return image_list[current_index + 1] # Move to the next image
end
end
function decrement_image(current_image, image_list)
current_index = findfirst(isequal(current_image), image_list)
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
else
return image_list[current_index - 1] # Move to the previous image
end
end
# == Reactive code == # == Reactive code ==
# reactive code to make the UI interactive # reactive code to make the UI interactive
@app begin @app begin
@ -27,7 +48,7 @@ rgb_ViridisPalette =reinterpret(ColorTypes.RGB24, ViridisPalette)
# Interface non Variables # Interface non Variables
@out warning_fr = "" @out warning_fr = ""
@out btnStartDisable = false @out btnStartDisable = true
@out btnPlotDisable = true @out btnPlotDisable = true
@in warning_msg = false @in warning_msg = false
@ -40,8 +61,10 @@ rgb_ViridisPalette =reinterpret(ColorTypes.RGB24, ViridisPalette)
@in triqColor = 0 @in triqColor = 0
# Interface Buttons # Interface Buttons
@in Main_Process = false # To generate images @in mainProcess = false # To generate images
@in Generate_Plot = false # To generate plot @in createSumPlot = false # To generate sum spectrum plot
@in image3dPlot = false # To generate 3d plot based on current image
@in triq3dPlot = false # To generate 3d plot based on current triq image
@in progress = false @in progress = false
@in progressPlot = false @in progressPlot = false
@in triqEnabled = false @in triqEnabled = false
@ -50,12 +73,6 @@ rgb_ViridisPalette =reinterpret(ColorTypes.RGB24, ViridisPalette)
@in ImgPlusT = false @in ImgPlusT = false
@in ImgMinusT = false @in ImgMinusT = false
@out indeximg = 0
@out indeximgTriq = 0
@out lastimg = 0
@out lastimgTriq = 0
# 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
@ -70,11 +87,28 @@ rgb_ViridisPalette =reinterpret(ColorTypes.RGB24, ViridisPalette)
@out full_routeMz = "" @out full_routeMz = ""
@out full_routeMz2 = "" @out full_routeMz2 = ""
# WIP # For the creation of images with a more specific mass charge
@out int_nmass = 0 @out text_nmass = ""
@out dec_nmass = 0.0
# Interface Plot # 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
@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
@out current_msi = ""
@out current_col_msi = ""
@out current_triq = ""
@out current_col_triq = ""
@out indeximg = 0
@out indeximgTriq = 0
@out lastimg = 0
@out lastimgTriq = 0
# Interface Plot 2d
layoutSpectra = PlotlyBase.Layout( layoutSpectra = PlotlyBase.Layout(
title = "SUM Spectrum plot", title = "SUM Spectrum plot",
xaxis = PlotlyBase.attr( xaxis = PlotlyBase.attr(
@ -86,22 +120,42 @@ rgb_ViridisPalette =reinterpret(ColorTypes.RGB24, ViridisPalette)
showgrid = true showgrid = true
) )
) )
# Dummy 2D surface plot
traceSpectra = PlotlyBase.scatter(x=[], y=[], mode="lines") traceSpectra = PlotlyBase.scatter(x=[], y=[], mode="lines")
# Create conection to frontend
@out plotdata = [traceSpectra] @out plotdata = [traceSpectra]
@out plotlayout = layoutSpectra @out plotlayout = layoutSpectra
# Interface Plot 3d
# Define the layout for the 3D plot
layout3D = PlotlyBase.Layout(
title = "3D Surface Plot",
scene = attr(
xaxis_title = "X",
yaxis_title = "Y",
zaxis_title = "Z"
)
)
# Dummy 3D surface plot
trace3D = PlotlyBase.surface(x=[1:10], y=[1:10], z=[1:10], colorscale="Viridis")
# Create conection to frontend
@out plotdata3d = [trace3D]
@out plotlayout3d = layout3D
# println("3D trace defined: ", trace3D)
# == 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
"""
@onchange triqEnabled begin @onchange triqEnabled begin
if !triqEnabled # just in case that they remove an image manually, we use the least intensive button to get all images and re-order them.
#triqProb = 0.0 msi_bmp = sort(filter(filename -> startswith(filename, "MSI_") && endswith(filename, ".bmp"), readdir("public")),lt=natural)
#triqColor = 0 col_msi_png = sort(filter(filename -> startswith(filename, "colorbar_MSI_") && endswith(filename, ".png"), readdir("public")),lt=natural)
triq_bmp = sort(filter(filename -> startswith(filename, "TrIQ_") && endswith(filename, ".bmp"), readdir("public")),lt=natural)
col_triq_png = sort(filter(filename -> startswith(filename, "colorbar_TrIQ_") && endswith(filename, ".png"), readdir("public")),lt=natural)
end end
end
"""
@onchange file_name begin @onchange file_name begin
msg = "" msg = ""
@ -136,10 +190,11 @@ rgb_ViridisPalette =reinterpret(ColorTypes.RGB24, ViridisPalette)
end end
""" """
@onbutton Main_Process begin @onbutton mainProcess begin
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
indeximg = floor(Int, Nmass) indeximg = floor(Int, Nmass)
text_nmass = replace(string(Nmass), "." => "_")
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."
@ -155,26 +210,48 @@ rgb_ViridisPalette =reinterpret(ColorTypes.RGB24, ViridisPalette)
msg = "Incorrect TrIQ values, please adjust accordingly and try again." msg = "Incorrect TrIQ values, please adjust accordingly and try again."
warning_msg = true warning_msg = true
else else
SaveBitmap(joinpath("public", "TrIQ_$(floor(Int, Nmass)).bmp"),TrIQ(slice, Int(triqColor), triqProb),ViridisPalette) SaveBitmap(joinpath("public", "TrIQ_$(text_nmass).bmp"),TrIQ(slice, Int(triqColor), triqProb),ViridisPalette)
# Use timestamp to refresh image interface container # Use timestamp to refresh image interface container
imgIntT = "/TrIQ_$(floor(Int, Nmass)).bmp?t=$(timestamp)" imgIntT = "/TrIQ_$(text_nmass).bmp?t=$(timestamp)"
msgtriq = "TrIQ image with the Nmass of $(floor(Int, Nmass))" # Get current image
current_triq = "TrIQ_$(text_nmass).bmp"
msgtriq = "TrIQ image with the Nmass of $(replace(text_nmass, "_" => "."))"
# Create colorbar
ticks = round.(range(0, stop = maximum(TrIQ(slice, Int(triqColor), triqProb)), length = 10), digits = 2) ticks = round.(range(0, stop = maximum(TrIQ(slice, Int(triqColor), triqProb)), length = 10), digits = 2)
Colorbar(fig[1, 1], colormap = rgb_ViridisPalette, limits = (0, maximum(TrIQ(slice, Int(triqColor), triqProb))),ticks = ticks, label = "Intensity") Colorbar(fig[1, 1], colormap = rgb_ViridisPalette, limits = (0, maximum(TrIQ(slice, Int(triqColor), triqProb))),ticks = ticks, label = "Intensity")
save("public/colorbar_TrIQ_$(floor(Int, Nmass)).png", fig) save("public/colorbar_TrIQ_$(text_nmass).png", fig)
colorbarT = "/colorbar_TrIQ_$(text_nmass).png?t=$(timestamp)"
# Get current colorbar
current_col_triq = "colorbar_TrIQ_$(text_nmass).png"
# We update the directory to include the new placed images.
triq_bmp = sort(filter(filename -> startswith(filename, "TrIQ_") && endswith(filename, ".bmp"), readdir("public")),lt=natural)
col_triq_png = sort(filter(filename -> startswith(filename, "colorbar_TrIQ_") && endswith(filename, ".png"), readdir("public")),lt=natural)
msg = "The file has been created successfully inside the 'public' folder of the app." msg = "The file has been created successfully inside the 'public' folder of the app."
colorbarT = "/colorbar_TrIQ_$(floor(Int, Nmass)).png?t=$(timestamp)" #println("all msi in folder = ",triq_bmp)
#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
SaveBitmap(joinpath("public", "MSI_$(floor(Int, Nmass)).bmp"),IntQuant(slice),ViridisPalette) SaveBitmap(joinpath("public", "MSI_$(text_nmass).bmp"),IntQuant(slice),ViridisPalette)
# Use timestamp to refresh image interface container # Use timestamp to refresh image interface container
imgInt = "/MSI_$(floor(Int, Nmass)).bmp?t=$(timestamp)" imgInt = "/MSI_$(text_nmass).bmp?t=$(timestamp)"
msgimg = "image with the Nmass of $(floor(Int, Nmass))" # Get current image
current_msi = "MSI_$(text_nmass).bmp"
msgimg = "image with the Nmass of $(replace(text_nmass, "_" => "."))"
# Create colorbar
ticks = round.(range(0, stop = maximum(slice), length = 10), digits = 2) ticks = round.(range(0, stop = maximum(slice), length = 10), digits = 2)
Colorbar(fig[1, 1], colormap = rgb_ViridisPalette, limits = (0, maximum(slice)),ticks = ticks, label = "Intensity") Colorbar(fig[1, 1], colormap = rgb_ViridisPalette, limits = (0, maximum(slice)),ticks = ticks, label = "Intensity")
save("public/colorbar_MSI_$(floor(Int, Nmass)).png", fig) save("public/colorbar_MSI_$(text_nmass).png", fig)
colorbar = "/colorbar_MSI_$(text_nmass).png?t=$(timestamp)"
# Get current colorbar
current_col_msi = "colorbar_MSI_$(text_nmass).png"
# We update the directory to include the new placed images.
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)
msg = "The file has been created successfully inside the 'public' folder of the app." msg = "The file has been created successfully inside the 'public' folder of the app."
colorbar = "/colorbar_MSI_$(floor(Int, Nmass)).png?t=$(timestamp)" #println("all msi in folder = ",msi_bmp)
#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)"
@ -194,8 +271,8 @@ rgb_ViridisPalette =reinterpret(ColorTypes.RGB24, ViridisPalette)
progress = false progress = false
end end
@onbutton Generate_Plot begin @onbutton createSumPlot begin
msg = "" msg = "Sum spectrum plot selected"
full_route = joinpath( file_route, file_name ) full_route = joinpath( file_route, file_name )
progressPlot = true progressPlot = true
if isfile(full_route) # Check if the file exists if isfile(full_route) # Check if the file exists
@ -203,6 +280,7 @@ rgb_ViridisPalette =reinterpret(ColorTypes.RGB24, ViridisPalette)
btnStartDisable = false btnStartDisable = false
full_routeMz = split( full_route, "." )[1] * ".mzML" # Splitting the route from imzml to mzml so the plotting can work full_routeMz = split( full_route, "." )[1] * ".mzML" # Splitting the route from imzml to mzml so the plotting can work
if isfile(full_routeMz) && (full_routeMz2 == "" || full_routeMz2 != full_routeMz) # Check if the mzml exists if isfile(full_routeMz) && (full_routeMz2 == "" || full_routeMz2 != full_routeMz) # Check if the mzml exists
println("I'm working as intended")
btnPlotDisable = true btnPlotDisable = true
msg = "Loading plot..." msg = "Loading plot..."
spectraMz = LoadMzml(full_routeMz) spectraMz = LoadMzml(full_routeMz)
@ -227,61 +305,146 @@ rgb_ViridisPalette =reinterpret(ColorTypes.RGB24, ViridisPalette)
progressPlot = false progressPlot = false
end end
# WIP THESE NEED TO CHANGE, A BETTER BLIND SEARCH AND ALLOWANCE FOR DECIMAL IMAGES # Image loaders based on the position of the current image (increment and decrement for both normal and filter)
# Also needs to implement timestamp to force reload of image and update if needed. # And a pre-generated list from all image files from /public folder
@onbutton ImgMinus begin @onbutton ImgMinus begin
indeximg-=1 # Append a query string to force the image to refresh
while !isfile("public/MSI_$(indeximg).bmp") && indeximg > 0 timestamp = string(time_ns())
indeximg -= 1 new_msi = decrement_image(current_msi, msi_bmp)
end new_col_msi = decrement_image(current_col_msi, col_msi_png)
if(indeximg <= 0) # If it doesn't find a lower value image
indeximg = lastimg current_msi = new_msi
end current_col_msi = new_col_msi
imgInt = "/MSI_$(indeximg).bmp" imgInt = "/$(current_msi)?t=$(timestamp)"
colorbar = "/colorbar_MSI_$(indeximg).png" colorbar = "/$(current_col_msi)?t=$(timestamp)"
msgimg = "image with the Nmass of $(indeximg)"
lastimg = indeximg text_nmass = replace(current_msi, "MSI_" => "")
text_nmass = replace(text_nmass, ".bmp" => "")
msgimg = "image with the Nmass of $(replace(text_nmass, "_" => "."))"
end end
@onbutton ImgPlus begin @onbutton ImgPlus begin
indeximg+=1 # Append a query string to force the image to refresh
while !isfile("public/MSI_$(indeximg).bmp") && indeximg < 2001 timestamp = string(time_ns())
indeximg += 1 new_msi = increment_image(current_msi, msi_bmp)
end new_col_msi = increment_image(current_col_msi, col_msi_png)
if(indeximg >= 2001)
indeximg = lastimg current_msi = new_msi
end current_col_msi = new_col_msi
imgInt = "/MSI_$(indeximg).bmp" imgInt = "/$(current_msi)?t=$(timestamp)"
colorbar = "/colorbar_MSI_$(indeximg).png" colorbar = "/$(current_col_msi)?t=$(timestamp)"
msgimg = "image with the Nmass of $(indeximg)"
lastimg = indeximg text_nmass = replace(current_msi, "MSI_" => "")
text_nmass = replace(text_nmass, ".bmp" => "")
msgimg = "image with the Nmass of $(replace(text_nmass, "_" => "."))"
end end
@onbutton ImgMinusT begin @onbutton ImgMinusT begin
indeximgTriq-=1 # Append a query string to force the image to refresh
while !isfile("public/TrIQ_$(indeximgTriq).bmp") && indeximgTriq > 0 timestamp = string(time_ns())
indeximgTriq -= 1 new_msi = decrement_image(current_triq, triq_bmp)
end new_col_msi = decrement_image(current_col_triq, col_triq_png)
if(indeximgTriq <= 0) # If it doesn't find a lower value image
indeximgTriq = lastimgTriq current_triq = new_msi
end current_col_triq = new_col_msi
imgIntT = "/TrIQ_$(indeximgTriq).bmp" imgIntT = "/$(current_triq)?t=$(timestamp)"
colorbarT = "/colorbar_TrIQ_$(indeximgTriq).png" colorbarT = "/$(current_col_triq)?t=$(timestamp)"
msgtriq = "TrIQ image with the Nmass of $(indeximgTriq)"
lastimgTriq = indeximgTriq text_nmass = replace(current_triq, "TrIQ_" => "")
text_nmass = replace(text_nmass, ".bmp" => "")
msgtriq = "image with the Nmass of $(replace(text_nmass, "_" => "."))"
end end
@onbutton ImgPlusT begin @onbutton ImgPlusT begin
indeximgTriq+=1 # Append a query string to force the image to refresh
while !isfile("public/TrIQ_$(indeximgTriq).bmp") && indeximgTriq < 2001 timestamp = string(time_ns())
indeximgTriq += 1 new_msi = increment_image(current_triq, triq_bmp)
new_col_msi = increment_image(current_col_triq, col_triq_png)
current_triq = new_msi
current_col_triq = new_col_msi
imgIntT = "/$(current_triq)"
colorbarT = "/$(current_col_triq)"
text_nmass = replace(current_triq, "TrIQ_" => "")
text_nmass = replace(text_nmass, ".bmp" => "")
msgtriq = "image with the Nmass of $(replace(text_nmass, "_" => "."))"
end end
if(indeximgTriq >= 2001)
indeximgTriq = lastimgTriq # 3d plot
@onbutton image3dPlot begin
msg = "Image 3D plot selected"
cleaned_imgInt = replace(imgInt, r"\?.*" => "")
cleaned_imgInt = lstrip(cleaned_imgInt, '/')
var1 = joinpath( "public", cleaned_imgInt )
if isfile(var1)
try
img = FileIO.load(File{DataFormat{:BMP}}(var1))
img_gray = Gray.(img) # Convert to grayscale
img_array = Array(img_gray)
catch e
msg = "Failed to load and process image: $e"
warning_msg = true
println(msg)
end end
imgIntT = "/TrIQ_$(indeximgTriq).bmp" elevation = img_array / 255.0 # Normalize between 0 and 1
colorbarT = "/colorbar_TrIQ_$(indeximgTriq).png" # Smooth the image
msgtriq = "TrIQ image with the Nmass of $(indeximgTriq)" sigma = 4.0
lastimgTriq = indeximgTriq elevation_smoothed = imfilter(elevation, Kernel.gaussian(sigma))
# Create the X, Y meshgrid coordinates
x = 1:size(elevation_smoothed, 2)
y = 1:size(elevation_smoothed, 1)
X, Y = ndgrid(x, y)
trace3D = PlotlyBase.scatter(x = X[1, :], y =Y[:, 1], z=elevation_smoothed, colorscale="Viridis")
plotdata3d = [trace3D] # We add the data from the image to the plot
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 end
msg = "Plot loaded."
else
msg = "image could not be 3d plotted"
warning_msg = true
end
end
@onbutton triq3dPlot begin
msg = "TrIQ 3D plot selected"
cleaned_imgIntT = replace(imgIntT, r"\?.*" => "")
cleaned_imgIntT = lstrip(cleaned_imgIntT, '/')
var1 = joinpath( "public", cleaned_imgIntT )
if isfile(var1)
try
img = FileIO.load(File{DataFormat{:BMP}}(var1))
img_gray = Gray.(img) # Convert to grayscale
img_array = Array(img_gray)
catch e
msg = "Failed to load and process image: $e"
warning_msg = true
println(msg)
end
elevation = img_array / 255.0 # Normalize between 0 and 1
# Smooth the image
sigma = 4.0
elevation_smoothed = imfilter(elevation, Kernel.gaussian(sigma))
# Create the X, Y meshgrid coordinates
x = 1:size(elevation_smoothed, 2)
y = 1:size(elevation_smoothed, 1)
X, Y = ndgrid(x, y)
trace3D = PlotlyBase.scatter(x = X[1, :], y =Y[:, 1], z=elevation_smoothed, colorscale="Viridis")
plotdata3d = [trace3D] # We add the data from the image to the plot
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
msg = "Plot loaded."
else
msg = "image could not be 3d plotted"
warning_msg = true
end
end
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

View File

@ -15,24 +15,50 @@
<div id="intDivStyle" class="st-col col-12 col-sm st-module"> <div id="intDivStyle" class="st-col col-12 col-sm st-module">
<!--<q-file v-model="file_route" filled="" label="Select your imzML file" accept=".imzML"></q-file>--> <!--<q-file v-model="file_route" filled="" label="Select your imzML file" accept=".imzML"></q-file>-->
<q-input id="textRoute" standout="custom-standout" v-model="file_route" label="Insert the route to your imzML file"></q-input> <q-input id="textRoute" standout="custom-standout" v-model="file_route" label="Insert the route to your imzML file"></q-input>
<div class="row st-col col-14 col-sm"> <div class="row st-col col-12 col-sm">
<q-input id="textName" class="col-8" standout="custom-standout" v-model="file_name" label="Insert the name of your imzML file"></q-input> <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 id="btnStyle" class="col-4" :loading="progressPlot" :disabled="btnPlotDisable" icon="play_arrow" v-on:click="Generate_Plot = true"> <q-btn-dropdown
Generate Plot id="btnStyle"
class="col-3"
:loading="progressPlot"
:disable="btnPlotDisable"
label="Generate Plots"
icon="play_arrow"
>
<template v-slot:loading> <template v-slot:loading>
<q-spinner-hourglass class="on-left" /> <q-spinner-hourglass class="on-left" />
Loading Plot Loading Plot
</template> </template>
</q-btn>
<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="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>
<p id="lblFullRoute">full route: {{full_route}} {{warning_fr}}</p> <p id="lblFullRoute">full route: {{full_route}} {{warning_fr}}</p>
<!-- Variable Manipulation --> <!-- Variable Manipulation -->
<div class="row"> <div class="row">
<div class="st-col col-12 col-sm"> <div class="st-col col-12 col-sm">
<q-input standout="custom-standout" id="textNmass" v-model="Nmass" :dense="true" label="Mass-to-charge ratio of interest" type="number" :rules="[ val => !!val || '* Required', val => val >= 0 &amp;&amp; val <= 2000 || 'Need positive mass values',]"></q-input> <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>
<div class="st-col col-12 col-sm"> <div class="st-col col-12 col-sm">
<q-input standout="custom-standout" id="textTol" step="0.01" v-model="Tol" :dense="true" label="Mass-to-charge ratio Tolerance" type="number" :rules="[val => !!val || '* Required', val => val >= 0 &amp;&amp; val <= 1 || 'Needs to be in range between 0 and 1',]"></q-input> <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> </div>
<div class="row"> <div class="row">
@ -43,17 +69,17 @@
<!-- Triq Variable Manipulation --> <!-- Triq Variable Manipulation -->
<div class="row"> <div class="row">
<div class="st-col col-12 col-sm-8"> <div class="st-col col-12 col-sm-8">
<q-input standout="custom-standout" id="textTriqProb" step="0.01" v-model="triqProb" :dense="true" label="TrIQ Probability" type="number" :rules="[ <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 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> ]" :readonly="!triqEnabled" :disable="!triqEnabled"></q-input>
</div> </div>
<div class="st-col col-12 col-sm-4"> <div class="st-col col-12 col-sm-4">
<q-input standout="custom-standout" id="textTriqColor" step="1" v-model="triqColor" :dense="true" label="TrIQ Color Levels" type="number" :rules="[ <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 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> ]" :readonly="!triqEnabled" :disable="!triqEnabled"></q-input>
</div> </div>
</div> </div>
<q-btn id="btnStyle" :loading="progress" :disabled="btnStartDisable" icon="play_arrow" v-on:click="Main_Process = true" padding="lg"> <q-btn id="btnStyle" :loading="progress" :disabled="btnStartDisable" icon="play_arrow" v-on:click="mainProcess = true" padding="lg">
Start Process Start Process
<template v-slot:loading> <template v-slot:loading>
<q-spinner-hourglass class="on-left" /> <q-spinner-hourglass class="on-left" />
@ -111,7 +137,7 @@
</div> </div>
<!-- Bottom Right Div --> <!-- Bottom Right Div -->
<div class="st-col col-12 col-sm st-module" > <div class="st-col col-12 col-sm st-module" >
<h1>3d plot goes here</h1> <plotly id="plotStyle3d" :data="plotdata3d" :layout="plotlayout3d" class="st-col col-12 col-sm-12"></plotly>
</div> </div>
</div> </div>

View File

@ -1,18 +1,19 @@
PENDING PENDING
rmsi julia coherence with image creation Rmsi & julia coherence with image creation and colorbar
avoid image enlargement -> CURRENT WIP avoid image enlargement -> CURRENT WIP
image rotation? image flip upside down
colorbar revamp colorbar revamp
3d topography for images 3d topography for images -> CURRENT WIP
better blind search for images -> CURRENT WIP Multiple plot types
multiple plot types?
DONE DONE
quicker start for julia GUI Quicker start for julia GUI
better UI Better UI
better style of page refined style of page
more responsiveness improved responsiveness
UI functionality added UI functionality added
code cleaning Code cleanse
better code readability better code readability
Better blind search for images