Skip to content

Replaced append(Period) with add_interval(kwargs) #138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Nov 29, 2022
6 changes: 6 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
version: 2

build:
os: ubuntu-20.04
tools:
python: "3.9"

python:
install:
- method: pip
Expand Down
118 changes: 49 additions & 69 deletions notebooks/tutorial_alternative_calendars.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Create target periods and precursor periods as building blocks."
"Add target and precursor interval \"building blocks\" one by one to the calendar."
]
},
{
Expand All @@ -388,34 +388,14 @@
"metadata": {},
"outputs": [],
"source": [
"# create target periods\n",
"target_1 = s2spy.time.TargetPeriod(\"20d\")\n",
"target_2 = s2spy.time.TargetPeriod(\"20d\", \"10d\")\n",
"# create precursor periods\n",
"precursor_1 = s2spy.time.PrecursorPeriod(\"10d\", \"10d\")\n",
"precursor_2 = s2spy.time.PrecursorPeriod(\"10d\", \"-5d\")\n",
"precursor_3 = s2spy.time.PrecursorPeriod(\"10d\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Append building blocks to form calendar."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"# append building blocks to calendar object\n",
"calendar.append(target_1)\n",
"calendar.append(target_2)\n",
"calendar.append(precursor_1)\n",
"calendar.append(precursor_2)\n",
"calendar.append(precursor_3)"
"# add target periods\n",
"calendar.add_interval(\"target\", length=\"20d\")\n",
"calendar.add_interval(\"target\", length=\"20d\", gap=\"10d\") # You can add gaps between intervals\n",
"\n",
"# add precursor periods\n",
"calendar.add_interval(\"precursor\", \"10d\", \"-5d\") # The gap can be negative, leading to overlap\n",
"calendar.add_interval(\"precursor\", \"2W\") # Lengths can also be weeks, or months\n",
"calendar.add_interval(\"precursor\", \"1M\")"
]
},
{
Expand All @@ -427,7 +407,7 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 8,
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -469,25 +449,25 @@
" <tbody>\n",
" <tr>\n",
" <th>2022</th>\n",
" <td>[2022-11-26, 2022-12-06)</td>\n",
" <td>[2022-12-06, 2022-12-16)</td>\n",
" <td>[2022-12-11, 2022-12-21)</td>\n",
" <td>[2022-11-12, 2022-12-12)</td>\n",
" <td>[2022-12-12, 2022-12-26)</td>\n",
" <td>[2022-12-26, 2023-01-05)</td>\n",
" <td>[2022-12-31, 2023-01-20)</td>\n",
" <td>[2023-01-30, 2023-02-19)</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2021</th>\n",
" <td>[2021-11-26, 2021-12-06)</td>\n",
" <td>[2021-12-06, 2021-12-16)</td>\n",
" <td>[2021-12-11, 2021-12-21)</td>\n",
" <td>[2021-11-12, 2021-12-12)</td>\n",
" <td>[2021-12-12, 2021-12-26)</td>\n",
" <td>[2021-12-26, 2022-01-05)</td>\n",
" <td>[2021-12-31, 2022-01-20)</td>\n",
" <td>[2022-01-30, 2022-02-19)</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2020</th>\n",
" <td>[2020-11-26, 2020-12-06)</td>\n",
" <td>[2020-12-06, 2020-12-16)</td>\n",
" <td>[2020-12-11, 2020-12-21)</td>\n",
" <td>[2020-11-12, 2020-12-12)</td>\n",
" <td>[2020-12-12, 2020-12-26)</td>\n",
" <td>[2020-12-26, 2021-01-05)</td>\n",
" <td>[2020-12-31, 2021-01-20)</td>\n",
" <td>[2021-01-30, 2021-02-19)</td>\n",
" </tr>\n",
Expand All @@ -498,15 +478,15 @@
"text/plain": [
"i_interval -3 -2 \\\n",
"anchor_year \n",
"2022 [2022-11-26, 2022-12-06) [2022-12-06, 2022-12-16) \n",
"2021 [2021-11-26, 2021-12-06) [2021-12-06, 2021-12-16) \n",
"2020 [2020-11-26, 2020-12-06) [2020-12-06, 2020-12-16) \n",
"2022 [2022-11-12, 2022-12-12) [2022-12-12, 2022-12-26) \n",
"2021 [2021-11-12, 2021-12-12) [2021-12-12, 2021-12-26) \n",
"2020 [2020-11-12, 2020-12-12) [2020-12-12, 2020-12-26) \n",
"\n",
"i_interval -1 1 \\\n",
"anchor_year \n",
"2022 [2022-12-11, 2022-12-21) [2022-12-31, 2023-01-20) \n",
"2021 [2021-12-11, 2021-12-21) [2021-12-31, 2022-01-20) \n",
"2020 [2020-12-11, 2020-12-21) [2020-12-31, 2021-01-20) \n",
"2022 [2022-12-26, 2023-01-05) [2022-12-31, 2023-01-20) \n",
"2021 [2021-12-26, 2022-01-05) [2021-12-31, 2022-01-20) \n",
"2020 [2020-12-26, 2021-01-05) [2020-12-31, 2021-01-20) \n",
"\n",
"i_interval 2 \n",
"anchor_year \n",
Expand All @@ -515,7 +495,7 @@
"2020 [2021-01-30, 2021-02-19) "
]
},
"execution_count": 9,
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -536,7 +516,7 @@
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": 9,
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -565,7 +545,7 @@
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": 10,
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -607,33 +587,33 @@
" <tbody>\n",
" <tr>\n",
" <th>2020</th>\n",
" <td>[2020-11-26, 2020-12-06)</td>\n",
" <td>[2020-12-06, 2020-12-16)</td>\n",
" <td>[2020-12-11, 2020-12-21)</td>\n",
" <td>[2020-11-12, 2020-12-12)</td>\n",
" <td>[2020-12-12, 2020-12-26)</td>\n",
" <td>[2020-12-26, 2021-01-05)</td>\n",
" <td>[2020-12-31, 2021-01-20)</td>\n",
" <td>[2021-01-30, 2021-02-19)</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2019</th>\n",
" <td>[2019-11-26, 2019-12-06)</td>\n",
" <td>[2019-12-06, 2019-12-16)</td>\n",
" <td>[2019-12-11, 2019-12-21)</td>\n",
" <td>[2019-11-12, 2019-12-12)</td>\n",
" <td>[2019-12-12, 2019-12-26)</td>\n",
" <td>[2019-12-26, 2020-01-05)</td>\n",
" <td>[2019-12-31, 2020-01-20)</td>\n",
" <td>[2020-01-30, 2020-02-19)</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2018</th>\n",
" <td>[2018-11-26, 2018-12-06)</td>\n",
" <td>[2018-12-06, 2018-12-16)</td>\n",
" <td>[2018-12-11, 2018-12-21)</td>\n",
" <td>[2018-11-12, 2018-12-12)</td>\n",
" <td>[2018-12-12, 2018-12-26)</td>\n",
" <td>[2018-12-26, 2019-01-05)</td>\n",
" <td>[2018-12-31, 2019-01-20)</td>\n",
" <td>[2019-01-30, 2019-02-19)</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017</th>\n",
" <td>[2017-11-26, 2017-12-06)</td>\n",
" <td>[2017-12-06, 2017-12-16)</td>\n",
" <td>[2017-12-11, 2017-12-21)</td>\n",
" <td>[2017-11-12, 2017-12-12)</td>\n",
" <td>[2017-12-12, 2017-12-26)</td>\n",
" <td>[2017-12-26, 2018-01-05)</td>\n",
" <td>[2017-12-31, 2018-01-20)</td>\n",
" <td>[2018-01-30, 2018-02-19)</td>\n",
" </tr>\n",
Expand All @@ -644,17 +624,17 @@
"text/plain": [
"i_interval -3 -2 \\\n",
"anchor_year \n",
"2020 [2020-11-26, 2020-12-06) [2020-12-06, 2020-12-16) \n",
"2019 [2019-11-26, 2019-12-06) [2019-12-06, 2019-12-16) \n",
"2018 [2018-11-26, 2018-12-06) [2018-12-06, 2018-12-16) \n",
"2017 [2017-11-26, 2017-12-06) [2017-12-06, 2017-12-16) \n",
"2020 [2020-11-12, 2020-12-12) [2020-12-12, 2020-12-26) \n",
"2019 [2019-11-12, 2019-12-12) [2019-12-12, 2019-12-26) \n",
"2018 [2018-11-12, 2018-12-12) [2018-12-12, 2018-12-26) \n",
"2017 [2017-11-12, 2017-12-12) [2017-12-12, 2017-12-26) \n",
"\n",
"i_interval -1 1 \\\n",
"anchor_year \n",
"2020 [2020-12-11, 2020-12-21) [2020-12-31, 2021-01-20) \n",
"2019 [2019-12-11, 2019-12-21) [2019-12-31, 2020-01-20) \n",
"2018 [2018-12-11, 2018-12-21) [2018-12-31, 2019-01-20) \n",
"2017 [2017-12-11, 2017-12-21) [2017-12-31, 2018-01-20) \n",
"2020 [2020-12-26, 2021-01-05) [2020-12-31, 2021-01-20) \n",
"2019 [2019-12-26, 2020-01-05) [2019-12-31, 2020-01-20) \n",
"2018 [2018-12-26, 2019-01-05) [2018-12-31, 2019-01-20) \n",
"2017 [2017-12-26, 2018-01-05) [2017-12-31, 2018-01-20) \n",
"\n",
"i_interval 2 \n",
"anchor_year \n",
Expand All @@ -664,7 +644,7 @@
"2017 [2018-01-30, 2018-02-19) "
]
},
"execution_count": 11,
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
Expand Down
41 changes: 24 additions & 17 deletions s2spy/_base_calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from abc import abstractmethod
from typing import Tuple
from typing import Union
import numpy as np
import pandas as pd
import xarray as xr
from pandas.tseries.offsets import DateOffset
Expand All @@ -31,14 +30,12 @@ class BaseCalendar(ABC):
@abstractmethod
def __init__(
self,
anchor,
):
anchor: str,
) -> None:
"""For initializing calendars, the following five variables will be required."""
self._anchor, self._anchor_fmt = self._parse_anchor(anchor)
self._targets: list[TargetPeriod] = []
self._precursors: list[PrecursorPeriod] = []
self._total_length_target = 0
self._total_length_precursor = 0

