Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions kosmorrolib/enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,61 @@ class SeasonType(Enum):
SEPTEMBER_EQUINOX = 2
DECEMBER_SOLSTICE = 3

def localize(self, position: Position) -> LocalizedSeasonType:
"""Return the local season that corresponds to the given position's latitude.

Args:
season (SeasonType): The season to localize.
position (Position): The position to localize the season for.

Returns:
SeasonType: The localized season.

Raises:
ValueError: If the latitude is 0 (equator).

)

>>> from kosmorrolib import Position
>>> SeasonType.MARCH_EQUINOX.localize(Position(0, 1))
Traceback (most recent call last):
...
ValueError: Cannot localize seasons for this latitude.

>>> SeasonType.MARCH_EQUINOX.localize(Position(1, 1))
<LocalizedSeasonType.SPRING: 1>

>>> SeasonType.MARCH_EQUINOX.localize(Position(-1, 1))
<LocalizedSeasonType.AUTUMN: 3>
"""
if position.latitude == 0: # Equator
raise ValueError("Cannot localize seasons for this latitude.")

if position.latitude < 0: # Southern hemisphere
seasons = {
self.MARCH_EQUINOX: LocalizedSeasonType.AUTUMN,
self.JUNE_SOLSTICE: LocalizedSeasonType.WINTER,
self.SEPTEMBER_EQUINOX: LocalizedSeasonType.SPRING,
self.DECEMBER_SOLSTICE: LocalizedSeasonType.SUMMER,
}

else: # Nothern hemisphere
seasons = {
self.MARCH_EQUINOX: LocalizedSeasonType.SPRING,
self.JUNE_SOLSTICE: LocalizedSeasonType.SUMMER,
self.SEPTEMBER_EQUINOX: LocalizedSeasonType.AUTUMN,
self.DECEMBER_SOLSTICE: LocalizedSeasonType.WINTER,
}

return seasons[self]


class LocalizedSeasonType(Enum):
WINTER = 0
SPRING = 1
SUMMER = 2
AUTUMN = 3


class EventType(Enum):
"""An enumeration for the supported event types."""
Expand Down
85 changes: 49 additions & 36 deletions kosmorrolib/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from kosmorrolib.model import (
Event,
Object,
Position,
Star,
Planet,
get_aster,
Expand Down Expand Up @@ -360,43 +361,50 @@ def f(start_time: Time, end_time: Time, utc_offset: Union[int, float]) -> [Event
return f


def _search_earth_season_change(
start_time: Time, end_time: Time, utc_offset: Union[int, float]
) -> [Event]:
"""Function to find earth season change event.
def _search_earth_season_change(position: Position | None):
def f(start_time: Time, end_time: Time, utc_offset: int) -> [Event]:
"""Function to find earth season change event.

**Warning:** this is an internal function, not intended for use by end-developers.
**Warning:** this is an internal function, not intended for use by end-developers.

Will return JUNE SOLSTICE on 2020/06/20:
Will return JUNE SOLSTICE on 2020/06/20:

>>> season_change = _search_earth_season_change(get_timescale().utc(2020, 6, 20), get_timescale().utc(2020, 6, 21), 0)
>>> len(season_change)
1
>>> season_change[0].event_type
<EventType.SEASON_CHANGE: 7>
>>> season_change[0].details
{'season': <SeasonType.JUNE_SOLSTICE: 1>}
>>> season_change = _search_earth_season_change(get_timescale().utc(2020, 6, 20), get_timescale().utc(2020, 6, 21), 0)
>>> len(season_change)
1
>>> season_change[0].event_type
<EventType.SEASON_CHANGE: 7>
>>> season_change[0].details
{'season': <SeasonType.JUNE_SOLSTICE: 1>}

Will return nothing if there is no season change event in the period of time being calculated:
Will return nothing if there is no season change event in the period of time being calculated:

>>> _search_earth_season_change(get_timescale().utc(2021, 6, 17), get_timescale().utc(2021, 6, 18), 0)
[]
"""
events = []
event_time, event_id = almanac.find_discrete(
start_time, end_time, almanac.seasons(get_skf_objects())
)
if len(event_time) == 0:
return []
events.append(
Event(
EventType.SEASON_CHANGE,
[],
translate_to_utc_offset(event_time.utc_datetime()[0], utc_offset),
details={"season": SeasonType(event_id[0])},
>>> _search_earth_season_change(get_timescale().utc(2021, 6, 17), get_timescale().utc(2021, 6, 18), 0)
[]
"""
events = []
event_time, event_id = almanac.find_discrete(
start_time, end_time, almanac.seasons(get_skf_objects())
)
)
return events
if len(event_time) == 0:
return []

season = SeasonType(event_id[0])

if position is not None:
season = season.localize(position)

events.append(
Event(
EventType.SEASON_CHANGE,
[],
translate_to_timezone(event_time.utc_datetime()[0], timezone),
details={"season": season},
)
)
return events

return f


def _search_lunar_eclipse(
Expand Down Expand Up @@ -476,9 +484,12 @@ def is_in_penumbra(time: Time):


def get_events(
for_date: date = date.today(), utc_offset: Union[int, float] = 0, **argv
for_date: date = date.today(),
utc_offset: Union[int, float] = 0,
position: Position | None = None,
**argv
) -> [Event]:
"""Calculate and return a list of events for the given date, adjusted to the given UTC offset if any.
"""Calculate and return a list of events for the given date, adjusted to the given timezone if any.

Find events that happen on April 4th, 2020 (show hours in UTC):

Expand Down Expand Up @@ -514,7 +525,8 @@ def get_events(
kosmorrolib.exceptions.OutOfRangeDateError: The date must be between 1899-07-28 and 2053-10-08

:param for_date: the date for which the events must be calculated
:param utc_offset: the UTC offset to adapt the results to. If not given, defaults to 0.
:param utc_offset: the timezone to adapt the results to. If not given, defaults to 0.
:param position: the position to localize the events to.
:return: a list of events found for the given date.
"""

Expand Down Expand Up @@ -542,7 +554,7 @@ def get_events(
_search_perigee(ASTERS[1]),
_search_apogee(EARTH, from_aster=ASTERS[0]),
_search_perigee(EARTH, from_aster=ASTERS[0]),
_search_earth_season_change,
_search_earth_season_change(position),
_search_lunar_eclipse,
]:
found_events.append(fun(start_time, end_time, utc_offset))
Expand All @@ -565,6 +577,7 @@ def search_events(
end: date,
start: date = date.today(),
utc_offset: Union[int, float] = 0,
position: Position | None = None,
) -> [Event]:
"""Search between `start` and `end` dates, and return a list of matching events for the given time range, adjusted to a given UTC offset.

Expand Down Expand Up @@ -645,7 +658,7 @@ def _search_all_perigee_events(
EventType.MAXIMAL_ELONGATION: _search_maximal_elongations,
EventType.APOGEE: _search_all_apogee_events,
EventType.PERIGEE: _search_all_perigee_events,
EventType.SEASON_CHANGE: _search_earth_season_change,
EventType.SEASON_CHANGE: _search_earth_season_change(position),
EventType.LUNAR_ECLIPSE: _search_lunar_eclipse,
}

Expand Down
2 changes: 1 addition & 1 deletion tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
failures = 0
tests = 0

for module in [events, ephemerides, model]:
for module in [events, ephemerides, model, enum]:
(f, t) = testmod(module, optionflags=NORMALIZE_WHITESPACE)
failures += f
tests += t
Expand Down
Loading