Skip to content

Commit

Permalink
feat(event): add support for Earth seasons (#24)
Browse files Browse the repository at this point in the history
* chore: fix files to commit on tag

* fix(ephemerides): fix a bug that made the ephemerides calculations impossible for the Poles (#21)

* chore: fix the target branch on Dependabot's config

* ci: remove Commitlint workflow (replaced by semantic-pull-request) (#25)

* ci: remove Commitlint workflow (replaced by semantic-pull-request)

* ci: fix doctests not running correctly on some OS and Python versions

* Add season change event in events.py and enum.py

* Add minor change in season change event

* Add documentation, change enum constants, change output object of _search_earth_season_change

* Minor changes to _search_earth_season_change

* Update EventType enum, update class of details

* Fix minor bugs

* docs: Update docs for _search_earth_season_change and _search_conjunction.chore: make minor changes to _search_earth_season_change

* Update: minor changes to match Python coding style.

* Update: minor changes to match Python coding style. Docs: update docstring of _search_earth_season_change and _search_conjunction

* test:update legacy tests for events.py. update: update enum.py and events.py to match black coding style.

* Fix some minor issues with Black and Event.details field

Co-authored-by: Jérôme Deuchnord <jerome@deuchnord.fr>
Co-authored-by: Jérôme Deuchnord <Deuchnord@users.noreply.github.com>

BREAKING CHANGE: the `Event.details` field is now a dictionary (was previously a string).
  • Loading branch information
LiamNgn authored and Jérôme Deuchnord committed Oct 26, 2021
1 parent be25dd4 commit ad96b8b
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 13 deletions.
10 changes: 9 additions & 1 deletion kosmorrolib/enum.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3

from enum import Enum, auto
from enum import Enum


class MoonPhaseType(Enum):
Expand All @@ -16,6 +16,13 @@ class MoonPhaseType(Enum):
WANING_CRESCENT = 8


class SeasonType(Enum):
MARCH_EQUINOX = 0
JUNE_SOLSTICE = 1
SEPTEMBER_EQUINOX = 2
DECEMBER_SOLSTICE = 3


class EventType(Enum):
"""An enumeration for the supported event types."""

Expand All @@ -25,6 +32,7 @@ class EventType(Enum):
MAXIMAL_ELONGATION = 4
MOON_PERIGEE = 5
MOON_APOGEE = 6
SEASON_CHANGE = 7


class ObjectType(Enum):
Expand Down
74 changes: 66 additions & 8 deletions kosmorrolib/events.py
Expand Up @@ -5,16 +5,34 @@
from skyfield.errors import EphemerisRangeError
from skyfield.timelib import Time
from skyfield.searchlib import find_discrete, find_maxima, find_minima
from skyfield import almanac
from numpy import pi

from .model import Event, Star, Planet, ASTERS
from .dateutil import translate_to_timezone
from .enum import EventType, ObjectIdentifier
from .exceptions import OutOfRangeDateError
from .core import get_timescale, get_skf_objects, flatten_list
from kosmorrolib.model import Event, Star, Planet, ASTERS
from kosmorrolib.dateutil import translate_to_timezone
from kosmorrolib.enum import EventType, ObjectIdentifier, SeasonType
from kosmorrolib.exceptions import OutOfRangeDateError
from kosmorrolib.core import get_timescale, get_skf_objects, flatten_list


def _search_conjunction(start_time: Time, end_time: Time, timezone: int) -> [Event]:
"""Function to search conjunction.
**Warning:** this is an internal function, not intended for use by end-developers.
Will return MOON and VENUS opposition on 2021-06-12:
>>> conjunction = _search_conjunction(get_timescale().utc(2021,6,12),get_timescale().utc(2021,6,13),0)
>>> len(conjunction)
1
>>> conjunction[0].objects
[<Object type=SATELLITE name=MOON />, <Object type=PLANET name=VENUS />]
Will return nothing if no conjunction happens:
>>> _search_conjunction(get_timescale().utc(2021,6,17),get_timescale().utc(2021,6,18),0)
[]
"""
earth = get_skf_objects()["earth"]
aster1 = None
aster2 = None
Expand Down Expand Up @@ -177,13 +195,13 @@ def get_elongation(time: Time):
)

for i, time in enumerate(times):
elongation = elongations[i]
elongation = round(elongations[i], 1)
events.append(
Event(
EventType.MAXIMAL_ELONGATION,
[aster],
translate_to_timezone(time.utc_datetime(), timezone),
details="{:.3n}°".format(elongation),
details={"deg": elongation},
)
)

Expand Down Expand Up @@ -245,6 +263,45 @@ def _search_moon_perigee(start_time: Time, end_time: Time, timezone: int) -> [Ev
return events


def _search_earth_season_change(
start_time: Time, end_time: Time, timezone: int
) -> [Event]:
"""Function to find earth season change event.
**Warning:** this is an internal function, not intended for use by end-developers.
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>}
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_timezone(event_time.utc_datetime()[0], timezone),
details={"season": SeasonType(event_id[0])},
)
)
return events


def get_events(for_date: date = date.today(), timezone: int = 0) -> [Event]:
"""Calculate and return a list of events for the given date, adjusted to the given timezone if any.
Expand All @@ -265,7 +322,7 @@ def get_events(for_date: date = date.today(), timezone: int = 0) -> [Event]:
If there is no events for the given date, then an empty list is returned:
>>> get_events(date(2021, 3, 20))
>>> get_events(date(2021, 4, 20))
[]
:param for_date: the date for which the events must be calculated
Expand All @@ -289,6 +346,7 @@ def get_events(for_date: date = date.today(), timezone: int = 0) -> [Event]:
_search_maximal_elongations,
_search_moon_apogee,
_search_moon_perigee,
_search_earth_season_change,
]:
found_events.append(fun(start_time, end_time, timezone))

Expand Down
2 changes: 1 addition & 1 deletion kosmorrolib/model.py
Expand Up @@ -154,7 +154,7 @@ def __init__(
objects: [Object],
start_time: datetime,
end_time: Union[datetime, None] = None,
details: str = None,
details: {str: any} = None,
):
self.event_type = event_type
self.objects = objects
Expand Down
6 changes: 3 additions & 3 deletions tests/events.py
Expand Up @@ -74,7 +74,7 @@
EventType.MAXIMAL_ELONGATION,
[ASTERS[2]],
datetime(2020, 2, 10, 13, 46),
details="18.2°",
details={"deg": 18.2},
),
Event(EventType.MOON_PERIGEE, [ASTERS[1]], datetime(2020, 2, 10, 20, 34)),
],
Expand All @@ -86,14 +86,14 @@
EventType.MAXIMAL_ELONGATION,
[ASTERS[2]],
datetime(2020, 3, 24, 1, 56),
details="27.8°",
details={"deg": 27.8},
),
Event(EventType.MOON_APOGEE, [ASTERS[1]], datetime(2020, 3, 24, 15, 39)),
Event(
EventType.MAXIMAL_ELONGATION,
[ASTERS[3]],
datetime(2020, 3, 24, 21, 58),
details="46.1°",
details={"deg": 46.1},
),
],
),
Expand Down

0 comments on commit ad96b8b

Please sign in to comment.