Use pyhomogenize without any netCDF files; basics

Firstly, we want to use pyhomogenize’s basics class. We can create our own time axis and do not need any netCDF files to be read.

[1]:
import pyhomogenize as pyh

basics = pyh.basics()

Let’s see the default attributes containing a time format for converting strings into cftime.datetime object, a calendar used for this convertion and a frequncy string for creating a CFTimeIndex.

[2]:
basics.__dict__
[2]:
{'fmt': '%Y-%m-%dT%H:%M:%S', 'calendar': 'standard', 'frequency': 'D'}

We can change the default attributes by calling basics again.

[3]:
basics = pyh.basics(fmt="%Y%m%d", calendar="noleap")
basics.__dict__
[3]:
{'fmt': '%Y%m%d', 'calendar': 'noleap', 'frequency': 'D'}

Now, we convert a user-given string into a cftime.datetime object and vice versa. Here again we can specify the time format and the calendar. Note that the default values will not be overwritten after the conversion.

[4]:
date_start = basics.str_to_date("20210101")
date_start
[4]:
cftime.datetime(2021, 1, 1, 0, 0, 0, 0, calendar='noleap', has_year_zero=True)
[5]:
date_start = basics.str_to_date("2021-01-01", fmt="%Y-%m-%d", calendar="standard")
date_start
[5]:
cftime.datetime(2021, 1, 1, 0, 0, 0, 0, calendar='gregorian', has_year_zero=False)
[6]:
basics.__dict__
[6]:
{'fmt': '%Y%m%d', 'calendar': 'noleap', 'frequency': 'D'}

By default, cftime.datetime instance atributes that are not represented by fmt will be set to 0 as you can see in the above examples. It is possible to set the unmentioned instance attributes to the last possible value too. Instance attributes which frequency is higher than a second are still be ignored.

[7]:
date_end = basics.str_to_date("20211231", mode="end", calendar="standard")
date_end
[7]:
cftime.DatetimeGregorian(2021, 12, 31, 23, 59, 59, 0, has_year_zero=False)

Now, let’s do it vice versa. Here again, we can specify the string format

[8]:
str_start = basics.date_to_str(date_start, fmt="%Y-%m-%d")
str_end = basics.date_to_str(date_end, fmt="%Y-%m-%d")
str_start, str_end
[8]:
('2021-01-01', '2021-12-31')

Let’s build a CFTimeIndex with a monthly frequency. As left and right bounds we can use both str’s and cftime.datetime objects.

[9]:
date_range = basics.date_range(start=str_start, end=str_end, frequency="mon")
date_range
[9]:
CFTimeIndex([2021-01-16 12:00:00, 2021-02-15 00:00:00, 2021-03-16 12:00:00,
             2021-04-16 00:00:00, 2021-05-16 12:00:00, 2021-06-16 00:00:00,
             2021-07-16 12:00:00, 2021-08-16 12:00:00, 2021-09-16 00:00:00,
             2021-10-16 12:00:00, 2021-11-16 00:00:00, 2021-12-16 12:00:00],
            dtype='object', length=12, calendar='noleap', freq='None')
[10]:
date_range = basics.date_range(start=date_start, end=date_end, frequency="mon")
date_range
[10]:
CFTimeIndex([2021-01-16 12:00:00, 2021-02-15 00:00:00, 2021-03-16 12:00:00,
             2021-04-16 00:00:00, 2021-05-16 12:00:00, 2021-06-16 00:00:00,
             2021-07-16 12:00:00, 2021-08-16 12:00:00, 2021-09-16 00:00:00,
             2021-10-16 12:00:00, 2021-11-16 00:00:00, 2021-12-16 12:00:00],
            dtype='object', length=12, calendar='gregorian', freq='None')

Note, if frequency equals ‘mon’ the time steps are set to the middle of the month. To get the beginning or the end of the months use ‘MS’ os ‘M’.

[11]:
date_range_start = basics.date_range(start=date_start, end=date_end, frequency="MS")
date_range_start
[11]:
CFTimeIndex([2021-01-01 00:00:00, 2021-02-01 00:00:00, 2021-03-01 00:00:00,
             2021-04-01 00:00:00, 2021-05-01 00:00:00, 2021-06-01 00:00:00,
             2021-07-01 00:00:00, 2021-08-01 00:00:00, 2021-09-01 00:00:00,
             2021-10-01 00:00:00, 2021-11-01 00:00:00, 2021-12-01 00:00:00],
            dtype='object', length=12, calendar='gregorian', freq='MS')
[12]:
date_range_end = basics.date_range(start=date_start, end=date_end, frequency="M")
date_range_end
[12]:
CFTimeIndex([2021-01-31 00:00:00, 2021-02-28 00:00:00, 2021-03-31 00:00:00,
             2021-04-30 00:00:00, 2021-05-31 00:00:00, 2021-06-30 00:00:00,
             2021-07-31 00:00:00, 2021-08-31 00:00:00, 2021-09-30 00:00:00,
             2021-10-31 00:00:00, 2021-11-30 00:00:00, 2021-12-31 00:00:00],
            dtype='object', length=12, calendar='gregorian', freq='M')

Now, we can check whether the date_range’s values contain the first and the last day of the month.

[13]:
basics.is_month_start(date_range)
[13]:
[False,
 False,
 False,
 False,
 False,
 False,
 False,
 False,
 False,
 False,
 False,
 False]
[14]:
basics.is_month_end(date_range)
[14]:
[False,
 False,
 False,
 False,
 False,
 False,
 False,
 False,
 False,
 False,
 False,
 False]
[15]:
basics.is_month_start(date_range_start)
[15]:
[True, True, True, True, True, True, True, True, True, True, True, True]

The last basics method is to crop or limit a date_range to user-specified start and end month values. The new date_range should start with and with the a season.

[16]:
date_range_limit = basics.date_range_to_frequency_limits(
    date_range=date_range, smonth=[3, 6, 9, 12], emonth=[2, 5, 8, 11], get_range=True
)
date_range_limit
[16]:
CFTimeIndex([2021-03-16 12:00:00, 2021-04-16 00:00:00, 2021-05-16 12:00:00,
             2021-06-16 00:00:00, 2021-07-16 12:00:00, 2021-08-16 12:00:00,
             2021-09-16 00:00:00, 2021-10-16 12:00:00, 2021-11-16 00:00:00],
            dtype='object', length=9, calendar='gregorian', freq='None')

Instead of specifying a date_range you can specify a start and end date and a frequency

[17]:
date_range_limit = basics.date_range_to_frequency_limits(
    start=date_start,
    end=date_end,
    frequency="mon",
    smonth=[3, 6, 9, 12],
    emonth=[2, 5, 8, 11],
    get_range=True,
)
date_range_limit
[17]:
CFTimeIndex([2021-03-16 12:00:00, 2021-04-16 00:00:00, 2021-05-16 12:00:00,
             2021-06-16 00:00:00, 2021-07-16 12:00:00, 2021-08-16 12:00:00,
             2021-09-16 00:00:00, 2021-10-16 12:00:00, 2021-11-16 00:00:00],
            dtype='object', length=9, calendar='gregorian', freq='None')

To get only the left and right borders:

[18]:
left, right = basics.date_range_to_frequency_limits(
    start=date_start,
    end=date_end,
    frequency="mon",
    smonth=[3, 6, 9, 12],
    emonth=[2, 5, 8, 11],
)
left, right
[18]:
(cftime.DatetimeGregorian(2021, 3, 16, 12, 0, 0, 0, has_year_zero=False),
 cftime.DatetimeGregorian(2021, 11, 16, 0, 0, 0, 0, has_year_zero=False))