Now the comparative view offers more options to compare to, fixed small mistakes
This commit is contained in:
parent
47bba11f15
commit
59630bdd95
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,8 +1,6 @@
|
|||||||
public/*
|
public/*
|
||||||
|
public/css/imgOver.png
|
||||||
!public/css/
|
!public/css/
|
||||||
!public/css/autogenerated.css
|
!public/css/autogenerated.css
|
||||||
!public/css/LABI_logo.png
|
!public/css/LABI_logo.png
|
||||||
log/*
|
log/*
|
||||||
|
|
||||||
|
|
||||||
Manifest.toml
|
|
||||||
|
|||||||
623
app.jl
623
app.jl
@ -13,341 +13,9 @@ using Images
|
|||||||
using LinearAlgebra
|
using LinearAlgebra
|
||||||
using NativeFileDialog # Opens the file explorer depending on the OS
|
using NativeFileDialog # Opens the file explorer depending on the OS
|
||||||
using StipplePlotly
|
using StipplePlotly
|
||||||
using Base64
|
|
||||||
include("./julia_imzML_visual.jl")
|
include("./julia_imzML_visual.jl")
|
||||||
@genietools
|
@genietools
|
||||||
|
|
||||||
# == Code import ==
|
|
||||||
# add your data analysis code here or in the lib folder. Code in lib/ will be
|
|
||||||
# automatically loaded
|
|
||||||
|
|
||||||
# == Search functions ==
|
|
||||||
function increment_image(current_image, image_list)
|
|
||||||
if isempty(image_list)
|
|
||||||
return nothing
|
|
||||||
end
|
|
||||||
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)
|
|
||||||
if isempty(image_list)
|
|
||||||
return nothing
|
|
||||||
end
|
|
||||||
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
|
|
||||||
|
|
||||||
## Plot Image functions
|
|
||||||
# loadImgPlot recieves the local directory of the image as a string,
|
|
||||||
# returns the layout and data for the heatmap plotly plot
|
|
||||||
# this function loads the image into a plot
|
|
||||||
function loadImgPlot(interfaceImg::String)
|
|
||||||
# Load the image
|
|
||||||
cleaned_img=replace(interfaceImg, r"\?.*" => "")
|
|
||||||
cleaned_img=lstrip(cleaned_img, '/')
|
|
||||||
var=joinpath("./public", cleaned_img)
|
|
||||||
img=load(var)
|
|
||||||
#println("type of img: $(typeof(img))")
|
|
||||||
# Convert to grayscale
|
|
||||||
img_gray=Gray.(img)
|
|
||||||
img_array=Array(img_gray)
|
|
||||||
#println(typeof(img_array))
|
|
||||||
elevation=Float32.(Array(img_array)) ./ 255.0
|
|
||||||
#println("type of elevation: $(typeof(elevation))")
|
|
||||||
# Get the X, Y coordinates of the image
|
|
||||||
height, width=size(img_array)
|
|
||||||
#println("height: $(height), width: $(width)")
|
|
||||||
X=collect(1:width)
|
|
||||||
Y=collect(1:height)
|
|
||||||
|
|
||||||
# Create the layout
|
|
||||||
layout=PlotlyBase.Layout(
|
|
||||||
xaxis=PlotlyBase.attr(
|
|
||||||
visible=false,
|
|
||||||
scaleanchor="y"
|
|
||||||
),
|
|
||||||
yaxis=PlotlyBase.attr(
|
|
||||||
visible=false
|
|
||||||
),
|
|
||||||
margin=attr(l=0,r=0,t=0,b=0,pad=0)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create the trace for the image
|
|
||||||
trace=PlotlyBase.heatmap(
|
|
||||||
z=elevation,
|
|
||||||
x=X,
|
|
||||||
y=-Y,
|
|
||||||
name="",
|
|
||||||
showlegend=false,
|
|
||||||
colorscale="Viridis",
|
|
||||||
showscale=false,
|
|
||||||
colorbar=attr(
|
|
||||||
title=attr(
|
|
||||||
text="Intensity",
|
|
||||||
font=attr(
|
|
||||||
size=14,
|
|
||||||
color="black"
|
|
||||||
),
|
|
||||||
side="right"
|
|
||||||
),
|
|
||||||
ticks="outside",
|
|
||||||
ticklen=2,
|
|
||||||
tickwidth=0.5,
|
|
||||||
nticks=5,
|
|
||||||
tickformat=".2g"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
plotdata=[trace]
|
|
||||||
plotlayout=layout
|
|
||||||
return plotdata, plotlayout, width, height
|
|
||||||
end
|
|
||||||
|
|
||||||
function loadImgPlot(interfaceImg::String, overlayImg::String, imgTrans::Float64)
|
|
||||||
timestamp=string(time_ns())
|
|
||||||
# Load the main image
|
|
||||||
cleaned_img = replace(interfaceImg, r"\?.*" => "")
|
|
||||||
cleaned_img = lstrip(cleaned_img, '/')
|
|
||||||
var = joinpath("./public", cleaned_img)
|
|
||||||
img = load(var)
|
|
||||||
# Convert to grayscale
|
|
||||||
img_gray = Gray.(img)
|
|
||||||
img_array = Array(img_gray)
|
|
||||||
elevation = Float32.(Array(img_array)) ./ 255.0
|
|
||||||
# Get the X, Y coordinates of the image
|
|
||||||
height, width = size(img_array)
|
|
||||||
#println("height: $(-height), width: $(width)")
|
|
||||||
X = collect(1:width)
|
|
||||||
Y = collect(1:height)
|
|
||||||
#println("height: $(X), width: $(-Y)")
|
|
||||||
|
|
||||||
# Create the layout with overlay image
|
|
||||||
layoutImg = PlotlyBase.Layout(
|
|
||||||
images = [attr(
|
|
||||||
#source = "data:image/png;base64,$overlayImg",
|
|
||||||
#source = "https://images.plot.ly/language-icons/api-home/python-logo.png",
|
|
||||||
source = "$(overlayImg)?t=$(timestamp)",
|
|
||||||
xref = "x",
|
|
||||||
yref = "y",
|
|
||||||
x = 0,
|
|
||||||
y = 0,
|
|
||||||
sizex = width,
|
|
||||||
sizey = -height,
|
|
||||||
sizing = "stretch",
|
|
||||||
opacity = imgTrans,
|
|
||||||
layer = "above" # Place the overlay image in the foreground
|
|
||||||
)],
|
|
||||||
xaxis = PlotlyBase.attr(
|
|
||||||
visible = false,
|
|
||||||
scaleanchor = "y",
|
|
||||||
range = [1, width]
|
|
||||||
),
|
|
||||||
yaxis = PlotlyBase.attr(
|
|
||||||
visible = false,
|
|
||||||
range = [-height,-1]
|
|
||||||
),
|
|
||||||
margin = attr(l = 0, r = 0, t = 0, b = 0, pad = 0)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create the trace for the main image
|
|
||||||
trace = PlotlyBase.heatmap(
|
|
||||||
z = elevation,
|
|
||||||
x = X,
|
|
||||||
y = -Y,
|
|
||||||
name = "",
|
|
||||||
showlegend = false,
|
|
||||||
colorscale = "Viridis",
|
|
||||||
showscale = false
|
|
||||||
)
|
|
||||||
|
|
||||||
plotdata = [trace]
|
|
||||||
plotlayout = layoutImg
|
|
||||||
return plotdata, plotlayout, width, height
|
|
||||||
end
|
|
||||||
|
|
||||||
# loadContourPlot recieves the local directory of the image as a string,
|
|
||||||
# returns the layout and data for the contour plotly plot
|
|
||||||
# this function loads the image and applies a gaussian filter
|
|
||||||
# to smoothen it and loads it into a plot
|
|
||||||
function loadContourPlot(interfaceImg::String)
|
|
||||||
# Load the image
|
|
||||||
cleaned_img=replace(interfaceImg, r"\?.*" => "")
|
|
||||||
cleaned_img=lstrip(cleaned_img, '/')
|
|
||||||
var=joinpath("./public", cleaned_img)
|
|
||||||
img=load(var)
|
|
||||||
img_gray=Gray.(img)
|
|
||||||
img_array=Array(img_gray)
|
|
||||||
# parse matrix to int32 to closely resemble similarity to original bitmap
|
|
||||||
elevation=Float32.(Array(img_array))./ 255.0 # Normalize between 0 and 1
|
|
||||||
|
|
||||||
# Smooth the image
|
|
||||||
sigma=3.0
|
|
||||||
kernel=Kernel.gaussian(sigma)
|
|
||||||
elevation_smoothed=imfilter(elevation, kernel)
|
|
||||||
|
|
||||||
# Create the X, Y meshgrid coordinates
|
|
||||||
x=1:size(elevation_smoothed, 2)
|
|
||||||
y=1:size(elevation_smoothed, 1)
|
|
||||||
X=repeat(reshape(x, 1, length(x)), length(y), 1)
|
|
||||||
Y=repeat(reshape(y, length(y), 1), 1, length(x))
|
|
||||||
|
|
||||||
layout=PlotlyBase.Layout(
|
|
||||||
title="2D Topographic Map of $cleaned_img",
|
|
||||||
xaxis=PlotlyBase.attr(
|
|
||||||
title="X",
|
|
||||||
scaleanchor="y"
|
|
||||||
),
|
|
||||||
yaxis=PlotlyBase.attr(
|
|
||||||
title="Y"
|
|
||||||
),
|
|
||||||
margin=attr(l=0,r=0,t=120,b=0,pad=0)
|
|
||||||
)
|
|
||||||
trace=PlotlyBase.contour(
|
|
||||||
z=elevation_smoothed,
|
|
||||||
x=X[1, :], # Use the first row
|
|
||||||
y=-Y[:, 1], # Use the first column
|
|
||||||
contours_coloring="Viridis",
|
|
||||||
colorscale="Viridis",
|
|
||||||
colorbar=attr(
|
|
||||||
tickformat=".2g"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
plotdata=[trace]
|
|
||||||
plotlayout=layout
|
|
||||||
return plotdata, plotlayout
|
|
||||||
end
|
|
||||||
# loadSurfacePlot recieves the local directory of the image as a string,
|
|
||||||
# returns the layout and data for the surface plotly plot
|
|
||||||
# this function loads the image and applies a gaussian filter
|
|
||||||
# to smoothen it and loads it into a 3D plot
|
|
||||||
function loadSurfacePlot(interfaceImg::String)
|
|
||||||
# Load the image
|
|
||||||
cleaned_img=replace(interfaceImg, r"\?.*" => "")
|
|
||||||
cleaned_img=lstrip(cleaned_img, '/')
|
|
||||||
var=joinpath("./public", cleaned_img)
|
|
||||||
img=load(var)
|
|
||||||
#println("Image type:", typeof(img))
|
|
||||||
img_gray=Gray.(img) # Convert to grayscale
|
|
||||||
#println("Grayscale image type:", typeof(img_gray))
|
|
||||||
img_array=Array(img_gray)
|
|
||||||
elevation=Float32.(Array(img_array)) ./ 255.0 # Normalize between 0 and 1
|
|
||||||
#println("Elevation size:", size(elevation))
|
|
||||||
# Smooth the image
|
|
||||||
sigma=3.0
|
|
||||||
kernel=Kernel.gaussian(sigma)
|
|
||||||
#println(size(kernel))
|
|
||||||
elevation_smoothed=imfilter(elevation, kernel)
|
|
||||||
#println("Smoothed elevation size:", size(elevation_smoothed))
|
|
||||||
# Transpose the elevation_smoothed array
|
|
||||||
# Create the X, Y meshgrid coordinates
|
|
||||||
x=1:size(elevation_smoothed, 2)
|
|
||||||
y=1:size(elevation_smoothed, 1)
|
|
||||||
X=repeat(reshape(x, 1, length(x)), length(y), 1)
|
|
||||||
#println("Size of X:", size(X))
|
|
||||||
Y=repeat(reshape(y, length(y), 1), 1, length(x))
|
|
||||||
#println("Size of Y:", size(Y))
|
|
||||||
# Calculate the number of ticks and aspect ratio for the 3d plot
|
|
||||||
x_nticks=min(20, length(x))
|
|
||||||
y_nticks=min(20, length(y))
|
|
||||||
z_nticks=5
|
|
||||||
aspect_ratio=attr(x=1, y=length(y) / length(x), z=0.5)
|
|
||||||
# Define the layout for the 3D plot
|
|
||||||
layout3D=PlotlyBase.Layout(
|
|
||||||
title="3D Surface Plot of $cleaned_img",
|
|
||||||
scene=attr(
|
|
||||||
xaxis_nticks=x_nticks,
|
|
||||||
yaxis_nticks=y_nticks,
|
|
||||||
zaxis_nticks=z_nticks,
|
|
||||||
camera=attr(eye=attr(x=0, y=1, z=0.5)),
|
|
||||||
aspectratio=aspect_ratio
|
|
||||||
),
|
|
||||||
margin=attr(l=0,r=0,t=120,b=0,pad=0)
|
|
||||||
)
|
|
||||||
# Transpose the elevation_smoothed array if Y axis is longer than X axis to fix chopping
|
|
||||||
elevation_smoothed=transpose(elevation_smoothed)
|
|
||||||
if size(elevation_smoothed, 1) < size(elevation_smoothed, 2)
|
|
||||||
Y=-Y
|
|
||||||
else
|
|
||||||
X=-X
|
|
||||||
end
|
|
||||||
|
|
||||||
trace3D=PlotlyBase.surface(
|
|
||||||
x=X[1, :],
|
|
||||||
y=Y[:, 1],
|
|
||||||
z=elevation_smoothed,
|
|
||||||
contours_z=attr(
|
|
||||||
show=true,
|
|
||||||
usecolormap=true,
|
|
||||||
highlightcolor="limegreen",
|
|
||||||
project_z=true
|
|
||||||
),
|
|
||||||
colorscale="Viridis",
|
|
||||||
colorbar=attr(
|
|
||||||
tickformat=".2g"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
plotdata=[trace3D]
|
|
||||||
plotlayout=layout3D
|
|
||||||
return plotdata, plotlayout
|
|
||||||
end
|
|
||||||
|
|
||||||
function crossLinesPlot(x, y, maxwidth, maxheight)
|
|
||||||
# Define the coordinates for the two lines
|
|
||||||
l1_x=[0, maxwidth]
|
|
||||||
l1_y=[y, y]
|
|
||||||
l2_x=[x, x]
|
|
||||||
l2_y=[0, maxheight]
|
|
||||||
|
|
||||||
# Create the line traces
|
|
||||||
trace1=PlotlyBase.scatter(x=l1_x, y=l1_y, mode="lines",line=attr(color="red", width=0.5),name="Line X",showlegend=false)
|
|
||||||
trace2=PlotlyBase.scatter(x=l2_x, y=l2_y, mode="lines",line=attr(color="red", width=0.5),name="Line Y",showlegend=false)
|
|
||||||
|
|
||||||
return trace1, trace2
|
|
||||||
end
|
|
||||||
|
|
||||||
function log_tick_formatter(values::Vector{Float64})
|
|
||||||
#println("values: $(values) + type: $(typeof(values))")
|
|
||||||
# Initialize exponents dictionary
|
|
||||||
exponents=zeros(Int, length(values))
|
|
||||||
formValues=zeros(Float64, length(values))
|
|
||||||
for i in 1:length(values)
|
|
||||||
value = values[i]
|
|
||||||
#println("value: $(value)")
|
|
||||||
if value >= 1000 # positive formatting for notation
|
|
||||||
while value >= 1000
|
|
||||||
value /= 10
|
|
||||||
exponents[i] += 1
|
|
||||||
end
|
|
||||||
#println("value: $(value) x10^$(exponents[i])")
|
|
||||||
elseif value > 0 && value < 1 # negative formatting for notation
|
|
||||||
while value < 1
|
|
||||||
value *= 10
|
|
||||||
exponents[i] -= 1
|
|
||||||
end
|
|
||||||
#values[i] = round(values[i], digits=2)
|
|
||||||
#println("value: $(value) x10^$(exponents[i])")
|
|
||||||
end
|
|
||||||
#formatted_values[i] = values[i] != 0 ? "$(round(values[i], digits=2))x10" * Makie.UnicodeFun.to_superscript(exponents[i]) : "0"
|
|
||||||
formValues[i]=value
|
|
||||||
end
|
|
||||||
#return formatted_values
|
|
||||||
#return map(v -> values * "x10" * Makie.UnicodeFun.to_superscript(round(Int64, v)), exponents)
|
|
||||||
#println("formated values: $(formValues) + type: $(typeof(formValues))")
|
|
||||||
#println("exponents: $(exponents) + type: $(typeof(exponents))")
|
|
||||||
#return map((v, e) -> "$(round(v, digits=2))x10" * Makie.UnicodeFun.to_superscript(e), formValues, exponents)
|
|
||||||
return map((v, e) -> e == 0 ? "$(round(v, sigdigits=2))" : "$(round(v, sigdigits=2))x10" * Makie.UnicodeFun.to_superscript(e), formValues, exponents)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
# == Reactive code ==
|
# == Reactive code ==
|
||||||
# Reactive code to make the UI interactive
|
# Reactive code to make the UI interactive
|
||||||
@app begin
|
@app begin
|
||||||
@ -356,7 +24,6 @@ end
|
|||||||
# @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
|
|
||||||
|
|
||||||
## Interface non Variables
|
## Interface non Variables
|
||||||
@out btnStartDisable=true
|
@out btnStartDisable=true
|
||||||
@ -396,6 +63,11 @@ end
|
|||||||
@in imgMinus=false
|
@in imgMinus=false
|
||||||
@in imgPlusT=false
|
@in imgPlusT=false
|
||||||
@in imgMinusT=false
|
@in imgMinusT=false
|
||||||
|
# Image change comparative buttons
|
||||||
|
@in imgPlusComp=false
|
||||||
|
@in imgMinusComp=false
|
||||||
|
@in imgPlusTComp=false
|
||||||
|
@in imgMinusTComp=false
|
||||||
|
|
||||||
## Tabulation variables
|
## Tabulation variables
|
||||||
@out tabIDs=["tab0","tab1","tab2","tab3","tab4"]
|
@out tabIDs=["tab0","tab1","tab2","tab3","tab4"]
|
||||||
@ -410,6 +82,11 @@ end
|
|||||||
@out imgIntT="/.bmp" # image Interface TrIQ
|
@out imgIntT="/.bmp" # image Interface TrIQ
|
||||||
@out colorbar="/.png"
|
@out colorbar="/.png"
|
||||||
@out colorbarT="/.png"
|
@out colorbarT="/.png"
|
||||||
|
# interface controlling for the comparative view
|
||||||
|
@out imgIntComp="/.bmp" # image Interface
|
||||||
|
@out imgIntTComp="/.bmp" # image Interface TrIQ
|
||||||
|
@out colorbarComp="/.png"
|
||||||
|
@out colorbarTComp="/.png"
|
||||||
@out imgWidth=0
|
@out imgWidth=0
|
||||||
@out imgHeight=0
|
@out imgHeight=0
|
||||||
|
|
||||||
@ -418,7 +95,8 @@ end
|
|||||||
@in progressOptical = false
|
@in progressOptical = false
|
||||||
@out btnOpticalDisable = true
|
@out btnOpticalDisable = true
|
||||||
@in btnOptical = false
|
@in btnOptical = false
|
||||||
@out opticalImg = ""
|
@in btnOpticalT = false
|
||||||
|
@in opticalOverTriq = false
|
||||||
|
|
||||||
# Messages to interface variables
|
# Messages to interface variables
|
||||||
@out msg=""
|
@out msg=""
|
||||||
@ -444,6 +122,11 @@ end
|
|||||||
@out current_col_msi=""
|
@out current_col_msi=""
|
||||||
@out current_triq=""
|
@out current_triq=""
|
||||||
@out current_col_triq=""
|
@out current_col_triq=""
|
||||||
|
# We reiterate the process to display in the comparative view
|
||||||
|
@out current_msiComp=""
|
||||||
|
@out current_col_msiComp=""
|
||||||
|
@out current_triqComp=""
|
||||||
|
@out current_col_triqComp=""
|
||||||
|
|
||||||
## Time measurement variables
|
## Time measurement variables
|
||||||
@out sTime=time()
|
@out sTime=time()
|
||||||
@ -465,9 +148,16 @@ end
|
|||||||
traceImg=PlotlyBase.heatmap(x=[], y=[])
|
traceImg=PlotlyBase.heatmap(x=[], y=[])
|
||||||
@out plotdataImg=[traceImg]
|
@out plotdataImg=[traceImg]
|
||||||
@out plotlayoutImg=layoutImg
|
@out plotlayoutImg=layoutImg
|
||||||
|
# For the image in the comparative view
|
||||||
|
@out plotdataImgComp=[traceImg]
|
||||||
|
@out plotlayoutImgComp=layoutImg
|
||||||
|
|
||||||
# For triq image
|
# For triq image
|
||||||
@out plotdataImgT=[traceImg]
|
@out plotdataImgT=[traceImg]
|
||||||
@out plotlayoutImgT=layoutImg
|
@out plotlayoutImgT=layoutImg
|
||||||
|
# For the triq image in the comparative view
|
||||||
|
@out plotdataImgTComp=[traceImg]
|
||||||
|
@out plotlayoutImgTComp=layoutImg
|
||||||
# Interface Plot Spectrum
|
# Interface Plot Spectrum
|
||||||
layoutSpectra=PlotlyBase.Layout(
|
layoutSpectra=PlotlyBase.Layout(
|
||||||
title="SUM Spectrum plot",
|
title="SUM Spectrum plot",
|
||||||
@ -592,21 +282,22 @@ end
|
|||||||
end
|
end
|
||||||
|
|
||||||
@onbutton mainProcess begin
|
@onbutton mainProcess begin
|
||||||
#@onchange Nmass 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
|
||||||
btnPlotDisable=true
|
btnPlotDisable=true
|
||||||
btnSpectraDisable=true
|
btnSpectraDisable=true
|
||||||
text_nmass=replace(string(Nmass), "." => "_")
|
text_nmass=replace(string(Nmass), "." => "_")
|
||||||
sTime=time()
|
sTime=time()
|
||||||
#full_route=joinpath(file_route, file_name)
|
|
||||||
if isfile(full_route) && Nmass > 0 && Tol > 0 && Tol <=1 && colorLevel > 1 && colorLevel < 257
|
if isfile(full_route) && Nmass > 0 && Tol > 0 && Tol <=1 && colorLevel > 1 && colorLevel < 257
|
||||||
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)
|
||||||
msg="File loaded. Creating Spectra with the specific mass and tolerance, please be patient."
|
msg="File loaded. Creating Spectra with the specific mass and tolerance, please be patient."
|
||||||
#slice=GetSlice(spectra, Nmass, Tol)
|
try
|
||||||
slice=GetMzSliceJl(spectra,Nmass,Tol)
|
slice=GetMzSliceJl(spectra,Nmass,Tol)
|
||||||
|
catch e
|
||||||
|
println("the error is in the slice: $e")
|
||||||
|
end
|
||||||
fig=CairoMakie.Figure(size=(150, 250)) # Container
|
fig=CairoMakie.Figure(size=(150, 250)) # Container
|
||||||
# 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())
|
||||||
@ -616,11 +307,18 @@ end
|
|||||||
warning_msg=true
|
warning_msg=true
|
||||||
else
|
else
|
||||||
image_path=joinpath("./public", "TrIQ_$(text_nmass).bmp")
|
image_path=joinpath("./public", "TrIQ_$(text_nmass).bmp")
|
||||||
sliceTriq=TrIQ(slice, colorLevel, triqProb)
|
valid_slice = false
|
||||||
#println("slice raw: $(typeof(slice))")
|
while Tol <= 1.0 && !valid_slice
|
||||||
#println("TriQ matrix: $(typeof(sliceTriq))")
|
try
|
||||||
|
slice = GetMzSliceJl(spectra, Nmass, Tol)
|
||||||
|
sliceTriq = TrIQ(slice, colorLevel, triqProb)
|
||||||
|
valid_slice = true
|
||||||
|
catch e
|
||||||
|
msg="Warning: insufficient tolerance, inputs modified to allow the creation of an image regardless = $Tol: $e"
|
||||||
|
Tol += 0.1
|
||||||
|
end
|
||||||
|
end
|
||||||
sliceTriq=reverse(sliceTriq, dims=2)
|
sliceTriq=reverse(sliceTriq, dims=2)
|
||||||
##SaveBitmap(joinpath("public", "TrIQ_$(text_nmass).bmp"),sliceTriq,ViridisPalette)
|
|
||||||
SaveBitmapCl(joinpath("public", "TrIQ_$(text_nmass).bmp"),sliceTriq,ViridisPalette)
|
SaveBitmapCl(joinpath("public", "TrIQ_$(text_nmass).bmp"),sliceTriq,ViridisPalette)
|
||||||
# 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)"
|
||||||
@ -631,15 +329,8 @@ end
|
|||||||
# Create colorbar
|
# Create colorbar
|
||||||
bound = julia_mzML_imzML.GetOutlierThres(slice, triqProb)
|
bound = julia_mzML_imzML.GetOutlierThres(slice, triqProb)
|
||||||
levels = range(bound[1],stop=bound[2], length=8)
|
levels = range(bound[1],stop=bound[2], length=8)
|
||||||
#println("range of the levels 1: $(levels)")
|
|
||||||
levels = vcat(levels, 2*levels[end]-levels[end-1])
|
levels = vcat(levels, 2*levels[end]-levels[end-1])
|
||||||
#println("range of the levels 2: $(levels) + $(length(levels))")
|
|
||||||
#ticks=round.(range(0, (stop=maximum(slice)*triqProb), length=10), sigdigits=3)
|
|
||||||
#ticks=range(0, (stop=maximum(slice)*triqProb), length=5)
|
|
||||||
#println("ticks: $(typeof(ticks))")
|
|
||||||
Colorbar(fig[1, 1], colormap=cgrad(:viridis, colorLevel, categorical=true), limits=(0, bound[2]),ticks=levels,tickformat=log_tick_formatter, label="Intensity", size = 25)
|
Colorbar(fig[1, 1], colormap=cgrad(:viridis, colorLevel, categorical=true), limits=(0, bound[2]),ticks=levels,tickformat=log_tick_formatter, label="Intensity", size = 25)
|
||||||
#Colorbar(fig[1, 1], colormap=cgrad(:viridis, colorLevel, categorical=true), limits=(0, maximum(slice)*triqProb),ticks=ticks, label="Intensity", size = 25)
|
|
||||||
#println("Colorbar: $(typeof(fig))")
|
|
||||||
save("public/colorbar_TrIQ_$(text_nmass).png", fig)
|
save("public/colorbar_TrIQ_$(text_nmass).png", fig)
|
||||||
colorbarT="/colorbar_TrIQ_$(text_nmass).png?t=$(timestamp)"
|
colorbarT="/colorbar_TrIQ_$(text_nmass).png?t=$(timestamp)"
|
||||||
# Get current colorbar
|
# Get current colorbar
|
||||||
@ -651,17 +342,16 @@ 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"
|
||||||
selectedTab="tab1"
|
selectedTab="tab1"
|
||||||
#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
|
||||||
image_path=joinpath("./public", "MSI_$(text_nmass).bmp")
|
image_path=joinpath("./public", "MSI_$(text_nmass).bmp")
|
||||||
##sliceQuant=IntQuant(slice)
|
##sliceQuant=IntQuant(slice)
|
||||||
sliceQuant=IntQuantCl(slice,Int(colorLevel-1))
|
try
|
||||||
#println("slice raw: $(typeof(slice))")
|
sliceQuant=IntQuantCl(slice,Int(colorLevel-1))
|
||||||
#println("slice in intQuant: $(typeof(sliceQuant))")
|
catch e
|
||||||
|
println("the error is in the non triq slice: $e")
|
||||||
|
end
|
||||||
sliceQuant=reverse(sliceQuant, dims=2)
|
sliceQuant=reverse(sliceQuant, dims=2)
|
||||||
##SaveBitmap(joinpath("public", "MSI_$(text_nmass).bmp"),sliceQuant,ViridisPalette)
|
|
||||||
SaveBitmapCl(joinpath("public", "MSI_$(text_nmass).bmp"),sliceQuant,ViridisPalette)
|
SaveBitmapCl(joinpath("public", "MSI_$(text_nmass).bmp"),sliceQuant,ViridisPalette)
|
||||||
# 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)"
|
||||||
@ -671,9 +361,6 @@ end
|
|||||||
msgimg="Image with the Nmass of $(replace(text_nmass, "_" => "."))"
|
msgimg="Image with the Nmass of $(replace(text_nmass, "_" => "."))"
|
||||||
# Create colorbar
|
# Create colorbar
|
||||||
levels=range(0,maximum(slice),length=8)
|
levels=range(0,maximum(slice),length=8)
|
||||||
#ticks=round.(range(0, stop=maximum(slice), length=10), sigdigits=3)
|
|
||||||
#ticks=range(0, stop=maximum(slice), length=5)
|
|
||||||
#Colorbar(fig[1, 1], colormap=cgrad(:viridis, colorLevel, categorical=true), limits=(0, maximum(slice)),ticks=ticks, label="Intensity", size = 25)
|
|
||||||
Colorbar(fig[1, 1], colormap=cgrad(:viridis, colorLevel, categorical=true), limits=(0, maximum(slice)),ticks=levels,tickformat=log_tick_formatter, label="Intensity", size = 25)
|
Colorbar(fig[1, 1], colormap=cgrad(:viridis, colorLevel, categorical=true), limits=(0, maximum(slice)),ticks=levels,tickformat=log_tick_formatter, label="Intensity", size = 25)
|
||||||
save("public/colorbar_MSI_$(text_nmass).png", fig)
|
save("public/colorbar_MSI_$(text_nmass).png", fig)
|
||||||
colorbar="/colorbar_MSI_$(text_nmass).png?t=$(timestamp)"
|
colorbar="/colorbar_MSI_$(text_nmass).png?t=$(timestamp)"
|
||||||
@ -686,8 +373,6 @@ end
|
|||||||
fTime=time()
|
fTime=time()
|
||||||
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 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)"
|
||||||
@ -717,7 +402,6 @@ end
|
|||||||
@onbutton createSumPlot begin
|
@onbutton createSumPlot begin
|
||||||
msg="Sum spectrum plot selected"
|
msg="Sum spectrum plot selected"
|
||||||
sTime=time()
|
sTime=time()
|
||||||
#full_route=joinpath( file_route, file_name )
|
|
||||||
if isfile(full_routeMz) # Check if the file exists
|
if isfile(full_routeMz) # Check if the file exists
|
||||||
progressSpectraPlot=true
|
progressSpectraPlot=true
|
||||||
btnPlotDisable=true
|
btnPlotDisable=true
|
||||||
@ -737,19 +421,11 @@ end
|
|||||||
autosize=false,
|
autosize=false,
|
||||||
margin=attr(l=0,r=0,t=120,b=0,pad=0)
|
margin=attr(l=0,r=0,t=120,b=0,pad=0)
|
||||||
)
|
)
|
||||||
# dims=size(spectraMz)
|
|
||||||
# scansMax=dims[2] # we get the total of scansMax
|
|
||||||
#spectraMz = convert(Array{Float64,2}, spectraMz)
|
|
||||||
#min_length = min(length(spectraMz[1,:]), length(spectraMz[2,:]))
|
|
||||||
try
|
try
|
||||||
xSpectraMz=mean(spectraMz[1,:])
|
xSpectraMz=mean(spectraMz[1,:])
|
||||||
ySpectraMz=mean(spectraMz[2,:])
|
ySpectraMz=mean(spectraMz[2,:])
|
||||||
#println("length of xSpectraMz: $(length(xSpectraMz))")
|
|
||||||
#println("length of ySpectraMz: $(length(ySpectraMz))")
|
|
||||||
catch e
|
catch e
|
||||||
#println("an error was found: $e")
|
#println("an error was found: $e")
|
||||||
msg="there was an error with the mzML, please try again: $e"
|
|
||||||
warning_msg=true
|
|
||||||
xSpectraMz=spectraMz[1,1]
|
xSpectraMz=spectraMz[1,1]
|
||||||
ySpectraMz=spectraMz[2,1]
|
ySpectraMz=spectraMz[2,1]
|
||||||
end
|
end
|
||||||
@ -783,7 +459,6 @@ end
|
|||||||
@onbutton createXYPlot begin
|
@onbutton createXYPlot begin
|
||||||
msg="Sum spectrum plot selected"
|
msg="Sum spectrum plot selected"
|
||||||
sTime=time()
|
sTime=time()
|
||||||
#full_route=joinpath( file_route, file_name )
|
|
||||||
if isfile(full_routeMz) # Check if the file exists
|
if isfile(full_routeMz) # Check if the file exists
|
||||||
progressSpectraPlot=true
|
progressSpectraPlot=true
|
||||||
btnStartDisable=true
|
btnStartDisable=true
|
||||||
@ -851,7 +526,7 @@ end
|
|||||||
# 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)
|
||||||
if new_msi!=nothing || new_col_msi!=nothing
|
if new_msi!=nothing || new_col_msi!=nothing
|
||||||
@ -955,6 +630,119 @@ end
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Image loaders for the comparative view
|
||||||
|
@onbutton imgMinusComp begin
|
||||||
|
# Append a query string to force the image to refresh
|
||||||
|
timestamp=string(time_ns())
|
||||||
|
# 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)
|
||||||
|
col_msi_png=sort(filter(filename -> startswith(filename, "colorbar_MSI_") && endswith(filename, ".png"), readdir("public")),lt=natural)
|
||||||
|
|
||||||
|
new_msi=decrement_image(current_msiComp, msi_bmp)
|
||||||
|
new_col_msi=decrement_image(current_col_msiComp, col_msi_png)
|
||||||
|
if new_msi!=nothing || new_col_msi!=nothing
|
||||||
|
current_msiComp=new_msi
|
||||||
|
current_col_msiComp=new_col_msi
|
||||||
|
imgIntComp="/$(current_msiComp)?t=$(timestamp)"
|
||||||
|
colorbarComp="/$(current_col_msiComp)?t=$(timestamp)"
|
||||||
|
|
||||||
|
text_nmass=replace(current_msiComp, "MSI_" => "")
|
||||||
|
text_nmass=replace(text_nmass, ".bmp" => "")
|
||||||
|
msgimg="Image with the Nmass of $(replace(text_nmass, "_" => "."))"
|
||||||
|
# Process the image in the function
|
||||||
|
plotdataImgComp, plotlayoutImgComp, _, _=loadImgPlot(imgIntComp)
|
||||||
|
btnOpticalDisable = false
|
||||||
|
else
|
||||||
|
traceImg=PlotlyBase.heatmap(x=[], y=[])
|
||||||
|
plotdataImgComp=[traceImg]
|
||||||
|
msgimg=""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@onbutton imgPlusComp begin
|
||||||
|
# Append a query string to force the image to refresh
|
||||||
|
timestamp=string(time_ns())
|
||||||
|
# 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)
|
||||||
|
col_msi_png=sort(filter(filename -> startswith(filename, "colorbar_MSI_") && endswith(filename, ".png"), readdir("public")),lt=natural)
|
||||||
|
|
||||||
|
new_msi=increment_image(current_msiComp, msi_bmp)
|
||||||
|
new_col_msi=increment_image(current_col_msiComp, col_msi_png)
|
||||||
|
if new_msi!=nothing || new_col_msi!=nothing
|
||||||
|
current_msiComp=new_msi
|
||||||
|
current_col_msiComp=new_col_msi
|
||||||
|
imgIntComp="/$(current_msiComp)?t=$(timestamp)"
|
||||||
|
colorbarComp="/$(current_col_msiComp)?t=$(timestamp)"
|
||||||
|
|
||||||
|
text_nmass=replace(current_msiComp, "MSI_" => "")
|
||||||
|
text_nmass=replace(text_nmass, ".bmp" => "")
|
||||||
|
msgimg="Image with the Nmass of $(replace(text_nmass, "_" => "."))"
|
||||||
|
# Process the image in the function
|
||||||
|
plotdataImgComp, plotlayoutImgComp, _, _=loadImgPlot(imgIntComp)
|
||||||
|
btnOpticalDisable = false
|
||||||
|
else
|
||||||
|
traceImg=PlotlyBase.heatmap(x=[], y=[])
|
||||||
|
plotdataImgComp=[traceImg]
|
||||||
|
msgimg=""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@onbutton imgMinusTComp begin
|
||||||
|
# Append a query string to force the image to refresh
|
||||||
|
timestamp=string(time_ns())
|
||||||
|
# Update the array of images with TrIQ filter listed in the public folder
|
||||||
|
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)
|
||||||
|
|
||||||
|
new_msi=decrement_image(current_triqComp, triq_bmp)
|
||||||
|
new_col_msi=decrement_image(current_col_triqComp, col_triq_png)
|
||||||
|
if new_msi!=nothing || new_col_msi!=nothing
|
||||||
|
current_triqComp=new_msi
|
||||||
|
current_col_triqComp=new_col_msi
|
||||||
|
imgIntTComp="/$(current_triqComp)?t=$(timestamp)"
|
||||||
|
colorbarTComp="/$(current_col_triqComp)?t=$(timestamp)"
|
||||||
|
|
||||||
|
text_nmass=replace(current_triqComp, "TrIQ_" => "")
|
||||||
|
text_nmass=replace(text_nmass, ".bmp" => "")
|
||||||
|
msgtriq="TrIQ image with the Nmass of $(replace(text_nmass, "_" => "."))"
|
||||||
|
# Process the image in the function
|
||||||
|
plotdataImgTComp, plotlayoutImgTComp, _, _=loadImgPlot(imgIntTComp)
|
||||||
|
btnOpticalDisable = false
|
||||||
|
else
|
||||||
|
traceImg=PlotlyBase.heatmap(x=[], y=[])
|
||||||
|
plotdataImgTComp=[traceImg]
|
||||||
|
msgtriq=""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@onbutton imgPlusTComp begin
|
||||||
|
# Append a query string to force the image to refresh
|
||||||
|
timestamp=string(time_ns())
|
||||||
|
# Update the array of images with TrIQ filter listed in the public folder
|
||||||
|
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)
|
||||||
|
|
||||||
|
new_msi=increment_image(current_triqComp, triq_bmp)
|
||||||
|
new_col_msi=increment_image(current_col_triqComp, col_triq_png)
|
||||||
|
if new_msi!=nothing || new_col_msi!=nothing
|
||||||
|
current_triqComp=new_msi
|
||||||
|
current_col_triqComp=new_col_msi
|
||||||
|
imgIntTComp="/$(current_triqComp)?t=$(timestamp)"
|
||||||
|
colorbarTComp="/$(current_col_triqComp)?t=$(timestamp)"
|
||||||
|
|
||||||
|
text_nmass=replace(current_triqComp, "TrIQ_" => "")
|
||||||
|
text_nmass=replace(text_nmass, ".bmp" => "")
|
||||||
|
msgtriq="TrIQ image with the Nmass of $(replace(text_nmass, "_" => "."))"
|
||||||
|
# Process the image in the function
|
||||||
|
plotdataImgTComp, plotlayoutImgTComp, _, _=loadImgPlot(imgIntTComp)
|
||||||
|
btnOpticalDisable = false
|
||||||
|
else
|
||||||
|
traceImg=PlotlyBase.heatmap(x=[], y=[])
|
||||||
|
plotdataImgTComp=[traceImg]
|
||||||
|
msgtriq=""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# 3d plot
|
# 3d plot
|
||||||
@onbutton image3dPlot begin
|
@onbutton image3dPlot begin
|
||||||
msg="Image 3D plot selected"
|
msg="Image 3D plot selected"
|
||||||
@ -1125,64 +913,49 @@ 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
|
||||||
if selectedTab == "tab2"
|
if selectedTab == "tab2"
|
||||||
if !isempty(xSpectraMz)
|
if !isempty(xSpectraMz)
|
||||||
#println("Clicked data on sum spectrum plot : ", data_click)
|
|
||||||
spectracoords=reshape(plotdata, 1, length(plotdata))
|
spectracoords=reshape(plotdata, 1, length(plotdata))
|
||||||
#println("Spectra: $(ndims(spectracoords))")
|
|
||||||
# Extract x and y values from data_click
|
# Extract x and y values from data_click
|
||||||
cursor_data=data_click["cursor"]
|
cursor_data=data_click["cursor"]
|
||||||
x_value=cursor_data["x"]
|
x_value = cursor_data["x"]
|
||||||
y_value=cursor_data["y"] # Get the x and y values from the click of the cursor
|
y_value = cursor_data["y"]
|
||||||
closest_distance=Inf
|
|
||||||
|
# Find the minimum x-value in spectracoords
|
||||||
|
min_x_value = minimum([minimum(val[:x]) for val in spectracoords if !isempty(val[:x])])
|
||||||
|
# Adjust x_value and spectracoords x-values to start from 0
|
||||||
|
adjusted_x_value = x_value - min_x_value
|
||||||
|
|
||||||
|
closest_distance = Inf
|
||||||
for val in spectracoords
|
for val in spectracoords
|
||||||
# Find the index where x is within a range
|
adjusted_x = val[:x] .- min_x_value
|
||||||
start_idx=findfirst(x -> x >= x_value - 10, val[:x])
|
start_idx = findfirst(x -> x >= adjusted_x_value - 20, adjusted_x)
|
||||||
end_idx=findlast(x -> x <= x_value + 10, val[:x])
|
end_idx = findlast(x -> x <= adjusted_x_value + 20, adjusted_x)
|
||||||
|
|
||||||
# Ensure the index are valid and within range
|
|
||||||
if start_idx !== nothing && end_idx !== nothing
|
if start_idx !== nothing && end_idx !== nothing
|
||||||
for i in start_idx:end_idx
|
for i in start_idx:end_idx
|
||||||
spectra_x=val[:x][i]
|
spectra_x = adjusted_x[i]
|
||||||
spectra_y=val[:y][i]
|
spectra_y = val[:y][i]
|
||||||
distance=sqrt((spectra_x - x_value)^2 + (spectra_y - y_value)^2) # Calculate distance
|
distance = sqrt((spectra_x - adjusted_x_value)^2 + (spectra_y - y_value)^2)
|
||||||
if distance < closest_distance
|
if distance < closest_distance
|
||||||
closest_distance=distance
|
closest_distance = distance
|
||||||
Nmass=round(spectra_x, digits=2)
|
Nmass = round(spectra_x + min_x_value, digits=2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
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,
|
|
||||||
margin=attr(l=0,r=0,t=120,b=0,pad=0)
|
|
||||||
)
|
|
||||||
traceSpectra=PlotlyBase.scatter(x=xSpectraMz, y=ySpectraMz, mode="lines",name="Spectra",showlegend=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)
|
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
|
plotdata=[traceSpectra,trace2] # We add the data from spectra and the red line to the plot
|
||||||
plotlayout=layoutSpectra
|
|
||||||
end
|
end
|
||||||
elseif selectedTab == "tab1"
|
elseif selectedTab == "tab1"
|
||||||
#println("you have clicked the triq image")
|
|
||||||
cursor_data=data_click["cursor"]
|
cursor_data=data_click["cursor"]
|
||||||
xCoord=Int32(round(cursor_data["x"]))
|
xCoord=Int32(round(cursor_data["x"]))
|
||||||
|
yCoord=Int32(round(cursor_data["y"]))
|
||||||
if xCoord < 1
|
if xCoord < 1
|
||||||
xCoord=1
|
xCoord=1
|
||||||
elseif xCoord > imgWidth
|
elseif xCoord > imgWidth
|
||||||
@ -1193,14 +966,13 @@ end
|
|||||||
elseif yCoord < -imgHeight
|
elseif yCoord < -imgHeight
|
||||||
yCoord=-imgHeight
|
yCoord=-imgHeight
|
||||||
end # Get the x and y values from the click of the cursor and make sure they don't exceed image proportions
|
end # Get the x and y values from the click of the cursor and make sure they don't exceed image proportions
|
||||||
#plotdataImgT, plotlayoutImgT, imgWidth, imgHeight=loadImgPlot(imgIntT)
|
|
||||||
plotdataImgT=filter(trace -> !(get(trace, :name, "") in ["Line X", "Line Y"]), plotdataImgT)
|
plotdataImgT=filter(trace -> !(get(trace, :name, "") in ["Line X", "Line Y"]), plotdataImgT)
|
||||||
trace1, trace2=crossLinesPlot(xCoord, yCoord, imgWidth, -imgHeight)
|
trace1, trace2=crossLinesPlot(xCoord, yCoord, imgWidth, -imgHeight)
|
||||||
plotdataImgT=append!(plotdataImgT, [trace1, trace2])
|
plotdataImgT=append!(plotdataImgT, [trace1, trace2])
|
||||||
elseif selectedTab == "tab0"
|
elseif selectedTab == "tab0"
|
||||||
#println("you have clicked the normal image")
|
|
||||||
cursor_data=data_click["cursor"]
|
cursor_data=data_click["cursor"]
|
||||||
xCoord=Int32(round(cursor_data["x"]))
|
xCoord=Int32(round(cursor_data["x"]))
|
||||||
|
yCoord=Int32(round(cursor_data["y"]))
|
||||||
if xCoord < 1
|
if xCoord < 1
|
||||||
xCoord=1
|
xCoord=1
|
||||||
elseif xCoord > imgWidth
|
elseif xCoord > imgWidth
|
||||||
@ -1211,7 +983,6 @@ end
|
|||||||
elseif yCoord < -imgHeight
|
elseif yCoord < -imgHeight
|
||||||
yCoord=-imgHeight
|
yCoord=-imgHeight
|
||||||
end # Get the x and y values from the click of the cursor and make sure they don't exceed image proportions
|
end # Get the x and y values from the click of the cursor and make sure they don't exceed image proportions
|
||||||
#plotdataImg, plotlayoutImg, imgWidth, imgHeight=loadImgPlot(imgInt)
|
|
||||||
plotdataImg=filter(trace -> !(get(trace, :name, "") in ["Line X", "Line Y","Optical"]), plotdataImg)
|
plotdataImg=filter(trace -> !(get(trace, :name, "") in ["Line X", "Line Y","Optical"]), plotdataImg)
|
||||||
trace1, trace2=crossLinesPlot(xCoord, yCoord, imgWidth, -imgHeight)
|
trace1, trace2=crossLinesPlot(xCoord, yCoord, imgWidth, -imgHeight)
|
||||||
plotdataImg=append!(plotdataImg, [trace1, trace2])
|
plotdataImg=append!(plotdataImg, [trace1, trace2])
|
||||||
@ -1219,19 +990,51 @@ end
|
|||||||
end
|
end
|
||||||
|
|
||||||
@onbutton btnOptical begin
|
@onbutton btnOptical begin
|
||||||
timestamp=string(time_ns())
|
|
||||||
imgRoute=pick_file(; filterlist="png,bmp,jpg,jpeg")
|
imgRoute=pick_file(; filterlist="png,bmp,jpg,jpeg")
|
||||||
|
selectedTab="tab0"
|
||||||
|
plotdataImgT, plotlayoutImgT, imgWidth, imgHeight=loadImgPlot(imgIntT)
|
||||||
if isnothing(imgRoute)
|
if isnothing(imgRoute)
|
||||||
println("No file selected")
|
msg="No optical image selected"
|
||||||
else
|
else
|
||||||
img=load(imgRoute)
|
img=load(imgRoute)
|
||||||
save("./public/css/imgOver.png",img)
|
save("./public/css/imgOver.png",img)
|
||||||
plotdataImg, plotlayoutImg, imgWidth, imgHeight=loadImgPlot(imgInt,"/css/imgOver.png",imgTrans)
|
plotdataImg, plotlayoutImg, imgWidth, imgHeight=loadImgPlot(imgInt,"/css/imgOver.png",imgTrans)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
@onbutton btnOpticalT begin
|
||||||
|
imgRoute=pick_file(; filterlist="png,bmp,jpg,jpeg")
|
||||||
|
selectedTab="tab1"
|
||||||
|
plotdataImg, plotlayoutImg, imgWidth, imgHeight=loadImgPlot(imgInt)
|
||||||
|
if isnothing(imgRoute)
|
||||||
|
msg="No optical image selected"
|
||||||
|
else
|
||||||
|
img=load(imgRoute)
|
||||||
|
save("./public/css/imgOver.png",img)
|
||||||
|
plotdataImgT, plotlayoutImgT, imgWidth, imgHeight=loadImgPlot(imgIntT,"/css/imgOver.png",imgTrans)
|
||||||
|
opticalOverTriq=true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@onchange imgTrans begin
|
@onchange imgTrans begin
|
||||||
plotdataImg, plotlayoutImg, imgWidth, imgHeight=loadImgPlot(imgInt,"/css/imgOver.png",imgTrans)
|
if !opticalOverTriq
|
||||||
|
plotdataImg, plotlayoutImg, imgWidth, imgHeight=loadImgPlot(imgInt,"/css/imgOver.png",imgTrans)
|
||||||
|
else
|
||||||
|
plotdataImgT, plotlayoutImgT, imgWidth, imgHeight=loadImgPlot(imgIntT,"/css/imgOver.png",imgTrans)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@onchange opticalOverTriq begin
|
||||||
|
if !opticalOverTriq
|
||||||
|
plotdataImg, plotlayoutImg, imgWidth, imgHeight=loadImgPlot(imgInt,"/css/imgOver.png",imgTrans)
|
||||||
|
plotdataImgT, plotlayoutImgT, imgWidth, imgHeight=loadImgPlot(imgIntT)
|
||||||
|
selectedTab="tab0"
|
||||||
|
else
|
||||||
|
plotdataImg, plotlayoutImg, imgWidth, imgHeight=loadImgPlot(imgInt)
|
||||||
|
plotdataImgT, plotlayoutImgT, imgWidth, imgHeight=loadImgPlot(imgIntT,"/css/imgOver.png",imgTrans)
|
||||||
|
selectedTab="tab1"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@mounted watchplots()
|
@mounted watchplots()
|
||||||
|
|||||||
33
app.jl.html
33
app.jl.html
@ -143,8 +143,19 @@
|
|||||||
</q-item>
|
</q-item>
|
||||||
</q-list>
|
</q-list>
|
||||||
</q-btn-dropdown>
|
</q-btn-dropdown>
|
||||||
<q-btn id="btnStyle" icon="search" class="q-ma-sm" :disable="btnOpticalDisable" v-on:click="btnOptical=true"
|
<q-btn-dropdown id="btnStyle" icon="search" class="q-ma-sm" :disable="btnOpticalDisable"
|
||||||
label="Load your optical Image"></q-btn>
|
label="Load your optical image">
|
||||||
|
<q-item clickable v-close-popup v-on:click="btnOptical=true">
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label>Over normal image</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-item clickable v-close-popup v-on:click="btnOpticalT=true">
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label>Over TrIQ image</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-btn-dropdown>
|
||||||
<div class="q-mx-sm">
|
<div class="q-mx-sm">
|
||||||
<q-slider color="black" v-model="imgTrans" :min="0.0" :max="1" :step="0.1" :disable="btnOpticalDisable" />
|
<q-slider color="black" v-model="imgTrans" :min="0.0" :max="1" :step="0.1" :disable="btnOpticalDisable" />
|
||||||
<q-badge style="background-color: #009f90;"> Transparency: {{ imgTrans }}</q-badge>
|
<q-badge style="background-color: #009f90;"> Transparency: {{ imgTrans }}</q-badge>
|
||||||
@ -245,6 +256,8 @@
|
|||||||
<q-slider color="black" v-model="imgTrans" :min="0.0" :max="1" :step="0.1" :disable="btnOpticalDisable" />
|
<q-slider color="black" v-model="imgTrans" :min="0.0" :max="1" :step="0.1" :disable="btnOpticalDisable" />
|
||||||
<q-badge style="background-color: #009f90;"> Transparency: {{ imgTrans }}</q-badge>
|
<q-badge style="background-color: #009f90;"> Transparency: {{ imgTrans }}</q-badge>
|
||||||
</div>
|
</div>
|
||||||
|
<q-toggle id="btnOpticalOver" v-on:click="opticalOverTriq" v-model="opticalOverTriq" color="black"
|
||||||
|
label="Optical over TrIQ"></q-toggle>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
|
|
||||||
<q-card-section class="q-pt-none col-12">
|
<q-card-section class="q-pt-none col-12">
|
||||||
@ -313,17 +326,17 @@
|
|||||||
<!-- Content for Tab 0 -->
|
<!-- Content for Tab 0 -->
|
||||||
<!-- Btn image changer -->
|
<!-- Btn image changer -->
|
||||||
<div>
|
<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_back" class="q-my-sm" v-on:click="imgMinusComp=true"></q-btn>
|
||||||
<q-btn id="btnStyle" icon="arrow_forward" class="q-my-sm on-right" v-on:click="imgPlus=true"></q-btn>
|
<q-btn id="btnStyle" icon="arrow_forward" class="q-my-sm on-right" v-on:click="imgPlusComp=true"></q-btn>
|
||||||
</div>
|
</div>
|
||||||
<!-- Image manager -->
|
<!-- Image manager -->
|
||||||
<div id="image-container" class="row st-col col-12">
|
<div id="image-container" class="row st-col col-12">
|
||||||
<div class="col-10 q-pa-none q-ma-none ">
|
<div class="col-10 q-pa-none q-ma-none ">
|
||||||
<plotly id="plotStyle" :data="plotdataImg" :layout="plotlayoutImg" class="q-pa-none q-ma-none">
|
<plotly id="plotStyle" :data="plotdataImgComp" :layout="plotlayoutImgComp" class="q-pa-none q-ma-none">
|
||||||
</plotly>
|
</plotly>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-2 q-pa-none q-ma-none ">
|
<div class="col-2 q-pa-none q-ma-none ">
|
||||||
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbar"></q-img>
|
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbarComp"></q-img>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p>{{msgimg}}</p>
|
<p>{{msgimg}}</p>
|
||||||
@ -333,17 +346,17 @@
|
|||||||
<!-- Content for Tab 1 -->
|
<!-- Content for Tab 1 -->
|
||||||
<!-- Triq Btn image changer -->
|
<!-- Triq Btn image changer -->
|
||||||
<div>
|
<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_back" class="q-my-sm" v-on:click="imgMinusTComp=true"></q-btn>
|
||||||
<q-btn id="btnStyle" icon="arrow_forward" class="q-my-sm on-right" v-on:click="imgPlusT=true"></q-btn>
|
<q-btn id="btnStyle" icon="arrow_forward" class="q-my-sm on-right" v-on:click="imgPlusTComp=true"></q-btn>
|
||||||
</div>
|
</div>
|
||||||
<!-- Triq Image manager -->
|
<!-- Triq Image manager -->
|
||||||
<div id="image-container" class="row st-col col-12">
|
<div id="image-container" class="row st-col col-12">
|
||||||
<div class="col-10 q-pa-none q-ma-none ">
|
<div class="col-10 q-pa-none q-ma-none ">
|
||||||
<plotly id="plotStyle" :data="plotdataImgT" :layout="plotlayoutImgT" class="q-pa-none q-ma-none">
|
<plotly id="plotStyle" :data="plotdataImgTComp" :layout="plotlayoutImgTComp" class="q-pa-none q-ma-none">
|
||||||
</plotly>
|
</plotly>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-2 q-pa-none q-ma-none ">
|
<div class="col-2 q-pa-none q-ma-none ">
|
||||||
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbarT"></q-img>
|
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbarTComp"></q-img>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p>{{msgtriq}}</p>
|
<p>{{msgtriq}}</p>
|
||||||
|
|||||||
@ -78,3 +78,309 @@ function GetMzSliceJl(imzML, mass, tolerance)
|
|||||||
replace!(image, NaN => 0.0)
|
replace!(image, NaN => 0.0)
|
||||||
return image
|
return image
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# == Search functions ==
|
||||||
|
# Functions that recieve a list to update, and the current direction both as string for
|
||||||
|
# searching in the directory the position the list is going
|
||||||
|
function increment_image(current_image, image_list)
|
||||||
|
if isempty(image_list)
|
||||||
|
return nothing
|
||||||
|
end
|
||||||
|
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)
|
||||||
|
if isempty(image_list)
|
||||||
|
return nothing
|
||||||
|
end
|
||||||
|
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
|
||||||
|
|
||||||
|
## Plot Image functions
|
||||||
|
# loadImgPlot recieves the local directory of the image as a string,
|
||||||
|
# returns the layout and data for the heatmap plotly plot
|
||||||
|
# this function loads the image into a plot
|
||||||
|
function loadImgPlot(interfaceImg::String)
|
||||||
|
# Load the image
|
||||||
|
cleaned_img=replace(interfaceImg, r"\?.*" => "")
|
||||||
|
cleaned_img=lstrip(cleaned_img, '/')
|
||||||
|
var=joinpath("./public", cleaned_img)
|
||||||
|
img=load(var)
|
||||||
|
# Convert to grayscale
|
||||||
|
img_gray=Gray.(img)
|
||||||
|
img_array=Array(img_gray)
|
||||||
|
elevation=Float32.(Array(img_array)) ./ 255.0
|
||||||
|
# Get the X, Y coordinates of the image
|
||||||
|
height, width=size(img_array)
|
||||||
|
X=collect(1:width)
|
||||||
|
Y=collect(1:height)
|
||||||
|
|
||||||
|
# Create the layout
|
||||||
|
layout=PlotlyBase.Layout(
|
||||||
|
xaxis=PlotlyBase.attr(
|
||||||
|
visible=false,
|
||||||
|
scaleanchor="y"
|
||||||
|
),
|
||||||
|
yaxis=PlotlyBase.attr(
|
||||||
|
visible=false
|
||||||
|
),
|
||||||
|
margin=attr(l=0,r=0,t=0,b=0,pad=0)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create the trace for the image
|
||||||
|
trace=PlotlyBase.heatmap(
|
||||||
|
z=elevation,
|
||||||
|
x=X,
|
||||||
|
y=-Y,
|
||||||
|
name="",
|
||||||
|
showlegend=false,
|
||||||
|
colorscale="Viridis",
|
||||||
|
showscale=false,
|
||||||
|
colorbar=attr(
|
||||||
|
title=attr(
|
||||||
|
text="Intensity",
|
||||||
|
font=attr(
|
||||||
|
size=14,
|
||||||
|
color="black"
|
||||||
|
),
|
||||||
|
side="right"
|
||||||
|
),
|
||||||
|
ticks="outside",
|
||||||
|
ticklen=2,
|
||||||
|
tickwidth=0.5,
|
||||||
|
nticks=5,
|
||||||
|
tickformat=".2g"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
plotdata=[trace]
|
||||||
|
plotlayout=layout
|
||||||
|
return plotdata, plotlayout, width, height
|
||||||
|
end
|
||||||
|
# loadImgPlot recieves the local directory of the image as a string, the local directory o the overlay image
|
||||||
|
# and the transparency its required to have. Returns the layout and data for the heatmap plotly plot
|
||||||
|
# this function loads the image into a plot
|
||||||
|
function loadImgPlot(interfaceImg::String, overlayImg::String, imgTrans::Float64)
|
||||||
|
timestamp=string(time_ns())
|
||||||
|
# Load the main image
|
||||||
|
cleaned_img = replace(interfaceImg, r"\?.*" => "")
|
||||||
|
cleaned_img = lstrip(cleaned_img, '/')
|
||||||
|
var = joinpath("./public", cleaned_img)
|
||||||
|
img = load(var)
|
||||||
|
# Convert to grayscale
|
||||||
|
img_gray = Gray.(img)
|
||||||
|
img_array = Array(img_gray)
|
||||||
|
elevation = Float32.(Array(img_array)) ./ 255.0
|
||||||
|
# Get the X, Y coordinates of the image
|
||||||
|
height, width = size(img_array)
|
||||||
|
X = collect(1:width)
|
||||||
|
Y = collect(1:height)
|
||||||
|
|
||||||
|
# Create the layout with overlay image
|
||||||
|
layoutImg = PlotlyBase.Layout(
|
||||||
|
images = [attr(
|
||||||
|
source = "$(overlayImg)?t=$(timestamp)",
|
||||||
|
xref = "x",
|
||||||
|
yref = "y",
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
sizex = width,
|
||||||
|
sizey = -height,
|
||||||
|
sizing = "stretch",
|
||||||
|
opacity = imgTrans,
|
||||||
|
layer = "above" # Place the overlay image in the foreground
|
||||||
|
)],
|
||||||
|
xaxis = PlotlyBase.attr(
|
||||||
|
visible = false,
|
||||||
|
scaleanchor = "y",
|
||||||
|
range = [0, width]
|
||||||
|
),
|
||||||
|
yaxis = PlotlyBase.attr(
|
||||||
|
visible = false,
|
||||||
|
range = [-height,0]
|
||||||
|
),
|
||||||
|
margin = attr(l = 0, r = 0, t = 0, b = 0, pad = 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create the trace for the main image
|
||||||
|
trace = PlotlyBase.heatmap(
|
||||||
|
z = elevation,
|
||||||
|
x = X,
|
||||||
|
y = -Y,
|
||||||
|
name = "",
|
||||||
|
showlegend = false,
|
||||||
|
colorscale = "Viridis",
|
||||||
|
showscale = false
|
||||||
|
)
|
||||||
|
|
||||||
|
plotdata = [trace]
|
||||||
|
plotlayout = layoutImg
|
||||||
|
return plotdata, plotlayout, width, height
|
||||||
|
end
|
||||||
|
|
||||||
|
# loadContourPlot recieves the local directory of the image as a string,
|
||||||
|
# returns the layout and data for the contour plotly plot
|
||||||
|
# this function loads the image and applies a gaussian filter
|
||||||
|
# to smoothen it and loads it into a plot
|
||||||
|
function loadContourPlot(interfaceImg::String)
|
||||||
|
# Load the image
|
||||||
|
cleaned_img=replace(interfaceImg, r"\?.*" => "")
|
||||||
|
cleaned_img=lstrip(cleaned_img, '/')
|
||||||
|
var=joinpath("./public", cleaned_img)
|
||||||
|
img=load(var)
|
||||||
|
img_gray=Gray.(img)
|
||||||
|
img_array=Array(img_gray)
|
||||||
|
elevation=Float32.(Array(img_array))./ 255.0 # Normalize between 0 and 1
|
||||||
|
|
||||||
|
# Smooth the image
|
||||||
|
sigma=3.0
|
||||||
|
kernel=Kernel.gaussian(sigma)
|
||||||
|
elevation_smoothed=imfilter(elevation, kernel)
|
||||||
|
|
||||||
|
# Create the X, Y meshgrid coordinates
|
||||||
|
x=1:size(elevation_smoothed, 2)
|
||||||
|
y=1:size(elevation_smoothed, 1)
|
||||||
|
X=repeat(reshape(x, 1, length(x)), length(y), 1)
|
||||||
|
Y=repeat(reshape(y, length(y), 1), 1, length(x))
|
||||||
|
|
||||||
|
layout=PlotlyBase.Layout(
|
||||||
|
title="2D Topographic Map of $cleaned_img",
|
||||||
|
xaxis=PlotlyBase.attr(
|
||||||
|
title="X",
|
||||||
|
scaleanchor="y"
|
||||||
|
),
|
||||||
|
yaxis=PlotlyBase.attr(
|
||||||
|
title="Y"
|
||||||
|
),
|
||||||
|
margin=attr(l=0,r=0,t=120,b=0,pad=0)
|
||||||
|
)
|
||||||
|
trace=PlotlyBase.contour(
|
||||||
|
z=elevation_smoothed,
|
||||||
|
x=X[1, :], # Use the first row
|
||||||
|
y=-Y[:, 1], # Use the first column
|
||||||
|
contours_coloring="Viridis",
|
||||||
|
colorscale="Viridis",
|
||||||
|
colorbar=attr(
|
||||||
|
tickformat=".2g"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
plotdata=[trace]
|
||||||
|
plotlayout=layout
|
||||||
|
return plotdata, plotlayout
|
||||||
|
end
|
||||||
|
# loadSurfacePlot recieves the local directory of the image as a string,
|
||||||
|
# returns the layout and data for the surface plotly plot
|
||||||
|
# this function loads the image and applies a gaussian filter
|
||||||
|
# to smoothen it and loads it into a 3D plot
|
||||||
|
function loadSurfacePlot(interfaceImg::String)
|
||||||
|
# Load the image
|
||||||
|
cleaned_img=replace(interfaceImg, r"\?.*" => "")
|
||||||
|
cleaned_img=lstrip(cleaned_img, '/')
|
||||||
|
var=joinpath("./public", cleaned_img)
|
||||||
|
img=load(var)
|
||||||
|
img_gray=Gray.(img) # Convert to grayscale
|
||||||
|
img_array=Array(img_gray)
|
||||||
|
elevation=Float32.(Array(img_array)) ./ 255.0 # Normalize between 0 and 1
|
||||||
|
# Smooth the image
|
||||||
|
sigma=3.0
|
||||||
|
kernel=Kernel.gaussian(sigma)
|
||||||
|
elevation_smoothed=imfilter(elevation, kernel)
|
||||||
|
# Create the X, Y meshgrid coordinates
|
||||||
|
x=1:size(elevation_smoothed, 2)
|
||||||
|
y=1:size(elevation_smoothed, 1)
|
||||||
|
X=repeat(reshape(x, 1, length(x)), length(y), 1)
|
||||||
|
Y=repeat(reshape(y, length(y), 1), 1, length(x))
|
||||||
|
# Calculate the number of ticks and aspect ratio for the 3d plot
|
||||||
|
x_nticks=min(20, length(x))
|
||||||
|
y_nticks=min(20, length(y))
|
||||||
|
z_nticks=5
|
||||||
|
aspect_ratio=attr(x=1, y=length(y) / length(x), z=0.5)
|
||||||
|
# Define the layout for the 3D plot
|
||||||
|
layout3D=PlotlyBase.Layout(
|
||||||
|
title="3D Surface Plot of $cleaned_img",
|
||||||
|
scene=attr(
|
||||||
|
xaxis_nticks=x_nticks,
|
||||||
|
yaxis_nticks=y_nticks,
|
||||||
|
zaxis_nticks=z_nticks,
|
||||||
|
camera=attr(eye=attr(x=0, y=1, z=0.5)),
|
||||||
|
aspectratio=aspect_ratio
|
||||||
|
),
|
||||||
|
margin=attr(l=0,r=0,t=120,b=0,pad=0)
|
||||||
|
)
|
||||||
|
# Transpose the elevation_smoothed array if Y axis is longer than X axis to fix chopping
|
||||||
|
elevation_smoothed=transpose(elevation_smoothed)
|
||||||
|
if size(elevation_smoothed, 1) < size(elevation_smoothed, 2)
|
||||||
|
Y=-Y
|
||||||
|
else
|
||||||
|
X=-X
|
||||||
|
end
|
||||||
|
|
||||||
|
trace3D=PlotlyBase.surface(
|
||||||
|
x=X[1, :],
|
||||||
|
y=Y[:, 1],
|
||||||
|
z=elevation_smoothed,
|
||||||
|
contours_z=attr(
|
||||||
|
show=true,
|
||||||
|
usecolormap=true,
|
||||||
|
highlightcolor="limegreen",
|
||||||
|
project_z=true
|
||||||
|
),
|
||||||
|
colorscale="Viridis",
|
||||||
|
colorbar=attr(
|
||||||
|
tickformat=".2g"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
plotdata=[trace3D]
|
||||||
|
plotlayout=layout3D
|
||||||
|
return plotdata, plotlayout
|
||||||
|
end
|
||||||
|
# This function recieves the x and y coords currently selected, and the dimentions of
|
||||||
|
# the image to create two traces that will display in a cross section
|
||||||
|
function crossLinesPlot(x, y, maxwidth, maxheight)
|
||||||
|
# Define the coordinates for the two lines
|
||||||
|
l1_x=[0, maxwidth]
|
||||||
|
l1_y=[y, y]
|
||||||
|
l2_x=[x, x]
|
||||||
|
l2_y=[0, maxheight]
|
||||||
|
|
||||||
|
# Create the line traces
|
||||||
|
trace1=PlotlyBase.scatter(x=l1_x, y=l1_y, mode="lines",line=attr(color="red", width=0.5),name="Line X",showlegend=false)
|
||||||
|
trace2=PlotlyBase.scatter(x=l2_x, y=l2_y, mode="lines",line=attr(color="red", width=0.5),name="Line Y",showlegend=false)
|
||||||
|
|
||||||
|
return trace1, trace2
|
||||||
|
end
|
||||||
|
|
||||||
|
# This function is used for giving colorbar values a visual format
|
||||||
|
# that shortens long values giving them scientific notation
|
||||||
|
function log_tick_formatter(values::Vector{Float64})
|
||||||
|
# Initialize exponents dictionary
|
||||||
|
exponents=zeros(Int, length(values))
|
||||||
|
formValues=zeros(Float64, length(values))
|
||||||
|
for i in 1:length(values)
|
||||||
|
value = values[i]
|
||||||
|
if value >= 1000 # positive formatting for notation
|
||||||
|
while value >= 1000
|
||||||
|
value /= 10
|
||||||
|
exponents[i] += 1
|
||||||
|
end
|
||||||
|
elseif value > 0 && value < 1 # negative formatting for notation
|
||||||
|
while value < 1
|
||||||
|
value *= 10
|
||||||
|
exponents[i] -= 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
formValues[i]=value
|
||||||
|
end
|
||||||
|
return map((v, e) -> e == 0 ? "$(round(v, sigdigits=2))" : "$(round(v, sigdigits=2))x10" * Makie.UnicodeFun.to_superscript(e), formValues, exponents)
|
||||||
|
|
||||||
|
end
|
||||||
Loading…
x
Reference in New Issue
Block a user