Compare commits

...
4 Commits
11 changed files with 241 additions and 35 deletions

No files matched your search

+3 -2
View File
@@ -155,7 +155,7 @@ class ProfileXYZ(Profile, SQLSubModel):
"ADD COLUMN deleted BOOLEAN NOT NULL DEFAULT FALSE" "ADD COLUMN deleted BOOLEAN NOT NULL DEFAULT FALSE"
) )
if major == "0" and int(minor) <=2: if major == "0" and int(minor) <= 2:
if int(release) < 9: if int(release) < 9:
execute( execute(
"ALTER TABLE geometry_profileXYZ " + "ALTER TABLE geometry_profileXYZ " +
@@ -335,7 +335,8 @@ class ProfileXYZ(Profile, SQLSubModel):
f"{self.pamhyr_id}, {self._db_format(self.is_deleted())}, " + f"{self.pamhyr_id}, {self._db_format(self.is_deleted())}, " +
f"{ind}, '{self._db_format(self._name)}', " + f"{ind}, '{self._db_format(self._name)}', " +
f"{self.reach.pamhyr_id}, {self.rk}, {self.num}, " + f"{self.reach.pamhyr_id}, {self.rk}, {self.num}, " +
f"{self.code1}, {self.code1}, {sl}, {self._status.scenario_id}, {self._db_format(self._enabled)}" + f"{self.code1}, {self.code1}, {sl}, {self._status.scenario_id}, " +
f"{self._db_format(self._enabled)}" +
")" ")"
) )
+33
View File
@@ -375,6 +375,28 @@ class Reach(SQLSubModel):
) )
) )
def get_z_min_enabled_profiles(self):
return list(
map(
lambda profile: profile.z_min(),
filter(
lambda profile: len(profile) > 0 and profile.is_enabled,
self.profiles
)
)
)
def get_z_max_enabled_profiles(self):
return list(
map(
lambda profile: profile.z_max(),
filter(
lambda profile: len(profile) > 0 and profile.is_enabled,
self.profiles
)
)
)
def get_rk(self): def get_rk(self):
"""List of profiles rk """List of profiles rk
@@ -383,6 +405,17 @@ class Reach(SQLSubModel):
""" """
return [profile.rk for profile in self.profiles] return [profile.rk for profile in self.profiles]
def get_rk_enabled_profiles(self):
return list(
map(
lambda profile: profile.rk,
filter(
lambda profile: len(profile) > 0 and profile.is_enabled,
self.profiles
)
)
)
def get_rk_complete_profiles(self): def get_rk_complete_profiles(self):
return list( return list(
map( map(
@@ -167,7 +167,11 @@ class InitialConditionsTemperature(SQLSubModel):
return True return True
def __len__(self): def __len__(self):
return len(self._data) return len(self.data)
@property
def data(self):
return list(filter(lambda item: not item.is_deleted(), self._data))
@property @property
def name(self): def name(self):
+1 -1
View File
@@ -527,7 +527,7 @@ class Results(SQLSubModel):
i = 0 i = 0
for reach in new_results._river.reachs: for reach in new_results._river.reachs:
nb = len(reach.profiles) nb = len(reach.profiles)
reach.set_global_index(range(i, i + nb + 1)) reach.set_global_index(range(i, i + nb))
i += nb i += nb
if "Z" in table_data: if "Z" in table_data:
+1
View File
@@ -154,6 +154,7 @@ class Profile(SQLSubModel):
"len_data, data, scenario " + "len_data, data, scenario " +
"FROM results_data " + "FROM results_data " +
f"WHERE scenario = {scenario.id} " + f"WHERE scenario = {scenario.id} " +
f"AND result = {data['result_pid']} " +
f"AND reach = {reach.pamhyr_id} " + f"AND reach = {reach.pamhyr_id} " +
f"AND section = {profile.pamhyr_id}" f"AND section = {profile.pamhyr_id}"
) )
+57
View File
@@ -907,6 +907,63 @@ Last export at: @date."""
def weather_parameters(self): def weather_parameters(self):
return self._WeatherParameters return self._WeatherParameters
def profile_dependencies(self, profile):
"""Return model data which directly reference *profile*.
PK-based intervals are deliberately not included: only explicit
references to the profile object prevent it from being disabled.
"""
dependencies = []
def add(kind, item, association):
dependencies.append({
"kind": kind,
"item": item,
"association": association,
})
for reach in list(self._initial_conditions._dict):
initial_conditions = self._initial_conditions.get(reach)
for data in initial_conditions.data:
if data["section"] is profile:
add("initial_condition", data, "section")
for structure in self._hydraulic_structures.lst:
if structure.input_section is profile:
add("hydraulic_structure", structure, "input_section")
if structure.output_section is profile:
add("hydraulic_structure", structure, "output_section")
for tab in self._lateral_contribution._tabs_list:
for contribution in self._lateral_contribution.get_tab(tab):
if contribution.begin_section is profile:
add("lateral_contribution", contribution, "begin_section")
if contribution.end_section is profile:
add("lateral_contribution", contribution, "end_section")
for parameter in self._WeatherParameters.lst:
if parameter.begin_section is profile:
add("weather_parameter", parameter, "begin_section")
if parameter.end_section is profile:
add("weather_parameter", parameter, "end_section")
reach_id = profile.reach.pamhyr_id
for initial_condition in self._InitialConditionsTemperature.lst:
for specification in initial_condition.data:
same_reach = specification.reach == reach_id
same_rk = (
specification.start_rk == profile.rk or
specification.end_rk == profile.rk
)
if same_reach and same_rk:
add(
"initial_condition_temperature",
specification,
"cross_section_pk",
)
return dependencies
def get_params(self, solver): def get_params(self, solver):
if solver in self._parameters: if solver in self._parameters:
return self._parameters[solver] return self._parameters[solver]
-1
View File
@@ -204,7 +204,6 @@ class ProfileWindow(PamhyrWindow):
self._tablemodel.beginResetModel() self._tablemodel.beginResetModel()
self._tablemodel._data = profile self._tablemodel._data = profile
# update lst to display correct data and apply connexions to add/remove points
self._tablemodel._setup_lst() self._tablemodel._setup_lst()
self._tablemodel.endResetModel() self._tablemodel.endResetModel()
+58
View File
@@ -19,6 +19,7 @@
from PyQt5.QtCore import QCoreApplication from PyQt5.QtCore import QCoreApplication
from View.Translate import MainTranslate from View.Translate import MainTranslate
from View.WeatherParameters.translate import WeatherParametersTranslate
_translate = QCoreApplication.translate _translate = QCoreApplication.translate
@@ -47,6 +48,63 @@ class GeometryTranslate(MainTranslate):
self._dict["cross_section_enabled_count"] = _translate( self._dict["cross_section_enabled_count"] = _translate(
"Geometry", "Cross-section enabled ({count} disabled)" "Geometry", "Cross-section enabled ({count} disabled)"
) )
self._dict["profile_disable_blocked"] = _translate(
"Geometry", "The cross-section cannot be disabled."
)
self._dict["profile_disable_blocked_info"] = _translate(
"Geometry",
"It is referenced by the following data:\n{dependencies}\n\n"
"Change or remove these associations before disabling it."
)
self._dict["profile_dependency"] = _translate(
"Geometry", "{kind} “{name}” ({association})"
)
self._dict["initial_condition"] = _translate(
"Geometry", "Initial condition"
)
self._dict["initial_condition_temperature"] = _translate(
"Geometry", "Initial condition temperature"
)
self._dict["hydraulic_structure"] = _translate(
"Geometry", "Hydraulic structure"
)
self._dict["lateral_contribution"] = _translate(
"Geometry", "Lateral contribution"
)
self._dict["weather_parameter"] = _translate(
"Geometry", "Weather parameter"
)
self._dict["section"] = _translate("Geometry", "cross-section")
self._dict["input_section"] = _translate(
"Geometry", "input cross-section"
)
self._dict["output_section"] = _translate(
"Geometry", "output cross-section"
)
self._dict["begin_section"] = _translate(
"Geometry", "first cross-section"
)
self._dict["end_section"] = _translate(
"Geometry", "last cross-section"
)
self._dict["cross_section_pk"] = _translate(
"Geometry", "cross-section PK"
)
weather_parameters = WeatherParametersTranslate().get_dict(
"weather_parameters"
)
self._sub_dict["weather_parameter_types"] = {
"AT": weather_parameters["air_temperature"],
"SH": weather_parameters["specific_humidity"],
"GR": weather_parameters["global_radiation"],
"RWS": weather_parameters["reference_wind_speed"],
"GT": weather_parameters["surface_temperature"],
"GFR": weather_parameters["surface_flow_rate"],
"ALB": weather_parameters["albedo"],
"SC": weather_parameters["shading_coefficient"],
"CCF": weather_parameters["cloud_cover_fraction"],
}
self._dict["transverse_abscissa"] = _translate( self._dict["transverse_abscissa"] = _translate(
"Geometry", "Transverse abscissa (m)" "Geometry", "Transverse abscissa (m)"
+45 -1
View File
@@ -544,7 +544,8 @@ class GeometryWindow(PamhyrWindow):
def _set_checkbox_state(self): def _set_checkbox_state(self):
rows = self.index_selected_rows() rows = self.index_selected_rows()
editable = not self._study.is_read_only() editable = not self._study.is_read_only()
disabled_count = self._reach.number_profiles - self._reach.number_enabled_profiles disabled_count = (self._reach.number_profiles -
self._reach.number_enabled_profiles)
self._checkbox.setText( self._checkbox.setText(
self._trad["cross_section_enabled_count"].format( self._trad["cross_section_enabled_count"].format(
count=disabled_count count=disabled_count
@@ -573,6 +574,49 @@ class GeometryWindow(PamhyrWindow):
if len(rows) == 0: if len(rows) == 0:
return return
if not enabled:
blocked = []
for row in rows:
profile = self._reach.profile(row)
dependencies = self._study.river.profile_dependencies(profile)
if len(dependencies) != 0:
blocked.append((profile, dependencies))
if len(blocked) != 0:
details = []
for profile, dependencies in blocked:
details.append(f"{profile.name}:")
for dependency in dependencies:
item = dependency["item"]
if dependency["kind"] == "weather_parameter":
name = self._trad.get_dict(
"weather_parameter_types"
).get(item.type, item.type)
else:
name = getattr(item, "name", "")
if name == "":
name = self._trad[dependency["kind"]]
details.append(
" - " +
self._trad["profile_dependency"].format(
kind=self._trad[dependency["kind"]],
name=name,
association=self._trad[
dependency["association"]
],
)
)
self._set_checkbox_state()
self.message_box(
self._trad["profile_disable_blocked"],
self._trad["profile_disable_blocked_info"].format(
dependencies="\n".join(details)
),
window_title=self._trad["warning"],
)
return
self._checkbox.setTristate(False) self._checkbox.setTristate(False)
self._table.enabled(rows, enabled) self._table.enabled(rows, enabled)
+11 -8
View File
@@ -64,6 +64,7 @@ class SelectProfileDialog(PamhyrDialog):
self._reach = reach self._reach = reach
self._profile = None self._profile = None
self._profiles = self._reach.reach.enabled_profiles
self.setup_combobox() self.setup_combobox()
@@ -73,17 +74,19 @@ class SelectProfileDialog(PamhyrDialog):
list( list(
map( map(
lambda p: p.display_name(), lambda p: p.display_name(),
self._reach.reach.profiles))) self._profiles)))
if len(self._profiles) == 0:
self.find(QDialogButtonBox, "buttonBox")\
.button(QDialogButtonBox.Ok)\
.setEnabled(False)
def accept(self): def accept(self):
profile = self.get_combobox_text("comboBox") index = self.find(QComboBox, "comboBox").currentIndex()
if not 0 <= index < len(self._profiles):
return
self._profile = next( self._profile = self._profiles[index]
filter(
lambda p: p.display_name() == profile,
self._reach.reach.profiles
)
)
super(SelectProfileDialog, self).accept() super(SelectProfileDialog, self).accept()
+27 -21
View File
@@ -62,6 +62,8 @@ class PlotRKC(PamhyrPlot):
self._auto_relim_update = True self._auto_relim_update = True
self._autoscale_update = False self._autoscale_update = False
self.profile = None
@property @property
def results(self): def results(self):
return self.data return self.data
@@ -71,9 +73,19 @@ class PlotRKC(PamhyrPlot):
self.data = results self.data = results
self._current_timestamp = max(self._timestamps) self._current_timestamp = max(self._timestamps)
@staticmethod
def reach_geometry(reach):
"""Return geometry values for profiles present in the results."""
return (
reach.geometry.get_rk_enabled_profiles(),
reach.geometry.get_z_min_enabled_profiles(),
reach.geometry.get_z_max_enabled_profiles()
)
@timer @timer
def draw(self, highlight=None): def draw(self, highlight=None):
self.init_axes() self.init_axes()
self.profile = None
if self.results is None: if self.results is None:
return return
@@ -104,7 +116,7 @@ class PlotRKC(PamhyrPlot):
def draw_bottom_with_bedload(self, reach): def draw_bottom_with_bedload(self, reach):
results = self.results[self._current_res_id] results = self.results[self._current_res_id]
rk = reach.geometry.get_rk() rk, _, _ = self.reach_geometry(reach)
table = results.get("table")["zfd"] table = results.get("table")["zfd"]
ts = results.get_timestamp_id(self._current_timestamp) ts = results.get_timestamp_id(self._current_timestamp)
@@ -136,8 +148,7 @@ class PlotRKC(PamhyrPlot):
for hs in lhs: for hs in lhs:
x = hs.input_section.rk x = hs.input_section.rk
z_min = reach.geometry.get_z_min() _, z_min, z_max = self.reach_geometry(reach)
z_max = reach.geometry.get_z_max()
self.canvas.axes.plot( self.canvas.axes.plot(
[x, x], [x, x],
@@ -157,9 +168,7 @@ class PlotRKC(PamhyrPlot):
) )
def draw_bottom_geometry(self, reach): def draw_bottom_geometry(self, reach):
rk = reach.geometry.get_rk() rk, z_min, _ = self.reach_geometry(reach)
z_min = reach.geometry.get_z_min()
z_max = reach.geometry.get_z_max()
self.line_rk_zmin = self.canvas.axes.plot( self.line_rk_zmin = self.canvas.axes.plot(
rk, z_min, rk, z_min,
@@ -170,10 +179,9 @@ class PlotRKC(PamhyrPlot):
self._river_bottom = z_min self._river_bottom = z_min
def draw_water_elevation(self, reach): def draw_water_elevation(self, reach):
if len(reach.geometry.profiles) != 0: if len(reach.profiles) != 0:
result = self.results[self._current_res_id] result = self.results[self._current_res_id]
rk = reach.geometry.get_rk() rk, _, _ = self.reach_geometry(reach)
z_min = reach.geometry.get_z_min()
table = result.get("table")["Z"] table = result.get("table")["Z"]
ts = result.get_timestamp_id(self._current_timestamp) ts = result.get_timestamp_id(self._current_timestamp)
@@ -201,10 +209,9 @@ class PlotRKC(PamhyrPlot):
) )
def draw_water_elevation_max(self, reach): def draw_water_elevation_max(self, reach):
if len(reach.geometry.profiles) != 0: if len(reach.profiles) != 0:
result = self.results[self._current_res_id] result = self.results[self._current_res_id]
rk = reach.geometry.get_rk() rk, _, _ = self.reach_geometry(reach)
z_min = reach.geometry.get_z_min()
table = result.get("table")["Z"] table = result.get("table")["Z"]
ts = result.get_timestamp_id(self._current_timestamp) ts = result.get_timestamp_id(self._current_timestamp)
@@ -250,9 +257,7 @@ class PlotRKC(PamhyrPlot):
self.canvas.draw_idle() self.canvas.draw_idle()
def draw_current(self, reach): def draw_current(self, reach):
rk = reach.geometry.get_rk() rk, z_min, z_max = self.reach_geometry(reach)
z_min = reach.geometry.get_z_min()
z_max = reach.geometry.get_z_max()
self.profile, = self.canvas.axes.plot( self.profile, = self.canvas.axes.plot(
[ [
@@ -349,8 +354,7 @@ class PlotRKC(PamhyrPlot):
def update_water_elevation(self): def update_water_elevation(self):
result = self.results[self._current_res_id] result = self.results[self._current_res_id]
reach = result.river.reach(self._current_reach_id) reach = result.river.reach(self._current_reach_id)
rk = reach.geometry.get_rk() rk, _, _ = self.reach_geometry(reach)
z_min = reach.geometry.get_z_min()
table = result.get("table")["Z"] table = result.get("table")["Z"]
ts = result.get_timestamp_id(self._current_timestamp) ts = result.get_timestamp_id(self._current_timestamp)
@@ -380,11 +384,13 @@ class PlotRKC(PamhyrPlot):
self.update_idle() self.update_idle()
def update_current(self): def update_current(self):
if not self._init or self.profile is None:
self.draw()
return
results = self.results[self._current_res_id] results = self.results[self._current_res_id]
reach = results.river.reach(self._current_reach_id) reach = results.river.reach(self._current_reach_id)
rk = reach.geometry.get_rk() rk, z_min, z_max = self.reach_geometry(reach)
z_min = reach.geometry.get_z_min()
z_max = reach.geometry.get_z_max()
cid = self._current_profile_id cid = self._current_profile_id
self.profile.set_data( self.profile.set_data(
@@ -396,7 +402,7 @@ class PlotRKC(PamhyrPlot):
def update_bottom_with_bedload(self): def update_bottom_with_bedload(self):
results = self.results[self._current_res_id] results = self.results[self._current_res_id]
reach = results.river.reach(self._current_reach_id) reach = results.river.reach(self._current_reach_id)
rk = reach.geometry.get_rk() rk, _, _ = self.reach_geometry(reach)
# z = self.sl_compute_current_z(reach) # z = self.sl_compute_current_z(reach)
table = results.get("table")["zfd"] table = results.get("table")["zfd"]