diff --git a/3D_app/pages/ascan.py b/3D_app/pages/ascan.py index 0c8c5c9..4b16907 100644 --- a/3D_app/pages/ascan.py +++ b/3D_app/pages/ascan.py @@ -12,17 +12,13 @@ from Bscan_Cscan_trait import * dash.register_page( - __name__, - path="/ascan", - title="A-Scan filters", - name="A-Scan filters", - description="Apply filters on the A-Scan", + __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, 20) ] # on lit les fichiers et on les met dans un tableau @@ -30,7 +26,7 @@ pre_volume = np.array(lire_fichier_csv(dossier, fichiers_selectionnes)) volume = pre_volume[:, :, :] data_traits = volume dim_x, dim_y, dim_z = volume.shape - +click=None X, Y, Z = np.mgrid[0:dim_x, 0:dim_y, 0:dim_z] # on définit le thème de l'application pio.templates.default = "plotly_dark" @@ -54,20 +50,20 @@ layout = html.Div( dbc.Select( id="select-ascan-filter1", options=[ - {"label": "Transformer du Hilbert", "value": "1"}, + {"label": "transformer du Hilbert", "value": "1"}, ], value=1, style={"margin-bottom": "15px"}, ), ], - width=3, + width=2, ), dbc.Col( [ dbc.Select( id="select-ascan-filter2", options=[ - {"label": "No filter ", "value": "2"}, + {"label": "sans filtre ", "value": "2"}, {"label": "filtre passe bas ", "value": "3"}, {"label": "filtre de moyenne mobile", "value": "4"}, {"label": "filtre adaptatif (wiener)", "value": "5"}, @@ -84,14 +80,14 @@ layout = html.Div( style={"margin-bottom": "15px"}, ), ], - width=3, + width=2, ), dbc.Col( [ dbc.Select( id="select-ascan-filter3", options=[ - {"label": "No filter ", "value": "2"}, + {"label": "sans filtre ", "value": "2"}, {"label": "filtre passe bas ", "value": "3"}, {"label": "filtre de moyenne mobile", "value": "4"}, {"label": "filtre adaptatif (wiener)", "value": "5"}, @@ -108,41 +104,50 @@ layout = html.Div( style={"margin-bottom": "15px"}, ), ], - width=3, + width=2, ), dbc.Col( [ - html.Div( - [ - dbc.Label( - "Apply selection on all data", - style={"margin": "auto 0"}, - ), - dbc.Button( - id="button-validate-filter", - children=dbc.Spinner( - html.Div("Apply", id="loading"), - show_initially=False, - ), - color="primary", - ), - ], - style={ - "justifyContent": "space-between", - "display": "flex", - }, + dbc.Label( + "apply the filters", + style={"marginRight": "5px"}, + ), + dbc.Button( + id="button-validate-filter", + children=dbc.Spinner( + html.Div("Valider", id="loading"), show_initially=False + ), + color="primary", + style={"marginBottom": "15px"}, ), ], - width=3, + width=2, + ), + dbc.Col( + [ + dbc.Label( + "Save data", + style={"marginRight": "5px"}, + ), + dbc.Button( + id="button-save-data", + children=dbc.Spinner( + html.Div("save", id="save"), show_initially=False + ), + color="primary", + style={"marginBottom": "15px"}, + ), + ], + width=2, ), ] ), dbc.Row( [ dbc.Col( - html.B(" 1st filter settings "), + [html.Br(), html.B(" paramètre du 1er filtre ")], width=2, - style={"textAlign": "center", "padding": "3.5vh"}, + style={"textAlign": "center"}, ), dbc.Col( [ @@ -151,7 +156,7 @@ layout = html.Div( id="input-ascan-solo-fs", type="number", placeholder="Fs", - value=1, + value=100, step=0.1, ), ], @@ -159,11 +164,11 @@ layout = html.Div( ), dbc.Col( [ - dbc.Label("Cut Off ", html_for="cut off"), + dbc.Label("cut off ", html_for="cut off"), dbc.Input( id="input-ascan-solo-cutoff", type="number", - placeholder="Cut Off", + placeholder="cut_off", value=1, step=0.1, ), @@ -172,11 +177,11 @@ layout = html.Div( ), dbc.Col( [ - dbc.Label("Order ", html_for="order"), + dbc.Label("order ", html_for="order"), dbc.Input( id="input-ascan-solo-order", type="number", - placeholder="Order", + placeholder="order", value=1, step=1, ), @@ -185,11 +190,11 @@ layout = html.Div( ), dbc.Col( [ - dbc.Label("Window size ", html_for="window size"), + dbc.Label("window size ", html_for="window size"), dbc.Input( id="input-ascan-solo-windowsize", type="number", - placeholder="Window_size", + placeholder="window_size", value=1, step=1, ), @@ -197,9 +202,9 @@ layout = html.Div( width=1, ), dbc.Col( - html.B(" 2nd filter settings "), + [html.Br(), html.B(" paramètre du 2e filtre ")], width=2, - style={"textAlign": "center", "padding": "3.5vh"}, + style={"textAlign": "center"}, ), dbc.Col( [ @@ -208,7 +213,7 @@ layout = html.Div( id="input-ascan-solo-fs-2", type="number", placeholder="Fs", - value=1, + value=100, step=0.1, ), ], @@ -216,11 +221,11 @@ layout = html.Div( ), dbc.Col( [ - dbc.Label("Cut Off ", html_for="cut off"), + dbc.Label("cut off ", html_for="cut off"), dbc.Input( id="input-ascan-solo-cutoff-2", type="number", - placeholder="Cut Off", + placeholder="cut_off", value=1, step=0.1, ), @@ -229,11 +234,11 @@ layout = html.Div( ), dbc.Col( [ - dbc.Label("Order ", html_for="order"), + dbc.Label("order ", html_for="order"), dbc.Input( id="input-ascan-solo-order-2", type="number", - placeholder="Order", + placeholder="order", value=1, step=1, ), @@ -242,11 +247,11 @@ layout = html.Div( ), dbc.Col( [ - dbc.Label("Window size ", html_for="window size"), + dbc.Label("window size ", html_for="window size"), dbc.Input( id="input-ascan-solo-windowsize-2", type="number", - placeholder="Window_size", + placeholder="window_size", value=1, step=1, ), @@ -283,7 +288,7 @@ layout = html.Div( ), ] ), - dbc.Label("X"), + dbc.Label("x"), dcc.Slider( id="layer-slider-ascan-solo-x", min=1, @@ -294,7 +299,7 @@ layout = html.Div( str(i): str(i) for i in range(1, dim_z + 1, max(1, int(dim_z / 20))) }, ), - dbc.Label("Y"), + dbc.Label("y"), dcc.Slider( id="layer-slider-ascan-solo-y", min=1, @@ -305,7 +310,7 @@ layout = html.Div( str(i): str(i) for i in range(1, dim_x + 1, max(1, int(dim_x / 20))) }, ), - dbc.Label("Z"), + dbc.Label("z"), dcc.RangeSlider( id="layer-slider-ascan-solo-z", min=1, @@ -316,12 +321,10 @@ layout = html.Div( str(i): str(i) for i in range(1, dim_y + 1, max(1, int(dim_y / 20))) }, ), - html.Div(id="loading-fullscreen"), ], style={"padding": "20px"}, ) - @callback( Output("store-filters", "data"), [ @@ -416,13 +419,65 @@ def update_filter_values(select_filtre_1, select_filtre_2): ] + +@callback( + Output("loading", "children"), + Input("button-validate-filter", "n_clicks"), + [ + State("select-ascan-filter1", "value"), + State("select-ascan-filter2", "value"), + State("select-ascan-filter3", "value"), + State("input-ascan-solo-fs", "value"), + State("input-ascan-solo-cutoff", "value"), + State("input-ascan-solo-order", "value"), + State("input-ascan-solo-windowsize", "value"), + State("input-ascan-solo-fs-2", "value"), + State("input-ascan-solo-cutoff-2", "value"), + State("input-ascan-solo-order-2", "value"), + State("input-ascan-solo-windowsize-2", "value"), + ] +) +def load_button(n_clicks, + selec_transforme_hilbert, + select_filtre_1,select_filtre_2, + fs_filtre_1,cutoff_filtre_1, + order_filtre_1,windowsize_filtre_1, + fs_filtre_2,cutoff_filtre_2,order_filtre_2,windowsize_filtre_2, +): + bouton = "Valider" + global data_traits,click + if n_clicks != click: + data_traits=Cscant(data_input=data_traits, + sel1=int(selec_transforme_hilbert),sel2=int(select_filtre_1), + sel3=int(select_filtre_2), + fs_1=int(fs_filtre_1),cut_off_1=float(cutoff_filtre_1), + order_1=int(order_filtre_1),window_size_1=int(windowsize_filtre_1), + fs_2=int(fs_filtre_2),cut_off_2=float(cutoff_filtre_2), + order_2=int(order_filtre_2),window_size2=int(windowsize_filtre_2)) + bouton = "Valider" + click=n_clicks + return bouton + + +@callback( + Output("save", "children"), + Input("button-save-data","n_clicks"), +) +def save_data(n_clicks): + bouton = "save" + global data_traits + if n_clicks!=None: + np.save('Dataset/saves/datat.npy',data_traits) + bouton = "save" + return bouton + + # callback to update the heatmap @callback( [ Output("heatmap-ascan-solo", "figure"), Output("heatmap-bscan-solo", "figure"), Output("heatmap-fft-solo", "figure"), - Output("loading", "children"), ], [ Input("layer-slider-ascan-solo-x", "value"), @@ -442,7 +497,7 @@ def update_filter_values(select_filtre_1, select_filtre_2): State("input-ascan-solo-cutoff-2", "value"), State("input-ascan-solo-order-2", "value"), State("input-ascan-solo-windowsize-2", "value"), - ], + ] ) def update_heatmap_ascan( select_ascan_x, @@ -462,6 +517,7 @@ def update_heatmap_ascan( windowsize_filtre_2, ): # TODO: implement the filter + print("debut du traitement") data_avec_traitement = volume[ int(select_ascan_y) - 1, @@ -498,23 +554,7 @@ def update_heatmap_ascan( int(windowsize_filtre_2), ) print("fin du traitement") - bouton = "Apply" - if n_clicks != None: - data_traits = Cscant( - volume, - int(selec_transforme_hilbert), - int(select_filtre_1), - int(select_filtre_2), - float(fs_filtre_1), - float(cutoff_filtre_1), - int(order_filtre_1), - int(windowsize_filtre_1), - float(fs_filtre_2), - float(cutoff_filtre_2), - int(order_filtre_2), - int(windowsize_filtre_2), - ) - bouton = "Apply" + fig = px.line(title="A-scan") new_trace = go.Scatter(y=data_avec_traitement, mode="lines", name=" Ascan trait ") fig.add_trace(new_trace) @@ -524,21 +564,10 @@ def update_heatmap_ascan( fig.add_trace(new_trace) fig.update_layout(xaxis_title="indix", yaxis_title="amplitude") - data_bscan = Bscant( - volume[select_ascan_y - 1, select_ascan_z[0] : select_ascan_z[1], :], - int(selec_transforme_hilbert), - int(select_filtre_1), - int(select_filtre_2), - float(fs_filtre_1), - float(cutoff_filtre_1), - int(order_filtre_1), - int(windowsize_filtre_1), - float(fs_filtre_2), - float(cutoff_filtre_2), - int(order_filtre_2), - int(windowsize_filtre_2), - ) + data_bscan=Bscant(volume[select_ascan_y - 1, select_ascan_z[0] : select_ascan_z[1], :],int(selec_transforme_hilbert),int(select_filtre_1),int(select_filtre_2),float(fs_filtre_1), + float(cutoff_filtre_1),int(order_filtre_1),int(windowsize_filtre_1),float(fs_filtre_2),float(cutoff_filtre_2),int(order_filtre_2),int(windowsize_filtre_2),) + fig2 = px.imshow( data_bscan, color_continuous_scale="Jet", @@ -549,14 +578,14 @@ def update_heatmap_ascan( data_sans_traitement_fft = np.fft.fft( volume[ int(select_ascan_y) - 1, - select_ascan_z[0] : select_ascan_z[1], + int(select_ascan_z[0]) : int(select_ascan_z[1]), int(select_ascan_x) - 1, ] ) fig3 = px.line(title="FFT") - trace3 = go.Scatter(y=np.abs(data_sans_traitement_fft), mode="lines", name=" FFT ") + trace3 = go.Scatter(y=np.abs(data_sans_traitement_fft[int(select_ascan_z[0]) :int(int(select_ascan_z[1])/2)]), mode="lines", name=" FFT ") fig3.add_trace(trace3) fig3.update_layout( xaxis_title="FFT indix", yaxis_title="FFT of signal (Mangnitude)" ) - return [fig, fig2, fig3, bouton] + return [fig, fig2, fig3] diff --git a/3D_app/pages/home.py b/3D_app/pages/home.py index 786cd89..2cbe34f 100644 --- a/3D_app/pages/home.py +++ b/3D_app/pages/home.py @@ -6,29 +6,20 @@ import numpy as np import plotly.express as px import plotly.io as pio from util import * +from selection_filtre import * from os.path import join import diskcache +from pages.ascan import data_traits, pre_volume -dash.register_page(__name__, path="/", description="The home page of the web app") -# 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) -] -cache = diskcache.Cache("./cache") -background_callback_manager = DiskcacheManager(cache) - -# on charge le fichier numpy -# fichiers = np.load("Dataset/npy/export.npy") +dash.register_page(__name__, path="/") # 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 @@ -263,7 +254,7 @@ Ascan_card = dbc.Fade( dcc.Slider( id="layer-slider-ascan-fullscreen", min=0, - max=dim_x - 1, + max=dim_x, value=0, step=1, marks={ @@ -345,7 +336,7 @@ Bscan_card_xy = dbc.Fade( dcc.Slider( id="layer-slider-bscan-zx-fullscreen", min=0, - max=dim_x - 1, + max=dim_x, value=0, step=1, marks={ @@ -470,14 +461,18 @@ layout = html.Div( # on défini les callbacks # callback pour le plot 3D @callback( - [Output("3dplot", "figure"), Output("fade-3dplot", "is_in")], + [Output("3dplot", "figure")], [ Input("iso-slider", "value"), Input("y-slider", "value"), Input("store-settings", "data"), ], [dash.dependencies.State("fade-3dplot", "is_in")], + running=[ + (Output("fade-3dplot", "is_in"), False, True), + ], ) +### a revoir### def update_3dplot(iso_value, y_values, settings, is_in): if settings["use_real_values"]: y_min, y_max = y_values @@ -508,7 +503,7 @@ def update_3dplot(iso_value, y_values, settings, is_in): ) ) - return [fig, True] + return [fig] # callback pour le plot 3D en plein écran @@ -516,6 +511,7 @@ def update_3dplot(iso_value, y_values, settings, is_in): Output("3dplot-fullscreen", "figure"), [Input("iso-slider-fullscreen", "value"), Input("y-slider-fullscreen", "value")], ) +### à revoir ### def update_3dplot_fullscreen(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] @@ -544,15 +540,18 @@ def update_3dplot_fullscreen(iso_value, y_values): # callback pour le A-scan @callback( - [Output("heatmap-ascan", "figure"), Output("fade-ascan", "is_in")], + [Output("heatmap-ascan", "figure")], [Input("layer-slider-bscan-zx", "value"), Input("layer-slider-bscan-xy", "value")], [dash.dependencies.State("fade-ascan", "is_in")], + running=[ + (Output("fade-ascan", "is_in"), False, True), + ], prevent_initial_call=True, ) def update_heatmap_ascan(layer, layer1, is_in): fig = px.line(y=volume[layer - 1, :, layer1], title="A-scan") - return [fig, True] + return [fig] # callback pour le A-scan en plein écran @@ -570,10 +569,12 @@ def update_heatmap_ascan_fullscreen(layer): [ Output("heatmap-bscan-zx", "figure"), Output("store-bscan-zx-layer", "data"), - Output("fade-bscan-xy", "is_in"), ], [Input("layer-slider-bscan-zx", "value")], [dash.dependencies.State("fade-bscan-zx", "is_in")], + running=[ + (Output("fade-bscan-xy", "is_in"), False, True), + ], prevent_initial_call=True, ) def update_heatmap_bscan_zx(layer, is_in): @@ -584,7 +585,7 @@ def update_heatmap_bscan_zx(layer, is_in): title="B-scan ZX", ) - return [fig, layer, True] + return [fig, layer] # callback pour les B-scan ZX en plein écran @@ -605,20 +606,19 @@ 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("fade-bscan-zx", "is_in"), - ], + [Output("heatmap-bscan-xy", "figure"), Output("store-bscan-xy-layer", "data")], [Input("layer-slider-bscan-xy", "value")], [dash.dependencies.State("fade-bscan-xy", "is_in")], + running=[ + (Output("fade-bscan-zx", "is_in"), False, True), + ], prevent_initial_call=True, ) 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, True] + return [fig, layer] # callback pour les B-scan ZX en plein écran @@ -823,7 +823,7 @@ def update_settings( prevent_initial_call=True, ) def redef_data(data): - global volume, pre_volume, dim_x, dim_y, dim_z, X, Y, Z + global volume, dim_x, dim_y, dim_z, X, Y, Z volume = pre_volume[ :: data["echantillonage_x"], :: data["echantillonage_y"], @@ -852,7 +852,7 @@ def redef_data(data): "Apply", ] - +""" @callback( [Input("store-filters", "data"), Input("store-settings", "data")], ) @@ -903,45 +903,37 @@ def apply_filters(data, settings): :: settings["echantillonage_z"], ] return None - +""" @callback( + Output("store-files", "data", allow_duplicate=True), Input("store-files", "data"), - [ - State("store-settings", "data"), - State("layer-slider-bscan-zx", "value"), - State("layer-slider-bscan-xy", "value"), - State("iso-slider", "value"), - State("y-slider", "value"), - ], + State("store-settings", "data"), prevent_initial_call=True, ) -def update_files(data, settings, layer_zx, layer_xy, iso, y): - global pre_volume, dim_y +def update_files(data, settings): + global pre_volume, volume, dim_x, dim_y, dim_z, X, Y, Z if data is None or data == "": return None + + # Charger le nouveau volume pre_volume = np.load(join("Dataset/saves", data)) - redef_data(settings) - update_3dplot(iso, y, settings, False) - update_heatmap_ascan(layer_zx, layer_xy, False) - update_heatmap_bscan_zx(layer_zx, False) - update_heatmap_bscan_xy(layer_xy, False) + print("New volume loaded:", pre_volume.shape) + + # Appliquer les nouveaux paramètres d'échantillonnage + volume = pre_volume[ + ::settings["echantillonage_x"], + ::settings["echantillonage_y"], + ::settings["echantillonage_z"], + ] + dim_x, dim_y, dim_z = volume.shape + X, Y, Z = np.mgrid[0:dim_x, 0:dim_y, 0:dim_z] + print("Volume updated with new dimensions:", volume.shape) + + # Mettre à jour les graphiques + update_3dplot(0, [0, dim_y // 2], settings, False) + update_heatmap_ascan(0, 0, False) + update_heatmap_bscan_zx(0, False) + update_heatmap_bscan_xy(0, False) + return None - - -@callback( - Output("save-toast", "is_open"), - Input("save-save", "n_clicks"), - [ - State("save-input", "value"), - State("save-format", "value"), - ], -) -def save_data(n_clicks, filename, format): - if n_clicks is None: - return False - if format == "raw": - np.save(join("Dataset/saves", filename), pre_volume) - else: - np.save(join("Dataset/saves", filename), volume) - return True