diff --git a/cli/crue10_model_for_maps.py b/cli/crue10_model_for_maps.py
index 253f479..8ab7907 100755
--- a/cli/crue10_model_for_maps.py
+++ b/cli/crue10_model_for_maps.py
@@ -29,7 +29,7 @@
def crue10_model_for_maps(args):
study = Etude(args.etu_path)
- model = study.get_modele(args.mo_name)
+ modele = study.get_modele(args.mo_name)
modele.read_all()
logger.info(modele.summary())
@@ -63,7 +63,7 @@ def crue10_model_for_maps(args):
schema = {
'geometry': 'Polygon',
'properties': OrderedDict([('NOM', 'str'), ('modele', 'str'), ('sousmodele', 'str'),
- ('noeud_reference', 'str'), ('is_active', 'bool')]),
+ ('noeud', 'str'), ('is_active', 'bool')]),
}
with fiona.open(os.path.join(args.out_folder, 'casiers.shp'), 'w', 'ESRI Shapefile', schema) as out_shp:
for sous_modele in modele.sous_modeles:
@@ -74,7 +74,7 @@ def crue10_model_for_maps(args):
'NOM': casier.id,
'modele': model_name,
'sousmodele': sous_modele.id,
- 'noeud_reference': casier.noeud_reference.id,
+ 'noeud': casier.noeud_reference.id,
'is_active': casier.is_active,
}
}
@@ -144,11 +144,11 @@ def crue10_model_for_maps(args):
# Build list of coordinates following upstream section, left ending points, downstream section and
# right ending point
coords = []
- coords += branche.sections[0].geom_trace.coords
- for section in branche.sections[1:-1]:
+ coords += branche.get_section_amont().geom_trace.coords
+ for section in branche.liste_sections_dans_branche[1:-1]:
coords.append(section.geom_trace.coords[-1])
- coords += reversed(branche.sections[-1].geom_trace.coords)
- for section in reversed(branche.sections[1:-1]):
+ coords += reversed(branche.get_section_aval().geom_trace.coords)
+ for section in reversed(branche.liste_sections_dans_branche[1:-1]):
coords.append(section.geom_trace.coords[0])
polygon = Polygon(coords).buffer(args.sm_buffer)
diff --git a/cli/crue10_model_topographical_graph.py b/cli/crue10_model_topographical_graph.py
index 5da1d9b..944558b 100755
--- a/cli/crue10_model_topographical_graph.py
+++ b/cli/crue10_model_topographical_graph.py
@@ -9,7 +9,7 @@
* il s'agit d'une vue schématique avec tous les noeuds/casiers et les branches
(aucune information géographique)
* l'orientation des branches correspond au sens de la ligne qui se termine par
- une flèche (branche fluviale) ou un symbole qui est "côté noeud_reference aval"
+ une flèche (branche fluviale) ou un symbole qui est "côté noeud aval"
(la seule exception concerne les branches orifices dont la position du symbole
tient compte du sens de l'orifice)
* les branches ou sous-modèles inactifs sont en pointillés
diff --git a/cli/crue9_dc_topographical_graph.py b/cli/crue9_dc_topographical_graph.py
index 058447d..5216586 100755
--- a/cli/crue9_dc_topographical_graph.py
+++ b/cli/crue9_dc_topographical_graph.py
@@ -9,7 +9,7 @@
* il s'agit d'une vue schématique avec tous les noeuds/casiers et les branches
(aucune information géographique)
* l'orientation des branches correspond au sens de la ligne qui se termine par
- une flèche (branche fluviale) ou un symbole qui est "côté noeud_reference aval"
+ une flèche (branche fluviale) ou un symbole qui est "côté noeud aval"
* la coloration des lignes dépend du type de branches
* la forme des noeuds et des casiers (avec leur nom associé) sont différentes
* les parties commentées ou shunter (par un GOTO) sont ignorées
diff --git a/crue10/data/templates/drso.xml b/crue10/data/templates/drso.xml
index 6963b0d..f3db848 100644
--- a/crue10/data/templates/drso.xml
+++ b/crue10/data/templates/drso.xml
@@ -55,7 +55,7 @@
- {%- for section in branche.sections %}
+ {%- for section in branche.liste_sections_dans_branche %}
{% if loop.first %}Amont{% elif loop.last %}Aval{% else %}Interne{% endif %}
{{ section.xp|float2str }}
@@ -76,11 +76,11 @@
{%- endif %}
-
+
Amont
0.0
-
+
Aval
{{ branche.length }}
diff --git a/crue10/emh/branche.py b/crue10/emh/branche.py
index 63ee8b5..61ecae7 100644
--- a/crue10/emh/branche.py
+++ b/crue10/emh/branche.py
@@ -48,7 +48,7 @@ class Branche(ABC):
- geom : polyline branch trace
- noeud_amont : upstream node
- noeud_aval : downstream node
- - liste_sections <[crue10.emh.section.Section]>: list of sections
+ - liste_sections_dans_branche <[crue10.emh.section.Section]>: list of sections
- comment : optional text explanation
"""
@@ -88,7 +88,7 @@ def __init__(self, nom_branche, noeud_amont, noeud_aval, branch_type, is_active=
self.geom = None
self.noeud_amont = noeud_amont
self.noeud_aval = noeud_aval
- self.sections = []
+ self.liste_sections_dans_branche = []
self.comment = ''
@staticmethod
@@ -98,11 +98,17 @@ def get_id_type_from_name(branch_type_name):
return type_id
return None
+ def get_section_amont(self):
+ return self.liste_sections_dans_branche[0]
+
+ def get_section_aval(self):
+ return self.liste_sections_dans_branche[-1]
+
@property
def length(self):
"""Length displayed in FC (may differ from geometry)"""
if self.type in Branche.TYPES_WITH_LENGTH:
- return self.sections[-1].xp
+ return self.get_section_aval().xp
else:
return 0.0
@@ -125,7 +131,7 @@ def ajouter_section_dans_branche(self, section, xp):
if not isinstance(section, SectionSansGeometrie):
raise CrueError("La %s ne peut porter que des SectionSansGeometrie" % self)
section.xp = xp
- self.sections.append(section)
+ self.liste_sections_dans_branche.append(section)
def set_geom(self, geom):
check_isinstance(geom, LineString)
@@ -139,7 +145,7 @@ def shift_sectionprofil_to_extremity(self):
if self.geom is None:
raise CrueErrorGeometryNotFound(self)
for pos in (0, -1):
- section = self.sections[pos]
+ section = self.liste_sections_dans_branche[pos]
if isinstance(section, SectionProfil):
if pos == 0:
node = self.noeud_amont.geom
@@ -151,7 +157,7 @@ def shift_sectionprofil_to_extremity(self):
if isinstance(section_point, Point):
dx = node.x - section_point.x
dy = node.y - section_point.y
- self.sections[pos].set_trace(
+ self.liste_sections_dans_branche[pos].set_trace(
translate(section.geom_trace, xoff=dx, yoff=dy))
def normalize_sections_xp(self):
@@ -159,20 +165,20 @@ def normalize_sections_xp(self):
Recompute section xp to correspond to geometric distance (original values are taken from drso).
Last section xp will correspond exactly to the branch length.
"""
- xp_max = self.sections[-1].xp
+ xp_max = self.get_section_aval().xp
length = self.geom.length
if self.type in Branche.TYPES_WITH_LENGTH and abs(xp_max - length) > DIFF_XP_TO_WARN:
logger.warn("La longueur de la branche `%s` est estimée à %.2fm (non pas %.2fm)."
% (self.id, length, xp_max))
- for i, section in enumerate(self.sections):
+ for i, section in enumerate(self.liste_sections_dans_branche):
try:
section.xp = section.xp * length / xp_max
except ZeroDivisionError:
- section.xp = (i / (len(self.sections) - 1)) * length
+ section.xp = (i / (len(self.liste_sections_dans_branche) - 1)) * length
def __repr__(self):
- return "Branche [%i] #%s: %s -> %s (%i sections)" % (self.type, self.id,
- self.noeud_amont, self.noeud_aval, len(self.sections))
+ return "Branche [%i] #%s: %s -> %s (%i sections)" % (self.type, self.id, self.noeud_amont, self.noeud_aval,
+ len(self.liste_sections_dans_branche))
class BranchePdC(Branche):
diff --git a/crue10/modele.py b/crue10/modele.py
index 0f608af..3945591 100644
--- a/crue10/modele.py
+++ b/crue10/modele.py
@@ -151,7 +151,7 @@ def ajouter_sous_modele(self, sous_modele):
self.liste_sous_modeles.append(sous_modele)
def ajouter_depuis_modele(self, modele):
- """Add sous_modele in current modele with the related initial conditions"""
+ """Add modele in current modele with the related initial conditions"""
for sous_modele in modele.susoubmodels:
self.ajouter_sous_modele(sous_modele)
@@ -327,7 +327,7 @@ def write_mascaret_geometry(self, geo_path):
for i_branche, branche in enumerate(sous_modele.iter_on_branches([20])):
if branche.has_geom() and branche.is_active:
reach = Reach(i_branche, name=branche.id)
- for section in branche.sections:
+ for section in branche.liste_sections_dans_branche:
if not isinstance(section, SectionProfil):
raise CrueError("The `%s`, which is not a SectionProfil, could not be written" % section)
masc_section = Section(i_section, section.xp, name=section.id)
@@ -357,7 +357,7 @@ def write_shp_limites_lits_numerotes(self, shp_path):
for branche in sous_modele.iter_on_branches():
for i_lit, lit_name in enumerate(LitNumerote.LIMIT_NAMES):
coords = []
- for section in branche.sections:
+ for section in branche.liste_sections_dans_branche:
if isinstance(section, SectionProfil):
if i_lit == 0:
point = section.interp_point(section.lits_numerotes[0].xt_min)
diff --git a/crue10/results.py b/crue10/results.py
index b099ed5..dbe16dd 100644
--- a/crue10/results.py
+++ b/crue10/results.py
@@ -93,6 +93,7 @@ class RunResults:
"""
Results data for a single Run
- rcal_root : rcal XML element
+ - rcal_path : path to rcal file
- rcal_folder : folder path to rcal file
- nb_errors : number of errors in ccal.csv
- nb_warnings : number of warnings in ccal.csv
@@ -110,6 +111,7 @@ class RunResults:
def __init__(self, rcal_path):
self.rcal_root = ET.parse(rcal_path).getroot()
+ self.rcal_path = rcal_path
self.rcal_folder = os.path.dirname(rcal_path)
self.nb_errors = -1
self.nb_warnings = -1
@@ -128,11 +130,6 @@ def __init__(self, rcal_path):
self._read_rescalc()
self._set_res_pattern()
- @property
- def model_name(self):
- """Modele name with 'Mo_' preffix"""
- return os.path.basename(self.rcal_folder)
-
@property
def run_id(self):
return os.path.basename(os.path.normpath(os.path.join(self.rcal_folder, '..')))
@@ -157,7 +154,8 @@ def _add_emh_names(self, elt, emh_sec):
self.emh[emh_sec].append(emh_name)
def _read_ccal(self):
- ccal_path = os.path.join(self.rcal_folder, self.model_name[3:] + '.ccal.csv')
+ ccal_path = self.rcal_path[:-9] + '.ccal.csv' # to replace '.rcal.csv' => FIXME: it should be based on ocal
+ print(ccal_path)
if not os.path.exists(ccal_path):
raise CrueError("Le fichier de compte rendu de calcul `%s` est introuvable" % ccal_path)
self.nb_errors = 0
diff --git a/crue10/sous_modele.py b/crue10/sous_modele.py
index f1ff1b9..be08d63 100644
--- a/crue10/sous_modele.py
+++ b/crue10/sous_modele.py
@@ -54,7 +54,7 @@ class SousModele(FichierXML):
Crue10 sous_modele
- id : sous_modele identifier
- noeuds <{crue10.emh.noeud.Noeud}>: nodes
- - sections <{crue10.emh.section.Section}>: sections
+ - liste_sections_dans_branche <{crue10.emh.section.Section}>: list of branches
(SectionProfil, SectionIdem, SectionInterpolee or SectionSansGeometrie)
- branches <{crue10.emh.section.SectionInterpolee}>: branches (only those with geometry are considered)
- casiers <{crue10.emh.casier.Casier}>: casiers
@@ -148,25 +148,31 @@ def get_noeud(self, nom_noeud):
try:
return self.noeuds[nom_noeud]
except KeyError:
- raise CrueError("Le noeud_reference %s n'est pas dans le sous-modèle %s" % (nom_noeud, self))
+ raise CrueError("Le noeud %s n'est pas dans le %s" % (nom_noeud, self))
def get_section(self, nom_section):
try:
return self.sections[nom_section]
except KeyError:
- raise CrueError("La section %s n'est pas dans le sous-modèle %s" % (nom_section, self))
+ raise CrueError("La section %s n'est pas dans le %s" % (nom_section, self))
def get_branche(self, nom_branche):
try:
return self.branches[nom_branche]
except KeyError:
- raise CrueError("La branche %s n'est pas dans le sous-modèle %s" % (nom_branche, self))
+ raise CrueError("La branche %s n'est pas dans le %s" % (nom_branche, self))
def get_casier(self, nom_casier):
try:
return self.casiers[nom_casier]
except KeyError:
- raise CrueError("Le casier %s n'est pas dans le sous-modèle %s" % (nom_casier, self))
+ raise CrueError("Le casier %s n'est pas dans le %s" % (nom_casier, self))
+
+ def get_loi_frottement(self, nom_loi_frottement):
+ try:
+ return self.lois_frottement[nom_loi_frottement]
+ except KeyError:
+ raise CrueError("La loi de frottement %s n'est pas dans le %s" % (nom_loi_frottement, self))
def iter_on_sections(self, section_type=None, ignore_inactive=False):
for _, section in self.sections.items():
@@ -231,8 +237,9 @@ def _read_drso(self, filter_branch_types=None):
if section_type == 'SectionProfil':
section = SectionProfil(nom_section, emh_section.find(PREFIX + 'ProfilSection').get('NomRef'))
elif section_type == 'SectionIdem':
- # Only to preserve order of sections, the SectionIdem instance is set below
+ # Sets temporary to None to preserve order of sections, SectionIdem instance is set below
self.sections[nom_section] = None
+ # ajouter_section can not be called in this case, continue statement is mandatory!
continue
elif section_type == 'SectionInterpolee':
section = SectionInterpolee(nom_section)
@@ -250,11 +257,10 @@ def _read_drso(self, filter_branch_types=None):
nom_section = emh_section.get('Nom')
if section_type == 'SectionIdem':
- parent_section = self.sections[emh_section.find(PREFIX + 'Section').get('NomRef')]
+ parent_section = self.get_section(emh_section.find(PREFIX + 'Section').get('NomRef'))
section = SectionIdem(nom_section, parent_section)
-
section.comment = get_optional_commentaire(emh_section)
- self.sections[nom_section] = section
+ self.set_section(section)
elif emh_group.tag == (PREFIX + 'Branches'):
if filter_branch_types is None:
@@ -306,10 +312,10 @@ def _read_drso(self, filter_branch_types=None):
# Add section pilotage
if isinstance(branche, BrancheBarrageGenerique) or isinstance(branche, BrancheBarrageFilEau):
branche.section_pilote = \
- self.sections[emh_branche.find(PREFIX + 'SectionPilote').get('NomRef')]
+ self.get_section(emh_branche.find(PREFIX + 'SectionPilote').get('NomRef'))
for emh_section in emh_sections:
- section = self.sections[emh_section.get('NomRef')]
+ section = self.get_section(emh_section.get('NomRef'))
xp = float(emh_section.find(PREFIX + 'Xp').text)
if isinstance(branche, BrancheSaintVenant):
section.CoefPond = float(emh_section.find(PREFIX + 'CoefPond').text)
@@ -353,7 +359,7 @@ def _read_dptg(self):
if emh_group.tag == (PREFIX + 'DonPrtGeoProfilSections'):
for emh in emh_group.findall(PREFIX + 'ProfilSection'):
nom_section = emh.get('Nom').replace('Ps_', 'St_') # Not necessary consistant
- section = self.sections[nom_section]
+ section = self.get_section(nom_section)
section.comment_profilsection = get_optional_commentaire(emh)
fente = emh.find(PREFIX + 'Fente')
@@ -381,12 +387,12 @@ def _read_dptg(self):
if emh_group.tag == (PREFIX + 'DonPrtGeoSections'):
for emh in emh_group.findall(PREFIX + 'DonPrtGeoSectionIdem'):
- self.sections[emh.get('NomRef')].dz = float(emh.find(PREFIX + 'Dz').text)
+ self.get_section(emh.get('NomRef')).dz_section_reference = float(emh.find(PREFIX + 'Dz').text)
if emh_group.tag == (PREFIX + 'DonPrtGeoBranches'):
for emh in emh_group.findall(PREFIX + 'DonPrtGeoBrancheSaintVenant'):
nom_branche = emh.get('NomRef')
- self.branches[nom_branche].CoefSinuo = float(emh.find(PREFIX + 'CoefSinuo').text)
+ self.get_branche(nom_branche).CoefSinuo = float(emh.find(PREFIX + 'CoefSinuo').text)
def _read_dcsp(self):
root = self._get_xml_root_and_set_comment('dcsp')
@@ -403,12 +409,12 @@ def _read_dcsp(self):
branche.comment_loi = get_optional_commentaire(pdc_elt)
elif emh.tag == PREFIX + 'DonCalcSansPrtBrancheSeuilTransversal':
- branche.formule_pdc = emh.find(PREFIX + 'FormulePdc').text
- branche.elts_seuil = parse_elem_seuil(emh, with_pdc=True)
+ branche.formule_pertes_de_charge = emh.find(PREFIX + 'FormulePdc').text
+ branche.liste_elements_seuil = parse_elem_seuil(emh, with_pdc=True)
elif emh.tag == PREFIX + 'DonCalcSansPrtBrancheSeuilLateral':
- branche.formule_pdc = emh.find(PREFIX + 'FormulePdc').text
- branche.elts_seuil = parse_elem_seuil(emh, with_pdc=True)
+ branche.formule_pertes_de_charge = emh.find(PREFIX + 'FormulePdc').text
+ branche.liste_elements_seuil = parse_elem_seuil(emh, with_pdc=True)
elif emh.tag == PREFIX + 'DonCalcSansPrtBrancheOrifice':
elem_orifice = emh.find(PREFIX + 'ElemOrifice')
@@ -439,7 +445,7 @@ def _read_dcsp(self):
elif emh.tag == PREFIX + 'DonCalcSansPrtBrancheBarrageFilEau':
branche.QLimInf = float(emh.find(PREFIX + 'QLimInf').text)
branche.QLimSup = float(emh.find(PREFIX + 'QLimSup').text)
- branche.elts_seuil = parse_elem_seuil(emh, with_pdc=False)
+ branche.liste_elements_seuil = parse_elem_seuil(emh, with_pdc=False)
regime_denoye_elt = emh.find(PREFIX + 'RegimeDenoye')
branche.loi_QZam = parse_loi(regime_denoye_elt)
branche.comment_denoye = get_optional_commentaire(regime_denoye_elt)
@@ -669,6 +675,12 @@ def write_all(self, folder, folder_config=None):
if self.casiers:
self._write_shp_casiers(sm_folder)
+ def set_section(self, section):
+ check_isinstance(section, Section)
+ if section.id not in self.sections:
+ raise CrueError("La section %s n'existe pas" % section.id)
+ self.sections[section.id] = section
+
def set_active_sections(self):
"""
Sections are set to active if they are connected to a branch (active or not!)
@@ -677,7 +689,7 @@ def set_active_sections(self):
section.is_active = False
for branche in self.iter_on_branches():
- for section in branche.sections:
+ for section in branche.liste_sections_dans_branche:
section.is_active = branche.is_active
def get_connected_branche(self, nom_section):
@@ -685,7 +697,7 @@ def get_connected_branche(self, nom_section):
Returns the connected branche if found, else returns None
"""
for branche in self.iter_on_branches():
- if nom_section in [section.id for section in branche.sections]:
+ if nom_section in [section.id for section in branche.liste_sections_dans_branche]:
return branche
return None
@@ -711,10 +723,10 @@ def get_connected_casier(self, noeud):
def remove_sectioninterpolee(self):
"""Remove all `SectionInterpolee` which are internal sections"""
for branche in self.iter_on_branches():
- for section in branche.sections[1:-1]:
+ for section in branche.liste_sections_dans_branche[1:-1]:
if isinstance(section, SectionInterpolee):
- branche.sections.remove(section) # remove element (current iteration)
- self.sections.pop(section.id)
+ branche.liste_sections_dans_branche.remove(section) # remove element (current iteration)
+ self.liste_sections_dans_branche.pop(section.id)
if len(list(self.iter_on_sections_interpolees())) != 0:
raise CrueError("Des SectionInterpolee n'ont pas pu être supprimées : %s"
% list(self.iter_on_sections_interpolees()))
@@ -728,11 +740,11 @@ def convert_sectionidem_to_sectionprofil(self):
"""
for branche in self.iter_on_branches():
branche.normalize_sections_xp()
- for j, section in enumerate(branche.sections):
+ for j, section in enumerate(branche.liste_sections_dans_branche):
if isinstance(section, SectionIdem):
# Find if current SectionIdem is located at geographic position of its original SectionProfil
located_at_parent_section = False
- if j == 0 or j == len(branche.sections) - 1:
+ if j == 0 or j == len(branche.liste_sections_dans_branche) - 1:
# Determine node name at junction
nom_noeud = branche.noeud_amont.id if j == 0 else branche.noeud_aval.id
@@ -741,7 +753,7 @@ def convert_sectionidem_to_sectionprofil(self):
branches.remove(branche)
for br in branches:
section_pos = 0 if br.noeud_amont.id == nom_noeud else -1
- section_at_node = br.sections[section_pos]
+ section_at_node = br.liste_sections_dans_branche[section_pos]
if section_at_node is section.section_reference:
located_at_parent_section = True
break
@@ -751,8 +763,8 @@ def convert_sectionidem_to_sectionprofil(self):
if not located_at_parent_section:
# Overwrite SectionProfil original trace by the orthogonal trace because their location differ
new_section.build_orthogonal_trace(branche.geom)
- self.sections[section.id] = new_section
- branche.sections[j] = new_section
+ self.set_section(new_section)
+ branche.liste_sections_dans_branche[j] = new_section
def normalize_geometry(self):
for branche in self.iter_on_branches():
diff --git a/requirements.txt b/requirements.txt
index b8b6d9a..4111639 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,6 +2,7 @@ fiona
future # python2 only packages
jinja2
lxml
+matplotlib # only required for some snippets
numpy
pydot # only required for Modele.write_topological_graph
shapely
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 85fcf1c..e2a2915 100644
--- a/setup.py
+++ b/setup.py
@@ -9,7 +9,7 @@
setup(
name='Crue10_tools',
- version='0.1',
+ version='1.0',
author='Luc Duron',
author_email='l.duron@cnr.tm.fr',
packages=find_packages(),
diff --git a/snippets/lire_sous_modele.py b/snippets/lire_sous_modele.py
index 91e1722..c91df0b 100644
--- a/snippets/lire_sous_modele.py
+++ b/snippets/lire_sous_modele.py
@@ -26,9 +26,9 @@
branch = sous_modele.get_branche('Br_VRH99.900')
print(branch)
# Sections of a single branch
- print(branch.sections)
+ print(branch.liste_sections_dans_branche)
# Select a section (the first in this case) with its index within the branch
- section = branch.sections[0]
+ section = branch.liste_sections_dans_branche[0]
print(section)
print(section.get_coord(add_z=True)) # 3D coordinates
# Select another section by its identifier
diff --git a/snippets/post_crue_VS.py b/snippets/post_crue_VS.py
index b75ef57..4446648 100644
--- a/snippets/post_crue_VS.py
+++ b/snippets/post_crue_VS.py
@@ -34,7 +34,7 @@
'properties': {'id_branche': 'str', **{var: 'str' for var in variables}}
}
with fiona.open(os.path.join(model_folder, 'check_at_branches.shp'), 'w', 'ESRI Shapefile', schema) as out_shp:
- for sous_modele in modele.sous_modeles:
+ for sous_modele in modele.liste_sous_modeles:
sous_modele.convert_sectionidem_to_sectionprofil()
print(sous_modele.summary())
@@ -43,12 +43,12 @@
values = {var: 'NA' for var in variables}
idx_section = results.emh['Section'].index(
- branche.sections[0].id) # same results for upstream and downstream sections
+ branche.get_section_amont().id) # same results for upstream and downstream sections
values['Qmin'] = round(Qmin_at_sections[idx_section], 0)
values['Qmax'] = round(Qmax_at_sections[idx_section], 0)
if branche.type in (2, 4):
- values['Zseuil_min'] = branche.elts_seuil.min(axis=0)[1]
+ values['Zseuil_min'] = branche.liste_elements_seuil.min(axis=0)[1]
layer = {
'geometry': mapping(branche.geom),