feat: Update volume slider range and default values

chore: Refactor code for improved readability and maintainability
This commit is contained in:
2024-06-17 13:55:15 +02:00
parent f611abde66
commit 34982dd973
8 changed files with 127 additions and 78 deletions

View File

@ -1,4 +1,3 @@
from re import I
from dash import callback, Input, Output, State
from selection_filtre import switch_case
import plotly.graph_objects as go
@ -185,16 +184,16 @@ def get_callbacks():
data_avec_traitement = switch_case(
data_avec_traitement,
int(select_filtre_1),
float(fs_filtre_1),
float(cutoff_filtre_1),
int(fs_filtre_1),
int(cutoff_filtre_1),
int(order_filtre_1),
int(windowsize_filtre_1),
)
data_avec_traitement = switch_case(
data_avec_traitement,
int(select_filtre_2),
float(fs_filtre_2),
float(cutoff_filtre_2),
int(fs_filtre_2),
int(cutoff_filtre_2),
int(order_filtre_2),
int(windowsize_filtre_2),
)
@ -250,7 +249,7 @@ def get_callbacks():
data_sans_traitement_fft = np.fft.fft(
volume[
int(select_ascan_y) - 1,
select_ascan_z[0] : select_ascan_z[1],
select_ascan_z[0] : int(select_ascan_z[1] / 2),
int(select_ascan_x) - 1,
]
)

View File

