diff --git a/src/View/InitialConditions/Window.py b/src/View/InitialConditions/Window.py
index d8484aba..649e3459 100644
--- a/src/View/InitialConditions/Window.py
+++ b/src/View/InitialConditions/Window.py
@@ -263,6 +263,7 @@ class InitialConditionsWindow(PamhyrWindow):
workdir = os.path.dirname(self._study.filename)
return self.file_dialog(
+ select_file=True,
callback=lambda d: self._import_from_file(d[0]),
directory=workdir,
default_suffix=".BIN",
diff --git a/src/View/Results/CustomPlot/CustomPlotValuesSelectionDialog.py b/src/View/Results/CustomPlot/CustomPlotValuesSelectionDialog.py
index 796934fb..631a530a 100644
--- a/src/View/Results/CustomPlot/CustomPlotValuesSelectionDialog.py
+++ b/src/View/Results/CustomPlot/CustomPlotValuesSelectionDialog.py
@@ -45,6 +45,7 @@ class CustomPlotValuesSelectionDialog(PamhyrDialog):
self.setup_check_boxs()
self.value = None
+ self.export_to_csv = False
def setup_radio_buttons(self):
self._radio = []
@@ -95,4 +96,6 @@ class CustomPlotValuesSelectionDialog(PamhyrDialog):
)
self.value = x, y
+ self.export_to_csv = self.find(QCheckBox,
+ "checkBox_export").isChecked()
super().accept()
diff --git a/src/View/Results/Window.py b/src/View/Results/Window.py
index 03be2da7..f51ed02c 100644
--- a/src/View/Results/Window.py
+++ b/src/View/Results/Window.py
@@ -20,6 +20,8 @@ import os
import csv
import logging
+from numpy import sqrt
+
from datetime import datetime
from tools import trace, timer, logger_exception
@@ -489,12 +491,17 @@ class ResultsWindow(PamhyrWindow):
dlg = CustomPlotValuesSelectionDialog(parent=self)
if dlg.exec():
x, y = dlg.value
- self.create_new_tab_custom_plot(x, y)
+ export = dlg.export_to_csv
+ self.create_new_tab_custom_plot(x, y, export)
- def create_new_tab_custom_plot(self, x: str, y: list):
+ def create_new_tab_custom_plot(self, x: str, y: list, export: bool):
name = f"{x}: {','.join(y)}"
wname = f"tab_custom_{x}_{y}"
+ if export:
+ self.export(x, y)
+ return
+
tab_widget = self.find(QTabWidget, f"tabWidget")
# This plot already exists
@@ -534,6 +541,7 @@ class ResultsWindow(PamhyrWindow):
grid.addWidget(canvas, 1, 0)
widget.setLayout(grid)
tab_widget.addTab(widget, name)
+ tab_widget.setCurrentWidget(widget)
def _copy(self):
logger.info("TODO: copy")
@@ -582,18 +590,28 @@ class ResultsWindow(PamhyrWindow):
self._button_last.setEnabled(True)
self._button_play.setIcon(self._icon_start)
- def export(self):
+ def export(self, x: str, y: list):
+
+ logger.debug(
+ "Export custom plot for: " +
+ f"{x} -> {','.join(y)}"
+ )
self.file_dialog(
- select_file=False,
- callback=lambda d: self.export_to(d[0])
+ callback=lambda f: self.export_to(f[0], x, y),
+ default_suffix=".csv",
+ file_filter=["CSV (*.csv)"],
)
- def export_to(self, directory):
+ def export_to(self, filename, x, y):
timestamps = sorted(self._results.get("timestamps"))
- for reach in self._results.river.reachs:
- self.export_reach(reach, directory, timestamps)
+ if x == "rk":
+ timestamp = self._get_current_timestamp()
+ self._export_rk(timestamp, y, filename)
+ elif x == "time":
+ profile = self._get_current_profile()
+ self._export_time(profile, y, filename)
- def export_reach(self, reach, directory, timestamps):
+ def export_all(self, reach, directory, timestamps):
name = reach.name
name = name.replace(" ", "-")
if len(timestamps) == 1:
@@ -607,47 +625,14 @@ class ResultsWindow(PamhyrWindow):
with open(file_name, 'w', newline='') as csvfile:
writer = csv.writer(csvfile, delimiter=',',
quotechar='|', quoting=csv.QUOTE_MINIMAL)
- if len(timestamps) > 1:
- writer.writerow(["name", "rk", "data-file"])
- for profile in reach.profiles:
- p_file_name = os.path.join(
- directory,
- f"cs_{profile.geometry.id}.csv"
- )
-
- writer.writerow([
- profile.name,
- profile.rk,
- p_file_name
- ])
-
- self.export_profile(reach,
- profile,
- p_file_name,
- timestamps)
- else:
- ts = timestamps[0]
- writer.writerow(self._table["raw_data"]._headers)
- for row in range(self._table["raw_data"].rowCount()):
- line = []
- for column in range(self._table["raw_data"].columnCount()):
- index = self._table["raw_data"].index(row, column)
- line.append(self._table["raw_data"].data(index))
- writer.writerow(line)
-
- def export_profile(self, reach, profile, file_name, timestamps):
- with open(file_name, 'w', newline='') as csvfile:
- writer = csv.writer(csvfile, delimiter=',',
- quotechar='|', quoting=csv.QUOTE_MINIMAL)
-
- writer.writerow(["timestamp", "z", "q"])
-
- for ts in timestamps:
- writer.writerow([
- ts,
- profile.get_ts_key(ts, "Z"),
- profile.get_ts_key(ts, "Q"),
- ])
+ ts = timestamps[0]
+ writer.writerow(self._table["raw_data"]._headers)
+ for row in range(self._table["raw_data"].rowCount()):
+ line = []
+ for column in range(self._table["raw_data"].columnCount()):
+ index = self._table["raw_data"].index(row, column)
+ line.append(self._table["raw_data"].data(index))
+ writer.writerow(line)
def export_current(self):
self.file_dialog(
@@ -657,9 +642,144 @@ class ResultsWindow(PamhyrWindow):
def export_current_to(self, directory):
reach = self._results.river.reachs[self._get_current_reach()]
- self.export_reach(reach, directory, [self._get_current_timestamp()])
+ self.export_all(reach, directory, [self._get_current_timestamp()])
def delete_tab(self, index):
tab_widget = self.find(QTabWidget, f"tabWidget")
self._additional_plot.pop(tab_widget.tabText(index))
tab_widget.removeTab(index)
+
+ def _export_rk(self, timestamp, y, filename):
+ reach = self._results.river.reachs[self._get_current_reach()]
+ rk = reach.geometry.get_rk()
+ my_dict = {}
+ if "elevation" in y:
+ my_dict["elevation"] = reach.geometry.get_z_min()
+ if "discharge" in y:
+ my_dict["discharge"] = list(
+ map(
+ lambda p: p.get_ts_key(timestamp, "Q"),
+ reach.profiles
+ )
+ )
+ if "water_elevation" in y:
+ my_dict["water_elevation"] = list(
+ map(
+ lambda p: p.get_ts_key(timestamp, "Z"),
+ reach.profiles
+ )
+ )
+ if "velocity" in y:
+ my_dict["velocity"] = list(
+ map(
+ lambda p: p.geometry.speed(
+ p.get_ts_key(timestamp, "Q"),
+ p.get_ts_key(timestamp, "Z")),
+ reach.profiles
+ )
+ )
+ if "depth" in y:
+ my_dict["depth"] = list(
+ map(
+ lambda p: p.geometry.max_water_depth(
+ p.get_ts_key(timestamp, "Z")),
+ reach.profiles
+ )
+ )
+ if "mean_depth" in y:
+ my_dict["mean_depth"] = list(
+ map(
+ lambda p: p.geometry.mean_water_depth(
+ p.get_ts_key(timestamp, "Z")),
+ reach.profiles
+ )
+ )
+ if "froude" in y:
+ my_dict["froude"] = list(
+ map(
+ lambda p:
+ p.geometry.speed(
+ p.get_ts_key(timestamp, "Q"),
+ p.get_ts_key(timestamp, "Z")) /
+ sqrt(9.81 * (
+ p.geometry.wet_area(
+ p.get_ts_key(timestamp, "Z")) /
+ p.geometry.wet_width(
+ p.get_ts_key(timestamp, "Z"))
+ )),
+ reach.profiles
+ )
+ )
+ if "wet_area" in y:
+ my_dict["wet_area"] = list(
+ map(
+ lambda p: p.geometry.wet_area(
+ p.get_ts_key(timestamp, "Z")),
+ reach.profiles
+ )
+ )
+
+ with open(filename, 'w', newline='') as csvfile:
+ writer = csv.writer(csvfile, delimiter=',',
+ quotechar='|', quoting=csv.QUOTE_MINIMAL)
+ header = ["rk"] + y
+ writer.writerow(header)
+ for row in range(len(rk)):
+ line = [rk[row]]
+ for var in y:
+ line.append(my_dict[var][row])
+ writer.writerow(line)
+
+ def _export_time(self, profile, y, filename):
+ reach = self._results.river.reachs[self._get_current_reach()]
+ profile = reach.profile(profile)
+ ts = list(self._results.get("timestamps"))
+ ts.sort()
+ my_dict = {}
+ z = profile.get_key("Z")
+ q = profile.get_key("Q")
+ if "elevation" in y:
+ my_dict["elevation"] = [profile.geometry.z_min()] * len(ts)
+ if "discharge" in y:
+ my_dict["discharge"] = q
+ if "water_elevation" in y:
+ my_dict["water_elevation"] = z
+ if "velocity" in y:
+ my_dict["velocity"] = list(
+ map(
+ lambda q, z: profile.geometry.speed(q, z),
+ q, z
+ )
+ )
+ if "depth" in y:
+ my_dict["depth"] = list(
+ map(lambda z: profile.geometry.max_water_depth(z), z)
+ )
+ if "mean_depth" in y:
+ my_dict["mean_depth"] = list(
+ map(lambda z: profile.geometry.mean_water_depth(z), z)
+ )
+ if "froude" in y:
+ my_dict["froude"] = list(
+ map(lambda z, q:
+ profile.geometry.speed(q, z) /
+ sqrt(9.81 * (
+ profile.geometry.wet_area(z) /
+ profile.geometry.wet_width(z))
+ ), z, q)
+ )
+ if "wet_area" in y:
+ my_dict["wet_area"] = list(
+ map(lambda z: profile.geometry.wet_area(z), z)
+ )
+
+ with open(filename, 'w', newline='') as csvfile:
+ writer = csv.writer(csvfile, delimiter=',',
+ quotechar='|', quoting=csv.QUOTE_MINIMAL)
+ header = ["time"] + y
+ writer.writerow(header)
+ for row in range(len(ts)):
+ line = [ts[row]]
+ for var in y:
+ line.append(my_dict[var][row])
+ writer.writerow(line)
diff --git a/src/View/Tools/ASubWindow.py b/src/View/Tools/ASubWindow.py
index e985217f..32d7a873 100644
--- a/src/View/Tools/ASubWindow.py
+++ b/src/View/Tools/ASubWindow.py
@@ -85,7 +85,7 @@ class WindowToolKit(object):
return header, values
- def file_dialog(self, select_file=True,
+ def file_dialog(self, select_file=None,
callback=lambda x: None,
directory=None,
default_suffix=None,
@@ -107,16 +107,19 @@ class WindowToolKit(object):
dialog = QFileDialog(self, options=options)
- if select_file:
- mode = QFileDialog.FileMode.ExistingFile
+ if select_file is not None:
+ if select_file:
+ mode = QFileDialog.FileMode.ExistingFile
+ else:
+ mode = QFileDialog.FileMode.Directory
else:
- mode = QFileDialog.FileMode.Directory
+ mode = QFileDialog.FileMode.AnyFile
dialog.setFileMode(mode)
if directory is not None:
dialog.setDirectory(directory)
- if select_file:
+ if select_file is not False:
if default_suffix is not None:
dialog.setDefaultSuffix(default_suffix)
diff --git a/src/View/ui/CustomPlotValuesSelectionDialog.ui b/src/View/ui/CustomPlotValuesSelectionDialog.ui
index 88ca363c..fb9334d1 100644
--- a/src/View/ui/CustomPlotValuesSelectionDialog.ui
+++ b/src/View/ui/CustomPlotValuesSelectionDialog.ui
@@ -7,7 +7,7 @@
0
0
414
- 482
+ 81
@@ -44,35 +44,37 @@
-
-
+
Qt::Horizontal
-
- QDialogButtonBox::Cancel|QDialogButtonBox::Ok
-
+ -
+
+
-
+
+
+ Export to CSV
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
+
+
-
- buttonBox
- accepted()
- Dialog
- accept()
-
-
- 248
- 254
-
-
- 157
- 274
-
-
-
buttonBox
rejected()
@@ -89,5 +91,21 @@
+
+ buttonBox
+ accepted()
+ Dialog
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+