Bitmap is now normalized in creation, which evenly distributes colors of the colorTable better, now IntQuant allows for coloLevel adjustments
This commit is contained in:
parent
df0d82910b
commit
fdd625d3e0
@ -22,7 +22,7 @@ A Graphical User Interface for MSI in Julia: https://github.com/CINVESTAV-LABI/j
|
|||||||
```
|
```
|
||||||
julia --project=. start_MSI_GUI.jl
|
julia --project=. start_MSI_GUI.jl
|
||||||
```
|
```
|
||||||
3. After the script has finished loading, it should open a page (http://127.0.0.1:1481/) in your browser with the web app running.
|
3. After the script has finished loading, You can open a page (http://127.0.0.1:1481/) in your browser with the web app running.
|
||||||
|
|
||||||
Additional notes:<br>
|
Additional notes:<br>
|
||||||
After the first boot initializes the packages in your computer, subsequent uses of the app should not take longer to load.<br>
|
After the first boot initializes the packages in your computer, subsequent uses of the app should not take longer to load.<br>
|
||||||
|
|||||||
33
app.jl
33
app.jl
@ -13,6 +13,7 @@ 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 Printf
|
||||||
include("./julia_imzML_visual.jl")
|
include("./julia_imzML_visual.jl")
|
||||||
@genietools
|
@genietools
|
||||||
|
|
||||||
@ -121,7 +122,8 @@ function loadContourPlot(interfaceImg::String)
|
|||||||
img=load(var)
|
img=load(var)
|
||||||
img_gray=Gray.(img)
|
img_gray=Gray.(img)
|
||||||
img_array=Array(img_gray)
|
img_array=Array(img_gray)
|
||||||
elevation=Float32.(Array(img_gray)) ./ 255.0 # Normalize between 0 and 1
|
# parse matrix to int32 to closely resemble similarity to original bitmap
|
||||||
|
elevation=int32.(Array(img_gray))
|
||||||
|
|
||||||
# Smooth the image
|
# Smooth the image
|
||||||
sigma=3.0
|
sigma=3.0
|
||||||
@ -487,7 +489,7 @@ end
|
|||||||
text_nmass=replace(string(Nmass), "." => "_")
|
text_nmass=replace(string(Nmass), "." => "_")
|
||||||
sTime=time()
|
sTime=time()
|
||||||
#full_route=joinpath(file_route, file_name)
|
#full_route=joinpath(file_route, file_name)
|
||||||
if isfile(full_route) && Nmass > 0 && Tol > 0 && Tol <=1
|
if isfile(full_route) && Nmass > 0 && Tol > 0 && Tol <=1 && 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)
|
||||||
@ -497,12 +499,12 @@ end
|
|||||||
# Append a query string to force the image to refresh
|
# Append a query string to force the image to refresh
|
||||||
timestamp=string(time_ns())
|
timestamp=string(time_ns())
|
||||||
if triqEnabled # If we have TrIQ
|
if triqEnabled # If we have TrIQ
|
||||||
if colorLevel < 2 || colorLevel > 256 || triqProb < 0.8 || triqProb > 1
|
if triqProb < 0.8 || triqProb > 1
|
||||||
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
|
||||||
image_path=joinpath("./public", "TrIQ_$(text_nmass).bmp")
|
image_path=joinpath("./public", "TrIQ_$(text_nmass).bmp")
|
||||||
sliceTriq=TrIQ(slice, Int(colorLevel), triqProb)
|
sliceTriq=TrIQ(slice, colorLevel, triqProb)
|
||||||
#println("slice raw: $(typeof(slice))")
|
#println("slice raw: $(typeof(slice))")
|
||||||
#println("TriQ matrix: $(typeof(sliceTriq))")
|
#println("TriQ matrix: $(typeof(sliceTriq))")
|
||||||
sliceTriq=reverse(sliceTriq, dims=2)
|
sliceTriq=reverse(sliceTriq, dims=2)
|
||||||
@ -514,9 +516,20 @@ end
|
|||||||
# Get current image
|
# Get current image
|
||||||
current_triq="TrIQ_$(text_nmass).bmp"
|
current_triq="TrIQ_$(text_nmass).bmp"
|
||||||
msgtriq="TrIQ image with the Nmass of $(replace(text_nmass, "_" => "."))"
|
msgtriq="TrIQ image with the Nmass of $(replace(text_nmass, "_" => "."))"
|
||||||
# Create colorbar
|
# Create colorbar
|
||||||
ticks=round.(range(0, (stop=maximum(sliceTriq)*triqProb), length=15), sigdigits=3)
|
#ticks=round.(range(0, (stop=maximum(slice)*triqProb), length=10), sigdigits=3)
|
||||||
Colorbar(fig[1, 1], colormap=cgrad(:viridis, colorLevel, categorical=true), limits=(0, maximum(sliceTriq)*triqProb),ticks=ticks, label="Intensity", size = 25)
|
ticks=range(0, (stop=maximum(slice)*triqProb), length=5)
|
||||||
|
|
||||||
|
"""
|
||||||
|
function log_tick_formatter(values)
|
||||||
|
return map(v -> "10" * Makie.UnicodeFun.to_superscript(round(Int64, v)), values)
|
||||||
|
end
|
||||||
|
"""
|
||||||
|
|
||||||
|
println("ticks: $(typeof(ticks))")
|
||||||
|
#Colorbar(fig[1, 1], colormap=cgrad(:viridis, colorLevel, categorical=true), limits=(0, maximum(slice)*triqProb),ticks=ticks,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
|
||||||
@ -534,7 +547,7 @@ 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,colorLevel)
|
sliceQuant=IntQuantCl(slice,Int(colorLevel-1))
|
||||||
#println("slice raw: $(typeof(slice))")
|
#println("slice raw: $(typeof(slice))")
|
||||||
#println("slice in intQuant: $(typeof(sliceQuant))")
|
#println("slice in intQuant: $(typeof(sliceQuant))")
|
||||||
sliceQuant=reverse(sliceQuant, dims=2)
|
sliceQuant=reverse(sliceQuant, dims=2)
|
||||||
@ -548,8 +561,8 @@ end
|
|||||||
msgimg="Image with the Nmass of $(replace(text_nmass, "_" => "."))"
|
msgimg="Image with the Nmass of $(replace(text_nmass, "_" => "."))"
|
||||||
# Create colorbar
|
# Create colorbar
|
||||||
#ticks=round.(range(0, stop=maximum(slice), length=10), sigdigits=3)
|
#ticks=round.(range(0, stop=maximum(slice), length=10), sigdigits=3)
|
||||||
ticks=round.(range(0, stop=maximum(sliceQuant), length=15), sigdigits=3)
|
ticks=range(0, stop=maximum(slice), length=5)
|
||||||
Colorbar(fig[1, 1], colormap=cgrad(:viridis, colorLevel, categorical=true), limits=(0, maximum(sliceQuant)),ticks=ticks, label="Intensity", size = 25)
|
Colorbar(fig[1, 1], colormap=cgrad(:viridis, colorLevel, categorical=true), limits=(0, maximum(slice)),ticks=ticks, 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)"
|
||||||
# Get current colorbar
|
# Get current colorbar
|
||||||
|
|||||||
10
app.jl.html
10
app.jl.html
@ -60,18 +60,16 @@
|
|||||||
<div class="st-col col-4 col-sm q-ma-sm">
|
<div class="st-col col-4 col-sm q-ma-sm">
|
||||||
<q-input standout="custom-standout" id="textNmass" step="0.01" v-model="Nmass"
|
<q-input standout="custom-standout" id="textNmass" step="0.01" v-model="Nmass"
|
||||||
label="Mass-to-charge ratio of interest" type="number"
|
label="Mass-to-charge ratio of interest" type="number"
|
||||||
:rules="[ val => !!val || '* Required', val => val >= 0.0 || 'Need positive mass values',]"></q-input>
|
:rules="[ val => !!val || '* Required', val => val >= 0.0 || 'Need positive mass values']"></q-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="st-col col-4 col-sm q-ma-sm">
|
<div class="st-col col-4 col-sm q-ma-sm">
|
||||||
<q-input standout="custom-standout" id="textTol" step="0.05" v-model="Tol"
|
<q-input standout="custom-standout" id="textTol" step="0.005" v-model="Tol"
|
||||||
label="Mass-to-charge ratio tolerance" type="number"
|
label="Mass-to-charge ratio tolerance" type="number"
|
||||||
:rules="[val => !!val || '* Required', val => val >= 0.0 && val <= 1.0 || 'Needs to be in range between 0 and 1',]"></q-input>
|
:rules="[val => !!val || '* Required', val => val >= 0.0 && val <= 1.0 || 'Needs to be in range between 0 and 1']"></q-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="st-col col-4 col-sm q-ma-sm">
|
<div class="st-col col-4 col-sm q-ma-sm">
|
||||||
<q-input standout="custom-standout" id="textcolorLevel" step="1" v-model="colorLevel"
|
<q-input standout="custom-standout" id="textcolorLevel" step="1" v-model="colorLevel"
|
||||||
label="Color level" type="number" :rules="[
|
label="Color level" type="number" :rules="[ val => !!val || '* Required', val => val >= 2 && val <= 256 || 'Needs to be in range between 2 and 256']"></q-input>
|
||||||
val => triqEnabled ? ( '* Required', val >= 4 && val <= 256 || 'Needs to be in range between 2 and 256') : true
|
|
||||||
]"></q-input>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@ -15,14 +15,16 @@ end
|
|||||||
# SaveBitmap is also originally a function of the mzML imzML library in julia,
|
# SaveBitmap is also originally a function of the mzML imzML library in julia,
|
||||||
# This function dinamically adjust the color palete adjusting to the ammount of colors
|
# This function dinamically adjust the color palete adjusting to the ammount of colors
|
||||||
# available in pixmap
|
# available in pixmap
|
||||||
function SaveBitmapCl( name,
|
function SaveBitmapCl( name, pixMap::Array{UInt8,2}, colorTable::Array{UInt32,1} )
|
||||||
pixMap::Array{UInt8,2},
|
|
||||||
colorTable::Array{UInt32,1} )
|
|
||||||
# Get image dimensions
|
# Get image dimensions
|
||||||
dim = size( pixMap )
|
dim = size( pixMap )
|
||||||
if length( dim ) != 2
|
if length( dim ) != 2
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
# Normalize pixel values to get a more accurate reading of the image
|
||||||
|
min_val = minimum(pixMap)
|
||||||
|
max_val = maximum(pixMap)
|
||||||
|
pixMap = round.(UInt8, 255 * (pixMap .- min_val) ./ (max_val - min_val))
|
||||||
# Compute row padding
|
# Compute row padding
|
||||||
padding = ( 4 - dim[1] & 0x3 ) & 0x3
|
padding = ( 4 - dim[1] & 0x3 ) & 0x3
|
||||||
# Compute file dimensions. Header = 14 + 40 + ( 256 * 4 ) = 1078
|
# Compute file dimensions. Header = 14 + 40 + ( 256 * 4 ) = 1078
|
||||||
@ -36,17 +38,12 @@ function SaveBitmapCl( name,
|
|||||||
# Save info header
|
# Save info header
|
||||||
write( stream, UInt32[ 40, dim[1], dim[2], 0x80001, 0 ] )
|
write( stream, UInt32[ 40, dim[1], dim[2], 0x80001, 0 ] )
|
||||||
write( stream, UInt32[ imgBytes, 0, 0, 256, 0 ] )
|
write( stream, UInt32[ imgBytes, 0, 0, 256, 0 ] )
|
||||||
# Get unique colors displayed in pixMap
|
# Save color table
|
||||||
unique_colors = unique(vec(pixMap))
|
write( stream, colorTable )
|
||||||
n_colors = length(unique_colors)
|
if length( colorTable ) < 256
|
||||||
# Color levels can't surpass 256
|
fixTable = zeros( UInt32, 256 - length( colorTable ) )
|
||||||
levels = min(n_colors, 256)
|
write( stream, fixTable )
|
||||||
extendedColorTable = zeros(UInt32, 256)
|
|
||||||
for i in 1:256
|
|
||||||
idx = ceil(Int, i * levels / 256)
|
|
||||||
extendedColorTable[i] = colorTable[idx]
|
|
||||||
end
|
end
|
||||||
write(stream, extendedColorTable)
|
|
||||||
# Save image pixels
|
# Save image pixels
|
||||||
if padding == 0
|
if padding == 0
|
||||||
for i = 1:dim[2]
|
for i = 1:dim[2]
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using Pkg
|
using Pkg
|
||||||
|
sTime=time()
|
||||||
Pkg.activate(".")
|
Pkg.activate(".")
|
||||||
Pkg.instantiate()
|
Pkg.instantiate()
|
||||||
Pkg.gc()
|
Pkg.gc()
|
||||||
@ -31,6 +32,8 @@ Genie.loadapp()
|
|||||||
# Start the Genie server
|
# Start the Genie server
|
||||||
@async begin
|
@async begin
|
||||||
up(host="127.0.0.1", port=1481)
|
up(host="127.0.0.1", port=1481)
|
||||||
|
eTime=round(time()-sTime,digits=3)
|
||||||
|
println("Julia MSI GUI took $(eTime) seconds booting")
|
||||||
url = "http://127.0.0.1:1481"
|
url = "http://127.0.0.1:1481"
|
||||||
# Open the URL in the default web browser based on the OS
|
# Open the URL in the default web browser based on the OS
|
||||||
if Sys.isapple()
|
if Sys.isapple()
|
||||||
@ -43,5 +46,4 @@ Genie.loadapp()
|
|||||||
@async run(`Start-Process $url`) # For Windows
|
@async run(`Start-Process $url`) # For Windows
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
wait()
|
wait()
|
||||||
Loading…
x
Reference in New Issue
Block a user