#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Apr 19 14:22:34 2018

@author: jonasg
"""

from pyaerocom.helpers import cftime_to_datetime64
from pyaerocom.io.testfiles import get
from pyaerocom import GriddedData

if __name__ == "__main__":
    times = GriddedData(get()["models"]["ecmwf_osuite"],
                        var_name="od550aer").time

    for k in range(1000):
        ts = cftime_to_datetime64(times.points, times.units)
Example #2
0
def check_time_coord(cube, ts_type, year):
    """Method that checks the time coordinate of an iris Cube
    
    This method checks if the time dimension of a cube is accessible and 
    according to the standard (i.e. fully usable). It only checks, and does not
    correct. For the latter, please see :func:`correct_time_coord`.
    
    Parameters
    ----------
    cube : Cube
        cube containing data
    ts_type : str
        temporal resolution of data (e.g. "hourly", "daily"). This information
        is e.g. encrypted in the filename of a NetCDF file and may be 
        accessed using :class:`pyaerocom.io.FileConventionRead`
    year : int
        interger specifying year of observation, e.g. 2017
    
    Returns
    -------
    bool
        True, if time dimension is ok, False if not
    """
    
    ok = True
    test_idx = [0,1,2,7] #7, since last accessible index in a 3hourly dataset of one day is 7
    try:
        try:
            t = cube.coord("time")
        except:
            raise AttributeError("Cube does not contain time dimension")
        if not isinstance(t, iris.coords.DimCoord):
            raise AttributeError("Time is not a DimCoord instance")
        try:
            cftime_to_datetime64(0, cfunit=t.units)
        except:
            raise ValueError("Could not convert time unit string")
        tres_np = TSTR_TO_NP_TD[ts_type]
        conv = TSTR_TO_NP_DT[ts_type]
        base = datetime64("%s-01-01 00:00:00" %year).astype(conv)
        test_datenums = asarray(test_idx)
        ts_nominal = base + test_datenums.astype(tres_np)
        dts_nominal = ts_nominal[1:] - ts_nominal[:-1]
        ts_values = cftime_to_datetime64(t[test_idx].points, cfunit=t.units).astype(conv)
        dts_values = ts_values[1:] - ts_values[:-1]
        if not all(ts_values == ts_nominal):
            raise ValueError("Time match error, nominal dates for test array"
                             "%s (unit=%s): %s\nReceived values after "
                             "conversion: %s"
                             %(test_datenums, t.units.origin,
                               ts_nominal, ts_values))
        elif not all(dts_values == dts_nominal):
            raise ValueError("Time match error, time steps for test array"
                             "%s (unit=%s): %s\nReceived values after "
                             "conversion: %s"
                             %(test_datenums, t.units.origin,
                               dts_nominal, dts_values))
    except Exception as e:
        logger.warning("Invalid time dimension.\n"
                       "Error message: {}".format(repr(e)))
        ok = False
    return ok
Example #3
0
def check_time_coord(cube, ts_type, year):
    """Method that checks the time coordinate of an iris Cube
    
    This method checks if the time dimension of a cube is accessible and 
    according to the standard (i.e. fully usable). It only checks, and does not
    correct. For the latter, please see :func:`correct_time_coord`.
    
    Parameters
    ----------
    cube : Cube
        cube containing data
    ts_type : str
        pyaerocom ts_type
    year : 
        year of data
    
    Returns
    -------
    bool
        True, if time dimension is ok, False if not
    """
    try:
        t = cube.coord("time")
    except:
        raise AttributeError("Cube does not contain time dimension")
    if not isinstance(t, iris.coords.DimCoord):
        raise AttributeError("Time is not a DimCoord instance")
    try:
        cftime_to_datetime64(0, cfunit=t.units)
    except:
        raise ValueError("Could not convert time unit string")

    tidx = make_datetimeindex(ts_type, year)

    num_per = len(tidx)
    num = len(t.points)

    if not num == num_per:
        if tidx[0].is_leap_year:
            if not _check_leap_year(num, num_per, ts_type):
                raise UnresolvableTimeDefinitionError(
                    'Expected {} timestamps but '
                    'data has {}'.format(len(tidx), num))
        else:
            raise UnresolvableTimeDefinitionError('Expected {} timestamps but '
                                                  'data has {}'.format(
                                                      len(tidx), num))

    pstr = TS_TYPE_TO_PANDAS_FREQ[ts_type]
    # ToDo: check why MS is not working for period conversion
    if pstr == 'MS':
        pstr = 'M'
    # convert first and last timestamps of index array into periods
    # (e.g. January and December for monthly data)
    per0 = tidx[0].to_period(pstr)
    per1 = tidx[-1].to_period(pstr)

    # first and last timestamp in data
    t0, t1 = cftime_to_datetime64([t.points[0], t.points[-1]], cfunit=t.units)

    if not per0.start_time <= t0 <= per0.end_time:
        raise ValueError('First timestamp of data {} does not lie in first '
                         'period: {}'.format(t0, per0))
    elif not per1.start_time <= t1 <= per1.end_time:
        raise ValueError('Last timestamp of data {} does not lie in last '
                         'period: {}'.format(t1, per1))