|
@@ -1,6 +1,6 @@ |
|
|
#!/usr/bin/env python3 |
|
|
#!/usr/bin/env python3 |
|
|
|
|
|
|
|
|
from datetime import date as date_type |
|
|
|
|
|
|
|
|
from datetime import date |
|
|
|
|
|
|
|
|
from skyfield.errors import EphemerisRangeError |
|
|
from skyfield.errors import EphemerisRangeError |
|
|
from skyfield.timelib import Time |
|
|
from skyfield.timelib import Time |
|
@@ -9,7 +9,7 @@ from numpy import pi |
|
|
|
|
|
|
|
|
from .model import Event, Star, Planet, ASTERS |
|
|
from .model import Event, Star, Planet, ASTERS |
|
|
from .dateutil import translate_to_timezone |
|
|
from .dateutil import translate_to_timezone |
|
|
from .enum import EventType |
|
|
|
|
|
|
|
|
from .enum import EventType, ObjectIdentifier |
|
|
from .exceptions import OutOfRangeDateError |
|
|
from .exceptions import OutOfRangeDateError |
|
|
from .core import get_timescale, get_skf_objects, flatten_list |
|
|
from .core import get_timescale, get_skf_objects, flatten_list |
|
|
|
|
|
|
|
@@ -85,29 +85,61 @@ def _search_conjunction(start_time: Time, end_time: Time, timezone: int) -> [Eve |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _search_oppositions(start_time: Time, end_time: Time, timezone: int) -> [Event]: |
|
|
def _search_oppositions(start_time: Time, end_time: Time, timezone: int) -> [Event]: |
|
|
|
|
|
"""Function to search oppositions. |
|
|
|
|
|
|
|
|
|
|
|
**Warning:** this is an internal function, not intended for use by end-developers. |
|
|
|
|
|
|
|
|
|
|
|
Will return Mars opposition on 2020-10-13: |
|
|
|
|
|
|
|
|
|
|
|
>>> oppositions = _search_oppositions(get_timescale().utc(2020, 10, 13), get_timescale().utc(2020, 10, 14), 0) |
|
|
|
|
|
>>> len(oppositions) |
|
|
|
|
|
1 |
|
|
|
|
|
>>> oppositions[0].objects[0] |
|
|
|
|
|
<Object type=PLANET name=MARS /> |
|
|
|
|
|
|
|
|
|
|
|
Will return nothing if no opposition happens: |
|
|
|
|
|
|
|
|
|
|
|
>>> _search_oppositions(get_timescale().utc(2021, 3, 20), get_timescale().utc(2021, 3, 21), 0) |
|
|
|
|
|
[] |
|
|
|
|
|
""" |
|
|
earth = get_skf_objects()["earth"] |
|
|
earth = get_skf_objects()["earth"] |
|
|
sun = get_skf_objects()["sun"] |
|
|
sun = get_skf_objects()["sun"] |
|
|
aster = None |
|
|
aster = None |
|
|
|
|
|
|
|
|
def is_oppositing(time: Time) -> [bool]: |
|
|
def is_oppositing(time: Time) -> [bool]: |
|
|
|
|
|
diff = get_angle(time) |
|
|
|
|
|
return diff > 180 |
|
|
|
|
|
|
|
|
|
|
|
def get_angle(time: Time): |
|
|
earth_pos = earth.at(time) |
|
|
earth_pos = earth.at(time) |
|
|
|
|
|
|
|
|
sun_pos = earth_pos.observe( |
|
|
sun_pos = earth_pos.observe( |
|
|
sun |
|
|
sun |
|
|
).apparent() # Never do this without eyes protection! |
|
|
).apparent() # Never do this without eyes protection! |
|
|
aster_pos = earth_pos.observe(get_skf_objects()[aster.skyfield_name]).apparent() |
|
|
aster_pos = earth_pos.observe(get_skf_objects()[aster.skyfield_name]).apparent() |
|
|
|
|
|
|
|
|
_, lon1, _ = sun_pos.ecliptic_latlon() |
|
|
_, lon1, _ = sun_pos.ecliptic_latlon() |
|
|
_, lon2, _ = aster_pos.ecliptic_latlon() |
|
|
_, lon2, _ = aster_pos.ecliptic_latlon() |
|
|
return (lon1.degrees - lon2.degrees) > 180 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return lon1.degrees - lon2.degrees |
|
|
|
|
|
|
|
|
is_oppositing.rough_period = 1.0 |
|
|
is_oppositing.rough_period = 1.0 |
|
|
events = [] |
|
|
events = [] |
|
|
|
|
|
|
|
|
for aster in ASTERS: |
|
|
for aster in ASTERS: |
|
|
if not isinstance(aster, Planet) or aster.skyfield_name in ["MERCURY", "VENUS"]: |
|
|
|
|
|
|
|
|
if not isinstance(aster, Planet) or aster.identifier in [ |
|
|
|
|
|
ObjectIdentifier.MERCURY, |
|
|
|
|
|
ObjectIdentifier.VENUS, |
|
|
|
|
|
]: |
|
|
continue |
|
|
continue |
|
|
|
|
|
|
|
|
times, _ = find_discrete(start_time, end_time, is_oppositing) |
|
|
times, _ = find_discrete(start_time, end_time, is_oppositing) |
|
|
for time in times: |
|
|
for time in times: |
|
|
|
|
|
if get_angle(time) < 0: |
|
|
|
|
|
# If the angle is negative, then it is actually a false positive. |
|
|
|
|
|
# Just ignoring it. |
|
|
|
|
|
continue |
|
|
|
|
|
|
|
|
events.append( |
|
|
events.append( |
|
|
Event( |
|
|
Event( |
|
|
EventType.OPPOSITION, |
|
|
EventType.OPPOSITION, |
|
@@ -213,31 +245,40 @@ def _search_moon_perigee(start_time: Time, end_time: Time, timezone: int) -> [Ev |
|
|
return events |
|
|
return events |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_events(date: date_type = date_type.today(), timezone: int = 0) -> [Event]: |
|
|
|
|
|
|
|
|
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. |
|
|
"""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): |
|
|
Find events that happen on April 4th, 2020 (show hours in UTC): |
|
|
|
|
|
|
|
|
>>> get_events(date_type(2020, 4, 4)) |
|
|
|
|
|
|
|
|
>>> get_events(date(2020, 4, 4)) |
|
|
[<Event type=CONJUNCTION objects=[<Object type=PLANET name=MERCURY />, <Object type=PLANET name=NEPTUNE />] start=2020-04-04 01:14:39.063308+00:00 end=None details=None />] |
|
|
[<Event type=CONJUNCTION objects=[<Object type=PLANET name=MERCURY />, <Object type=PLANET name=NEPTUNE />] start=2020-04-04 01:14:39.063308+00:00 end=None details=None />] |
|
|
|
|
|
|
|
|
Find events that happen on April 4th, 2020 (show timezones in UTC+2): |
|
|
Find events that happen on April 4th, 2020 (show timezones in UTC+2): |
|
|
|
|
|
|
|
|
>>> get_events(date_type(2020, 4, 4), 2) |
|
|
|
|
|
|
|
|
>>> get_events(date(2020, 4, 4), 2) |
|
|
[<Event type=CONJUNCTION objects=[<Object type=PLANET name=MERCURY />, <Object type=PLANET name=NEPTUNE />] start=2020-04-04 03:14:39.063267+02:00 end=None details=None />] |
|
|
[<Event type=CONJUNCTION objects=[<Object type=PLANET name=MERCURY />, <Object type=PLANET name=NEPTUNE />] start=2020-04-04 03:14:39.063267+02:00 end=None details=None />] |
|
|
|
|
|
|
|
|
Find events that happen on April 3rd, 2020 (show timezones in UTC-2): |
|
|
Find events that happen on April 3rd, 2020 (show timezones in UTC-2): |
|
|
|
|
|
|
|
|
>>> get_events(date_type(2020, 4, 3), -2) |
|
|
|
|
|
|
|
|
>>> get_events(date(2020, 4, 3), -2) |
|
|
[<Event type=CONJUNCTION objects=[<Object type=PLANET name=MERCURY />, <Object type=PLANET name=NEPTUNE />] start=2020-04-03 23:14:39.063388-02:00 end=None details=None />] |
|
|
[<Event type=CONJUNCTION objects=[<Object type=PLANET name=MERCURY />, <Object type=PLANET name=NEPTUNE />] start=2020-04-03 23:14:39.063388-02:00 end=None details=None />] |
|
|
|
|
|
|
|
|
:param date: the date for which the events must be calculated |
|
|
|
|
|
|
|
|
If there is no events for the given date, then an empty list is returned: |
|
|
|
|
|
|
|
|
|
|
|
>>> get_events(date(2021, 3, 20)) |
|
|
|
|
|
[] |
|
|
|
|
|
|
|
|
|
|
|
:param for_date: the date for which the events must be calculated |
|
|
:param timezone: the timezone to adapt the results to. If not given, defaults to 0. |
|
|
:param timezone: the timezone to adapt the results to. If not given, defaults to 0. |
|
|
:return: a list of events found for the given date. |
|
|
:return: a list of events found for the given date. |
|
|
""" |
|
|
""" |
|
|
|
|
|
|
|
|
start_time = get_timescale().utc(date.year, date.month, date.day, -timezone) |
|
|
|
|
|
end_time = get_timescale().utc(date.year, date.month, date.day + 1, -timezone) |
|
|
|
|
|
|
|
|
start_time = get_timescale().utc( |
|
|
|
|
|
for_date.year, for_date.month, for_date.day, -timezone |
|
|
|
|
|
) |
|
|
|
|
|
end_time = get_timescale().utc( |
|
|
|
|
|
for_date.year, for_date.month, for_date.day + 1, -timezone |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
try: |
|
|
try: |
|
|
found_events = [] |
|
|
found_events = [] |
|
@@ -256,7 +297,7 @@ def get_events(date: date_type = date_type.today(), timezone: int = 0) -> [Event |
|
|
start_date = translate_to_timezone(error.start_time.utc_datetime(), timezone) |
|
|
start_date = translate_to_timezone(error.start_time.utc_datetime(), timezone) |
|
|
end_date = translate_to_timezone(error.end_time.utc_datetime(), timezone) |
|
|
end_date = translate_to_timezone(error.end_time.utc_datetime(), timezone) |
|
|
|
|
|
|
|
|
start_date = date_type(start_date.year, start_date.month, start_date.day) |
|
|
|
|
|
end_date = date_type(end_date.year, end_date.month, end_date.day) |
|
|
|
|
|
|
|
|
start_date = date(start_date.year, start_date.month, start_date.day) |
|
|
|
|
|
end_date = date(end_date.year, end_date.month, end_date.day) |
|
|
|
|
|
|
|
|
raise OutOfRangeDateError(start_date, end_date) from error |
|
|
raise OutOfRangeDateError(start_date, end_date) from error |