Modified the plotting routines so that they show the data interpolated on common spatial and temporal grids. Export to Excel files is now working.

dev-bjvincent-fix-UBSediFlow
Bjarne Vincent 2025-10-22 16:14:51 +02:00
parent fc438ee3a6
commit 1b46baa6d0
1 changed files with 89 additions and 121 deletions

View File

@ -1199,6 +1199,7 @@ class AcousticInversionTab(QWidget):
self.figure_SSC_fine.canvas.draw_idle()
def plot_SSC_sand(self):
data_id = self.combobox_acoustic_data_choice.currentIndex()
if self.combobox_acoustic_data_choice.count() <= 0:
@ -1315,9 +1316,11 @@ class AcousticInversionTab(QWidget):
def plot_SSC_sand_vertical_profile(self):
data_id = self.combobox_acoustic_data_choice.currentIndex()
if self.combobox_acoustic_data_choice.count() > 0:
if stg.SSC_sand[self.combobox_acoustic_data_choice.currentIndex()].shape == (0,):
if stg.SSC_sand[data_id].shape == (0,):
self.verticalLayout_groupbox_plot_vertical_profile_sand.removeWidget(self.toolbar_profile_sand)
self.verticalLayout_groupbox_plot_vertical_profile_sand.removeWidget(self.canvas_profile_sand)
@ -1328,9 +1331,9 @@ class AcousticInversionTab(QWidget):
self.verticalLayout_groupbox_plot_vertical_profile_sand.addWidget(self.toolbar_profile_sand)
self.verticalLayout_groupbox_plot_vertical_profile_sand.addWidget(self.canvas_profile_sand)
if stg.SSC_sand[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
if stg.SSC_sand[data_id].shape != (0,):
self.slider_sand.setMaximum(stg.SSC_fine[self.combobox_acoustic_data_choice.currentIndex()].shape[1])
self.slider_sand.setMaximum(stg.SSC_fine[data_id].shape[1])
self.verticalLayout_groupbox_plot_vertical_profile_sand.removeWidget(self.toolbar_profile_sand)
self.verticalLayout_groupbox_plot_vertical_profile_sand.removeWidget(self.canvas_profile_sand)
@ -1351,51 +1354,39 @@ class AcousticInversionTab(QWidget):
self.verticalLayout_groupbox_plot_vertical_profile_sand.addWidget(self.toolbar_profile_sand)
self.verticalLayout_groupbox_plot_vertical_profile_sand.addWidget(self.canvas_profile_sand)
if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.plot_sand , = self.axis_vertical_profile_SSC_sand.plot(
stg.SSC_sand[self.combobox_acoustic_data_choice.currentIndex()][:, self.slider_sand.value() -1],
-stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
stg.frequency_for_inversion[1]],
stg.SSC_sand[data_id][:, self.slider_sand.value() -1],
-stg.r2D_interp[data_id][:,0],
linestyle="solid", linewidth=1, color="k")
self.pcm_SSC_sand_vertical_line.set_data(
stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
stg.frequency_for_inversion[1],
self.slider_sand.value() - 1] *
np.ones(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
stg.frequency_for_inversion[1]].shape),
-stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
stg.frequency_for_inversion[1]])
stg.t2D_interp[data_id][0, self.slider_sand.value() - 1]
* np.ones( ( stg.r2D_interp[data_id].shape[0], 1 ) ),
-stg.r2D_interp[data_id][:, 0] )
self.figure_SSC_sand.canvas.draw_idle()
self.axis_vertical_profile_SSC_sand.set_ylim(
[-np.nanmax(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
stg.frequency_for_inversion[1]]),
-np.nanmin(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
stg.frequency_for_inversion[1]])])
[ -np.nanmax( stg.r2D_interp[data_id][:,0] ), -np.nanmin( stg.r2D_interp[data_id][:,0] ) ] )
else:
self.plot_sand , = self.axis_vertical_profile_SSC_sand.plot(
stg.SSC_sand[self.combobox_acoustic_data_choice.currentIndex()][:, self.slider_sand.value() -1],
-stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
stg.frequency_for_inversion[1]],
stg.SSC_sand[data_id][:, self.slider_sand.value() -1],
-stg.depth[data_id][stg.frequency_for_inversion[1].shape],
linestyle="solid", linewidth=1, color="k")
self.pcm_SSC_sand_vertical_line.set_data(
stg.time[self.combobox_acoustic_data_choice.currentIndex()][
stg.frequency_for_inversion[1], self.slider_sand.value() - 1] *
np.ones(stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
stg.frequency_for_inversion[1]].shape),
-stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
stg.frequency_for_inversion[1]])
stg.t2D_interp[data_id][0, self.slider_sand.value() - 1]
* np.ones( stg.depth[data_id][stg.frequency_for_inversion[1]].shape ),
-stg.depth[data_id][ stg.frequency_for_inversion[1] ] )
self.figure_SSC_sand.canvas.draw_idle()
self.axis_vertical_profile_SSC_sand.set_ylim(
[-np.nanmax(stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
[-np.nanmax(stg.depth[data_id][
stg.frequency_for_inversion[1]]),
-np.nanmin(stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
-np.nanmin(stg.depth[data_id][
stg.frequency_for_inversion[1]])])
# self.axis_SSC_fine.plot([], [], )
@ -1407,76 +1398,74 @@ class AcousticInversionTab(QWidget):
def update_plot_SSC_sand_vertical_profile(self):
data_id = self.combobox_acoustic_data_choice.currentIndex()
if stg.filename_BS_noise_data != []:
if stg.SSC_sand[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
if stg.SSC_sand[data_id].shape != (0,):
self.axis_vertical_profile_SSC_sand.cla()
if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_vertical_profile_SSC_sand.plot(
stg.SSC_sand[self.combobox_acoustic_data_choice.currentIndex()][:,
self.slider_sand.value() - 1],
-stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
stg.frequency_for_inversion[1]],
stg.SSC_sand[data_id][:, self.slider_sand.value() - 1],
-stg.r2D_interp[data_id][:, 0],
linestyle="solid", linewidth=1, color="k")
self.pcm_SSC_sand_vertical_line.set_data(
stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
stg.time_cross_section[data_id][
stg.frequency_for_inversion[1],
self.slider_sand.value() - 1] *
np.ones(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
np.ones(stg.depth_cross_section[data_id][
stg.frequency_for_inversion[1]].shape),
-stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
-stg.depth_cross_section[data_id][
stg.frequency_for_inversion[1]])
self.figure_SSC_sand.canvas.draw_idle()
self.axis_vertical_profile_SSC_sand.set_ylim(
[-np.nanmax(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
[-np.nanmax(stg.depth_cross_section[data_id][
stg.frequency_for_inversion[1]]),
-np.nanmin(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
-np.nanmin(stg.depth_cross_section[data_id][
stg.frequency_for_inversion[1]])])
else:
self.axis_vertical_profile_SSC_sand.plot(
stg.SSC_sand[self.combobox_acoustic_data_choice.currentIndex()][:,
self.slider_sand.value() - 1],
-stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
stg.frequency_for_inversion[1]],
stg.SSC_sand[data_id][:, self.slider_sand.value() - 1],
-stg.r2D_interp[data_id][:, 0],
linestyle="solid", linewidth=1, color="k")
self.pcm_SSC_sand_vertical_line.set_data(
stg.time[self.combobox_acoustic_data_choice.currentIndex()][
stg.time[data_id][
stg.frequency_for_inversion[1], self.slider_sand.value() - 1] *
np.ones(stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
np.ones(stg.depth[data_id][
stg.frequency_for_inversion[1]].shape),
-stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
-stg.depth[data_id][
stg.frequency_for_inversion[1]])
self.figure_SSC_sand.canvas.draw_idle()
self.axis_vertical_profile_SSC_sand.set_ylim(
[-np.nanmax(stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
[-np.nanmax(stg.depth[data_id][
stg.frequency_for_inversion[1]]),
-np.nanmin(stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
-np.nanmin(stg.depth[data_id][
stg.frequency_for_inversion[1]])])
if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
if stg.time_cross_section[data_id].shape != (0,):
time_sand_calibration = (
np.where(np.abs(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
np.where(np.abs(stg.time_cross_section[data_id][
stg.frequency_for_inversion[1]] - stg.time_sand[
stg.sand_sample_target[0][1]]) ==
np.nanmin(
np.abs(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
np.abs(stg.time_cross_section[data_id][
stg.frequency_for_inversion[1]] - stg.time_sand[
stg.sand_sample_target[0][1]])))[0][0]
)
if (stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
if (stg.time_cross_section[data_id][
stg.frequency_for_inversion[1], int(self.slider_sand.value())] ==
stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
stg.time_cross_section[data_id][
stg.frequency_for_inversion[1], int(time_sand_calibration)]):
self.axis_vertical_profile_SSC_sand.scatter(stg.Ctot_sand[stg.sand_sample_target[0][1]],
stg.depth_sand[stg.sand_sample_target[0][1]],
@ -1489,17 +1478,17 @@ class AcousticInversionTab(QWidget):
else:
time_sand_calibration = (
np.where(np.abs(stg.time[self.combobox_acoustic_data_choice.currentIndex()][
np.where(np.abs(stg.time[data_id][
stg.frequency_for_inversion[1]] - stg.time_sand[
stg.sand_sample_target[0][1]]) ==
np.nanmin(np.abs(stg.time[self.combobox_acoustic_data_choice.currentIndex()][
np.nanmin(np.abs(stg.time[data_id][
stg.frequency_for_inversion[1]] - stg.time_sand[
stg.sand_sample_target[0][1]])))[0][0]
)
if (stg.time[self.combobox_acoustic_data_choice.currentIndex()][
if (stg.time[data_id][
stg.frequency_for_inversion[1], int(self.slider_sand.value())] ==
stg.time[self.combobox_acoustic_data_choice.currentIndex()][
stg.time[data_id][
stg.frequency_for_inversion[1], int(time_sand_calibration)]):
self.axis_vertical_profile_SSC_sand.scatter(stg.Ctot_fine[stg.sand_sample_target[0][1]],
stg.depth_fine[stg.sand_sample_target[0][1]],
@ -1756,64 +1745,61 @@ class AcousticInversionTab(QWidget):
if ".ods" in filename:
engine = "odf"
else:
engine = 'xlsxwriter'
engine = "xlsxwriter"
with pd.ExcelWriter(
os.path.join(dirname, filename),
engine=engine
) as writer:
time_data = stg.t2D_interp
depth_data = stg.r2D_interp
for k in range(self.combobox_acoustic_data_choice.count()):
if stg.time_cross_section[k].shape != (0,):
time_data = stg.time_cross_section
else:
time_data = stg.time
if stg.depth_cross_section[k].shape != (0,):
depth_data = stg.depth_cross_section
else:
depth_data = stg.depth
dataset_name = self.combobox_acoustic_data_choice.itemText(k)
t = np.repeat(
time_data[k][stg.frequency_for_inversion[1]],
depth_data[k].shape[1]
)
time_shape = time_data[k].shape[1]
depth_shape = depth_data[k].shape[0]
r = np.zeros(
depth_data[k].shape[1] * time_data[k].shape[1]
)
t = np.repeat( time_data[k][0,:], depth_shape )
for i in range(time_data[k].shape[1]):
for j in range(depth_data[k].shape[1]):
r_id = i * depth_data[k].shape[1] + j
r = np.zeros( time_shape * depth_shape )
r[r_id] = depth_data[k][
int(stg.frequency_for_inversion[1]), j
]
for i in range(time_shape):
for j in range(depth_shape):
r_id = i * depth_shape + j
r[r_id] = depth_data[k][j, 0]
# If no SSC has been computed, fill
if stg.SSC_fine[k].shape == (0,):
stg.SSC_fine[k] = np.zeros(r.shape[0])
if stg.SSC_sand[k].shape == (0,):
stg.SSC_sand[k] = np.zeros(r.shape[0])
# Flatten the fine and sand SSC arrays in a column-major order (i.e., "the first index
# runs the fastest"):
ssc_fine = np.reshape( stg.SSC_fine[k], r.shape[0], 'F' ).tolist()
ssc_sand = np.reshape( stg.SSC_sand[k], r.shape[0], 'F' ).tolist()
result = pd.DataFrame(
{
'Time (sec)': list(t),
'Depth (m)': list(r),
'SSC_fine (g/L)': list(
stg.SSC_fine[k].reshape(t.shape[0])
),
'SSC_sand (g/L)': list(
stg.SSC_sand[k].reshape(t.shape[0])
),
'Time (sec)': t.tolist(),
'Depth (m)': r.tolist(),
'SSC_fine (g/L)': ssc_fine,
'SSC_sand (g/L)': ssc_sand,
}
)
gc.collect() # Force garbade collection
gc.collect() # Force garbage collection
result.to_excel(
writer, index=False, na_rep='NA',
sheet_name=stg.data_preprocessed[k],
)
result.to_excel( writer, index=False, na_rep='NA', engine=engine,
sheet_name=dataset_name )
def save_result_in_csv_file(self, dirname, filename):
@ -1839,6 +1825,9 @@ class AcousticInversionTab(QWidget):
ssc_fine = [] #List of flattened fine SSC arrays (g/L)
ssc_sand = [] #List of flattened sand SSC arrays (g/L)
time_data = stg.t2D_interp
depth_data = stg.r2D_interp
# Loop over all datasets loaded into AcouSed:
@ -1876,48 +1865,27 @@ class AcousticInversionTab(QWidget):
'''
# Retrieve the time stamps and vertical positions:
if stg.time_cross_section[k].shape != (0,):
time_data = stg.time_cross_section
else:
time_data = stg.time
if stg.depth_cross_section[k].shape != (0,):
depth_data = stg.depth_cross_section
else:
depth_data = stg.depth
# Form the 1D arrays of time stamps and vertical positions
# for the k-th dataset:
time_shape = time_data[k].shape[1]
depth_shape = depth_data[k].shape[1]
time_shape = time_data[k].shape[1] #Number of time stamps
depth_shape = depth_data[k].shape[0] #Number of vertical coordinates
d_id += np.repeat(k, depth_shape * time_shape).tolist() #Flattened array of the current dataset's index
tmp_t = np.repeat(
time_data[k][stg.frequency_for_inversion[1]],
depth_shape
) #Flattened array of time stamps
tmp_t = np.repeat(time_data[k][0,:], depth_shape) #Flattened array of time stamps
tmp_r = np.zeros(
depth_shape * time_shape
) #Initialise the flattened array of vertical positions
tmp_r = np.zeros(depth_shape * time_shape) #Initialise the flattened array of vertical positions
# Fill the flattened array of vertical positions:
for i in range(time_shape):
for j in range(depth_shape):
r_id = i * depth_shape + j
tmp_r[r_id] = (
depth_data[k][
int(stg.frequency_for_inversion[1]), j
]
)
tmp_r[r_id] = depth_data[k][j, 0]
# Add the flattened arrays of time stamps and vertical positions to their respective