From 44e2664abd004967e5111dd713d89fefec25c93c Mon Sep 17 00:00:00 2001 From: Le Stagiaire Date: Wed, 29 May 2024 16:18:38 +0200 Subject: [PATCH] feat: Add settings modal to main.py --- 3D_app/main.py | 50 ++- 3D_app/pages/ascan.py | 432 +++++++++++++++--------- 3D_app/pages/home.py | 756 ++++++++++++++++++++++-------------------- 3 files changed, 722 insertions(+), 516 deletions(-) diff --git a/3D_app/main.py b/3D_app/main.py index 0b62c24..e84d9b7 100644 --- a/3D_app/main.py +++ b/3D_app/main.py @@ -24,13 +24,40 @@ modal_overlay = dbc.Modal( size="lg", ) +modal_settings = dbc.Modal( + [ + dbc.ModalHeader("Settings"), + dbc.ModalBody( + [ + dbc.Switch( + id="use-real-values", + label="Use real values", + value=False, + className="me-2", + ), + dbc.Input( + id="echantillonage-x", + type="number", + placeholder="Echantillonage X", + style={"width": "100px"}, + ), + ] + ), + dbc.ModalFooter( + dbc.Button("Close", id="settings-close", className="settings-bn"), + ), + ], + id="settings-modal", + size="lg", +) + # on défini les boutons de la navbar button_gh = dbc.Button( "Learn more", id="howto-open", outline=True, color="secondary", - style={"textTransform": "none"}, + style={"textTransform": "none", "marginRight": "10px"}, ) button_howto = dbc.Button( @@ -42,6 +69,14 @@ button_howto = dbc.Button( style={"textTransform": "none", "marginRight": "10px"}, ) +button_settings = dbc.Button( + "Settings", + outline=True, + color="success", + id="settings-open", + style={"textTransform": "none"}, +) + navmenu = html.Div( dbc.Offcanvas( dbc.ListGroup( @@ -121,7 +156,7 @@ nav_bar = dbc.Navbar( [ dbc.Collapse( dbc.Nav( - [dbc.NavItem(button_howto), dbc.NavItem(button_gh)], + [dbc.NavItem(button_howto), dbc.NavItem(button_gh), dbc.NavItem(button_settings)], className="ml-auto", navbar=True, ), @@ -132,6 +167,7 @@ nav_bar = dbc.Navbar( align="right", ), modal_overlay, + modal_settings, navmenu, ], align="center", @@ -162,6 +198,16 @@ def toggle_modal(n1, n2, is_open): return not is_open return is_open +@app.callback( + Output("settings-modal", "is_open"), + [Input("settings-open", "n_clicks"), Input("settings-close", "n_clicks")], + [dash.dependencies.State("settings-modal", "is_open")], +) +def toggle_settings(n1, n2, is_open): + if n1 or n2: + return not is_open + return is_open + # callback pour le navmenu @app.callback( diff --git a/3D_app/pages/ascan.py b/3D_app/pages/ascan.py index 4532495..c3d5919 100644 --- a/3D_app/pages/ascan.py +++ b/3D_app/pages/ascan.py @@ -10,18 +10,20 @@ from filtrage import * from selection_filtre import * -dash.register_page(__name__, path="/ascan", title='A-Scan filters', name='A-Scan filters') +dash.register_page( + __name__, path="/ascan", title="A-Scan filters", name="A-Scan filters" +) # on définit le dossier et les fichiers à lire dossier = "Dataset/Shear_Wave_Rot00_CSV_Data" fichiers_selectionnes = [ - "Shear_x001-x101_y{:03d}_Rot00.csv".format(i) for i in range(10,13) + "Shear_x001-x101_y{:03d}_Rot00.csv".format(i) for i in range(10, 13) ] # on lit les fichiers et on les met dans un tableau pre_volume = np.array(lire_fichier_csv(dossier, fichiers_selectionnes)) volume = pre_volume[:, :, :] -data_traits=volume +data_traits = volume dim_x, dim_y, dim_z = volume.shape X, Y, Z = np.mgrid[0:dim_x, 0:dim_y, 0:dim_z] @@ -52,7 +54,8 @@ layout = html.Div( value=1, style={"margin-bottom": "15px"}, ), - ] + ], + width=3, ), dbc.Col( [ @@ -63,13 +66,20 @@ layout = html.Div( {"label": "filtre passe bas ", "value": "3"}, {"label": "filtre de moyenne mobile", "value": "4"}, {"label": "filtre adaptatif (wiener)", "value": "5"}, - {"label": "filtre à réponse impulsionnelle infinie", "value": "6"}, - {"label": "filtre à réponse impulsionnelle finie", "value": "7"}, + { + "label": "filtre à réponse impulsionnelle infinie", + "value": "6", + }, + { + "label": "filtre à réponse impulsionnelle finie", + "value": "7", + }, ], value=2, style={"margin-bottom": "15px"}, ), - ] + ], + width=3, ), dbc.Col( [ @@ -80,14 +90,20 @@ layout = html.Div( {"label": "filtre passe bas ", "value": "3"}, {"label": "filtre de moyenne mobile", "value": "4"}, {"label": "filtre adaptatif (wiener)", "value": "5"}, - {"label": "filtre à réponse impulsionnelle infinie", "value": "6"}, - {"label": "filtre à réponse impulsionnelle finie", "value": "7"}, + { + "label": "filtre à réponse impulsionnelle infinie", + "value": "6", + }, + { + "label": "filtre à réponse impulsionnelle finie", + "value": "7", + }, ], value=2, style={"margin-bottom": "15px"}, ), - - ] + ], + width=3, ), dbc.Col( [ @@ -98,165 +114,203 @@ layout = html.Div( color="primary", style={"marginBottom": "15px"}, ), - ] + ], + width=3, + ), + ] + ), + dbc.Row( + [ + dbc.Col( + dcc.Graph( + id="heatmap-ascan-solo", + config=configAScan, + style={"marginBottom": "15px"}, + ), # 'fig' is your 2D plotly figure + width=8, + ), + dbc.Col( + dcc.Graph( + id="heatmap-bscan-solo", + config=configAScan, + style={"marginBottom": "15px"}, + ), # 'fig' is your 2D plotly figure + width=4, ), ] ), - dcc.Graph( - id="heatmap-ascan-solo", - config=configAScan, - style={"marginBottom": "15px"}, - ), # 'fig' is your 2D plotly figure dbc.Label("x"), dcc.Slider( id="layer-slider-ascan-solo-x", min=1, - max=dim_z, + max=dim_z - 1, value=1, step=1, - marks={ - str(i): str(i) for i in range(1, dim_z+1,1) - }, + marks={str(i): str(i) for i in range(1, dim_z + 1, max(1, int(dim_z / 20)))}, ), dbc.Label("y"), dcc.Slider( id="layer-slider-ascan-solo-y", - min=1, - max=dim_x, - value=1, + min=0, + max=dim_x - 1, + value=0, step=1, - marks={ - str(i): str(i) for i in range(1, dim_x+1,1) - }, + marks={str(i): str(i) for i in range(0, dim_x + 1, max(1, int(dim_x / 20)))}, ), dbc.Row( [ - dbc.Label(" paramètre du 1er filtre ", html_for="Fs "), - dbc.Col( - [ - dbc.Label("Fs ", html_for="Fs "), - dbc.Input( - id="input-ascan-solo-fs", - type="number", - placeholder="Fs", - value=1, - step=0.1, - style={"marginTop": "15px"}, + dbc.Row( + [ + dbc.Label(" paramètre du 1er filtre ", html_for="Fs "), + dbc.Col( + [ + dbc.Label("Fs ", html_for="Fs "), + dbc.Input( + id="input-ascan-solo-fs", + type="number", + placeholder="Fs", + value=1, + step=0.1, + style={"marginTop": "15px"}, + ), + ], + width=3, + ), + dbc.Col( + [ + dbc.Label("cut off ", html_for="cut off"), + dbc.Input( + id="input-ascan-solo-cutoff", + type="number", + placeholder="cut_off", + value=1, + step=0.1, + style={"marginTop": "15px"}, + ), + ], + width=3, + ), + dbc.Col( + [ + dbc.Label("order ", html_for="order"), + dbc.Input( + id="input-ascan-solo-order", + type="number", + placeholder="order", + value=1, + step=1, + style={"marginTop": "15px"}, + ), + ], + width=3, + ), + dbc.Col( + [ + dbc.Label("window size ", html_for="window size"), + dbc.Input( + id="input-ascan-solo-windowsize", + type="number", + placeholder="window_size", + value=1, + step=1, + style={"marginTop": "15px"}, + ), + ], + width=3, + ), + ] ), - ], - width=3, + dbc.Row( + [ + dbc.Label("paramètre de 2eme filtre ", html_for="Fs "), + dbc.Col( + [ + dbc.Label("Fs ", html_for="Fs "), + dbc.Input( + id="input-ascan-solo-fs-2", + type="number", + placeholder="Fs", + value=1, + step=0.1, + style={"marginTop": "15px"}, + ), + ], + width=3, + ), + dbc.Col( + [ + dbc.Label("cut off ", html_for="cut off"), + dbc.Input( + id="input-ascan-solo-cutoff-2", + type="number", + placeholder="cut_off", + value=1, + step=0.1, + style={"marginTop": "15px"}, + ), + ], + width=3, + ), + dbc.Col( + [ + dbc.Label("order ", html_for="order"), + dbc.Input( + id="input-ascan-solo-order-2", + type="number", + placeholder="order", + value=1, + step=1, + style={"marginTop": "15px"}, + ), + ], + width=3, + ), + dbc.Col( + [ + dbc.Label("window size ", html_for="window size"), + dbc.Input( + id="input-ascan-solo-windowsize-2", + type="number", + placeholder="window_size", + value=1, + step=1, + style={"marginTop": "15px"}, + ), + ], + width=3, + ), + ] + ), + ] ), - dbc.Col( - [ - dbc.Label("cut off ", html_for="cut off"), - dbc.Input( - id="input-ascan-solo-cutoff", - type="number", - placeholder="cut_off", - value=1, - step=0.1, - style={"marginTop": "15px"}, - ), - ], - width=3, - ), - dbc.Col( - [ - dbc.Label("order ", html_for="order"), - dbc.Input( - id="input-ascan-solo-order", - type="number", - placeholder="order", - value=1, - step=1, - style={"marginTop": "15px"}, - ), - ], - width=3, - ), - dbc.Col( - [ - dbc.Label("window size ", html_for="window size"), - dbc.Input( - id="input-ascan-solo-windowsize", - type="number", - placeholder="window_size", - value=1, - step=1, - style={"marginTop": "15px"}, - ), - ], - width=3, - ),]), - dbc.Row( - [ - dbc.Label("paramètre de 2eme filtre ", html_for="Fs "), - dbc.Col( - [ - dbc.Label("Fs ", html_for="Fs "), - dbc.Input( - id="input-ascan-solo-fs-2", - type="number", - placeholder="Fs", - value=1, - step=0.1, - style={"marginTop": "15px"}, - ), - ], - width=3, - ), - dbc.Col( - [ - dbc.Label("cut off ", html_for="cut off"), - dbc.Input( - id="input-ascan-solo-cutoff-2", - type="number", - placeholder="cut_off", - value=1, - step=0.1, - style={"marginTop": "15px"}, - ), - ], - width=3, - ), - dbc.Col( - [ - dbc.Label("order ", html_for="order"), - dbc.Input( - id="input-ascan-solo-order-2", - type="number", - placeholder="order", - value=1, - step=1, - style={"marginTop": "15px"}, - ), - ], - width=3, - ), - dbc.Col( - [ - dbc.Label("window size ", html_for="window size"), - dbc.Input( - id="input-ascan-solo-windowsize-2", - type="number", - placeholder="window_size", - value=1, - step=1, - style={"marginTop": "15px"}, - ), - ], - width=3, - ), - ]), ], - style={"padding": "20px"}, ) +# callback to update filter values +@callback( + [ + Output("input-ascan-solo-fs", "disabled"), + Output("input-ascan-solo-cutoff", "disabled"), + Output("input-ascan-solo-order", "disabled"), + Output("input-ascan-solo-windowsize", "disabled"), + Output("input-ascan-solo-fs-2", "disabled"), + Output("input-ascan-solo-cutoff-2", "disabled"), + Output("input-ascan-solo-order-2", "disabled"), + Output("input-ascan-solo-windowsize-2", "disabled"), + ], + [ + Input("select-ascan-filter2", "value"), + Input("select-ascan-filter3", "value"), + ], +) +def update_filter_values(select_filtre_1, select_filtre_2): + return [select_filtre_1 == 2, select_filtre_1 == 2, select_filtre_1 == 2, select_filtre_1 == 2, select_filtre_2 == 2, select_filtre_2 == 2, select_filtre_2 == 2, select_filtre_2 == 2] + # callback to update the heatmap @callback( - Output("heatmap-ascan-solo", "figure"), + [Output("heatmap-ascan-solo", "figure"), Output("heatmap-bscan-solo", "figure")], [ Input("select-ascan-filter1", "value"), Input("select-ascan-filter2", "value"), @@ -274,25 +328,81 @@ layout = html.Div( Input("input-ascan-solo-windowsize-2", "value"), ], ) - -def update_heatmap_ascan(selec_transforme_hilbert,select_filtre_1,select_filtre_2,select_ascan_x,select_ascan_y,n_clicks,fs_filtre_1,cutoff_filtre_1,order_filtre_1,windowsize_filtre_1,fs_filtre_2,cutoff_filtre_2,order_filtre_2,windowsize_filtre_2): +def update_heatmap_ascan( + selec_transforme_hilbert, + select_filtre_1, + select_filtre_2, + select_ascan_x, + select_ascan_y, + n_clicks, + fs_filtre_1, + cutoff_filtre_1, + order_filtre_1, + windowsize_filtre_1, + fs_filtre_2, + cutoff_filtre_2, + order_filtre_2, + windowsize_filtre_2, +): # TODO: implement the filter print("debut du traitement") - data_avec_traitement=volume[int(select_ascan_y)-1,:,int(select_ascan_x)-1] - data_sans_traitement=volume[int(select_ascan_y)-1,:,int(select_ascan_x)-1] - data_avec_traitement=switch_case(data_avec_traitement,int(selec_transforme_hilbert)) - data_sans_traitement=switch_case(data_sans_traitement,int(selec_transforme_hilbert)) - data_avec_traitement=switch_case(data_avec_traitement,int(select_filtre_1),float(fs_filtre_1),float(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(order_filtre_2),int(windowsize_filtre_2)) + data_avec_traitement = volume[int(select_ascan_y) - 1, :, int(select_ascan_x) - 1] + data_sans_traitement = volume[int(select_ascan_y) - 1, :, int(select_ascan_x) - 1] + data_avec_traitement = switch_case( + data_avec_traitement, int(selec_transforme_hilbert) + ) + data_sans_traitement = switch_case( + data_sans_traitement, int(selec_transforme_hilbert) + ) + data_avec_traitement = switch_case( + data_avec_traitement, + int(select_filtre_1), + float(fs_filtre_1), + float(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(order_filtre_2), + int(windowsize_filtre_2), + ) print("fin du traitement") - if(n_clicks!=None): - data_traits=switch_case(data_traits,int(selec_transforme_hilbert)) - data_traits=switch_case(data_traits,int(select_filtre_1),float(fs_filtre_1),float(cutoff_filtre_1),int(order_filtre_1),int(windowsize_filtre_1)) - data_traits=switch_case(data_traits,int(select_filtre_2),float(fs_filtre_2),float(cutoff_filtre_2),int(order_filtre_2),int(windowsize_filtre_2)) - fig = px.line( title="A-scan") - new_trace = go.Scatter(y=data_avec_traitement, mode='lines', name=' Ascan trait ') + if n_clicks != None: + data_traits = switch_case(data_traits, int(selec_transforme_hilbert)) + data_traits = switch_case( + data_traits, + int(select_filtre_1), + float(fs_filtre_1), + float(cutoff_filtre_1), + int(order_filtre_1), + int(windowsize_filtre_1), + ) + data_traits = switch_case( + data_traits, + int(select_filtre_2), + float(fs_filtre_2), + float(cutoff_filtre_2), + int(order_filtre_2), + int(windowsize_filtre_2), + ) + fig = px.line(title="A-scan") + new_trace = go.Scatter(y=data_avec_traitement, mode="lines", name=" Ascan trait ") fig.add_trace(new_trace) - new_trace = go.Scatter(y=data_sans_traitement, mode='lines', name=' Ascan (hilbert) ') + new_trace = go.Scatter( + y=data_sans_traitement, mode="lines", name=" Ascan (hilbert) " + ) fig.add_trace(new_trace) - return fig \ No newline at end of file + + fig2 = px.imshow( + volume[select_ascan_y - 1, :, :], + color_continuous_scale="Jet", + aspect="auto", + title="B-scan ZX", + ) + + return [fig, fig2] diff --git a/3D_app/pages/home.py b/3D_app/pages/home.py index 04de9cc..5e1ba73 100644 --- a/3D_app/pages/home.py +++ b/3D_app/pages/home.py @@ -16,7 +16,7 @@ fichiers_selectionnes = [ ] # on charge le fichier numpy -fichiers = np.load("Dataset/npy/export.npy") +# fichiers = np.load("Dataset/npy/export.npy") # valeurs d'échantillonage echantillonage_x = 1 @@ -96,347 +96,354 @@ configBScanZX = { # on crée les cartes # carte pour le plot 3D -mesh_card = dbc.Card( - [ - dbc.CardBody( - [ - dbc.Row( - [ - dbc.Col( - html.H2( - "3D Plot", - className="card-title", - style={"textAlign": "left"}, - ), - width="4", - ), - dbc.Col( - dbc.Button( - html.I(className="bi bi-arrows-fullscreen"), - id="fullscreen-button-3dplot", - className="mb-3", - color="primary", - style={"marginBottom": "15px"}, - ), - ), - ], - ), - dcc.Graph( - id="3dplot", - figure=fig, - config=config3DPlot, - style={"marginBottom": "15px"}, - ), # 'fig' is your 3D plotly figure - dcc.Slider( - id="iso-slider", - min=volume.min(), - max=volume.max() / 2, - value=volume.min(), - marks={ - str(i): str(i) - for i in range( - int(volume.min()), - int(volume.max() / 2) + 1, - int((volume.max() / 2 - volume.min()) / 10), - ) - }, - step=1, - ), - dcc.RangeSlider( - id="y-slider", - min=0, - max=dim_y, - value=[0, dim_y / 2], - marks={ - str(i): str(i) - for i in range(0, int(dim_y) + 1, max(1, int(dim_y / 20))) - }, - step=1, - ), - dbc.Modal( - [ - dbc.ModalHeader(dbc.ModalTitle("3D Plot")), - dbc.ModalBody( - [ - dcc.Graph( - id="3dplot-fullscreen", - figure=fig, - config=config3DPlot, - style={"marginBottom": "15px", "height": "90%"}, - ), # 'fig' is your 3D plotly figure - dcc.Slider( - id="iso-slider-fullscreen", - min=volume.min(), - max=volume.max() / 2, - value=volume.min(), - marks={ - str(i): str(i) - for i in range( - int(volume.min()), - int(volume.max() / 2) + 1, - int((volume.max() / 2 - volume.min()) / 20), - ) - }, - step=1, +mesh_card = dbc.Fade( + dbc.Card( + [ + dbc.CardBody( + [ + dbc.Row( + [ + dbc.Col( + html.H2( + "3D Plot", + className="card-title", + style={"textAlign": "left"}, ), - dcc.RangeSlider( - id="y-slider-fullscreen", - min=0, - max=dim_y, - value=[0, dim_y / 2], - marks={ - str(i): str(i) - for i in range( - 0, int(dim_y) + 1, max(1, int(dim_y / 50)) - ) - }, - step=1, + width="4", + ), + dbc.Col( + dbc.Button( + html.I(className="bi bi-arrows-fullscreen"), + id="fullscreen-button-3dplot", + className="mb-3", + color="primary", + style={"marginBottom": "15px"}, ), - ] - ), - ], - id="modal-3dplot", - fullscreen=True, - ), - ] - ) - ] + ), + ], + ), + dcc.Graph( + id="3dplot", + figure=fig, + config=config3DPlot, + style={"marginBottom": "15px"}, + ), # 'fig' is your 3D plotly figure + dcc.Slider( + id="iso-slider", + min=volume.min(), + max=volume.max() / 2, + value=volume.min(), + marks={ + str(i): str(i) + for i in range( + int(volume.min()), + int(volume.max() / 2) + 1, + int((volume.max() / 2 - volume.min()) / 10), + ) + }, + step=1, + ), + dcc.RangeSlider( + id="y-slider", + min=0, + max=dim_y, + value=[0, dim_y / 2], + marks={ + str(i): str(i) + for i in range(0, int(dim_y) + 1, max(1, int(dim_y / 20))) + }, + step=1, + ), + dbc.Modal( + [ + dbc.ModalHeader(dbc.ModalTitle("3D Plot")), + dbc.ModalBody( + [ + dcc.Graph( + id="3dplot-fullscreen", + figure=fig, + config=config3DPlot, + style={"marginBottom": "15px", "height": "90%"}, + ), # 'fig' is your 3D plotly figure + dcc.Slider( + id="iso-slider-fullscreen", + min=volume.min(), + max=volume.max() / 2, + value=volume.min(), + marks={ + str(i): str(i) + for i in range( + int(volume.min()), + int(volume.max() / 2) + 1, + int( + (volume.max() / 2 - volume.min()) + / 20 + ), + ) + }, + step=1, + ), + dcc.RangeSlider( + id="y-slider-fullscreen", + min=0, + max=dim_y, + value=[0, dim_y / 2], + marks={ + str(i): str(i) + for i in range( + 0, + int(dim_y) + 1, + max(1, int(dim_y / 50)), + ) + }, + step=1, + ), + ] + ), + ], + id="modal-3dplot", + fullscreen=True, + ), + ] + ) + ] + ), + id="fade-3dplot", + is_in=False, + appear=False, ) # carte pour le A-scan -Ascan_card = dbc.Card( - [ - dbc.CardBody( - [ - dbc.Row( - [ - dbc.Col( - html.H2( - "A-scan", - className="card-title", - style={"textAlign": "left"}, - ), - width="4", - ), - dbc.Col( - dbc.Button( - html.I(className="bi bi-arrows-fullscreen"), - id="fullscreen-button-ascan", - className="mb-3", - color="primary", - style={"marginBottom": "15px"}, - ), - ), - ], - ), - dcc.Graph( - id="heatmap-ascan", - config=configAScan, - style={"marginBottom": "15px"}, - ), # 'fig' is your 2D plotly figure - dcc.Slider( - id="layer-slider-ascan", - min=0, - max=dim_x - 1, - value=0, - step=1, - marks={ - str(i): str(i) for i in range(0, dim_x, max(1, int(dim_x / 20))) - }, - ), - dcc.Slider( - id="ascan-slider", - min=1, - max=dim_z - 1, - value=0, - step=1, - marks={ - str(i): str(i) for i in range(1, dim_z, max(1, int(dim_z / 20))) - }, - ), - dbc.Modal( - [ - dbc.ModalHeader(dbc.ModalTitle("A-Scan")), - dbc.ModalBody( - [ - dcc.Graph( - id="heatmap-ascan-fullscreen", - config=configAScan, - style={"marginBottom": "15px"}, - ), # 'fig' is your 2D plotly figure - dcc.Slider( - id="layer-slider-ascan-fullscreen", - min=0, - max=dim_x, - value=0, - step=1, - marks={ - str(i): str(i) - for i in range( - 0, dim_x, max(1, int(dim_x / 50)) - ) - }, +Ascan_card = dbc.Fade( + dbc.Card( + [ + dbc.CardBody( + [ + dbc.Row( + [ + dbc.Col( + html.H2( + "A-scan", + className="card-title", + style={"textAlign": "left"}, ), - ] - ), - ], - id="modal-ascan", - fullscreen=True, - ), - ] - ) - ] + width="4", + ), + dbc.Col( + dbc.Button( + html.I(className="bi bi-arrows-fullscreen"), + id="fullscreen-button-ascan", + className="mb-3", + color="primary", + style={"marginBottom": "15px"}, + ), + ), + ], + ), + dcc.Graph( + id="heatmap-ascan", + config=configAScan, + style={"marginBottom": "15px"}, + ), # 'fig' is your 2D plotly figure + dbc.Modal( + [ + dbc.ModalHeader(dbc.ModalTitle("A-Scan")), + dbc.ModalBody( + [ + dcc.Graph( + id="heatmap-ascan-fullscreen", + config=configAScan, + style={"marginBottom": "15px"}, + ), # 'fig' is your 2D plotly figure + dcc.Slider( + id="layer-slider-ascan-fullscreen", + min=0, + max=dim_x, + value=0, + step=1, + marks={ + str(i): str(i) + for i in range( + 0, dim_x, max(1, int(dim_x / 50)) + ) + }, + ), + ] + ), + ], + id="modal-ascan", + fullscreen=True, + ), + ], + style={"height": "599px"}, + ) + ], + ), + id="fade-ascan", + is_in=False, + appear=False, ) # carte pour le B-scan ZX -Bscan_card_xy = dbc.Card( - [ - dbc.CardBody( - [ - dbc.Row( - [ - dbc.Col( - html.H2( - "B-scan ZX", - className="card-title", - style={"textAlign": "left"}, - ), - width="4", - ), - dbc.Col( - dbc.Button( - html.I(className="bi bi-arrows-fullscreen"), - id="fullscreen-button-bscan-zx", - className="mb-3", - color="primary", - style={"marginBottom": "15px"}, - ), - ), - ], - ), - dcc.Graph( - id="heatmap-bscan-zx", - config=configBScanZX, - style={"marginBottom": "15px"}, - ), # 'fig' is your 2D plotly figure - dcc.Slider( - id="layer-slider-bscan-zx", - min=0, - max=dim_x - 1, - value=0, - step=1, - marks={ - str(i): str(i) for i in range(0, dim_x, max(1, int(dim_x / 20))) - }, - ), - dbc.Modal( - [ - dbc.ModalHeader(dbc.ModalTitle("B-Scan ZX")), - dbc.ModalBody( - [ - dcc.Graph( - id="heatmap-bscan-zx-fullscreen", - config=configBScanXY, - style={"marginBottom": "15px"}, - ), # 'fig' is your 2D plotly figure - dcc.Slider( - id="layer-slider-bscan-zx-fullscreen", - min=0, - max=dim_x, - value=0, - step=1, - marks={ - str(i): str(i) - for i in range( - 0, dim_x + 1, max(1, int(dim_x / 50)) - ) - }, +Bscan_card_xy = dbc.Fade( + dbc.Card( + [ + dbc.CardBody( + [ + dbc.Row( + [ + dbc.Col( + html.H2( + "B-scan ZX", + className="card-title", + style={"textAlign": "left"}, ), - ] - ), - ], - id="modal-bscan-zx", - fullscreen=True, - ), - ] - ) - ] + width="4", + ), + dbc.Col( + dbc.Button( + html.I(className="bi bi-arrows-fullscreen"), + id="fullscreen-button-bscan-zx", + className="mb-3", + color="primary", + style={"marginBottom": "15px"}, + ), + ), + ], + ), + dcc.Graph( + id="heatmap-bscan-zx", + config=configBScanZX, + style={"marginBottom": "15px"}, + ), # 'fig' is your 2D plotly figure + dcc.Slider( + id="layer-slider-bscan-zx", + min=0, + max=dim_x - 1, + value=0, + step=1, + marks={ + str(i): str(i) + for i in range(0, dim_x, max(1, int(dim_x / 20))) + }, + ), + dbc.Modal( + [ + dbc.ModalHeader(dbc.ModalTitle("B-Scan ZX")), + dbc.ModalBody( + [ + dcc.Graph( + id="heatmap-bscan-zx-fullscreen", + config=configBScanXY, + style={"marginBottom": "15px", "height": "90%"}, + ), # 'fig' is your 2D plotly figure + dcc.Slider( + id="layer-slider-bscan-zx-fullscreen", + min=0, + max=dim_x, + value=0, + step=1, + marks={ + str(i): str(i) + for i in range( + 0, dim_x + 1, max(1, int(dim_x / 50)) + ) + }, + ), + ] + ), + ], + id="modal-bscan-zx", + fullscreen=True, + ), + ] + ) + ] + ), + id="fade-bscan-zx", + is_in=False, + appear=False, ) # carte pour le B-scan ZX -Bscan_card_zx = dbc.Card( - [ - dbc.CardBody( - [ - dbc.Row( - [ - dbc.Col( - html.H2( - "B-scan XY", - className="card-title", - style={"textAlign": "left"}, - ), - width="4", - ), - dbc.Col( - dbc.Button( - html.I(className="bi bi-arrows-fullscreen"), - id="fullscreen-button-bscan-xy", - className="mb-3", - color="primary", - style={"marginBottom": "15px"}, - ), - ), - ], - ), - dcc.Graph( - id="heatmap-bscan-xy", - config=configBScanXY, - style={"marginBottom": "15px"}, - ), # 'fig' is your 2D plotly figure - dcc.Slider( - id="layer-slider-bscan-xy", - min=1, - max=dim_z - 1, - value=1, - step=1, - marks={ - str(i): str(i) - for i in range(1, dim_z + 1, max(1, int(dim_z / 20))) - }, - ), - dbc.Modal( - [ - dbc.ModalHeader(dbc.ModalTitle("B-Scan XY")), - dbc.ModalBody( - [ - dcc.Graph( - id="heatmap-bscan-xy-fullscreen", - config=configBScanXY, - style={"marginBottom": "15px"}, - ), # 'fig' is your 2D plotly figure - dcc.Slider( - id="layer-slider-bscan-xy-fullscreen", - min=1, - max=dim_z - 1, - value=1, - step=1, - marks={ - str(i): str(i) - for i in range( - 1, dim_z + 1, max(1, int(dim_z / 50)) - ) - }, +Bscan_card_zx = dbc.Fade( + dbc.Card( + [ + dbc.CardBody( + [ + dbc.Row( + [ + dbc.Col( + html.H2( + "B-scan XY", + className="card-title", + style={"textAlign": "left"}, ), - ], - ), - ], - id="modal-bscan-xy", - fullscreen=True, - ), - ] - ) - ] + width="4", + ), + dbc.Col( + dbc.Button( + html.I(className="bi bi-arrows-fullscreen"), + id="fullscreen-button-bscan-xy", + className="mb-3", + color="primary", + style={"marginBottom": "15px"}, + ), + ), + ], + ), + dcc.Graph( + id="heatmap-bscan-xy", + config=configBScanXY, + style={"marginBottom": "15px"}, + ), # 'fig' is your 2D plotly figure + dcc.Slider( + id="layer-slider-bscan-xy", + min=1, + max=dim_z - 1, + value=1, + step=1, + marks={ + str(i): str(i) + for i in range(1, dim_z + 1, max(1, int(dim_z / 20))) + }, + ), + dbc.Modal( + [ + dbc.ModalHeader(dbc.ModalTitle("B-Scan XY")), + dbc.ModalBody( + [ + dcc.Graph( + id="heatmap-bscan-xy-fullscreen", + config=configBScanXY, + style={"marginBottom": "15px", "height": "90%"}, + ), # 'fig' is your 2D plotly figure + dcc.Slider( + id="layer-slider-bscan-xy-fullscreen", + min=1, + max=dim_z - 1, + value=1, + step=1, + marks={ + str(i): str(i) + for i in range( + 1, dim_z + 1, max(1, int(dim_z / 50)) + ) + }, + ), + ], + ), + ], + id="modal-bscan-xy", + fullscreen=True, + ), + ] + ) + ] + ), + id="fade-bscan-xy", + is_in=False, + appear=False, ) layout = html.Div( @@ -451,6 +458,7 @@ layout = html.Div( ), dcc.Store(id="store-bscan-xy-layer", data=1), dcc.Store(id="store-bscan-zx-layer", data=0), + dcc.Store(id="store-settings", data={"use_real_values": False, "echantillonage_x": 1, "echantillonage_y": 32, "echantillonage_z": 1}), ] ) @@ -458,17 +466,29 @@ layout = html.Div( # on défini les callbacks # callback pour le plot 3D @callback( - Output("3dplot", "figure"), - [Input("iso-slider", "value"), Input("y-slider", "value")], + [Output("3dplot", "figure"), Output("fade-3dplot", "is_in")], + [ + Input("iso-slider", "value"), + Input("y-slider", "value"), + Input("store-settings", "data"), + ], + [dash.dependencies.State("fade-3dplot", "is_in")], ) -def update_3dplot(iso_value, y_values): - y_min, y_max = y_values - selected_volume = volume[0:dim_x, int(y_min) : int(y_max), 0:dim_z] - X, Y, Z = np.mgrid[ - 0 : selected_volume.shape[0], - 0 : selected_volume.shape[1], - 0 : selected_volume.shape[2], - ] +def update_3dplot(iso_value, y_values, settings, is_in): + if settings["use_real_values"]: + y_min, y_max = y_values + selected_volume = volume[0:dim_x, int(y_min) : int(y_max), 0:dim_z] + X, Y, Z = [ + np.load("Dataset/npy/{}-values.npy".format(i)) for i in ["x", "y", "z"] + ] + else: + y_min, y_max = y_values + selected_volume = volume[0:dim_x, int(y_min) : int(y_max), 0:dim_z] + X, Y, Z = np.mgrid[ + 0 : selected_volume.shape[0], + 0 : selected_volume.shape[1], + 0 : selected_volume.shape[2], + ] fig = go.Figure( data=go.Volume( @@ -484,7 +504,7 @@ def update_3dplot(iso_value, y_values): ) ) - return fig + return [fig, True] # callback pour le plot 3D en plein écran @@ -520,12 +540,18 @@ def update_3dplot_fullscreen(iso_value, y_values): # callback pour le A-scan @callback( - Output("heatmap-ascan", "figure"), - Input("layer-slider-ascan", "value"), + [ + Output("heatmap-ascan", "figure"), + Output("fade-ascan", "is_in"), + ], + [Input("layer-slider-bscan-zx", "value"), Input("layer-slider-bscan-xy", "value")], + [dash.dependencies.State("fade-ascan", "is_in")], + prevent_initial_call=True, ) -def update_heatmap_ascan(layer): - fig = px.line(y=volume[layer - 1, :, 5], title="A-scan") - return fig +def update_heatmap_ascan(layer, layer1, is_in): + fig = px.line(y=volume[layer - 1, :, layer1], title="A-scan") + + return [fig, True] # callback pour le A-scan en plein écran @@ -543,11 +569,13 @@ def update_heatmap_ascan_fullscreen(layer): [ Output("heatmap-bscan-zx", "figure"), Output("store-bscan-zx-layer", "data"), + Output("fade-bscan-zx", "is_in"), ], [Input("layer-slider-bscan-zx", "value")], + [dash.dependencies.State("fade-bscan-zx", "is_in")], prevent_initial_call=True, ) -def update_heatmap_bscan_zx(layer): +def update_heatmap_bscan_zx(layer, is_in): fig = px.imshow( volume[layer - 1, :, :], color_continuous_scale="Jet", @@ -555,7 +583,7 @@ def update_heatmap_bscan_zx(layer): title="B-scan ZX", ) - return [fig, layer] + return [fig, layer, True] # callback pour les B-scan ZX en plein écran @@ -576,14 +604,20 @@ def update_heatmap_bscan_zx_fullscreen(layer): # callback pour les B-scan ZX @callback( - [Output("heatmap-bscan-xy", "figure"), Output("store-bscan-xy-layer", "data")], + [ + Output("heatmap-bscan-xy", "figure"), + Output("store-bscan-xy-layer", "data"), + Output("fade-bscan-xy", "is_in"), + ], [Input("layer-slider-bscan-xy", "value")], + [dash.dependencies.State("fade-bscan-xy", "is_in")], prevent_initial_call=True, ) -def update_heatmap_bscan_xy(layer): +def update_heatmap_bscan_xy(layer, is_in): fig = go.Figure(data=go.Heatmap(z=volume[:, :, layer], colorscale="Jet")) + fig.update_layout(title="B-scan XY") - return [fig, layer] + return [fig, layer, True] # callback pour les B-scan ZX en plein écran @@ -593,6 +627,7 @@ def update_heatmap_bscan_xy(layer): ) def update_heatmap_bscan_xy_fullscreen(layer): fig = go.Figure(data=go.Heatmap(z=volume[:, :, layer], colorscale="Jet")) + fig.update_layout(title="B-scan XY") return fig @@ -688,14 +723,18 @@ def display_bscan_xy_click_data(clickData): ) def display_bscan_zx_click_data(clickData): if clickData is None: - return [None, 1] + return [None, 0] bscan_xy = clickData["points"][0]["x"] return [clickData, bscan_xy] @callback( - [Output("heatmap-bscan-xy", "figure", allow_duplicate=True), Output("heatmap-bscan-zx", "figure", allow_duplicate=True)], + [ + Output("heatmap-bscan-xy", "figure", allow_duplicate=True), + Output("heatmap-bscan-zx", "figure", allow_duplicate=True), + Output("heatmap-ascan", "figure", allow_duplicate=True), + ], [Input("store-bscan-xy-layer", "data"), Input("store-bscan-zx-layer", "data")], prevent_initial_call=True, ) @@ -703,12 +742,13 @@ def update_bscan_layers(bscan_xy, bscan_zx): fig = go.Figure(data=go.Heatmap(z=volume[:, :, bscan_xy], colorscale="Jet")) fig.add_shape( type="line", - x0=0-1, + x0=0 - 1, y0=bscan_zx, x1=dim_y, y1=bscan_zx, line=dict(color="white", width=1), ) + fig.update_layout(title="B-scan XY") fig2 = px.imshow( volume[bscan_zx - 1, :, :], @@ -725,4 +765,14 @@ def update_bscan_layers(bscan_xy, bscan_zx): line=dict(color="white", width=1), ) - return [fig, fig2] + fig3 = px.line(y=volume[bscan_zx - 1, :, bscan_xy], title="A-scan") + + return [fig, fig2, fig3] + + +@callback( + Output("store-settings", "data"), + [Input("use-real-values", "value")], +) +def update_settings(use_real_values): + return {"use_real_values": use_real_values}