#!/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/>.
#
########################################################################
"""
Données d'observation et de prévision - Météo-France - Prévision Sympo
"""
from datetime import datetime as dt
import os.path
import pandas as pnd
import pyspc.core.exception as _exception
from pyspc.convention.meteofrance import SYMPO_DATE_FORMAT, SYMPO_VERSIONS
def date_parser(txt):
""""Convertisseur de date."""
return dt.strptime(txt, SYMPO_DATE_FORMAT)
[docs]
class Sympo_Data():
"""
Structure de données de prévision Sympo de Météo-France.
Attributes
----------
filename : str
Nom du fichier
"""
[docs]
def __init__(self, filename=None):
"""
Initialisation de l'instance de la classe Sympo_Data.
Parameters
----------
filename : str
Nom du fichier
"""
self.filename = filename
self.version, self.date_prod = self.split_basename(self.filename)
self.check_version()
def __str__(self):
"""Afficher les méta-données de l'instance Sympo_Data."""
text = """
*************************************
*********** MF - SYMPO **************
*************************************
* NOM FICHIER = {filename}
* VERSION RR3/SYMPO = {version}
* DATE PRODUCTION = {date_prod}
*************************************
"""
return text.format(**vars(self))
[docs]
def check_version(self):
"""Contrôler la version du fichier."""
_exception.raise_valueerror(
self.version not in self.get_versions(),
'Version de fichier rr3/sympo inconnue'
)
[docs]
def read(self):
"""
Lecture du fichier de données MF.
Returns
-------
pandas.DataFrame
Tableau des données
Examples
--------
>>> from pyspc.data.meteofrance import Sympo_Data
Premier format (fichier rr3)
>>> f = 'data/data/mf/rr3_200811010425'
>>> reader = Sympo_Data(filename=f)
>>> content = reader.read()
>>> content
ZONE DATE RR3 INTERVAL
0 0708 2008-11-01 06:00:00 9 7/15
1 0708 2008-11-01 09:00:00 14 10/20
2 0708 2008-11-01 12:00:00 14 10/20
3 0708 2008-11-01 15:00:00 14 10/20
4 0708 2008-11-01 18:00:00 14 10/20
5 0708 2008-11-01 21:00:00 14 10/20
6 0709 2008-11-01 06:00:00 5 3/10
7 0709 2008-11-01 09:00:00 11 7/15
8 0709 2008-11-01 12:00:00 11 7/15
9 0709 2008-11-01 15:00:00 11 7/15
10 0709 2008-11-01 18:00:00 11 7/15
11 0709 2008-11-01 21:00:00 11 7/15
Second format (fichier sympo)
>>> f = 'data/data/mf/sympo_201611200658'
>>> reader = Sympo_Data(filename=f)
>>> content = reader.read()
>>> content
ZONE DATE RR3 LPN ISO-0C
0 0708 2016-11-21 00:00:00 10.4 1800 2100
1 0708 2016-11-21 03:00:00 12.8 1900 2200
2 0708 2016-11-21 06:00:00 27.0 2200 2500
3 0708 2016-11-21 09:00:00 27.0 2400 2700
4 0708 2016-11-21 12:00:00 30.0 2400 2700
5 0708 2016-11-21 15:00:00 28.1 2400 2700
6 0708 2016-11-21 18:00:00 28.1 2500 2800
7 0708 2016-11-21 21:00:00 28.1 2500 2800
8 0708 2016-11-22 00:00:00 31.4 2500 2800
9 0708 2016-11-22 03:00:00 33.8 2400 2700
10 0708 2016-11-22 06:00:00 33.8 2400 2700
11 0708 2016-11-22 09:00:00 29.7 2300 2600
12 0709 2016-11-21 00:00:00 5.3 1900 2200
13 0709 2016-11-21 03:00:00 7.2 2200 2500
14 0709 2016-11-21 06:00:00 12.2 2400 2700
15 0709 2016-11-21 09:00:00 12.2 2500 2800
16 0709 2016-11-21 12:00:00 15.4 2500 2800
17 0709 2016-11-21 15:00:00 14.0 2600 2900
18 0709 2016-11-21 18:00:00 14.0 2700 3000
19 0709 2016-11-21 21:00:00 14.0 2600 2900
20 0709 2016-11-22 00:00:00 13.4 2600 2900
21 0709 2016-11-22 03:00:00 17.6 2600 2900
22 0709 2016-11-22 06:00:00 17.6 2600 2900
23 0709 2016-11-22 09:00:00 16.5 2400 2700
"""
if self.version == 'rr3':
return pnd.read_fwf(
self.filename,
colspecs=[(0, 4), (5, 20), (21, 25), (25, 35)],
names=['ZONE', 'DATE', 'RR3', 'INTERVAL'],
converters={'ZONE': str, 'DATE': date_parser, 'RR3': int},
)
if self.version == 'sympo':
return pnd.read_csv(
self.filename,
sep=' ',
index_col=False,
names=['ZONE', 'DATE', 'RR3', 'LPN', 'ISO-0C'],
converters={'ZONE': str, 'DATE': date_parser,
'LPN': int, 'ISO-0C': int},
)
raise ValueError('Version inconnue')
[docs]
def write(self, data=None):
"""
Ecrire le fichier de données MeteoFrance à partir d'un dictionnaire.
Parameters
----------
data : pandas.DataFrame
Tableau des données
"""
_exception.check_dataframe(data)
if self.version == 'rr3':
data['ZONE'] = data['ZONE'].map(
lambda x: f'{x.strip():<4s}')
data['DATE'] = data['DATE'].map(
lambda x: x.strftime(SYMPO_DATE_FORMAT))
data['RR3'] = data['RR3'].astype(str).map(
lambda x: f'{x.strip():>3s}')
# Attention: conserver l'espace dans le format de la ligne suivante
data['INTERVAL'] = data['INTERVAL'].map(
lambda x: f' {x.strip():<7s}')
with open(self.filename, 'w', encoding='utf-8', newline='\n') as f:
x = '\n'.join([y.strip() # .replace(' ', ' ')
for y in data.to_string(
header=False, index=False).split('\n')])
f.write(x)
f.write('\n')
return None
if self.version == 'sympo':
return data.to_csv(
self.filename,
sep=' ',
float_format='%.1f',
header=False,
index=False,
lineterminator='\n',
date_format=SYMPO_DATE_FORMAT
)
return None
[docs]
@staticmethod
def get_versions():
"""Lister des versions de Sympo."""
return sorted(SYMPO_VERSIONS)
[docs]
@staticmethod
def split_basename(filename=None):
"""
Extraire les informations depuis le nom du fichier de prévisions Sympo.
Parameters
----------
filename : str
Fichier de prévisions QMJ de PREMHYCE
Returns
-------
version : dt
Version Sympo (rr3 ou sympo)
date_prod : datetime
Date de production
Examples
--------
>>> from pyspc.data.meteofrance import Sympo_Data
Premier format (fichier rr3*)
>>> f = 'data/data/mf/rr3_200811010425'
>>> content = Sympo_Data(filename=f)
>>> content
('rr3', datetime.datetime(2008, 11, 1, 4, 25))
Second format (fichier sympo*)
>>> f = 'data/data/mf/sympo_201611200658'
>>> content = Sympo_Data.split_basename(f)
>>> content
('sympo', datetime.datetime(2016, 11, 20, 6, 58))
"""
info = os.path.basename(filename).split("_")
return info[0], dt.strptime(info[1], "%Y%m%d%H%M")