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