You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

62 lines
2.2 KiB

  1. #!/usr/bin/env python3
  2. # Kosmorro - Compute The Next Ephemerides
  3. # Copyright (C) 2019 Jérôme Deuchnord <jerome@deuchnord.fr>
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU Affero General Public License as
  7. # published by the Free Software Foundation, either version 3 of the
  8. # License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU Affero General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Affero General Public License
  16. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. from datetime import date as date_type
  18. from skyfield.timelib import Time
  19. from skyfield.almanac import find_discrete
  20. from .data import Event, Planet
  21. from .core import get_timescale, get_skf_objects, ASTERS
  22. def _search_oppositions(start_time: Time, end_time: Time) -> [Event]:
  23. earth = get_skf_objects()['earth']
  24. sun = get_skf_objects()['sun']
  25. aster = None
  26. def is_oppositing(time: Time) -> [bool]:
  27. earth_pos = earth.at(time)
  28. sun_pos = earth_pos.observe(sun).apparent() # Never do this without eyes protection!
  29. aster_pos = earth_pos.observe(get_skf_objects()[aster.skyfield_name]).apparent()
  30. _, lon1, _ = sun_pos.ecliptic_latlon()
  31. _, lon2, _ = aster_pos.ecliptic_latlon()
  32. return (lon1.degrees - lon2.degrees) > 180
  33. is_oppositing.rough_period = 1.0
  34. events = []
  35. for aster in ASTERS:
  36. if not isinstance(aster, Planet) or aster.name in ['Mercury', 'Venus']:
  37. continue
  38. times, _ = find_discrete(start_time, end_time, is_oppositing)
  39. for time in times:
  40. events.append(Event('OPPOSITION', aster, time))
  41. return events
  42. def search_events(date: date_type) -> [Event]:
  43. start_time = get_timescale().utc(date.year, date.month, date.day)
  44. end_time = get_timescale().utc(date.year, date.month, date.day + 1)
  45. return [
  46. opposition for opposition in _search_oppositions(start_time, end_time)
  47. ]