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))