#!/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 2018 - Vérification
"""
import collections
import numpy as np
import os
from pyspc.convention.grp18 import CAL_VERIF_DTYPES
import pyspc.core.exception as _exception
[docs]
class GRP_Verif():
"""
Structure des résultats des fiches de performance (PDF) de GRP *Calage*
Attributes
----------
filename : str
Nom de la fiche de performance
datatype : str
Type de fiche de performance
model : str
Modèle
loc : str
Bassin
timestep : str
Pas de temps de calcul
leadtime : str
Horizon de calage
threshold : float
Seuil de vigilance
"""
[docs]
def __init__(self, filename=None):
"""
Initialisation de l'instance de la classe <GRP_Verif>
Parameters
----------
filename : str
Nom de la fiche de performance
"""
self.filename = filename
config = self.split_basename(filename=filename)
self.datatype = config['datatype']
self.model = config['model']
self.loc = config['loc']
self.timestep = config['timestep']
self.leadtime = config['leadtime']
self.threshold = config['threshold']
def __str__(self):
"""
Afficher les méta-données de l'instance <GRP_Verif>
"""
text = """
*************************************
********** Classe GRP_Verif *********
*************************************
* NOM FICHIER = {filename}
* BASSIN VERSANT = {loc}
* HORIZON CALAGE = {hc}
* SEUIL CALAGE = {sc}
* SEUIL VIGILANCE = {sv}
*************************************
"""
return text.format(**vars(self))
[docs]
def read(self):
"""
Lecture de la fiche de performance (PDF) de GRP *Calage*
"""
if not os.path.exists(self.filename):
return OSError(f'Fichier inconnu: {self.filename}')
data = collections.OrderedDict()
names = ['Eff', 'POD', 'FAR', 'CSI']
cfg = None
with open(self.filename, 'r', encoding='iso-8859-1') as f:
for line in f.readlines():
if ':' not in line:
continue
content = line.replace('(%)', '').split(':')
header = content.pop(0).strip()
if header in names:
try:
value = float(content[-1].strip())
except ValueError:
value = np.nan
data[cfg].setdefault(header, value)
elif line.startswith("#! CONFIG"):
cfg = content[-1].split(' ')[-1].strip()
data.setdefault(cfg, {})
return data
[docs]
@classmethod
def split_basename(cls, filename=None, datatype=None):
"""
Extraire la configuration du calage depuis le nom de la fiche de
performance
Parameters
----------
filename : str
Nom de la fiche de performance
Returns
-------
meta : dict
Dictionnaire des informations
- datatype : Type de fiche de performance
- model : Modèle
- loc : Lieu, bassin
- timestep : Pas de temps du modèle
- leadtime : Horizon de calage
- threshold : Seuil de vigilance
Raise
-----
ValueError
Si le type de fiche de performance est incorrect
Examples
--------
>>> from pyspc.model.grp18.cal_verif import GRP_Verif
>>> f = 'data/model/grp18/cal/Perf_CALAG_GRP_RH10585x_PDT_00J01H00M_HOR_00J03H00M_SV_5.DAT'
>>> meta = GRP_Verif.split_basename(filename=filename)
>>> meta
{'datatype': 'rtime',
'model': 'GRP',
'loc': 'RH10585x',
'timestep': '00J01H00M',
'leadtime': '00J03H00M',
'threshold': '5'}
"""
_exception.check_str(filename)
basename = os.path.splitext(os.path.basename(filename))[0]
meta = basename.split('_')
try:
meta.pop(0) # Perf
datatype = CAL_VERIF_DTYPES[meta.pop(0)]
model = meta.pop(0)
loc = meta.pop(0)
meta.pop(0) # PDT
timestep = meta.pop(0)
meta.pop(0) # HOR
leadtime = meta.pop(0)
meta.pop(0) # SV
threshold = meta.pop(0)
except IndexError as ie:
raise ValueError('Nommage de la fiche de performance '
'incorrect') from ie
return {'datatype': datatype, 'model': model, 'loc': loc,
'timestep': timestep, 'leadtime': leadtime,
'threshold': threshold}
[docs]
@classmethod
def check_datatype(cls, datatype=None):
"""
Tester le type de fiche de performance
Parameters
----------
datatype : str
Nom du type de fiche de performance
Raise
-----
ValueError
Si le type de fiche de performance est incorrect
"""
if datatype not in cls.get_datatypes():
raise ValueError(
f"Type de fiche de performance est incorrect : '{datatype}'")
[docs]
@classmethod
def get_datatypes(cls):
"""
Liste des types de fiche de performance
Returns
-------
list
Types de fiche de performance
- cal : calage
- rtime : calage sur la période complète
"""
return sorted(CAL_VERIF_DTYPES.values())