Created
July 16, 2023 23:18
-
-
Save rhannequin/5845833a59194f7fcc3e1a13e5cc7a8d to your computer and use it in GitHub Desktop.
Ruby script to compute the best days to observe a celestial body, based on its elevation on the celestial sphere and its angular diamater, based on the IMCCE Opale API.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "date" | |
require "faraday" | |
host = "https://opale.imcce.fr" | |
observer_longitude = 2.3522 | |
observer_latitude = 48.8566 | |
body = 699 # https://www.imcce.fr/content/medias/recherche/equipes/asd/calceph/html/c/calceph.naifid.html | |
year = 2023 | |
first_date = Date.new(year, 1, 1) | |
last_date = Date.new(year, 12, 31) | |
number_of_dates = (last_date - first_date).to_i + 1 | |
number_of_hours = number_of_dates * 24 | |
conn = Faraday.new(url: host) do |builder| | |
builder.response :json | |
builder.response :logger | |
end | |
url = "/api/v1/phenomena/rts/10/#{first_date}/#{observer_latitude},#{observer_longitude}" | |
response = conn.get(url) do |req| | |
req.params["nbd"] = number_of_dates | |
req.params["twilight"] = true | |
end | |
rts = response.body["response"]["data"].first["10"] | |
# This doesn't work for latitudes above ~60° (north of Oslo, Norway), | |
# or below ~-60° (south of Ushuaia, Argentina), because there is no civil | |
# twilight at those latitudes close to the solstices. | |
sunlight_periods = rts.map do |el| | |
[ | |
Date.parse(el["calendarDate"]), | |
( | |
DateTime.parse(el["civilDawn"].first["date"]).to_time.. | |
DateTime.parse(el["civilDusk"].first["date"]).to_time | |
) | |
] | |
end.to_h | |
response = conn.get("/api/v1/positions/#{body}") do |req| | |
req.params["observer"] = "#{observer_latitude},#{observer_longitude}" | |
req.params["date"] = first_date.strftime("%FT%T") | |
req.params["step"] = "1H" | |
req.params["nbd"] = number_of_hours | |
req.params["frame"] = "TrueOfDate" | |
req.params["reference"] = "origin" | |
req.params["places"] = "apparent" | |
req.params["quantities"] = "radec,azel,dist,mag,phase,angdiam" | |
end | |
positions = response.body["response"]["data"].reject do |el| | |
sunlight_periods[DateTime.parse(el["date"]).to_date].cover?( | |
DateTime.parse(el["date"]).to_time | |
) || el["elevation"] < 0 | |
end | |
elevations = positions.sort_by { |el| el["elevation"] }.reverse | |
angular_diameter = positions.sort_by { |el| el["angDiameter"] }.reverse | |
best_of_all_hour = positions | |
.map do |el| | |
[ | |
el["date"], | |
angular_diameter.index(el) + elevations.index(el) | |
] | |
end.min_by { |rank| rank.last }.first | |
best_of_all = positions.find { |el| el["date"] == best_of_all_hour } | |
best_of = [ | |
["Best moment for elevation", elevations.first], | |
["Best moment for angular diameter", angular_diameter.first], | |
["Best moment for all", best_of_all] | |
].to_h | |
best_of.each do |title, el| | |
elevation_ranking = elevations.index(el) + 1 | |
ad_ranking = angular_diameter.index(el) + 1 | |
puts "---------------------------------" | |
puts title | |
puts "Date: #{DateTime.parse(el["date"]).to_time.utc}" | |
puts "Elevation: #{el["elevation"]} (##{elevation_ranking} of elevations)" | |
puts "Angular diameter: #{el["angDiameter"]} (##{ad_ranking} of angular diameters)" | |
puts "Magnitude: #{el["magnitude"]}" | |
puts "Distance: #{el["distance"]}" | |
end | |
# Output | |
# --------------------------------- | |
# Best moment for elevation | |
# Date: 2023-07-13 03:00:00 UTC | |
# Elevation: 30.52802388263536 (#1 of elevations) | |
# Angular diameter: 0.005098776354 (#735 of angular diameters) | |
# Magnitude: 0.66 | |
# Distance: 1354482644.95111 | |
# --------------------------------- | |
# Best moment for angular diameter | |
# Date: 2023-08-27 03:00:00 UTC | |
# Elevation: 17.082071830366313 (#960 of elevations) | |
# Angular diameter: 0.005268176823 (#1 of angular diameters) | |
# Magnitude: 0.43 | |
# Distance: 1310928678.75692 | |
# --------------------------------- | |
# Best moment for all | |
# Date: 2023-08-27 00:00:00 UTC | |
# Elevation: 29.387024727459007 (#70 of elevations) | |
# Angular diameter: 0.005268172202 (#9 of angular diameters) | |
# Magnitude: 0.43 | |
# Distance: 1310929828.67324 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment