#!/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 - Bulletins Précipitations
"""
from datetime import datetime as dt
import numpy as np
import pandas as pnd
from pyspc.io.xml.from_xml import from_file, get_attrib, remove_namespace
import pyspc.core.exception as _exception
[docs]
class BP_Data():
"""
Structure de données destinée à traiter les BP au format xml.
Attributes
----------
filename : str
Nom du fichier
"""
[docs]
def __init__(self, filename=None):
"""
Initialisation de l'instance de la classe BP_Data.
Parameters
----------
filename : str
Nom du fichier
"""
self.filename = filename
def __str__(self):
"""
Afficher les méta-données de l'instance BP_Data.
"""
text = """
*************************************
*********** MF - BP DATA ************
*************************************
* NOM FICHIER = {filename}
*************************************
"""
return text.format(**vars(self))
[docs]
def read(self):
"""
Lecture du BP au format XML.
Returns
-------
dict
Dictionnaire des informations
- alerts : dictionnaire des alertes {zone: (début, fin)}
- obs : pandas.DataFrame des valeurs observées
- prv : pandas.DataFrame des valeurs prévues
Examples
--------
>>> from datetime import datetime as dt
>>> from pyspc.data.meteofrance import BP_Data
Cas du fichier XML - version 2008
>>> f = 'data/data/mf/bp_ly_200811010718.xml'
>>> bp = BP_Data(filename=f)
>>> content = bp.read()
>>> content['alert']
{'401': (None, None),
'402': (dt(2008, 11, 1, 6, 3, 39), dt(2008, 11, 1, 23, 0)),
'403': (dt(2008, 11, 1, 6, 3, 39), dt(2008, 11, 1, 23, 0)),
'410': (dt(2008, 11, 1, 6, 3, 39), dt(2008, 11, 1, 23, 0)),
'411': (dt(2008, 11, 1, 6, 3, 39), dt(2008, 11, 1, 23, 0)),
'412': (dt(2008, 11, 1, 6, 3, 39), dt(2008, 11, 1, 23, 0)),
'413': (dt(2008, 11, 1, 6, 3, 39), dt(2008, 11, 1, 23, 0)),
'414': (dt(2008, 11, 1, 6, 3, 39), dt(2008, 11, 1, 23, 0)),
'415': (dt(2008, 11, 1, 6, 3, 39), dt(2008, 11, 1, 23, 0)),
'420': (None, None), '421': (None, None), '422': (None, None),
'423': (None, None), '424': (None, None), '425': (None, None),
'426': (None, None), '430': (None, None), '431': (None, None),
'432': (None, None), '433': (None, None), '440': (None, None),
'441': (None, None), '442': (None, None), '443': (None, None)}
>>> content['obs']
DATE DEBUT MAXRR AVGRR CODE DTPROD NAME PROVIDER
0 2008-10-31 06:00:00 NaN NaN 401 2008-11-01 06:03:39 Loire Morvan DIRCE
1 2008-10-31 06:00:00 NaN NaN 402 2008-11-01 06:03:39 Loire amont DIRCE
2 2008-10-31 06:00:00 NaN NaN 403 2008-11-01 06:03:39 Haut bassin Loire DIRCE
3 2008-10-31 06:00:00 NaN NaN 410 2008-11-01 06:03:39 Allier aval DIRCE
4 2008-10-31 06:00:00 NaN NaN 411 2008-11-01 06:03:39 Sioule DIRCE
5 2008-10-31 06:00:00 NaN NaN 412 2008-11-01 06:03:39 Dore DIRCE
6 2008-10-31 06:00:00 NaN NaN 413 2008-11-01 06:03:39 Allier amont DIRCE
7 2008-10-31 06:00:00 NaN NaN 414 2008-11-01 06:03:39 Allier intermediaire DIRCE
8 2008-10-31 06:00:00 NaN NaN 415 2008-11-01 06:03:39 Alagnon DIRCE
9 2008-10-31 06:00:00 NaN NaN 420 2008-11-01 06:03:39 Saone moyenne DIRCE
10 2008-10-31 06:00:00 NaN NaN 421 2008-11-01 06:03:39 Saone inferieure DIRCE
11 2008-10-31 06:00:00 NaN NaN 422 2008-11-01 06:03:39 Seille DIRCE
12 2008-10-31 06:00:00 NaN NaN 423 2008-11-01 06:03:39 Ain inferieur DIRCE
13 2008-10-31 06:00:00 NaN NaN 424 2008-11-01 06:03:39 Gier bas Dauphine DIRCE
14 2008-10-31 06:00:00 NaN NaN 425 2008-11-01 06:03:39 Rhone superieur DIRCE
15 2008-10-31 06:00:00 NaN NaN 426 2008-11-01 06:03:39 Rhone prealpin DIRCE
16 2008-10-31 06:00:00 NaN NaN 430 2008-11-01 06:03:39 Isere aval DIRCE
17 2008-10-31 06:00:00 NaN NaN 431 2008-11-01 06:03:39 Drac Romanche DIRCE
18 2008-10-31 06:00:00 NaN NaN 432 2008-11-01 06:03:39 Arly Isere moyenne DIRCE
19 2008-10-31 06:00:00 NaN NaN 433 2008-11-01 06:03:39 Haute Isere Arc DIRCE
20 2008-10-31 06:00:00 NaN NaN 440 2008-11-01 06:03:39 Yonne aval DIRCE
21 2008-10-31 06:00:00 NaN NaN 441 2008-11-01 06:03:39 Yonne intermediaire DIRCE
22 2008-10-31 06:00:00 NaN NaN 442 2008-11-01 06:03:39 Yonne-Morvan DIRCE
23 2008-10-31 06:00:00 NaN NaN 443 2008-11-01 06:03:39 Yonne-Auxois DIRCE
>>> content['prv']
DATE DEBUT MAXRR AVGRR CODE NAME DTPROD PROVIDER
0 2008-11-01 06:00:00 10/20 401 Loire Morvan 2008-11-01 06:03:39 DIRCE
1 2008-11-02 06:00:00 1/5 401 Loire Morvan 2008-11-01 06:03:39 DIRCE
2 2008-11-03 06:00:00 0 401 Loire Morvan 2008-11-01 06:03:39 DIRCE
3 2008-11-01 06:00:00 50/80 20/40 402 Loire amont 2008-11-01 06:03:39 DIRCE
4 2008-11-02 06:00:00 3/10 402 Loire amont 2008-11-01 06:03:39 DIRCE
5 2008-11-03 06:00:00 0 402 Loire amont 2008-11-01 06:03:39 DIRCE
6 2008-11-01 06:00:00 50/80 30/50 403 Haut bassin Loire 2008-11-01 06:03:39 DIRCE
7 2008-11-02 06:00:00 10/20 403 Haut bassin Loire 2008-11-01 06:03:39 DIRCE
8 2008-11-03 06:00:00 Tr/3 403 Haut bassin Loire 2008-11-01 06:03:39 DIRCE
9 2008-11-01 06:00:00 40/60 10/20 410 Allier aval 2008-11-01 06:03:39 DIRCE
10 2008-11-02 06:00:00 1/5 410 Allier aval 2008-11-01 06:03:39 DIRCE
11 2008-11-03 06:00:00 0 410 Allier aval 2008-11-01 06:03:39 DIRCE
12 2008-11-01 06:00:00 40/60 10/20 411 Sioule 2008-11-01 06:03:39 DIRCE
13 2008-11-02 06:00:00 7/15 411 Sioule 2008-11-01 06:03:39 DIRCE
14 2008-11-03 06:00:00 0 411 Sioule 2008-11-01 06:03:39 DIRCE
15 2008-11-01 06:00:00 50/80 40/60 412 Dore 2008-11-01 06:03:39 DIRCE
16 2008-11-02 06:00:00 3/10 412 Dore 2008-11-01 06:03:39 DIRCE
17 2008-11-03 06:00:00 0 412 Dore 2008-11-01 06:03:39 DIRCE
18 2008-11-01 06:00:00 50/80 30/50 413 Allier amont 2008-11-01 06:03:39 DIRCE
19 2008-11-02 06:00:00 15/30 413 Allier amont 2008-11-01 06:03:39 DIRCE
20 2008-11-03 06:00:00 Tr/3 413 Allier amont 2008-11-01 06:03:39 DIRCE
21 2008-11-01 06:00:00 40/60 30/50 414 Allier intermediaire 2008-11-01 06:03:39 DIRCE
22 2008-11-02 06:00:00 7/15 414 Allier intermediaire 2008-11-01 06:03:39 DIRCE
23 2008-11-03 06:00:00 0 414 Allier intermediaire 2008-11-01 06:03:39 DIRCE
24 2008-11-01 06:00:00 50/80 30/50 415 Alagnon 2008-11-01 06:03:39 DIRCE
25 2008-11-02 06:00:00 10/20 415 Alagnon 2008-11-01 06:03:39 DIRCE
26 2008-11-03 06:00:00 Tr/3 415 Alagnon 2008-11-01 06:03:39 DIRCE
27 2008-11-01 06:00:00 7/15 420 Saone moyenne 2008-11-01 06:03:39 DIRCE
28 2008-11-02 06:00:00 Tr/3 420 Saone moyenne 2008-11-01 06:03:39 DIRCE
29 2008-11-03 06:00:00 Tr/3 420 Saone moyenne 2008-11-01 06:03:39 DIRCE
.. ... ... ... ... ... ... ...
42 2008-11-01 06:00:00 Tr/3 425 Rhone superieur 2008-11-01 06:03:39 DIRCE
43 2008-11-02 06:00:00 3/10 425 Rhone superieur 2008-11-01 06:03:39 DIRCE
44 2008-11-03 06:00:00 Tr/3 425 Rhone superieur 2008-11-01 06:03:39 DIRCE
45 2008-11-01 06:00:00 Tr/3 426 Rhone prealpin 2008-11-01 06:03:39 DIRCE
46 2008-11-02 06:00:00 1/5 426 Rhone prealpin 2008-11-01 06:03:39 DIRCE
47 2008-11-03 06:00:00 Tr/3 426 Rhone prealpin 2008-11-01 06:03:39 DIRCE
48 2008-11-01 06:00:00 1/5 430 Isere aval 2008-11-01 06:03:39 DIRCE
49 2008-11-02 06:00:00 7/15 430 Isere aval 2008-11-01 06:03:39 DIRCE
50 2008-11-03 06:00:00 Tr/3 430 Isere aval 2008-11-01 06:03:39 DIRCE
51 2008-11-01 06:00:00 Tr/3 431 Drac Romanche 2008-11-01 06:03:39 DIRCE
52 2008-11-02 06:00:00 3/10 431 Drac Romanche 2008-11-01 06:03:39 DIRCE
53 2008-11-03 06:00:00 Tr/3 431 Drac Romanche 2008-11-01 06:03:39 DIRCE
54 2008-11-01 06:00:00 0 432 Arly Isere moyenne 2008-11-01 06:03:39 DIRCE
55 2008-11-02 06:00:00 1/5 432 Arly Isere moyenne 2008-11-01 06:03:39 DIRCE
56 2008-11-03 06:00:00 Tr/3 432 Arly Isere moyenne 2008-11-01 06:03:39 DIRCE
57 2008-11-01 06:00:00 Tr/3 433 Haute Isere Arc 2008-11-01 06:03:39 DIRCE
58 2008-11-02 06:00:00 7/15 433 Haute Isere Arc 2008-11-01 06:03:39 DIRCE
59 2008-11-03 06:00:00 Tr/3 433 Haute Isere Arc 2008-11-01 06:03:39 DIRCE
60 2008-11-01 06:00:00 3/10 440 Yonne aval 2008-11-01 06:03:39 DIRCE
61 2008-11-02 06:00:00 Tr/3 440 Yonne aval 2008-11-01 06:03:39 DIRCE
62 2008-11-03 06:00:00 0 440 Yonne aval 2008-11-01 06:03:39 DIRCE
63 2008-11-01 06:00:00 3/10 441 Yonne intermediaire 2008-11-01 06:03:39 DIRCE
64 2008-11-02 06:00:00 Tr/3 441 Yonne intermediaire 2008-11-01 06:03:39 DIRCE
65 2008-11-03 06:00:00 Tr/3 441 Yonne intermediaire 2008-11-01 06:03:39 DIRCE
66 2008-11-01 06:00:00 7/15 442 Yonne-Morvan 2008-11-01 06:03:39 DIRCE
67 2008-11-02 06:00:00 Tr/3 442 Yonne-Morvan 2008-11-01 06:03:39 DIRCE
68 2008-11-03 06:00:00 Tr/3 442 Yonne-Morvan 2008-11-01 06:03:39 DIRCE
69 2008-11-01 06:00:00 10/20 443 Yonne-Auxois 2008-11-01 06:03:39 DIRCE
70 2008-11-02 06:00:00 Tr/3 443 Yonne-Auxois 2008-11-01 06:03:39 DIRCE
71 2008-11-03 06:00:00 Tr/3 443 Yonne-Auxois 2008-11-01 06:03:39 DIRCE
Cas du fichier XML - version actuelle
>>> f = 'data/data/mf/bp_ic_201605310503.xml'
>>> bp = BP_Data(filename=f)
>>> content = bp.read()
>>> content['alerts']
{'70701': (dt(2016, 5, 31, 5, 2, 5), dt(2016, 5, 31, 14, 0)),
'70702': (dt(2016, 5, 31, 5, 2, 5), dt(2016, 5, 31, 14, 0)),
'70703': (dt(2016, 5, 31, 5, 2, 5), dt(2016, 5, 31, 14, 0)),
'70704': (dt(2016, 5, 31, 5, 2, 5), dt(2016, 5, 31, 14, 0)),
'70705': (dt(2016, 5, 31, 5, 2, 5), dt(2016, 5, 31, 14, 0)),
'70708': (dt(2016, 5, 31, 5, 2, 5), dt(2016, 5, 31, 14, 0)),
'70707': (dt(2016, 5, 31, 5, 2, 5), dt(2016, 5, 31, 14, 0)),
'70402': (dt(2016, 5, 31, 5, 2, 5), dt(2016, 5, 31, 14, 0)),
'70403': (dt(2016, 5, 31, 5, 2, 5), dt(2016, 5, 31, 14, 0)),
'70901': (dt(2016, 5, 31, 5, 2, 5), dt(2016, 5, 31, 14, 0)),
'71002': (dt(2016, 5, 31, 5, 2, 5), dt(2016, 5, 31, 14, 0)),
'71003': (dt(2016, 5, 31, 5, 2, 5), dt(2016, 5, 31, 14, 0)),
'71004': (dt(2016, 5, 31, 5, 2, 5), dt(2016, 5, 31, 14, 0)),
'71005': (dt(2016, 5, 31, 5, 2, 5), dt(2016, 5, 31, 14, 0)),
'71006': (dt(2016, 5, 31, 5, 2, 5), dt(2016, 5, 31, 14, 0)),
'71007': (dt(2016, 5, 31, 5, 2, 5), dt(2016, 5, 31, 14, 0))}
>>> content['obs']
DATE DEBUT MAXRR AVGRR CODE DTPROD NAME PROVIDER
0 2016-05-30 NaN 34.0 70701 2016-05-31 05:02:05 Boucles de Seine DIRIC
1 2016-05-30 NaN 30.0 70702 2016-05-31 05:02:05 Oise aval DIRIC
2 2016-05-30 NaN 28.0 70703 2016-05-31 05:02:05 Marne aval DIRIC
3 2016-05-30 NaN 31.0 70704 2016-05-31 05:02:05 Les Morins DIRIC
4 2016-05-30 NaN 41.0 70705 2016-05-31 05:02:05 Seine moyenne DIRIC
5 2016-05-30 NaN 53.0 70708 2016-05-31 05:02:05 Loing aval DIRIC
6 2016-05-30 NaN 50.0 70707 2016-05-31 05:02:05 Loing amont DIRIC
7 2016-05-30 NaN 21.0 70402 2016-05-31 05:02:05 Avre Eure amont DIRIC
8 2016-05-30 NaN 9.0 70403 2016-05-31 05:02:05 Perche DIRIC
9 2016-05-30 NaN 21.0 70901 2016-05-31 05:02:05 Loir amont DIRIC
10 2016-05-30 NaN 20.0 71002 2016-05-31 05:02:05 Cher aval Indre aval DIRIC
11 2016-05-30 NaN 33.0 71003 2016-05-31 05:02:05 Loire Tourangelle DIRIC
12 2016-05-30 NaN 30.0 71004 2016-05-31 05:02:05 Loire Giennoise DIRIC
13 2016-05-30 NaN 35.0 71005 2016-05-31 05:02:05 Sauldre DIRIC
14 2016-05-30 NaN 26.0 71006 2016-05-31 05:02:05 Yevre Cher moyen DIRIC
15 2016-05-30 NaN 22.0 71007 2016-05-31 05:02:05 Indre amont Arnon Theols DIRIC
>>> content['prv']
DATE DEBUT MAXRR AVGRR CODE NAME DTPROD PROVIDER
0 2016-05-31 15/30 70701 Boucles de Seine 2016-05-31 05:02:05 DIRIC
1 2016-06-01 Tr/3 70701 Boucles de Seine 2016-05-31 05:02:05 DIRIC
2 2016-06-02 7/15 70701 Boucles de Seine 2016-05-31 05:02:05 DIRIC
3 2016-05-31 15/30 70702 Oise aval 2016-05-31 05:02:05 DIRIC
4 2016-06-01 Tr/3 70702 Oise aval 2016-05-31 05:02:05 DIRIC
5 2016-06-02 7/15 70702 Oise aval 2016-05-31 05:02:05 DIRIC
6 2016-05-31 10/20 70703 Marne aval 2016-05-31 05:02:05 DIRIC
7 2016-06-01 Tr/3 70703 Marne aval 2016-05-31 05:02:05 DIRIC
8 2016-06-02 10/20 70703 Marne aval 2016-05-31 05:02:05 DIRIC
9 2016-05-31 15/30 70704 Les Morins 2016-05-31 05:02:05 DIRIC
10 2016-06-01 Tr/3 70704 Les Morins 2016-05-31 05:02:05 DIRIC
11 2016-06-02 10/20 70704 Les Morins 2016-05-31 05:02:05 DIRIC
12 2016-05-31 15/30 70705 Seine moyenne 2016-05-31 05:02:05 DIRIC
13 2016-06-01 Tr/3 70705 Seine moyenne 2016-05-31 05:02:05 DIRIC
14 2016-06-02 7/15 70705 Seine moyenne 2016-05-31 05:02:05 DIRIC
15 2016-05-31 15/30 70708 Loing aval 2016-05-31 05:02:05 DIRIC
16 2016-06-01 1/5 70708 Loing aval 2016-05-31 05:02:05 DIRIC
17 2016-06-02 10/20 70708 Loing aval 2016-05-31 05:02:05 DIRIC
18 2016-05-31 15/30 70707 Loing amont 2016-05-31 05:02:05 DIRIC
19 2016-06-01 1/5 70707 Loing amont 2016-05-31 05:02:05 DIRIC
20 2016-06-02 7/15 70707 Loing amont 2016-05-31 05:02:05 DIRIC
21 2016-05-31 15/30 70402 Avre Eure amont 2016-05-31 05:02:05 DIRIC
22 2016-06-01 Tr/3 70402 Avre Eure amont 2016-05-31 05:02:05 DIRIC
23 2016-06-02 7/15 70402 Avre Eure amont 2016-05-31 05:02:05 DIRIC
24 2016-05-31 15/30 70403 Perche 2016-05-31 05:02:05 DIRIC
25 2016-06-01 Tr/3 70403 Perche 2016-05-31 05:02:05 DIRIC
26 2016-06-02 1/5 70403 Perche 2016-05-31 05:02:05 DIRIC
27 2016-05-31 20/40 70901 Loir amont 2016-05-31 05:02:05 DIRIC
28 2016-06-01 1/5 70901 Loir amont 2016-05-31 05:02:05 DIRIC
29 2016-06-02 3/10 70901 Loir amont 2016-05-31 05:02:05 DIRIC
30 2016-05-31 20/40 71002 Cher aval Indre aval 2016-05-31 05:02:05 DIRIC
31 2016-06-01 1/5 71002 Cher aval Indre aval 2016-05-31 05:02:05 DIRIC
32 2016-06-02 3/10 71002 Cher aval Indre aval 2016-05-31 05:02:05 DIRIC
33 2016-05-31 20/40 71003 Loire Tourangelle 2016-05-31 05:02:05 DIRIC
34 2016-06-01 1/5 71003 Loire Tourangelle 2016-05-31 05:02:05 DIRIC
35 2016-06-02 3/10 71003 Loire Tourangelle 2016-05-31 05:02:05 DIRIC
36 2016-05-31 15/30 71004 Loire Giennoise 2016-05-31 05:02:05 DIRIC
37 2016-06-01 1/5 71004 Loire Giennoise 2016-05-31 05:02:05 DIRIC
38 2016-06-02 3/10 71004 Loire Giennoise 2016-05-31 05:02:05 DIRIC
39 2016-05-31 15/30 71005 Sauldre 2016-05-31 05:02:05 DIRIC
40 2016-06-01 1/5 71005 Sauldre 2016-05-31 05:02:05 DIRIC
41 2016-06-02 3/10 71005 Sauldre 2016-05-31 05:02:05 DIRIC
42 2016-05-31 15/30 71006 Yevre Cher moyen 2016-05-31 05:02:05 DIRIC
43 2016-06-01 1/5 71006 Yevre Cher moyen 2016-05-31 05:02:05 DIRIC
44 2016-06-02 3/10 71006 Yevre Cher moyen 2016-05-31 05:02:05 DIRIC
45 2016-05-31 15/30 71007 Indre amont Arnon Theols 2016-05-31 05:02:05 DIRIC
46 2016-06-01 1/5 71007 Indre amont Arnon Theols 2016-05-31 05:02:05 DIRIC
47 2016-06-02 1/5 71007 Indre amont Arnon Theols 2016-05-31 05:02:05 DIRIC
"""
# ---------------------------------------------------------------------
# 0- Fichier -> ElementTree
# ---------------------------------------------------------------------
tree = from_file(filename=self.filename)
# remove all existing namespaces
nsmap = tree.getroot().nsmap
if nsmap != {}:
for alias in nsmap:
remove_namespace(tree.getroot(), nsmap[alias])
# ---------------------------------------------------------------------
# 1- Balise racine -> runtime / provider
# ---------------------------------------------------------------------
element = tree.getroot()
dprod = get_attrib(element, 'dateProduction')
hprod = get_attrib(element, 'heureProduction')
runtime = dt.strptime(f"{dprod} {hprod}", "%Y-%m-%d %H-%M-%S")
provider = get_attrib(element, 'centreProducteur')
# ---------------------------------------------------------------------
# 2- Zones AP / Grandeur / AP
# ---------------------------------------------------------------------
zones = {get_attrib(item, 'id'): get_attrib(item, 'libelle')
for item in element.findall('ZoneAP')}
varnames = {get_attrib(item, 'id'): get_attrib(item, 'libelle')
for item in element.findall('ParametreAP')}
item = element.find('AlerteAP')
alerts = (_ap2dt(get_attrib(item, 'dateDebut'), runtime),
_ap2dt(get_attrib(item, 'dateFin'), runtime))
# ---------------------------------------------------------------------
# 3- Valeurs observées et prévues
# ---------------------------------------------------------------------
data = _process_DonneesAP(element, varnames)
alerts = {z: alerts if data[z]['alert'] else (None, None)
for z in data}
obs = pnd.concat([data[z]['obs'] for z in data], ignore_index=True)
obs['DTPROD'] = runtime
obs['NAME'] = obs['CODE'].map(lambda x: zones.get(x, None))
obs['PROVIDER'] = provider
prv = pnd.concat([data[z]['prv'] for z in data], ignore_index=True)
# Mise au format du rendu BP de pyspc.data.lamedo.BdApbp
prv['CODE'] = prv['CODE'].astype(str)
prv['NAME'] = prv['CODE'].map(lambda x: zones.get(x, None))
prv['DTPROD'] = runtime
prv['PROVIDER'] = provider
return {'alerts': alerts, 'obs': obs, 'prv': prv}
def _process_DonneesAP(element, varnames):
"""Traiter la balise DonneesAP."""
data = {}
if element is not None:
for item in element.findall('DonneesAP'):
z = get_attrib(item, 'idRefGeo')
d = {}
d['alert'] = get_attrib(item, 'alerteEnCours', bool)
d['obs'] = _process_DonneeObservee(item, varnames)
d['obs']['CODE'] = z
d['prv'] = _process_DonneePrevue(item, varnames)
d['prv']['CODE'] = z
data.setdefault(z, d)
return data
def _process_DonneeObservee(element, varnames):
"""Traiter la balise DonneeObservee."""
data = {v: [] for v in varnames.keys()}
index = []
if element is not None:
for item in element.findall('DonneeObservee'):
date = dt.strptime(get_attrib(item, 'dateDebut'), "%Y%m%d%H%M%S")
values = _process_Valeur(item)
for k in data.keys():
try:
v = float(values.get(k, ''))
except ValueError:
v = np.nan
data[k].append(v)
index.append(date)
df = pnd.DataFrame(data, index=index)
df.index.name = 'DATE DEBUT'
df = df.reset_index(level=['DATE DEBUT'])
return df
return None
def _process_DonneePrevue(element, varnames):
"""Traiter la balise DonneePrevue."""
data = {v: [] for v in varnames.keys()}
index = []
if element is not None:
for item in element.findall('DonneePrevue'):
date = dt.strptime(get_attrib(item, 'dateDebut'), "%Y%m%d%H%M%S")
values = _process_Valeur(item)
for k in data.keys():
data[k].append(values.get(k, ''))
index.append(date)
df = pnd.DataFrame(data, index=index)
df.index.name = 'DATE DEBUT'
df = df.reset_index(level=['DATE DEBUT'])
return df
return None
def _process_Valeur(element):
"""Traiter la balise Valeur."""
if element is not None:
return {get_attrib(item, 'idParametre'): get_attrib(item, 'valeur')
for item in element.findall('Valeur')}
return None
def _ap2dt(ap, dtprod):
"""
Convertir l'information textuelle de l'alerte précipitation en datetime.
Parameters
----------
ap : str
Alerte précipitation
dtprod : datetime
Date de production
Returns
-------
datetime
Date de l'alerte (dtprod si ap == 'Immédiate')
None
Si pas d'alerte
"""
if ap == "Immédiate":
return dtprod
if ap == "néant":
return None
return dt.strptime(ap, "%Y%m%d%H%M%S")
[docs]
def BP_value_to_interval(value):
"""
Renvoie l'intervalle de prévision selon la valeur fournie en argument.
Parameters
----------
value : float
Valeur de précipitations
Returns
-------
interval : str
Intervalle de précipitations
Examples
--------
>>> from pyspc.data.meteofrance import BP_value_to_interval
>>> BP_value_to_interval(value=2)
Tr/3
>>> BP_value_to_interval(value=17)
10/20
>>> BP_value_to_interval(value=42)
30/50
>>> BP_value_to_interval(value=83)
70/100
"""
_exception.check_numeric(value)
if value < 0:
raise ValueError('Valeur négative')
if value == 0:
return "0"
if value < 3:
return "Tr/3"
if value < 5:
return "1/5"
if value < 9:
return "3/10"
if value < 14:
return "7/15"
if value < 19:
return "10/20"
if value < 27:
return "15/30"
if value < 36:
return "20/40"
if value < 45:
return "30/50"
if value < 58:
return "40/60"
if value < 75:
return "50/80"
if value < 100:
return "70/100"
if value < 125:
return "100/130"
if value < 150:
return "120/150"
if value < 200:
return "150/200"
if value < 250:
return "200/250"
if value < 300:
return "250/300"
if value < 400:
return "300/400"
if value < 500:
return "400/500"
if value >= 500:
return "500/"
raise ValueError('Valeur incorrecte')