self.n_targets = 0
self._max_lag: int = 0
Expand Down Expand Up @@ -101,17 +98,8 @@ def _append(self, period_block):
# pylint: disable=protected-access
if period_block._target:
self._targets.append(period_block)
# count length
self._total_length_target += (
period_block.length.kwds["days"] + period_block.gap.kwds["days"]
)

else:
self._precursors.append(period_block)
# count length
self._total_length_precursor += (
period_block.length.kwds["days"] + period_block.gap.kwds["days"]
)

def _map_year(self, year: int) -> pd.Series:
"""Internal routine to return a concrete IntervalIndex for the given year.
Expand Down Expand Up @@ -175,9 +163,28 @@ def _get_skip_nyears(self) -> int:
Returns:
int: Number of years that need to be skipped.
"""
years = (self._total_length_target + self._total_length_precursor) / 365

return 0 if self._allow_overlap else int(np.ceil(years).astype(int) - 1)
if self._allow_overlap:
return 0

proto_year = 2000
skip_years = 0

start_calendar = self._get_anchor(proto_year)
for prec in self._precursors:
start_calendar -= prec.gap
start_calendar -= prec.length

while True:
prev_end_calendar = self._get_anchor(proto_year - 1 - skip_years)
for target in self._targets:
prev_end_calendar += target.gap
prev_end_calendar += target.length
if prev_end_calendar > start_calendar:
skip_years += 1
else:
break
Comment on lines +177 to +185
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very smart design 😎 🆒.


return skip_years

def set_max_lag(self, max_lag: int, allow_overlap: bool = False) -> None:
"""Set the maximum lag of a calendar.
Expand Down
Loading