@ -6,6 +6,7 @@ import plotly.express as px
from os.path import join
from util import lire_fichier_csv
from selection_filtre import switch_case
from callbacks.ascan import data_traits
# on définit le dossier et les fichiers à lire
dossier = "Dataset/Shear_transform"
@ -107,11 +108,15 @@ def get_callbacks():
Input("layer-slider-bscan-zx", "value"),
Input("layer-slider-bscan-xy", "value"),
],
[dash.dependencies.State("fade-ascan", "is_in")],
prevent_initial_call=True,
[State("fade-ascan", "is_in"), State("store-settings", "data")],
)
def update_heatmap_ascan(layer, layer1, is_in):
fig = px.line(y=volume[layer - 1, :, layer1], title="A-scan")
def update_heatmap_ascan(layer, layer1, is_in, settings):
if settings["apply_sampling_everywhere"]:
data = volume
else:
data = pre_volume
fig = px.line(y=data[layer - 1, :, layer1], title="A-scan")
return [fig, True]
@ -119,9 +124,15 @@ def get_callbacks():
@callback(
Output("heatmap-ascan-fullscreen", "figure"),
Input("layer-slider-ascan-fullscreen", "value"),
State("store-settings", "data")
)
def update_heatmap_ascan_fullscreen(layer):
fig = px.line(y=volume[layer - 1, :, 5], title="A-scan")
def update_heatmap_ascan_fullscreen(layer, settings):
if settings["apply_sampling_everywhere"]:
data = volume
else:
data = pre_volume
fig = px.line(y=data[layer - 1, :, 5], title="A-scan")
return fig
# callback pour les B-scan XY
@ -132,12 +143,16 @@ def get_callbacks():
Output("fade-bscan-xy", "is_in"),
],
[Input("layer-slider-bscan-zx", "value")],
[dash.dependencies.State("fade-bscan-zx", "is_in")],
prevent_initial_call=True,
[State("fade-bscan-zx", "is_in"), State("store-settings", "data")],
)
def update_heatmap_bscan_zx(layer, is_in):
def update_heatmap_bscan_zx(layer, is_in, settings):
if settings["apply_sampling_everywhere"]:
data = volume
else:
data = pre_volume
fig = px.imshow(
volume[layer - 1, :, :],
data[layer - 1, :, :],
color_continuous_scale="Jet",
aspect="auto",
title="B-scan ZX",
@ -149,10 +164,16 @@ def get_callbacks():
@callback(
Output("heatmap-bscan-zx-fullscreen", "figure"),
Input("layer-slider-bscan-zx-fullscreen", "value"),
State("store-settings", "data")
)
def update_heatmap_bscan_zx_fullscreen(layer):
def update_heatmap_bscan_zx_fullscreen(layer, settings):
if settings["apply_sampling_everywhere"]:
data = volume
else:
data = pre_volume
fig = px.imshow(
volume[layer - 1, :, :],
data[layer - 1, :, :],
color_continuous_scale="Jet",
aspect="auto",
title="B-scan ZX",
@ -168,11 +189,15 @@ def get_callbacks():
Output("fade-bscan-zx", "is_in"),
],
[Input("layer-slider-bscan-xy", "value")],
[dash.dependencies.State("fade-bscan-xy", "is_in")],
prevent_initial_call=True,
[State("fade-bscan-xy", "is_in"), State("store-settings", "data")],
)
def update_heatmap_bscan_xy(layer, is_in):
fig = go.Figure(data=go.Heatmap(z=volume[:, :, layer], colorscale="Jet"))
def update_heatmap_bscan_xy(layer, is_in, settings):
if settings["apply_sampling_everywhere"]:
data = volume
else:
data = pre_volume
fig = go.Figure(data=go.Heatmap(z=data[:, :, layer], colorscale="Jet"))
fig.update_layout(title="B-scan XY")
return [fig, layer, True]
@ -181,9 +206,15 @@ def get_callbacks():
@callback(
Output("heatmap-bscan-xy-fullscreen", "figure"),
Input("layer-slider-bscan-xy-fullscreen", "value"),
State("store-settings", "data"),
)
def update_heatmap_bscan_xy_fullscreen(layer):
fig = go.Figure(data=go.Heatmap(z=volume[:, :, layer], colorscale="Jet"))
def update_heatmap_bscan_xy_fullscreen(layer, settings):
if settings["apply_sampling_everywhere"]:
data = volume
else:
data = pre_volume
fig = go.Figure(data=go.Heatmap(z=data[:, :, layer], colorscale="Jet"))
fig.update_layout(title="B-scan XY")
return fig
@ -232,22 +263,6 @@ def get_callbacks():
return not is_open
return is_open
@callback(
[
Output("3dplot", "clickData"),
Output("layer-slider-bscan-xy", "value"),
Output("layer-slider-bscan-zx", "value"),
],
Input("3dplot", "clickData"),
)
def display_3dplot_click_data(clickData):
if clickData is None:
return [None, 1, 1]
bscan_xy = clickData["points"][0]["z"]
bscan_zx = clickData["points"][0]["x"]
return [clickData, bscan_xy, bscan_zx]
@callback(
[
Output("heatmap-bscan-xy", "clickData"),
@ -288,7 +303,7 @@ def get_callbacks():
prevent_initial_call=True,
)
def update_bscan_layers(bscan_xy, bscan_zx):
fig = go.Figure(data=go.Heatmap(z=volume[:, :, bscan_xy], colorscale="Jet"))
fig = go.Figure(data=go.Heatmap(z=pre_volume[:, :, bscan_xy], colorscale="Jet"))
fig.add_shape(
type="line",
x0=0 - 1,
@ -300,7 +315,7 @@ def get_callbacks():
fig.update_layout(title="B-scan XY")
fig2 = px.imshow(
volume[bscan_zx - 1, :, :],
pre_volume[bscan_zx - 1, :, :],
color_continuous_scale="Jet",
aspect="auto",
title="B-scan ZX",
@ -314,7 +329,7 @@ def get_callbacks():
line=dict(color="white", width=1),
)
fig3 = px.line(y=volume[bscan_zx - 1, :, bscan_xy], title="A-scan")
fig3 = px.line(y=pre_volume[bscan_zx - 1, :, bscan_xy], title="A-scan")
return [fig, fig2, fig3]
@ -329,6 +344,7 @@ def get_callbacks():
State("echantillonage-x", "value"),
State("echantillonage-y", "value"),
State("echantillonage-z", "value"),
State("apply-sampling-everywhere", "value"),
],
prevent_initial_call=True,
)
@ -339,6 +355,7 @@ def get_callbacks():
echantillonage_x_value,
echantillonage_y_value,
echantillonage_z_value,
apply_sampling,
):
if clicks != None and clicks == 1:
return [
@ -348,6 +365,7 @@ def get_callbacks():
"echantillonage_x": echantillonage_x_value,
"echantillonage_y": echantillonage_y_value,
"echantillonage_z": echantillonage_z_value,
"apply_sampling_everywhere": apply_sampling,
},
0,
]
@ -394,14 +412,14 @@ def get_callbacks():
{str(i): str(i) for i in range(0, dim_x, max(1, int(dim_x / 20)))},
dim_z - 1,
{str(i): str(i) for i in range(1, dim_z + 1, max(1, int(dim_z / 20)))},
volume.min(),
0,
volume.max() / 2,
{
str(i): str(i)
for i in range(
int(volume.min()),
0,
int(volume.max() / 2) + 1,
int((volume.max() / 2 - volume.min()) / 10),
int(volume.max() / 20),
)
},
dim_y,
@ -528,5 +546,5 @@ def get_callbacks():
if format == "raw":
np.save(join("Dataset/saves", filename), pre_volume)
else:
np.save(join("Dataset/saves", filename), volume)
np.save(join("Dataset/saves", filename), data_traits)
return True

