Code source de pyspc.core.keyseries

#!/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/>.
#
########################################################################
"""
Objets natifs et convention de pyspc - Clés des collections de Série de données
"""
import pyspc.core.exception as _exception
from pyspc.core.timeutil import str2dt


[docs] def str2tuple(s=None, sep=None, forceobs=False, forcesim=False): """ Convertir une chaine de caractères en tuple utilisé par pyspc.core.Series Parameters ---------- s : str Chaine de caractère à convertir sep : str Séparateur des champs. Défaut: '_' forceobs : bool Forcer la conversion en tant que série d'observation. Défaut: False forcesim : bool Forcer la conversion en tant que série de simulation. Défaut: False L'option forceobs a la préséance sur forcesim Returns ------- tuple Tuple servant de clé pour Series: - observation : (identifiant, grandeur, None) - simulation : (identifiant, grandeur, modele) - prévision : (identifiant, grandeur, (runtime, model, scen, tend)) See Also -------- pyspc.core.series.Series Examples -------- >>> from datetime import datetime as dt >>> from pyspc.core.keyseries import str2tuple Cas classiques >>> str2tuple('ID_GRD') ('ID', 'GRD', None) >>> str2tuple('ID_MDL_GRD') ('ID', 'GRD', 'MDL') >>> str2tuple('ID_20210301_GRD') ('ID', 'GRD', (dt(2021, 3, 1, 0, 0), None, None, None)) >>> str2tuple('ID_20210301_MDL_GRD') ('ID', 'GRD', (dt(2021, 3, 1, 0, 0), 'MDL', None, None)) >>> str2tuple('ID_20210301_MDL_SCN_GRD') ('ID', 'GRD', (dt(2021, 3, 1, 0, 0), 'MDL', 'SCN', None)) >>> str2tuple('ID_20210301_MDL_SCN_INC_GRD') ('ID', 'GRD', (dt(2021, 3, 1, 0, 0), 'MDL', 'SCN', 'INC')) >>> str2tuple('ID_2021030112_GRD') ('ID', 'GRD', (dt(2021, 3, 1, 12, 0), None, None, None)) >>> str2tuple('ID_2021030112_MDL_GRD') ('ID', 'GRD', (dt(2021, 3, 1, 12, 0), 'MDL', None, None)) >>> str2tuple('ID_2021030112_MDL_SCN_GRD') ('ID', 'GRD', (dt(2021, 3, 1, 12, 0), 'MDL', 'SCN', None)) >>> str2tuple('ID_2021030112_MDL_SCN_INC_GRD') ('ID', 'GRD', (dt(2021, 3, 1, 12, 0), 'MDL', 'SCN', 'INC')) >>> str2tuple('ID_202103011230_GRD') ('ID', 'GRD', (dt(2021, 3, 1, 12, 30), None, None, None)) >>> str2tuple('ID_202103011230_MDL_GRD') ('ID', 'GRD', (dt(2021, 3, 1, 12, 30), 'MDL', None, None)) >>> str2tuple('ID_202103011230_MDL_SCN_GRD') ('ID', 'GRD', (dt(2021, 3, 1, 12, 30), 'MDL', 'SCN', None)) >>> str2tuple('ID_202103011230_MDL_SCN_INC_GRD') ('ID', 'GRD', (dt(2021, 3, 1, 12, 30), 'MDL', 'SCN', 'INC')) Cas avec 'forceobs=True' >>> str2tuple('ID_GRD', forceobs=True) ('ID', 'GRD', None) >>> str2tuple('ID_MDL_GRD', forceobs=True) ('ID_MDL', 'GRD', None) >>> str2tuple('ID_20210301_GRD', forceobs=True) ('ID_20210301', 'GRD', None) >>> str2tuple('ID_20210301_MDL_GRD', forceobs=True) ('ID_20210301_MDL', 'GRD', None) >>> str2tuple('ID_20210301_MDL_SCN_GRD', forceobs=True) ('ID_20210301_MDL_SCN', 'GRD', None) >>> str2tuple('ID_20210301_MDL_SCN_INC_GRD', forceobs=True) ('ID_20210301_MDL_SCN_INC', 'GRD', None) Cas avec 'forcesim=True' >>> str2tuple('ID_GRD', forcesim=True) ('ID', 'GRD', None) >>> str2tuple('ID_MDL_GRD', forcesim=True) ('ID', 'GRD', 'MDL') >>> str2tuple('ID_20210301_GRD', forcesim=True) ('ID', 'GRD', '20210301') >>> str2tuple('ID_20210301_MDL_GRD', forcesim=True) ('ID', 'GRD', '20210301_MDL') >>> str2tuple('ID_20210301_MDL_SCN_GRD', forcesim=True) ('ID', 'GRD', '20210301_MDL_SCN') >>> str2tuple('ID_20210301_MDL_SCN_INC_GRD', forcesim=True) ('ID', 'GRD', '20210301_MDL_SCN_INC') """ # ------------------------------------------------------------------------- # 0- Contrôles # ------------------------------------------------------------------------- _exception.check_str(s) _exception.check_bool(forceobs) _exception.check_bool(forcesim) if sep is None: sep = '_' _exception.check_str(sep) # ------------------------------------------------------------------------- # 1- Grandeur # ------------------------------------------------------------------------- # Ancienne version avec str contenant le chemin d'un fichier # info = os.path.basename(os.path.splitext(s)[0]).split('_') # Nouvelle version: traiter une chaine de caractère sans supposer str=path info = s.split('_') varname = info.pop(-1) # ------------------------------------------------------------------------- # 2- Cas observation # ------------------------------------------------------------------------- if forceobs or len(info) == 1: return (sep.join(info), varname, None) # ------------------------------------------------------------------------- # 3- Cas simulation # ------------------------------------------------------------------------- code = info.pop(0) try: runtime = str2dt(info[0]) except (KeyError, ValueError): runtime = None if forcesim or runtime is None: return (code, varname, sep.join(info)) # ------------------------------------------------------------------------- # 4- Cas prévision # ------------------------------------------------------------------------- info.pop(0) # retirer runtime if not info: return (code, varname, (runtime, None, None, None)) model = info.pop(0) if not info: return (code, varname, (runtime, model, None, None)) scen = info.pop(0) if not info: return (code, varname, (runtime, model, scen, None)) uncert = info.pop(0) if not info: return (code, varname, (runtime, model, scen, uncert)) raise ValueError( f"La chaine de caractère est mal formatée. Il reste '{info}'")
[docs] def tuple2str(t=None, dtfmt=None, sep=None): """ Convertir un tuple utilisé par pyspc.core.Series en chaine de caractères Parameters ---------- t : tuple Tuple servant de clé pour Series: - observation : (identifiant, grandeur, None) - simulation : (identifiant, grandeur, modele) - prévision : (identifiant, grandeur, (runtime, model, scen, tend)) sep : str Séparateur des champs. Défaut: '_' dtfmt : str Format d'écriture des dates. Défaut: '%Y%m%d%H' Returns ------- s : str Chaine de caractère à convertir See Also -------- pyspc.core.keyseries.str2tuple Examples -------- >>> from datetime import datetime as dt >>> from pyspc.core.keyseries import tuple2str Cas par défaut >>> tuple2str(('ID', 'GRD', None)) ID_GRD >>> tuple2str(('ID', 'GRD', 'MDL')) ID_MDL_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 0, 0), None, None, None))) ID_2021030100_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 0, 0), 'MDL', None, None))) ID_2021030100_MDL_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 0, 0), 'MDL', 'SCN', None))) ID_2021030100_MDL_SCN_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 0, 0), 'MDL', 'SCN', 'INC'))) ID_2021030100_MDL_SCN_INC_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 12, 0), None, None, None))) ID_2021030112_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 12, 0), 'MDL', None, None))) ID_2021030112_MDL_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 12, 0), 'MDL', 'SCN', None))) ID_2021030112_MDL_SCN_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 12, 0), 'MDL', 'SCN', 'INC'))) ID_2021030112_MDL_SCN_INC_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 13, 30), None, None, None))) ID_2021030113_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 13, 30), 'MDL', None, None))) ID_2021030113_MDL_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 13, 30), 'MDL', 'SCN', None))) ID_2021030113_MDL_SCN_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 13, 30), 'MDL', 'SCN', 'INC'))) ID_2021030113_MDL_SCN_INC_GRD Cas avec 'dtfmt' définie par l'utilisateur >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 0, 0), None, None, None)), dtfmt='%Y%m%d%H%M') ID_202103010000_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 0, 0), 'MDL', None, None)), dtfmt='%Y%m%d%H%M') ID_202103010000_MDL_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 0, 0), 'MDL', 'SCN', None)), dtfmt='%Y%m%d%H%M') ID_202103010000_MDL_SCN_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 0, 0), 'MDL', 'SCN', 'INC')), dtfmt='%Y%m%d%H%M') ID_202103010000_MDL_SCN_INC_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 12, 0), None, None, None)), dtfmt='%Y%m%d%H%M') ID_202103011200_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 12, 0), 'MDL', None, None)), dtfmt='%Y%m%d%H%M') ID_202103011200_MDL_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 12, 0), 'MDL', 'SCN', None)), dtfmt='%Y%m%d%H%M') ID_202103011200_MDL_SCN_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 12, 0), 'MDL', 'SCN', 'INC')), dtfmt='%Y%m%d%H%M') ID_202103011200_MDL_SCN_INC_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 12, 30), None, None, None)), dtfmt='%Y%m%d%H%M') ID_202103011230_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 12, 30), 'MDL', None, None)), dtfmt='%Y%m%d%H%M') ID_202103011230_MDL_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 12, 30), 'MDL', 'SCN', None)), dtfmt='%Y%m%d%H%M') ID_202103011230_MDL_SCN_GRD >>> tuple2str(('ID', 'GRD', (dt(2021, 3, 1, 12, 30), 'MDL', 'SCN', 'INC')), dtfmt='%Y%m%d%H%M') ID_202103011230_MDL_SCN_INC_GRD """ # ------------------------------------------------------------------------- # 0- Contrôles # ------------------------------------------------------------------------- _exception.check_listlike(t) if dtfmt is None: dtfmt = '%Y%m%d%H' _exception.check_str(dtfmt) if sep is None: sep = '_' _exception.check_str(sep) # ------------------------------------------------------------------------- # 1- Identifiant et grandeur # ------------------------------------------------------------------------- try: code = t[0] varname = t[1] except IndexError as ie: raise ValueError("Le tuple est mal-formaté. Impossible d'extraire " "l'identifiant et/ou la grandeur") from ie _exception.check_str(code) _exception.check_str(varname) try: meta = t[2] except IndexError: meta = None # ------------------------------------------------------------------------- # 2- Cas observation # ------------------------------------------------------------------------- if meta is None: return sep.join([code, varname]) # ------------------------------------------------------------------------- # 3- Cas simulation # ------------------------------------------------------------------------- if isinstance(meta, str): return sep.join([code, meta, varname]) # ------------------------------------------------------------------------- # 4- Cas prévision # ------------------------------------------------------------------------- _exception.check_dt(meta[0]) meta = [x for x in meta if x is not None] meta[0] = meta[0].strftime(dtfmt) return sep.join([code, *meta, varname])