#!/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 - Classes communes."""
from collections import OrderedDict
import numpy as np
import pyspc.core.exception as _exception
from pyspc.core.location import Location
from pyspc.core.parameter import Parameter
[docs]
class BasicSerie():
"""
Structure basique d'un élément.
Attributes
----------
code : str
Lieu de la série
location : Location
Lieu de la série
parameter : Parameter
Grandeur de la série
varname : str
Grandeur de la série
spc_varname : str
Grandeur de la série selon la convention de pyspc
long_varname : str
Intitulé de la grandeur
timestep : timedelta
Pas de temps de la grandeur
timeunits : str
Unité de temps de la grandeur
units : str
Unité de la grandeur
dtfmt : str
Format de la date
np_dtype : str
Type de données de la grandeur
missing : float/int
Valeur manquante 'missing'
timezone : pytz
Fuseau horaire
See Also
--------
pyspc.core.parameter.Parameter
pyspc.core.location.Location
pyspc.core.provider.Provider
pyspc.core.common.BasicDict
"""
[docs]
def __init__(self, code=None, provider=None, varname=None, missing=None):
"""
Initialise l'instance de la classe BasicSerie.
Parameters
----------
code : str, Location
Lieu de la série
provider : str, Provider
Producteur de la série
varname : str, Parameter
Grandeur de la série
missing : float/int
Valeur manquante 'missing'
"""
super().__init__()
# =====================================================================
# Définition du lieu (code, location) : voir property/setter
# =====================================================================
self.code = code
# =====================================================================
# Définition du paramètre
# =====================================================================
self.parameter = (varname, provider)
self.missing = missing
# =====================================================================
# Autres méta-données
# =====================================================================
def __str__(self):
"""Afficher les méta-données de l'instance BasicSerie."""
text = """
*************************************
*********** BASIC SERIE *************
*************************************
* NOM VARIABLE SPC = {_spc_varname}
* INTITULE VARIABLE = {_long_varname}
* IDENTIFIANT = {_code}
* FOURNISSEUR = {_provider}
* NOM VARIABLE = {_varname}
* UNITE = {_units}
* VALEUR MANQUANTE = {_missing}
* PAS DE TEMPS = {_timestep}
* UNITE DE TEMPS = {_timeunits}
* FUSEAU HORAIRE = {_timezone}
*************************************
"""
return text.format(**vars(self))
@property
def code(self):
"""Identifiant de la série."""
return self._code
@code.setter
def code(self, code):
"""Définir l'identifiant de la série."""
# ---------------------------------------------------------------------
# Définition du lieu
# ---------------------------------------------------------------------
if isinstance(code, Location):
self._code = code.code
self._location = code
else:
self._code = code
try:
self._location = Location(code=code, loctype='point')
except ValueError:
self._location = None
@property
def location(self):
"""Lieu de la série."""
return self._location
@property
def parameter(self):
"""Grandeur de la série."""
return self._parameter
@parameter.setter
def parameter(self, parameter):
"""Définir la grandeur de la série."""
# ---------------------------------------------------------------------
# Récupération de la grandeur et du fournisseur
# ---------------------------------------------------------------------
try:
_exception.check_listlike(parameter)
varname = parameter[0]
provider = parameter[1]
except (IndexError, ValueError) as ive:
raise ValueError("L'attribut 'parameter' doit être défini à "
"partir du tuple (varname, provider)") from ive
# ---------------------------------------------------------------------
# Définition du paramètre
# ---------------------------------------------------------------------
if not isinstance(varname, Parameter):
self._parameter = Parameter(provider=provider, varname=varname)
else:
self._parameter = varname
self._varname = self.parameter.varname
self._provider = self.parameter.provider
self._spc_varname = self.parameter.spc_varname
self._long_varname = self.parameter.long_varname
self._timestep = self.parameter.timestep
self._timeunits = self.parameter.timeunits
self._units = self.parameter.units
self._dtfmt = self.parameter.dtfmt
self._np_dtype = self.parameter.np_dtype
@property
def dtfmt(self):
"""Format du datetime."""
return self._dtfmt
@dtfmt.setter
def dtfmt(self, parameter):
"""Format du datetime."""
raise AttributeError("Veuillez changer l'attribut 'parameter' au "
"lieu de cet attribut 'dtfmt'")
@property
def long_varname(self):
"""Intitulé de la grandeur."""
return self._long_varname
@long_varname.setter
def long_varname(self, parameter):
"""Intitulé de la grandeur."""
raise AttributeError("Veuillez changer l'attribut 'parameter' "
"au lieu de cet attribut 'long_varname'")
@property
def np_dtype(self):
"""Format des données dans les tableaux numpy et pandas."""
return self._np_dtype
@np_dtype.setter
def np_dtype(self, parameter):
"""Format des données dans les tableaux numpy et pandas."""
raise AttributeError(
"Veuillez changer l'attribut 'parameter' "
"au lieu de cet attribut 'np_dtype'")
@property
def spc_varname(self):
"""Grandeur de la série selon la convention de pyspc."""
return self._spc_varname
@spc_varname.setter
def spc_varname(self, parameter):
"""Définir la grandeur de la série."""
raise AttributeError("Veuillez changer l'attribut 'parameter' "
"au lieu de cet attribut 'spc_varname'")
@property
def timestep(self):
"""Pas de temps."""
return self._timestep
@timestep.setter
def timestep(self, parameter):
"""Pas de temps."""
raise AttributeError("Veuillez changer l'attribut 'parameter' "
"au lieu de cet attribut 'timestep'")
@property
def timeunits(self):
"""Unité de temps."""
return self._timeunits
@timeunits.setter
def timeunits(self, parameter):
"""Unité de temps."""
raise AttributeError("Veuillez changer l'attribut 'parameter' "
"au lieu de cet attribut 'timeunits'")
@property
def timezone(self):
"""Fuseau horaire."""
return self._timezone
@property
def units(self):
"""Unité de la variable."""
return self._units
@units.setter
def units(self, parameter):
"""Unité de la variable."""
raise AttributeError("Veuillez changer l'attribut 'parameter' "
"au lieu de cet attribut 'units'")
@property
def varname(self):
"""Grandeur de la série."""
return self._varname
@varname.setter
def varname(self, parameter):
"""Définir la grandeur de la série."""
raise AttributeError("Veuillez changer l'attribut 'parameter' "
"au lieu de cet attribut 'varname'")
@property
def provider(self):
"""Nom du fournisseur de la donnée."""
return self._provider
@provider.setter
def provider(self, parameter):
"""Nom du fournisseur de la donnée."""
raise AttributeError("Veuillez changer l'attribut 'parameter' "
"au lieu de cet attribut 'provider'")
@property
def missing(self):
"""Valeur manquante."""
return self._missing
@missing.setter
def missing(self, missing):
"""Définir Valeur manquante."""
if isinstance(missing, list):
self._missing = missing
elif isinstance(missing, np.ndarray):
self._missing = [missing]
elif isinstance(missing, (float, int)):
self._missing = [np.array(missing, 'f')]
else:
self._missing = self._parameter.missing
[docs]
class BasicDict(OrderedDict):
"""
Structure basique d'une collection sous forme de dictionnaire.
Attributes
----------
datatype : str
Type de la collection
name : str
Nom de la collection
See Also
--------
pyspc.core.common.BasicSerie
"""
[docs]
def __init__(self, datatype=None, name='collection'):
"""
Initialise l'instance de la classe BasicDict.
Parameters
----------
datatype : str
Type de la collection
name : str
Nom de la collection. Par défaut: 'series'
"""
super().__init__()
self._datatype = datatype
self._name = name
def __str__(self):
"""Afficher les méta-données de la collection."""
text = """
*************************************
********** BASIC DICT ***************
*************************************
* NOM DE LA COLLECTION = {_name}
* TYPE DE COLLECTION = {_datatype}
* NOMBRE DE SERIES = {length}
*************************************
"""
return text.format(**vars(self), length=len(self.keys()))
@property
def datatype(self):
"""Type de la collection."""
return self._datatype
@property
def name(self):
"""Nom de la collection."""
return self._name
@name.setter
def name(self, name):
"""Définir le nom de la collection."""
if isinstance(name, str):
self._name = name
def _arg2dict(self, arg):
"""
Traiter l'argument arg et renvoyer un dictionnaire.
Parameters
----------
arg : int, float, str, dict
Argument spéficique (dict) ou commun (autres cas)
Returns
-------
dict
Argument spécifié pour chaque série
- clé : toute <key> dans self.keys()
- valeur :
* si arg est un dictionnaire : arg.get(key, None)
* sinon : arg
"""
return {k: arg.get(k, None) if isinstance(arg, dict) else arg
for k in self.keys()}