View File

@ -42,12 +42,14 @@ def get_callbacks():
@callback(
Output("open-modal", "is_open"),
[Input("open-button", "n_clicks"), Input("open-close", "n_clicks")],
[Input("open-button", "n_clicks"), Input("open-close", "n_clicks"), Input("open-refresh", "n_clicks")],
[dash.dependencies.State("open-modal", "is_open")],
)
def toggle_open(n1, n2, is_open):
def toggle_open(n1, n2, n3, is_open):
if n1 or n2:
return not is_open
elif n3:
return True
return is_open
@ -88,6 +90,7 @@ def get_callbacks():
[
Output("open-modal", "is_open", allow_duplicate=True),
Output("store-files", "data"),
Output("opened-file", "children"),
],
Input({"type": "file-item", "index": ALL}, "n_clicks"),
State({"type": "file-item", "index": ALL}, "children"),
@ -96,11 +99,11 @@ def get_callbacks():
def open_file(n, filenames):
ctx = dash.callback_context
if not ctx.triggered or all(click is None for click in n):
return [None, ""]
return [None, "", "No file opened"]
file_index = ctx.triggered[0]["prop_id"].split(".")[0]
file_index = eval(file_index)
filename = filenames[file_index["index"]]
return [False, filename]
return [False, filename, f"Opened file: {filename}"]
@callback(

View File

@ -2,6 +2,7 @@ import sqlite3
from util import *
import numpy as np
import datetime
from progress.bar import IncrementalBar
timestamp_start = datetime.datetime.now()
@ -9,6 +10,7 @@ db = sqlite3.connect('data.sqlite')
cursor = db.cursor()
cursor.execute('CREATE TABLE IF NOT EXISTS volume (x INTEGER, y INTEGER, z INTEGER, value REAL)')
cursor.execute('CREATE TABLE IF NOT EXISTS properties (name TEXT, value TEXT)')
# on définit le dossier et les fichiers à lire
@ -21,17 +23,25 @@ fichiers_selectionnes = [
# fichiers_selectionnes = ['Shear_x001-x101_y{:03d}_Rot00.csv'.format(i) for i in range(10, 62)]
# on lit les fichiers et on les met dans un tableau
pre_volume = np.array(lire_fichier_csv(dossier, fichiers_selectionnes))
volume = pre_volume[:, ::32, :]
volume = np.array(lire_fichier_csv(dossier, fichiers_selectionnes))[:, ::16, :]
dim_x, dim_y, dim_z = volume.shape
X, Y, Z = np.mgrid[0:dim_x, 0:dim_y, 0:dim_z]
bar = IncrementalBar('Processing', max=dim_x*dim_y*dim_z, suffix="%(percent).2f%% - %(index)d/%(max)d (%(eta).3fs remaining estimated)",)
cursor.execute('DELETE FROM volume')
for x in range(dim_x):
for y in range(dim_y):
for z in range(dim_z):
cursor.execute('INSERT INTO volume (x, y, z, value) VALUES (?, ?, ?, ?)', (x, y, z, volume[x, y, z]))
bar.next()
bar.finish()
cursor.execute('DELETE FROM properties')
cursor.execute('INSERT INTO properties (name, value) VALUES (?, ?)', ('dim_x', str(dim_x)))
cursor.execute('INSERT INTO properties (name, value) VALUES (?, ?)', ('dim_y', str(dim_y)))
cursor.execute('INSERT INTO properties (name, value) VALUES (?, ?)', ('dim_z', str(dim_z)))
db.commit()
db.close()

View File

@ -6,21 +6,24 @@ from os.path import isfile, join
import diskcache
from json import load
from callbacks.main import *
import numpy as np
from util import lire_fichier_csv
cache = diskcache.Cache("./cache")
background_callback_manager = DiskcacheManager(cache)
# on crée l'application
app = dash.Dash(
__name__,
external_stylesheets=[dbc.themes.DARKLY, dbc.icons.BOOTSTRAP],
use_pages=True,
background_callback_manager=background_callback_manager,
)
config = load(open("config.json", "r"))
app.title = config["app_title"]
cache = diskcache.Cache("./cache")
background_callback_manager = DiskcacheManager(cache)
print("Reloading...")
@ -32,6 +35,23 @@ if "saves" not in listdir("Dataset"):
files = listdir("Dataset/saves")
# on définit le dossier et les fichiers à lire
dossier = "Dataset/Shear_transform"
fichiers_selectionnes = [
"Shear_x001-x101_y{:03d}_Rot00_transform.csv".format(i) for i in range(10, 14)
]
# valeurs d'échantillonage
echantillonage_x = 1
echantillonage_y = 32
echantillonage_z = 1
pre_volume = np.array(lire_fichier_csv(dossier, fichiers_selectionnes))
volume = pre_volume[::echantillonage_x, ::echantillonage_y, ::echantillonage_z]
dim_x, dim_y, dim_z = volume.shape
X, Y, Z = np.mgrid[0:dim_x, 0:dim_y, 0:dim_z]
# on lit le fichier modal.md pour le tuto
with open("assets/modal.md", "r") as f:
@ -101,6 +121,12 @@ modal_settings = dbc.Modal(
),
]
),
dbc.Switch(
id="apply-sampling-everywhere",
label="Apply sampling on A-Scan and B-Scan",
value=True,
className="me-2",
),
]
),
dbc.ModalFooter(
@ -325,6 +351,7 @@ nav_bar = dbc.Navbar(
dbc.NavItem(button_settings),
dbc.NavItem(button_open),
dbc.NavItem(button_save),
dbc.Label(id="opened-file", style={"marginLeft": "10px", "padding": "0 auto"}),
],
className="ml-auto",
navbar=True,
@ -365,6 +392,7 @@ app.layout = dbc.Container(
"echantillonage_x": 1,
"echantillonage_y": 32,
"echantillonage_z": 1,
"apply_sampling_everywhere": True,
},
),
dcc.Store(id="store-filters", data={}),

View File

@ -130,15 +130,15 @@ mesh_card = dbc.Fade(
), # 'fig' is your 3D plotly figure
dcc.Slider(
id="iso-slider",
min=volume.min(),
min=0,
max=volume.max() / 2,
value=volume.min(),
value=0,
marks={
str(i): str(i)
for i in range(
int(volume.min()),
0,
int(volume.max() / 2) + 1,
int((volume.max() / 2 - volume.min()) / 10),
int(volume.max() / 20),
)
},
step=1,