#!/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 2016 - Temps-réel archive
"""
from datetime import datetime as dt
import os.path
import pandas as pnd
import pyspc.core.exception as _exception
from pyspc.convention.grp16 import (
RT_ARCHIVE_DATEFORMAT, RT_ARCHIVE_FLOATFORMAT, RT_ARCHIVE_HEADERS,
RT_ARCHIVE_VARNAMES)
[docs]
class GRPRT_Archive():
"""
Structure de données GRPRT Archive (GRP *Temps Réel*)
- PV_10A.DAT
- QV_10A.DAT
- TV_10A.DAT
Attributes
----------
filename : str
Nom du fichier Archve de GRP *Temps-Réel*
varname : str
Variable
"""
[docs]
def __init__(self, filename=None):
"""
Initialisation de l'instance de la classe GRPRT_Archive
Parameters
----------
filename : str
Nom du fichier Archve de GRP *Temps-Réel*
"""
self.filename = filename
self.varname = self.split_basename(filename=self.filename)
self._check_varname(varname=self.varname)
def __str__(self):
"""
Afficher les méta-données de l'instance GRPRT_Archive
"""
text = """
*************************************
*********** GRP 2016 - RT Archive ***
*************************************
* NOM FICHIER = {filename}
* NOM VARIABLE = {varname}
*************************************
"""
return text.format(**vars(self))
def _check_varname(self, varname=None):
"""
Contrôler la variable
Parameters
----------
varname : str
Nom de la variable.
Raises
------
ValueError
Si la variable n'est pas reconnue par pyspc
"""
if varname not in self.get_varnames():
raise ValueError("Variable mal renseignée")
[docs]
def read(self):
"""
Lecture du fichier GRPRT_Archive
Returns
-------
pandas.DataFrame
Tableau des données d'archives de GRP Temps-Réel
Examples
--------
>>> from pyspc.model.grp16 import GRPRT_Archive
>>> f = 'data/model/grp16/rt/PV_10A.DAT'
>>> reader = GRP_Data(filename=f)
>>> reader
*************************************
*********** GRP 2016 - RT Archive ***
*************************************
* NOM FICHIER = data/model/grp16/rt/PV_10A.DAT
* NOM VARIABLE = PV
*************************************
>>> df = reader.read()
>>> df
Code 43091005
Date (TU)
2017-06-13 12:00:00 0.0
2017-06-13 13:00:00 0.0
2017-06-13 14:00:00 0.0
2017-06-13 15:00:00 23.8
2017-06-13 16:00:00 2.6
2017-06-13 17:00:00 2.2
2017-06-13 18:00:00 1.2
2017-06-13 19:00:00 4.9
2017-06-13 20:00:00 34.2
2017-06-13 21:00:00 0.2
2017-06-13 22:00:00 0.0
2017-06-13 23:00:00 0.0
>>> f = 'data/model/grp16/rt/QV_10A.DAT'
>>> reader = GRP_Data(filename=f)
>>> reader
*************************************
*********** GRP 2016 - RT Archive ***
*************************************
* NOM FICHIER = data/model/grp16/rt/QV_10A.DAT
* NOM VARIABLE = QV
*************************************
>>> df = reader.read()
>>> df
Code K0114030
Date (TU)
2017-06-13 12:00:00 0.57
2017-06-13 13:00:00 0.57
2017-06-13 14:00:00 0.56
2017-06-13 15:00:00 0.59
2017-06-13 16:00:00 0.58
2017-06-13 17:00:00 0.70
2017-06-13 18:00:00 11.20
2017-06-13 19:00:00 121.00
2017-06-13 20:00:00 203.00
2017-06-13 21:00:00 159.00
2017-06-13 22:00:00 92.80
2017-06-13 23:00:00 53.80
>>> f = 'data/model/grp16/rt/TV_10A.DAT'
>>> reader = GRP_Data(filename=f)
>>> reader
*************************************
*********** GRP 2016 - RT Archive ***
*************************************
* NOM FICHIER = data/model/grp16/rt/TV_10A.DAT
* NOM VARIABLE = TV
*************************************
>>> df = reader.read()
>>> df
Code 07105003
Date (TU)
2014-01-14 12:00:00 0.9
2014-01-14 13:00:00 1.1
2014-01-14 14:00:00 0.7
2014-01-14 15:00:00 0.6
2014-01-14 16:00:00 0.2
2014-01-14 17:00:00 -0.5
2014-01-14 18:00:00 -0.5
2014-01-14 19:00:00 -1.4
2014-01-14 20:00:00 -1.9
2014-01-14 21:00:00 -2.3
2014-01-14 22:00:00 -2.8
2014-01-14 23:00:00 -3.1
2014-01-15 00:00:00 -3.4
2014-01-15 01:00:00 -3.7
2014-01-15 02:00:00 -4.0
2014-01-15 03:00:00 -4.0
2014-01-15 04:00:00 -4.2
2014-01-15 05:00:00 -4.6
2014-01-15 06:00:00 -4.7
2014-01-15 07:00:00 -4.9
2014-01-15 08:00:00 -4.9
2014-01-15 09:00:00 -3.6
2014-01-15 10:00:00 -1.7
2014-01-15 11:00:00 0.3
2014-01-15 12:00:00 1.1
2014-01-15 13:00:00 2.1
2014-01-15 14:00:00 2.0
2014-01-15 15:00:00 2.2
2014-01-15 16:00:00 2.6
2014-01-15 17:00:00 2.1
2014-01-15 18:00:00 1.2
"""
converters = {}
converters[RT_ARCHIVE_HEADERS['loc']] = str
converters[RT_ARCHIVE_HEADERS['index']] = \
lambda x: dt.strptime(x, RT_ARCHIVE_DATEFORMAT)
for v in RT_ARCHIVE_VARNAMES:
converters[RT_ARCHIVE_HEADERS[(v, 'short')]] = float
df = pnd.read_csv(
self.filename,
sep=';',
header=0,
skiprows=4,
index_col=False,
converters=converters,
decimal=',',
encoding='iso-8859-1',
na_values=[' -9.0000', -9.0000]
)
# Nettoyer la colonne superflue
df.dropna(how="all", inplace=True, axis=1)
# Nettoyer les intitulés des colonnes
df.columns = [c.strip() for c in df.columns]
# Colonne 'DATE' -> Index
df = df.set_index(keys='Date (TU)', drop=True)
# Retirer les dates en doublon: ne conserver que la dernière
df = df[~df.index.duplicated(keep='last')]
# Colonne 'Code' -> Multi-Index (None, Code) avec None: ['Debit (l/s)']
df = df.pivot(columns='Code')
# Colonne 'Code' uniquement
df.columns = df.columns.droplevel(0)
# Unités
if self.varname.startswith('Q'):
df = df.map(lambda x: x / 1000.)
return df
[docs]
def write(self, data=None):
"""
Ecriture du fichier GRPRT_Archive
Parameters
----------
data : pandas.DataFrame
Tableau des données d'observation de GRP 2016
"""
_exception.check_dataframe(data)
if self.varname.startswith('Q'):
data = data.map(lambda x: x * 1000.)
# Entête
with open(self.filename, 'w',
encoding='iso-8859-1', newline='\r\n') as f:
f.write(RT_ARCHIVE_HEADERS[None] + '\n')
f.write(RT_ARCHIVE_HEADERS[(self.varname, 'long')] + '\n')
f.write(RT_ARCHIVE_HEADERS[(self.varname, 'desc')] + '\n')
f.write(RT_ARCHIVE_HEADERS[None] + '\n')
f.write(RT_ARCHIVE_HEADERS['loc'] + ';')
f.write(RT_ARCHIVE_HEADERS['index'] + ';')
f.write(RT_ARCHIVE_HEADERS[(self.varname, 'short')] + ';\n')
# Tableau de données
loc = data.columns[0]
data.columns = [self.varname]
# Index -> Colonne
data = data.reset_index()
# Ajout de la colonne 'loc'
data['loc'] = loc
# Re-arranger l'ordre des colonnes
data.columns = ['index', self.varname, 'loc']
data = data.reindex(columns=['loc', 'index', self.varname])
# Tableau de données
data['_'] = '' # Ajout d'une colonne fictive pour avoir ;\r\n
data.to_csv(
self.filename,
mode='a',
sep=';',
float_format=RT_ARCHIVE_FLOATFORMAT[self.varname],
header=False,
index=False,
date_format=RT_ARCHIVE_DATEFORMAT,
lineterminator='\r\n',
na_rep=' -9.0000'
)
[docs]
@classmethod
def get_varnames(cls):
"""
Définir le nom de la variable
"""
return sorted(RT_ARCHIVE_VARNAMES)
[docs]
@staticmethod
def split_basename(filename=None):
"""
Extraire les informations depuis le nom du fichier
de données GRP Archive (GRP *Temps-Réel*)
Parameters
----------
filename : str
Fichier de données GRP Archive (GRP *Temps-Réel*)
Returns
-------
varname : str
Nom de la variable
Examples
--------
>>> from pyspc.model.grp16 import GRPRT_Archive
>>> f = 'data/model/grp16/rt/PV_10A.DAT'
>>> varname = GRPRT_Archive.split_basename(filename=f)
>>> varname
PV
"""
if filename is None:
return None
return os.path.splitext(os.path.basename(filename))[0].split('_')[0]