Code source de pyspc.data.meteofrance.bp

#!/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')