#!/usr/bin/python3
# -*- coding: utf-8 -*-
########################################################################
#
# This file is part of python module <pyspc>.
# Copyright (C) 2013-2021 R. Marty
# (renaud.marty@developpement-durable.gouv.fr)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see COPYING.txt).
# If not, see <http://www.gnu.org/licenses/>.
#
########################################################################
"""Modélisations hydrologiques - GRP version 2022 - Runs"""
import collections
import pyspc.core.exception as _exception
from pyspc.convention.grp22 import (
RT_RUN_NAMES, RT_RUN_FORMAT, RT_RUN_CONVERTERS, RT_RUN_HEADER)
GRPRT_Run = collections.namedtuple('GRPRT_Run', RT_RUN_NAMES)
GRPRT_Run.__doc__ = """Run Temps Réel de GRP 2022
Attributes
----------
CODE : str
Code de la station hydrométrique
PDT : str
Pas de temps du modèle - format : str
xxJxxHxxM (exemple : str
00J01H00M pour le pas de temps 1h)
FT : str
Référentiel temporel des données d'entrée : str
"TU" (temps universel), "HH" (heure d'hiver française), "HL" (heure légale française été/hiver)
FD : str
Unité des débits d'entrée : str, " l/s", "m3/s"
C : int
Prévision avec GRP : str, 0 = NON, 1 = OUI
N : int
Utilisation de CEMANEIGE : str, 0 = NON, 1 = OUI
PRE : int
Code PRE associé à la station (ignoré si les formats d'import et d'export sont TXT)
PBV : int
Code PRE associé au bassin et utilisé pour exporter les pluies de bassins (ignoré si le format d'export est TXT)
SCE : int
Numéro de scénario de pluie associé au bassin (ignoré si le format d'import du scénario de pluie est TXT)
HORMAX : str
Horizon maximal des prévisions, format : str, xJxxHxxM
HOR1 : str
Horizon pour lesquels on calcule les prévisions passées, format : str, xxJxxHxxM
HOR2 : str
Horizon pour lesquels on calcule les prévisions passées, format : str, xxJxxHxxM
VIG1 : float
Seuil de vigilance pour le test sur les pluies (unité des prévisions (m3/s ou L/s))
VIG2 : float
2eme seuil de vigilance pour les abaques (unité des prévisions (m3/s ou L/s))
VIG3 : float
3eme seuil de vigilance pour les abaques (unité des prévisions (m3/s ou L/s))
A : int
Activation des abaques d'aide à la décision, 0 = NON, 1 = OUI
ECH : str
Echéance de prévision jusqu'à laquelle on regarde si un dépassement de seuil est prévu dans les abaques
format : str, xxJxxHxxM
CMN : int
Cumul minimal sur les abaques (0 par défaut, en mm)
CMX : int
Cumul maximal sur les abaques (-99 par défaut => calcul sur les données observées, en mm)
IX : int
Intensité maximale sur les abaques (-9 par défaut => calcul sur les données observées, en mm/(durée de l'intensité en pas de temps))
DI : int
Durée d'intensité (en pas de temps)
INC : int
Estimation de l'incertitude, 0 = NON, 1 = OUI
"""
[docs]
class GRPRT_Runs(list):
"""
Structure de données GRPRT_Run : liste de runs de GRP.
Attributes
----------
filename : str
Fichier **LISTE_BASSINS.DAT** de GRP *Temps-Réel*
See Also
--------
GRPRT_Run
"""
[docs]
def __init__(self, filename=None):
"""
Initialise l'instance de la classe GRPRT_Runs.
Parameters
----------
filename : str
Fichier **LISTE_BASSINS.DAT** de GRP *Temps Réel*
"""
super().__init__()
if filename is None:
raise ValueError('Nom de fichier inconnu')
self.filename = filename
def __str__(self):
"""Afficher les méta-données de l'instance GRPRT_Runs."""
if self:
strdata = '\n'
for run in self:
strdata += ' ==> '
strdata += RT_RUN_FORMAT.format(**run._asdict())
else:
strdata = ''
text = """
*************************************
*********** GRPRT 2022 - Runs *******
*************************************
* NOM FICHIER = {filename}
* RUNS {strdata}
*************************************
"""
return text.format(filename=self.filename, strdata=strdata)
[docs]
@staticmethod
def check_run(run):
"""Lister les valeurs correspondant aux paramètres de calage de GRP."""
if not isinstance(run, GRPRT_Run):
raise ValueError("Le run n'est pas un GRPRT_Run")
[docs]
def read(self, encoding='iso-8859-15'):
"""
Lecture du fichier LISTE_BASSINS.DAT de GRP *Temps Réel*.
Parameters
----------
encoding : str
Encodage du fichier, 'iso-8859-15' par défaut
Examples
--------
>>> from pyspc.model.grp22 import GRPRT_Runs
>>> f = 'data/model/grp22/rt/LISTE_Bassins.DAT'
>>> runs = GRPRT_Runs(filename=f)
>>> runs
*************************************
*********** GRPRT 2022 - Runs *******
*************************************
* NOM FICHIER = data/model/grp22/rt/LISTE_Bassins.DAT
* RUNS
*************************************
>>> runs.read
>>> runs
*************************************
*********** GRPRT 2022 - Runs *******
*************************************
* NOM FICHIER = data/model/grp22/rt/LISTE_Bassins.DAT
* RUNS
==> !K0045510!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J03H00M! 28.0! 14.0! 48.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0114030!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J06H00M! 93.0! 46.5! 140.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0134010!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J03H00M! 24.0! 12.0! 40.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0214010!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J03H00M! 43.0! 21.5! 86.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0243010!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J03H00M! 19.0! 9.5! 37.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0253020!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J06H00M! 50.0! 25.0! 80.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0258010!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J03H00M! 9.0! 4.5! 22.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0260010!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J06H00M! 285.0! 142.5! 585.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0274010!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J03H00M! 17.0! 8.5! 28.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0333010!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J06H00M! 24.0! 12.0! 39.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0356310!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J03H00M! 15.0! 7.5! 26.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0403010!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J03H00M! 82.0! 41.0! 138.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0454010!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J03H00M! 36.0! 18.0! 63.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0543010!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J18H00M! 52.0! 26.0! 80.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0550010!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J06H00M! 554.0! 277.0! 901.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0567520!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J03H00M! 23.0! 11.5! 39.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0614010!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J06H00M! 68.0! 34.0! 101.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0624510!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J03H00M! 15.0! 7.5! 31.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0643110!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J03H00M! 14.0! 7.0! 24.0!0!05J00H00M! 0!-99! -9! 1! 0!
==> !K0673310!00J01H00M!TU!m3/s!1!0!99999!99999!99999!05J00H00M!01J00H00M!00J06H00M! 19.0! 9.5! 41.0!0!05J00H00M! 0!-99! -9! 1! 0!
*************************************
>>> runs[0]
GRPRT_Run(CODE='K0045510', PDT='00J01H00M', FT='TU', FD='m3/s', C=1,
N=0, PRE=99999, PBV=99999, SCE=99999, HORMAX='05J00H00M',
HOR1='01J00H00M', HOR2='00J03H00M', VIG1=28.0, VIG2=14.0,
VIG3=48.0, A=0, ECH='05J00H00M', CMN=0, CMX=-99, IX=-9, DI=1,
INC=0)
See Also
--------
GRPRT_Run
"""
self.clear()
header_len = RT_RUN_HEADER.count('\n')
with open(self.filename, 'r', encoding=encoding) as f:
for _ in range(header_len):
f.readline()
for line in f.readlines():
info = line.split('!')[1:-1]
if len(info) != len(RT_RUN_NAMES):
_exception.Warning(
__name__,
"format de ligne incorrect")
continue
try:
run = {n: d(i.strip())
for n, d, i in zip(RT_RUN_NAMES,
RT_RUN_CONVERTERS,
info)}
run = GRPRT_Run(**run)
except (ValueError, SyntaxError):
_exception.Warning(
__name__,
"définition de ligne incorrecte")
else:
self.append(run)
[docs]
def write(self, encoding='iso-8859-15', newline='\r\n'):
r"""
Ecrire le fichier LISTE_BASSINS.DAT de GRP *Temps Réel*.
Parameters
----------
encoding : str
Encodage du fichier, 'iso-8859-15' par défaut
newline : str
Charactère de nouvelle ligne, '\\r\\n' par défaut
"""
with open(self.filename, 'w', encoding=encoding, newline=newline) as f:
f.write(RT_RUN_HEADER)
for run in self:
try:
self.check_run(run)
except ValueError as ve:
raise ValueError("Le run n'est pas un GRPRT_Run") from ve
run = run._asdict()
try:
f.write(RT_RUN_FORMAT.format(**run))
except ValueError:
_exception.Warning(
__name__,
f"Erreur de format lors de l'écriture du run\n{run}")