Skip to content
Snippets Groups Projects
Commit ea94f27f authored by fima's avatar fima :beers:
Browse files

Merge branch 'data_explorer' into 'main'

Data explorer with basic viz

See merge request !9
parents 0b24d0e1 5b7082bb
No related branches found
No related tags found
1 merge request!9Data explorer with basic viz
...@@ -2,12 +2,13 @@ import gradio as gr ...@@ -2,12 +2,13 @@ import gradio as gr
import numpy as np import numpy as np
import os import os
from qim3d.utils import internal_tools from qim3d.utils import internal_tools
from qim3d.io import DataLoader from qim3d.io import load
from qim3d.io.logger import log from qim3d.io.logger import log
import tifffile import tifffile
import outputformat as ouf import outputformat as ouf
import datetime import datetime
import matplotlib import matplotlib
# matplotlib.use("Agg") # matplotlib.use("Agg")
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
...@@ -31,17 +32,29 @@ class Interface: ...@@ -31,17 +32,29 @@ class Interface:
def create_interface(self): def create_interface(self):
with gr.Blocks(css=self.css_path) as gradio_interface: with gr.Blocks(css=self.css_path) as gradio_interface:
gr.Markdown("# Data Explorer \n Quick insights from large datasets") gr.Markdown("# Data Explorer")
with gr.Row(): with gr.Row():
data_path = gr.Textbox( with gr.Column(scale=0.75):
value="/home/fima/Downloads/MarineGatropod_1.tif", data_path = gr.Textbox(
max_lines=1, value="/home/fima/reconstructor-main/small_foram.h5",
label="Path to the 3D volume", max_lines=1,
label="Path to the 3D volume",
)
with gr.Column(scale=0.25):
dataset_name = gr.Textbox(
label="Dataset name (in case of H5 files, for example)"
)
with gr.Row(elem_classes="w-256"):
cmap = gr.Dropdown(
value="viridis",
choices=plt.colormaps(),
label="Colormap",
interactive=True,
) )
with gr.Row(elem_classes=" w-128"): with gr.Row(elem_classes="w-128"):
btn_run = gr.Button(value="Load & Run", elem_classes="btn btn-run") btn_run = gr.Button(value="Load & Run", elem_classes="btn btn-run")
# Outputs # Outputs
with gr.Row(): with gr.Row():
gr.Markdown("## Data overview") gr.Markdown("## Data overview")
...@@ -85,24 +98,10 @@ class Interface: ...@@ -85,24 +98,10 @@ class Interface:
pipeline.verbose = self.verbose pipeline.verbose = self.verbose
session = gr.State([]) session = gr.State([])
with gr.Row():
gr.Markdown("## Local thickness")
with gr.Row():
gr.Plot()
gr.Plot()
gr.Plot()
with gr.Row():
gr.Markdown("## Structure tensor")
with gr.Row():
gr.Plot()
gr.Plot()
gr.Plot()
### Gradio objects lists ### Gradio objects lists
# Inputs # Inputs
inputs = [zpos, ypos, xpos] inputs = [zpos, ypos, xpos, cmap, dataset_name]
# Outputs # Outputs
outputs = [ outputs = [
data_summary, data_summary,
...@@ -156,6 +155,8 @@ class Interface: ...@@ -156,6 +155,8 @@ class Interface:
session.zpos = args[0] session.zpos = args[0]
session.ypos = args[1] session.ypos = args[1]
session.xpos = args[2] session.xpos = args[2]
session.cmap = args[3]
session.dataset_name = args[4]
return session return session
...@@ -191,7 +192,6 @@ class Interface: ...@@ -191,7 +192,6 @@ class Interface:
else: else:
quiet = True quiet = True
interface.launch( interface.launch(
quiet=quiet, quiet=quiet,
height=self.height, height=self.height,
...@@ -208,6 +208,9 @@ class Session: ...@@ -208,6 +208,9 @@ class Session:
self.zpos = 0.5 self.zpos = 0.5
self.ypos = 0.5 self.ypos = 0.5
self.xpos = 0.5 self.xpos = 0.5
self.cmap = "viridis"
self.dataset_name = None
self.error_message = None
# Volume info # Volume info
self.zsize = None self.zsize = None
...@@ -229,40 +232,51 @@ class Session: ...@@ -229,40 +232,51 @@ class Session:
def get_data_info(self): def get_data_info(self):
# Open file # Open file
tif = tifffile.TiffFile(self.data_path) try:
first_slice = tif.pages[0] vol = load(
self.data_path, virtual_stack=True, dataset_name=self.dataset_name
)
except Exception as error_message:
self.error_message = error_message
return
first_slice = vol[0]
# Get info # Get info
self.zsize = len(tif.pages) self.zsize = len(vol)
self.ysize, self.xsize = first_slice.shape self.ysize, self.xsize = first_slice.shape
self.data_type = first_slice.dtype self.data_type = str(first_slice.dtype)
self.axes = tif.series[0].axes
self.last_modified = datetime.datetime.fromtimestamp( self.last_modified = datetime.datetime.fromtimestamp(
os.path.getmtime(self.data_path) os.path.getmtime(self.data_path)
).strftime("%Y-%m-%d %H:%M") ).strftime("%Y-%m-%d %H:%M")
self.file_size = os.path.getsize(self.data_path) self.file_size = os.path.getsize(self.data_path)
# Close file
tif.close()
def create_summary_dict(self): def create_summary_dict(self):
# Create dictionary # Create dictionary
self.summary_dict = { if self.error_message:
"Last modified": self.last_modified, self.summary_dict = {"error_mesage": self.error_message}
"File size": internal_tools.sizeof(self.file_size),
"Axes": self.axes, else:
"Z-size": str(self.zsize), self.summary_dict = {
"Y-size": str(self.ysize), "Last modified": self.last_modified,
"X-size": str(self.xsize), "File size": internal_tools.sizeof(self.file_size),
"Data type": self.data_type, "Z-size": str(self.zsize),
"Min value": self.min_value, "Y-size": str(self.ysize),
"Mean value": self.mean_intensity, "X-size": str(self.xsize),
"Max value": self.max_value, "Data type": self.data_type,
} "Min value": self.min_value,
"Mean value": self.mean_intensity,
"Max value": self.max_value,
}
def summary_str(self): def summary_str(self):
display_dict = {k: v for k, v in self.summary_dict.items() if v is not None} if "error_mesage" in self.summary_dict:
return ouf.showdict(display_dict, return_str=True, title="Data summary") error_box = ouf.boxtitle("ERROR", return_str=True)
return f"{error_box}\n{self.summary_dict['error_mesage']}"
else:
display_dict = {k: v for k, v in self.summary_dict.items() if v is not None}
return ouf.showdict(display_dict, return_str=True, title="Data summary")
def zslice_from_zpos(self): def zslice_from_zpos(self):
self.zslice = int(self.zpos * (self.zsize - 1)) self.zslice = int(self.zpos * (self.zsize - 1))
...@@ -295,7 +309,13 @@ class Pipeline: ...@@ -295,7 +309,13 @@ class Pipeline:
session.create_summary_dict() session.create_summary_dict()
# Memory map data as a virtual stack # Memory map data as a virtual stack
session.vol = DataLoader().load_tiff(session.data_path)
try:
session.vol = load(
session.data_path, virtual_stack=True, dataset_name=session.dataset_name
)
except:
return session
if self.verbose: if self.verbose:
log.info(ouf.br(3, return_str=True) + session.summary_str()) log.info(ouf.br(3, return_str=True) + session.summary_str())
...@@ -324,6 +344,7 @@ class Pipeline: ...@@ -324,6 +344,7 @@ class Pipeline:
def create_slice_fig(self, axis, session): def create_slice_fig(self, axis, session):
plt.close() plt.close()
vol = session.vol vol = session.vol
plt.set_cmap(session.cmap)
zslice = session.zslice_from_zpos() zslice = session.zslice_from_zpos()
yslice = session.yslice_from_ypos() yslice = session.yslice_from_ypos()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment