Source code for pymepps.loader.filehandler.filehandler

#!/bin/env python
# -*- coding: utf-8 -*-
# """
# Created on 16.11.16
#
# Created for pymepps
#
# @author: Tobias Sebastian Finn, tobias.sebastian.finn@studium.uni-hamburg.de
#
#     Copyright (C) {2016}  {Tobias Sebastian Finn}
#
#     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.  If not, see <http://www.gnu.org/licenses/>.
# """
# System modules
import abc
import os
import dateutil.parser
import pytz
import logging
import datetime
import collections

# External modules
import xarray as xr

# Internal modules


logger = logging.getLogger(__name__)


[docs]class FileHandler(object): def __init__(self, file_path): """ Base class for files with meteorological content. A FileHandler could extract the variables and metadata out of the files and could compress this data into one structure. Parameters ---------- file_path : str The path to the file, which should be opened. """ self.ds = None self.file = file_path self._var_names = None @property def var_names(self): if self._var_names is None: self._var_names = self._get_varnames() return self._var_names
[docs] @abc.abstractmethod def get_messages(self, var_name, **kwargs): pass
[docs] @abc.abstractmethod def get_timeseries(self, var_name, **kwargs): pass
@abc.abstractmethod def _get_varnames(self): pass def _get_metadata(self): pass @staticmethod def _check_list_in_list(sublist, check_list): in_list = False for ele in check_list: if [sub for sub in sublist if sub in ele]: in_list = True return in_list def _get_runtime(self, **kwargs): if 'runtime' in kwargs: ana = kwargs['runtime'] else: try: ana = self._get_dates_from_path(self.file)[0] except IndexError: ana = None return ana def _get_validtime(self, **kwargs): if 'validtime' in kwargs: time = kwargs['validtime'] else: try: time = self._get_dates_from_path(self.file)[1] except IndexError: time = None return time def _get_ensemble(self, **kwargs): if 'ensemble' in kwargs: ens = kwargs['ensemble'] else: ens = self._get_ensemble_from_path(self.file) return ens def _get_missing_coordinates(self, cube, grid_len=2, **kwargs): additional_coords = collections.OrderedDict() if not self._check_list_in_list( ['ana', 'runtime', 'referencetime'], list(cube.dims[:-grid_len])): additional_coords['runtime'] = self._get_runtime(**kwargs) if not self._check_list_in_list( ['ens', 'mem'], list(cube.dims[:-grid_len])): additional_coords['ensemble'] = self._get_ensemble(**kwargs) if not self._check_list_in_list( ['time', 'validtime'], list(cube.dims[:-2])): additional_coords['validtime'] = self._get_validtime( additional_coords, **kwargs) ds_coords = xr.Dataset(coords=additional_coords) cube.coords.update(ds_coords) cube = cube.expand_dims(list(additional_coords.keys())) return cube @staticmethod def _get_path_parts(path): base_path = os.path.normpath(path) base_path = os.path.splitext(base_path)[0] parts = base_path.split(os.sep) return parts def _get_ensemble_from_path(self, path): ens_member = None path_parts = self._get_path_parts(path) for part in reversed(path_parts): if part[:3]=='ens': ens_member = int(part[3:]) elif part=='det': ens_member = 0 if ens_member is None: ext = os.path.splitext(path)[1] try: ens_member = int(ext) except ValueError: ens_member = 0 return ens_member def _get_dates_from_path(self, path): dates = [] path_parts = self._get_path_parts(path) for part in path_parts: if len(part)>5: try: date = dateutil.parser.parse(part, ignoretz=True) date.replace(tzinfo=pytz.UTC) except ValueError: date = None if date is None: try: date = datetime.datetime.strptime(part, '%Y%m%d_%H%M') except ValueError: date = -9999 if date != -9999: dates.append(date) return dates