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
|
||||
```
|
||||
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>
|
||||
After the first boot initializes the packages in your computer, subsequent uses of the app should not take longer to load.<br>
|
||||
|
||||
31
app.jl
31
app.jl
@ -13,6 +13,7 @@ using Images
|
||||
using LinearAlgebra
|
||||
using NativeFileDialog # Opens the file explorer depending on the OS
|
||||
using StipplePlotly
|
||||
using Printf
|
||||
include("./julia_imzML_visual.jl")
|
||||
@genietools
|
||||
|
||||
@ -121,7 +122,8 @@ function loadContourPlot(interfaceImg::String)
|
||||
img=load(var)
|
||||
img_gray=Gray.(img)
|
||||
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
|
||||
sigma=3.0
|
||||
@ -487,7 +489,7 @@ end
|
||||
text_nmass=replace(string(Nmass), "." => "_")
|
||||
sTime=time()
|
||||
#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."
|
||||
try
|
||||
spectra=LoadImzml(full_route)
|
||||
@ -497,12 +499,12 @@ end
|
||||
# Append a query string to force the image to refresh
|
||||
timestamp=string(time_ns())
|
||||
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."
|
||||
warning_msg=true
|
||||
else
|
||||
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("TriQ matrix: $(typeof(sliceTriq))")
|
||||
sliceTriq=reverse(sliceTriq, dims=2)
|
||||
@ -515,8 +517,19 @@ end
|
||||
current_triq="TrIQ_$(text_nmass).bmp"
|
||||
msgtriq="TrIQ image with the Nmass of $(replace(text_nmass, "_" => "."))"
|
||||
# Create colorbar
|
||||
ticks=round.(range(0, (stop=maximum(sliceTriq)*triqProb), length=15), sigdigits=3)
|
||||
Colorbar(fig[1, 1], colormap=cgrad(:viridis, colorLevel, categorical=true), limits=(0, maximum(sliceTriq)*triqProb),ticks=ticks, label="Intensity", size = 25)
|
||||
#ticks=round.(range(0, (stop=maximum(slice)*triqProb), length=10), sigdigits=3)
|
||||
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)
|
||||
colorbarT="/colorbar_TrIQ_$(text_nmass).png?t=$(timestamp)"
|
||||
# Get current colorbar
|
||||
@ -534,7 +547,7 @@ end
|
||||
else # If we don't use TrIQ
|
||||
image_path=joinpath("./public", "MSI_$(text_nmass).bmp")
|
||||
##sliceQuant=IntQuant(slice)
|
||||
sliceQuant=IntQuantCl(slice,colorLevel)
|
||||
sliceQuant=IntQuantCl(slice,Int(colorLevel-1))
|
||||
#println("slice raw: $(typeof(slice))")
|
||||
#println("slice in intQuant: $(typeof(sliceQuant))")
|
||||
sliceQuant=reverse(sliceQuant, dims=2)
|
||||
@ -548,8 +561,8 @@ end
|
||||
msgimg="Image with the Nmass of $(replace(text_nmass, "_" => "."))"
|
||||
# Create colorbar
|
||||
#ticks=round.(range(0, stop=maximum(slice), length=10), sigdigits=3)
|
||||
ticks=round.(range(0, stop=maximum(sliceQuant), length=15), sigdigits=3)
|
||||
Colorbar(fig[1, 1], colormap=cgrad(:viridis, colorLevel, categorical=true), limits=(0, maximum(sliceQuant)),ticks=ticks, label="Intensity", size = 25)
|
||||
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)
|
||||
save("public/colorbar_MSI_$(text_nmass).png", fig)
|
||||
colorbar="/colorbar_MSI_$(text_nmass).png?t=$(timestamp)"
|
||||
# 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">
|
||||
<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 || 'Need positive mass values',]"></q-input>
|
||||
:rules="[ val => !!val || '* Required', val => val >= 0.0 || 'Need positive mass values']"></q-input>
|
||||
</div>
|
||||
<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"
|
||||
: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 class="st-col col-4 col-sm q-ma-sm">
|
||||
<q-input standout="custom-standout" id="textcolorLevel" step="1" v-model="colorLevel"
|
||||
label="Color level" type="number" :rules="[
|
||||
val => triqEnabled ? ( '* Required', val >= 4 && val <= 256 || 'Needs to be in range between 2 and 256') : true
|
||||
]"></q-input>
|
||||
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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
||||
@ -15,14 +15,16 @@ end
|
||||
# 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
|
||||
# available in pixmap
|
||||
function SaveBitmapCl( name,
|
||||
pixMap::Array{UInt8,2},
|
||||
colorTable::Array{UInt32,1} )
|
||||
function SaveBitmapCl( name, pixMap::Array{UInt8,2}, colorTable::Array{UInt32,1} )
|
||||
# Get image dimensions
|
||||
dim = size( pixMap )
|
||||
if length( dim ) != 2
|
||||
return 0
|
||||
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
|
||||
padding = ( 4 - dim[1] & 0x3 ) & 0x3
|
||||
# Compute file dimensions. Header = 14 + 40 + ( 256 * 4 ) = 1078
|
||||
@ -36,17 +38,12 @@ function SaveBitmapCl( name,
|
||||
# Save info header
|
||||
write( stream, UInt32[ 40, dim[1], dim[2], 0x80001, 0 ] )
|
||||
write( stream, UInt32[ imgBytes, 0, 0, 256, 0 ] )
|
||||
# Get unique colors displayed in pixMap
|
||||
unique_colors = unique(vec(pixMap))
|
||||
n_colors = length(unique_colors)
|
||||
# Color levels can't surpass 256
|
||||
levels = min(n_colors, 256)
|
||||
extendedColorTable = zeros(UInt32, 256)
|
||||
for i in 1:256
|
||||
idx = ceil(Int, i * levels / 256)
|
||||
extendedColorTable[i] = colorTable[idx]
|
||||
# Save color table
|
||||
write( stream, colorTable )
|
||||
if length( colorTable ) < 256
|
||||
fixTable = zeros( UInt32, 256 - length( colorTable ) )
|
||||
write( stream, fixTable )
|
||||
end
|
||||
write(stream, extendedColorTable)
|
||||
# Save image pixels
|
||||
if padding == 0
|
||||
for i = 1:dim[2]
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Pkg
|
||||
sTime=time()
|
||||
Pkg.activate(".")
|
||||
Pkg.instantiate()
|
||||
Pkg.gc()
|
||||
@ -31,6 +32,8 @@ Genie.loadapp()
|
||||
# Start the Genie server
|
||||
@async begin
|
||||
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"
|
||||
# Open the URL in the default web browser based on the OS
|
||||
if Sys.isapple()
|
||||
@ -43,5 +46,4 @@ Genie.loadapp()
|
||||
@async run(`Start-Process $url`) # For Windows
|
||||
end
|
||||
end
|
||||
|
||||
wait()
|
||||
Loading…
x
Reference in New Issue
Block a user