Interpolates a DataArray or Dataset indexed by a time coordinate to another calendar based on decimal year measure. Each timestamp in `source` and `target` are first converted to their decimal year equivalent then `source` is interpolated on the target coordinate. The decimal year o
(source, target, dim="time")
| 347 | |
| 348 | |
| 349 | def interp_calendar(source, target, dim="time"): |
| 350 | """Interpolates a DataArray or Dataset indexed by a time coordinate to |
| 351 | another calendar based on decimal year measure. |
| 352 | |
| 353 | Each timestamp in `source` and `target` are first converted to their decimal |
| 354 | year equivalent then `source` is interpolated on the target coordinate. |
| 355 | The decimal year of a timestamp is its year plus its sub-year component |
| 356 | converted to the fraction of its year. For example "2000-03-01 12:00" is |
| 357 | 2000.1653 in a standard calendar or 2000.16301 in a `"noleap"` calendar. |
| 358 | |
| 359 | This method should only be used when the time (HH:MM:SS) information of |
| 360 | time coordinate is not important. |
| 361 | |
| 362 | Parameters |
| 363 | ---------- |
| 364 | source: DataArray or Dataset |
| 365 | The source data to interpolate; must have a time coordinate of a valid |
| 366 | dtype (:py:class:`numpy.datetime64` or :py:class:`cftime.datetime` objects) |
| 367 | target: DataArray, DatetimeIndex, or CFTimeIndex |
| 368 | The target time coordinate of a valid dtype (np.datetime64 or cftime objects) |
| 369 | dim : str |
| 370 | The time coordinate name. |
| 371 | |
| 372 | Return |
| 373 | ------ |
| 374 | DataArray or Dataset |
| 375 | The source interpolated on the decimal years of target, |
| 376 | """ |
| 377 | from xarray.core.dataarray import DataArray |
| 378 | |
| 379 | if isinstance(target, pd.DatetimeIndex | CFTimeIndex): |
| 380 | target = DataArray(target, dims=(dim,), name=dim) |
| 381 | |
| 382 | if not _contains_datetime_like_objects( |
| 383 | source[dim].variable |
| 384 | ) or not _contains_datetime_like_objects(target.variable): |
| 385 | raise ValueError( |
| 386 | f"Both 'source.{dim}' and 'target' must contain datetime objects." |
| 387 | ) |
| 388 | |
| 389 | target_calendar = target.dt.calendar |
| 390 | if ( |
| 391 | source[dim].time.dt.year == 0 |
| 392 | ).any() and target_calendar in _CALENDARS_WITHOUT_YEAR_ZERO: |
| 393 | raise ValueError( |
| 394 | f"Source time coordinate contains dates with year 0, which is not supported by target calendar {target_calendar}." |
| 395 | ) |
| 396 | |
| 397 | out = source.copy() |
| 398 | out[dim] = _decimal_year(source[dim]) |
| 399 | target_idx = _decimal_year(target) |
| 400 | out = out.interp(**{dim: target_idx}) |
| 401 | out[dim] = target |
| 402 | return out |
searching dependent graphs…