astronoby 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/CHANGELOG.md +87 -3
  4. data/README.md +56 -32
  5. data/UPGRADING.md +50 -21
  6. data/docs/README.md +196 -0
  7. data/docs/angles.md +137 -0
  8. data/docs/celestial_bodies.md +107 -0
  9. data/docs/configuration.md +98 -0
  10. data/docs/coordinates.md +167 -0
  11. data/docs/ephem.md +85 -0
  12. data/docs/equinoxes_solstices_times.md +31 -0
  13. data/docs/glossary.md +152 -0
  14. data/docs/instant.md +139 -0
  15. data/docs/moon_phases.md +79 -0
  16. data/docs/observer.md +65 -0
  17. data/docs/reference_frames.md +138 -0
  18. data/docs/rise_transit_set_times.md +119 -0
  19. data/docs/twilight_times.md +123 -0
  20. data/lib/astronoby/bodies/earth.rb +8 -2
  21. data/lib/astronoby/bodies/jupiter.rb +17 -0
  22. data/lib/astronoby/bodies/mars.rb +17 -0
  23. data/lib/astronoby/bodies/mercury.rb +21 -0
  24. data/lib/astronoby/bodies/moon.rb +29 -36
  25. data/lib/astronoby/bodies/neptune.rb +21 -0
  26. data/lib/astronoby/bodies/saturn.rb +26 -0
  27. data/lib/astronoby/bodies/solar_system_body.rb +139 -29
  28. data/lib/astronoby/bodies/sun.rb +25 -2
  29. data/lib/astronoby/bodies/uranus.rb +5 -0
  30. data/lib/astronoby/bodies/venus.rb +25 -0
  31. data/lib/astronoby/cache.rb +188 -0
  32. data/lib/astronoby/configuration.rb +92 -0
  33. data/lib/astronoby/constants.rb +4 -1
  34. data/lib/astronoby/constellation.rb +12 -0
  35. data/lib/astronoby/constellations/data.rb +42 -0
  36. data/lib/astronoby/constellations/finder.rb +35 -0
  37. data/lib/astronoby/constellations/repository.rb +20 -0
  38. data/lib/astronoby/coordinates/equatorial.rb +3 -3
  39. data/lib/astronoby/data/constellations/constellation_names.dat +88 -0
  40. data/lib/astronoby/data/constellations/indexed_abbreviations.dat +88 -0
  41. data/lib/astronoby/data/constellations/radec_to_index.dat +238 -0
  42. data/lib/astronoby/data/constellations/sorted_declinations.dat +202 -0
  43. data/lib/astronoby/data/constellations/sorted_right_ascensions.dat +237 -0
  44. data/lib/astronoby/equinox_solstice.rb +2 -2
  45. data/lib/astronoby/events/moon_phases.rb +15 -14
  46. data/lib/astronoby/events/rise_transit_set_calculator.rb +32 -8
  47. data/lib/astronoby/events/twilight_calculator.rb +115 -60
  48. data/lib/astronoby/events/twilight_events.rb +28 -0
  49. data/lib/astronoby/instant.rb +7 -2
  50. data/lib/astronoby/julian_date.rb +78 -0
  51. data/lib/astronoby/mean_obliquity.rb +8 -10
  52. data/lib/astronoby/nutation.rb +11 -3
  53. data/lib/astronoby/observer.rb +1 -1
  54. data/lib/astronoby/precession.rb +48 -38
  55. data/lib/astronoby/reference_frame.rb +2 -1
  56. data/lib/astronoby/reference_frames/apparent.rb +1 -1
  57. data/lib/astronoby/reference_frames/mean_of_date.rb +1 -1
  58. data/lib/astronoby/reference_frames/topocentric.rb +1 -11
  59. data/lib/astronoby/time/greenwich_sidereal_time.rb +2 -2
  60. data/lib/astronoby/true_obliquity.rb +2 -3
  61. data/lib/astronoby/util/time.rb +1 -1
  62. data/lib/astronoby/version.rb +1 -1
  63. data/lib/astronoby.rb +8 -1
  64. metadata +59 -11
  65. data/Gemfile +0 -5
  66. data/Gemfile.lock +0 -102
  67. data/benchmark/README.md +0 -131
  68. data/benchmark/benchmark.rb +0 -259
  69. data/benchmark/data/imcce.csv.zip +0 -0
  70. data/benchmark/data/sun_calc.csv.zip +0 -0
  71. data/lib/astronoby/epoch.rb +0 -22
data/docs/angles.md ADDED
@@ -0,0 +1,137 @@
1
+ # Angles
2
+
3
+ `Astronoby::Angle` is one of the most important object in the library. An object
4
+ on the celestial sphere is described with angles, an observer's location on
5
+ Earth is described with angles, the distance between two points in the sky is
6
+ described with an angle.
7
+
8
+ ## Create an angle
9
+
10
+ You can create an instance of `Astronoby::Angle` with a value in different
11
+ units: radians, degrees or hours.
12
+
13
+ ```rb
14
+ Astronoby::Angle.from_radians(Math::PI)
15
+ Astronoby::Angle.from_degrees(180)
16
+ Astronoby::Angle.from_hours(12)
17
+ ```
18
+
19
+ You can also use the hour-minute-second (HMS) or degree-minute-second (DMS)
20
+ formats.
21
+
22
+ ```rb
23
+ Astronoby::Angle.from_hms(22, 45, 23)
24
+ Astronoby::Angle.from_dms(340, 45, 23)
25
+ ```
26
+
27
+ Alternatively, you can create an angle of 0 (regardless of the unit).
28
+
29
+ ```rb
30
+ Astronoby::Angle.zero
31
+ ```
32
+
33
+ Finally, you can create an angle from the ratio of a trigonometric function.
34
+
35
+ ```rb
36
+ Astronoby::Angle.acos(0)
37
+ Astronoby::Angle.asin(-1)
38
+ Astronoby::Angle.atan(1 / Math.sqrt(3))
39
+ ```
40
+
41
+ ## Convert between units
42
+
43
+ Once an angle object is instantiated, its value lives inside it. You need to
44
+ specify a unit to extract it.
45
+
46
+ ```rb
47
+ angle = Astronoby::Angle.from_degrees(180)
48
+
49
+ angle.degrees # => 180.0
50
+ angle.radians # => 3.141592653589793
51
+ angle.hours # => 12.0
52
+ ```
53
+
54
+ ## Format an angle
55
+
56
+ You can format an angle in HMS or DMS formatted strings.
57
+
58
+ ```rb
59
+ angle = Astronoby::Angle.from_degrees(155.76479)
60
+
61
+ angle.str(:dms) # => "+155° 45′ 53.2439″"
62
+ angle.str(:hms) # => "10h 23m 3.5496s"
63
+ ```
64
+
65
+ Alternatively you can extract these numbers without having to format them into a
66
+ string.
67
+
68
+ ```rb
69
+ angle = Astronoby::Angle.from_degrees(155.76479)
70
+
71
+ dms = angle.to_dms
72
+ dms.sign # => "+"
73
+ dms.degrees # => 155
74
+ dms.minutes # => 45
75
+ dms.seconds # => 53.2439
76
+
77
+ hms = angle.to_hms
78
+ hms.hours # => 10
79
+ hms.minutes # => 23
80
+ hms.seconds # => 3.5496
81
+ ```
82
+
83
+ ## Manipulate angles
84
+
85
+ You can compare an angle with another angle.
86
+
87
+ ```rb
88
+ Astronoby::Angle.from_hours(12) == Astronoby::Angle.from_degrees(180)
89
+ # => true
90
+
91
+ angle1 = Astronoby::Angle.from_degrees(90)
92
+ angle2 = Astronoby::Angle.from_hours(12)
93
+
94
+ angle1 < angle2 # => true
95
+ ```
96
+
97
+ ## Math with angles
98
+
99
+ Trigonometric functions can be applied to angles to get the value as a `Float`.
100
+ Please be aware some results won't be strictly exact because of the limited
101
+ precision of floating-point numbers and the limited amount of digits
102
+ of `Math::PI`.
103
+
104
+ ```rb
105
+ angle = Astronoby::Angle.from_degrees(180)
106
+
107
+ angle.cos # => -1.0
108
+ angle.sin # => 1.2246467991473532e-16, strictly supposed to be 0
109
+ angle.tan # => -1.2246467991473532e-16, strictly supposed to be 0
110
+ ```
111
+
112
+ You can add up or subtract angles into a new one. Multiplication and division
113
+ are not supported as they mathematically should return something else than an
114
+ angle.
115
+
116
+ ```rb
117
+ angle1 = Astronoby::Angle.from_hours(12)
118
+ angle2 = Astronoby::Angle.from_degrees(90)
119
+
120
+ angle3 = angle1 + angle2
121
+ angle3.degrees # => 270.0
122
+
123
+ angle4 = angle1 - angle2
124
+ angle4.degrees # => 90.0
125
+
126
+ angle5 = -angle1
127
+ angle5.degrees # => -180.0
128
+
129
+ angle1.positive? # => true
130
+ angle1.negative? # => false
131
+ ```
132
+
133
+ ## See also
134
+ - [Coordinates](coordinates.md) - for using angles in coordinate systems
135
+ - [Observer](observer.md) - for latitude and longitude
136
+ - [Reference Frames](reference_frames.md) - for position calculations
137
+ - [Celestial Bodies](celestial_bodies.md) - for object positions
@@ -0,0 +1,107 @@
1
+ # Celestial Bodies
2
+
3
+ Currently, Astronoby only supports the following major bodies of the Solar
4
+ System:
5
+ * the Sun (`Astronoby::Sun`)
6
+ * planets from Mercury to Neptune, including the Earth (`Astronoby::Earth`, ...)
7
+ * the Moon (`Astronoby::Moon`)
8
+
9
+ Given an ephemeris (`Astronoby::Ephem`) and an instant object
10
+ (`Astronoby::Instant`), these classes enable you to get instances which provide
11
+ positions in different reference frames.
12
+
13
+ You can learn more about [ephemerides] and [reference frames].
14
+
15
+ ```rb
16
+ ephem = Astronoby::Ephem.load("inpop19a.bsp")
17
+ time = Time.utc(2021, 7, 8)
18
+ instant = Astronoby::Instant.from_time(time)
19
+
20
+ venus = Astronoby::Venus.new(ephem: ephem, instant: instant)
21
+ apparent_position = venus.apparent.position
22
+
23
+ apparent_position.x.km.round
24
+ # => -148794622
25
+ ```
26
+
27
+ Each of these bodies also provides its own equatorial radius
28
+ (`Astronoby::Distance`).
29
+
30
+ ```rb
31
+ Astronoby::Venus::EQUATORIAL_RADIUS.meters
32
+ # => 6051800
33
+ ```
34
+
35
+ ## Attributes of planets
36
+
37
+ For all Solar System bodies, except the Sun and the Earth, the following
38
+ attributes are available. Note that dynamic values are accessible through
39
+ instance methods, while absolute values are accessible through class methods.
40
+
41
+ ### `#angular_diameter`
42
+
43
+ Size of the body in the sky. Returns a `Astronoby::Angle` object.
44
+
45
+ ```rb
46
+ venus.angular_diameter.str(:dms)
47
+ # => "+0° 0′ 11.4587″"
48
+ ```
49
+
50
+ ### `#constellation`
51
+
52
+ Constellation where the body appears in the sky as seen from Earth. Returns
53
+ a `Astronoby::Constellation` object.
54
+
55
+ ```rb
56
+ venus.constellation.name
57
+ # => "Cancer"
58
+
59
+ venus.constellation.abbreviation
60
+ # => "Cnc"
61
+ ```
62
+
63
+ ### `#phase_angle`
64
+
65
+ "Sun-object-Earth" angle. Returns a `Astronoby::Angle` object.
66
+
67
+ ```rb
68
+ venus.phase_angle.degrees.round
69
+ # => 40
70
+ ```
71
+
72
+ ### `#illuminated_fraction`
73
+
74
+ Fraction of the object's disk illuminated as seen from Earth. Returns a `Float`
75
+ between `0` and `1`.
76
+
77
+ ```rb
78
+ venus.illuminated_fraction.round(2)
79
+ # => 0.88
80
+ ```
81
+
82
+ ### `#apparent_magnitude`
83
+
84
+ Apparent brightness of the body. Returns a `Float`.
85
+
86
+ ```rb
87
+ venus.apparent_magnitude.round(2)
88
+ # => -3.89
89
+ ```
90
+
91
+ ### `::absolute_magnitude`
92
+
93
+ Absolute brightness of the body. Returns a `Float`.
94
+
95
+ ```rb
96
+ Astronoby::Venus.absolute_magnitude
97
+ # => -4.384
98
+ ```
99
+
100
+ [ephemerides]: ephem.md
101
+ [reference frames]: reference_frames.md
102
+
103
+ ## See also
104
+ - [Ephemerides](ephem.md) - for understanding data sources
105
+ - [Reference Frames](reference_frames.md) - for coordinate systems
106
+ - [Observer](observer.md) - for setting up observation locations
107
+ - [Angles](angles.md) - for working with angular measurements
@@ -0,0 +1,98 @@
1
+ # Configuration
2
+
3
+ Astronoby handles an internal configuration to enable users to tweak the
4
+ performance and precision of computed data.
5
+
6
+ ## Cache
7
+
8
+ Some calculations are expensive but also repetitive in the intermediate computed
9
+ data. To improve performance, an internal cache system has been developed.
10
+
11
+ ➡️ **Please note caching is disabled by default.**
12
+
13
+ ### Enable caching
14
+
15
+ You can turn caching on with the following command:
16
+
17
+ ```rb
18
+ Astronoby.configuration.cache_enabled = true
19
+ ```
20
+
21
+ Once caching is enabled, it will be used for the following parts of the library
22
+ with default precision values:
23
+ * [Geometric positions]
24
+ * [Topocentric positions] when computing rising/transit/setting times
25
+ * [Moon phases]
26
+ * Nutation
27
+ * Precession
28
+
29
+ ## Cache precision
30
+
31
+ When cache is enabled, some data is cached following a default precision
32
+ threshold so that precision doesn't noticeably decrease.
33
+
34
+ However, users may want to improve performance even more at the cost of some
35
+ precision.
36
+
37
+ It is possible to change the precision value for the following:
38
+ * Geometric position, default: `9`
39
+ * Topocentric position, default: `5`
40
+ * Nutation, default: `2`
41
+ * Precession, default: `2`
42
+
43
+ ### Precision value
44
+
45
+ The precision value is how much rounded instants are. Because instants are
46
+ stored as a [Julian Day], rounding may not seem very natural.
47
+
48
+ Let's take the example of `1`. Rounding a Julian Day with only one digit means
49
+ that all times within 8640 seconds will be rounded to the same instant, which
50
+ means a maximum rounding of 2.4 hours.
51
+
52
+ * `1`: 2.4 hours
53
+ * `2`: 14.4 minutes
54
+ * `3`: 86.4 seconds
55
+ * `4`: 8.6 seconds
56
+ * `5`: 0.86 seconds
57
+ * `6`: 0.086 seconds
58
+ * `7`: 0.0086 seconds
59
+ * ...
60
+
61
+ ### Setting custom precision
62
+
63
+ To set up your own precision, you can use:
64
+
65
+ ```rb
66
+ Astronoby.cache_precision(:geometric, 5)
67
+ ```
68
+
69
+ All geometric positions of the same celestial body within 0.86 seconds will be
70
+ rounded and cached.
71
+
72
+ ## Cache size
73
+
74
+ Cache has limited and configurable capacity, set by default to 10,000 stored
75
+ items. This value can be changed to any positive number.
76
+
77
+ ```rb
78
+ Astronoby.configuration.cache_enabled = true
79
+
80
+ Astronoby.cache.max_size
81
+ # => 10000
82
+
83
+ Astronoby.cache.max_size = 1000000
84
+
85
+ Astronoby.cache.max_size
86
+ # => 1000000
87
+ ```
88
+
89
+ [Geometric positions]: reference_frames.md#geometric
90
+ [Topocentric positions]: reference_frames.md#topocentric
91
+ [Moon phases]: moon_phases.md
92
+ [Julian Day]: https://en.wikipedia.org/wiki/Julian_day
93
+
94
+ ## See also
95
+ - [Reference Frames](reference_frames.md) - for understanding position calculations
96
+ - [Ephemerides](ephem.md) - for data sources
97
+ - [Performance Benchmarks](benchmarks/README.md) - for testing improvements
98
+ - [Cache System](cache.md) - for detailed caching information
@@ -0,0 +1,167 @@
1
+ # Coordinates
2
+
3
+ Astronoby provides three different types of coordinates:
4
+
5
+ * Equatorial
6
+ * Ecliptic
7
+ * Horizontal
8
+
9
+ Equatorial and ecliptic coordinates are available for each [reference frame],
10
+ while horizontal coordinates are only available for a topocentric position.
11
+
12
+ ## Equatorial
13
+
14
+ In Astronoby, equatorial coordinates are geocentric spherical coordinates. As
15
+ per [Wikipedia]'s definition:
16
+
17
+ > defined by an origin at the centre of Earth, fundamental plane consisting of
18
+ > the projection of Earth's equator onto the celestial sphere (forming the
19
+ > celestial equator, a primary direction towards the March equinox, and a
20
+ > right-handed convention.
21
+
22
+ They have two main angular attributes:
23
+
24
+ ### Right ascension
25
+
26
+ Angle measured East from the Vernal Equinox, the point where the Sun crosses the
27
+ celestial equator in March as it passes from the southern to the northern half
28
+ of the sky. By convention, right ascension is usually displayed in hours.
29
+
30
+ ```rb
31
+ ephem = Astronoby::Ephem.load("inpop19a.bsp")
32
+ time = Time.utc(1962, 7, 24)
33
+ instant = Astronoby::Instant.from_time(time)
34
+
35
+ saturn = Astronoby::Saturn.new(ephem: ephem, instant: instant)
36
+ equatorial = saturn.apparent.equatorial
37
+
38
+ equatorial.right_ascension.str(:hms)
39
+ # => "20h 45m 2.6702s"
40
+ ```
41
+
42
+ You can learn more about angles on the [Angle page].
43
+
44
+ ### Declination
45
+
46
+ Angle measured north and south of the celestial equator in degrees, with north
47
+ being positive. The North Celestial Pole is at +90° and the South Celestial Pole
48
+ is at -90°.
49
+
50
+ ```rb
51
+ equatorial.declination.str(:dms)
52
+ # => "-18° 46′ 16.1226″"
53
+ ```
54
+
55
+ ### Hour angle
56
+
57
+ Sometimes convenient for astronomers, a third attribute can be derived from
58
+ equatorial coordinates: the hour angle. It is the angle between the meridian
59
+ plane and the hour circle, meaning it depends on the observer's longitude and
60
+ time. By convention, the hour angle is usually displayed in hours.
61
+
62
+ ```rb
63
+ longitude = Astronoby::Angle.from_degrees(2)
64
+
65
+ equatorial.compute_hour_angle(longitude: longitude, time: time).str(:hms)
66
+ # => "23h 27m 54.9585s"
67
+ ```
68
+
69
+ ## Ecliptic
70
+
71
+ In Astronoby, ecliptic coordinates are geocentric spherical coordinates. Their
72
+ origin is the centre of Earth, their primary direction is towards the March
73
+ equinox, and they have a right-hand convention. Ecliptic coordinates are
74
+ particularly handy for representing positions of Solar System objects.
75
+
76
+ As per Wikipedia's definition:
77
+
78
+ > The celestial equator and the ecliptic are slowly moving due to perturbing
79
+ > forces on the Earth, therefore the orientation of the primary direction, their
80
+ > intersection at the March equinox, is not quite fixed. A slow motion of
81
+ > Earth's axis, precession, causes a slow, continuous turning of the coordinate
82
+ > system westward about the poles of the ecliptic. Superimposed on this is a
83
+ > smaller motion of the ecliptic, and a small oscillation of the Earth's axis,
84
+ > nutation.
85
+
86
+ This primary direction depends on the [reference frame] used.
87
+
88
+ They have two main angular attributes:
89
+
90
+ ### Latitude
91
+
92
+ The ecliptic latitude measures the angular distance of an object along the
93
+ ecliptic from the primary direction.
94
+
95
+ ```rb
96
+ ephem = Astronoby::Ephem.load("inpop19a.bsp")
97
+ time = Time.utc(1962, 7, 24)
98
+ instant = Astronoby::Instant.from_time(time)
99
+
100
+ saturn = Astronoby::Saturn.new(ephem: ephem, instant: instant)
101
+ ecliptic = saturn.apparent.ecliptic
102
+
103
+ ecliptic.latitude.str(:dms)
104
+ # => "-0° 41′ 27.5439″"
105
+ ```
106
+
107
+ ### Longitude
108
+
109
+ The ecliptic latitude measures the angular distance of an object from the
110
+ ecliptic towards the north (positive) or south (negative) ecliptic pole.
111
+
112
+ ```rb
113
+ ecliptic.longitude.str(:dms)
114
+ # => "+308° 38′ 33.1744″"
115
+ ```
116
+
117
+ ## Horizontal
118
+
119
+ Horizontal coordinates are the most observer-centred and human-intuitive
120
+ coordinates. They measure where an object is in the sky as seen from an observer
121
+ on Earth as "up and down" and "left and right".
122
+
123
+ In Astronoby, they can only be computed from a [topocentric position].
124
+
125
+ They have two main angular attributes:
126
+
127
+ ### Altitude
128
+
129
+ The angle between the object and the observer's local horizon.
130
+
131
+ ```rb
132
+ ephem = Astronoby::Ephem.load("inpop19a.bsp")
133
+ time = Time.utc(1962, 7, 24)
134
+ instant = Astronoby::Instant.from_time(time)
135
+
136
+ observer = Astronoby::Observer.new(
137
+ latitude: Astronoby::Angle.from_degrees(42),
138
+ longitude: Astronoby::Angle.from_degrees(2)
139
+ )
140
+
141
+ saturn = Astronoby::Saturn.new(ephem: ephem, instant: instant)
142
+ horizontal = saturn.observed_by(observer).horizontal
143
+
144
+ horizontal.altitude.str(:dms)
145
+ # => "+28° 46′ 39.5994″"
146
+ ```
147
+
148
+ ### Azimuth
149
+
150
+ The angle of the object around the horizon from the north and increasing
151
+ eastward.
152
+
153
+ ```rb
154
+ horizontal.azimuth.str(:dms)
155
+ # => "+171° 19′ 50.5798″"
156
+ ```
157
+
158
+ [reference frame]: reference_frames.md
159
+ [Wikipedia]: https://en.wikipedia.org/wiki/Equatorial_coordinate_system
160
+ [Angle page]: angles.md
161
+ [topocentric position]: reference_frames.md#topocentric
162
+
163
+ ## See also
164
+ - [Reference Frames](reference_frames.md) - for coordinate system details
165
+ - [Angles](angles.md) - for working with angular measurements
166
+ - [Observer](observer.md) - for location setup
167
+ - [Celestial Bodies](celestial_bodies.md) - for object positions
data/docs/ephem.md ADDED
@@ -0,0 +1,85 @@
1
+ # `Ephem`
2
+
3
+ `Astronoby` depends on the gem [`ephem`] which provides a Ruby interface for
4
+ <abbr title="Jet Propulsion Laboratory">JPL</abbr> SPICE binary kernels.
5
+
6
+ These kernels are extremely precise ephemerides produced by the JPL and are the
7
+ foundation of the data provided by Astronoby. The [IMCCE] also produces
8
+ kernels in the same format for their
9
+ <abbr title="Intégrateur numérique planétaire de l'Observatoire de Paris">INPOP</abbr>
10
+ model.
11
+
12
+ ## Download an ephemeris
13
+
14
+ To download an ephemeris, you can either do it manually or use `ephem` by
15
+ providing the filename.
16
+
17
+ ### Manually
18
+
19
+ Ephemerides are available for download from:
20
+ * the JPL public FTP interface: https://ssd.jpl.nasa.gov/ftp/eph/planets/bsp/
21
+ * the INPOP releases page of the IMCCE: https://www.imcce.fr/inpop
22
+
23
+ You can download any `.bsp` file. For the moment, Astronoby only supports the
24
+ planets of the Solar System, and the Sun and the Moon, so you need to
25
+ download a _Development Ephemeris_, which starts with `de` (i.e. `de421.bsp`),
26
+ or any of the INPOP ephemeris files (i.e. `inpop19a.bsp`).
27
+
28
+ ### With `Ephem`
29
+
30
+ If you already know the ephemeris you want to use, you can use `Ephem` to
31
+ download and store it for you:
32
+
33
+ ```rb
34
+ Astronoby::Ephem.download(name: "de421.bsp", target: "tmp/de421.bsp")
35
+ ```
36
+
37
+ ## Load an ephemeris
38
+
39
+ To compute the position of a Solar System body, you need to provide an ephemeris
40
+ to extract the data from. You can use `Astronoby::Ephem` to load the file you
41
+ downloaded.
42
+
43
+ ```rb
44
+ ephem = Astronoby::Ephem.load("tmp/de421.bsp")
45
+ ```
46
+
47
+ ## How to choose the right ephemeris?
48
+
49
+ JPL produces many different kernels over the years, with different accuracy and
50
+ ranges of supported years. Here are some that we recommend to begin with:
51
+ - `de421.bsp`: from 1900 to 2050, 17 MB
52
+ - `de440s.bsp`: from 1849 to 2150, 32 MB
53
+ - `inpop19a.bsp`: from 1900 to 2100, 22 MB
54
+
55
+ ## How to limit weight and increase speed?
56
+
57
+ The `Ephem` library offers a <abbr title="Command-Line Interface">CLI</abbr> to
58
+ produce excerpt ephemerides in order to limit the range of dates or bodies.
59
+
60
+ Here is an example to produce an excerpt ephemeris for the year 2025:
61
+
62
+ ```
63
+ ruby-ephem excerpt 2024-12-31 2026-01-01 de440s.bsp de440s_2025_excerpt.bsp
64
+ ```
65
+
66
+ You can also specify which bodies of the Solar System (or "targets") you want to
67
+ include:
68
+
69
+ ```
70
+ ruby-ephem excerpt --targets 10,399 2024-12-31 2026-01-01 inpop19a.bsp inpop19a_2025_sun_earth.bsp
71
+ ```
72
+
73
+ You may want to check how bodies are handled between JPL DE and IMCCE INPOP. For
74
+ example, the excerpt file from a JPL DE kernel needs to include targets `3` and
75
+ `399` for the Earth, while the excerpt file from a IMCCE INPOP kernel only needs
76
+ the target `399`.
77
+
78
+ [`ephem`]: https://github.com/rhannequin/ruby-ephem
79
+ [IMCCE]: https://www.imcce.fr
80
+
81
+ ## See also
82
+ - [Celestial Bodies](celestial_bodies.md) - for using ephemeris data
83
+ - [Reference Frames](reference_frames.md) - for coordinate calculations
84
+ - [Observer](observer.md) - for location-based calculations
85
+ - [Configuration](configuration.md) - for performance tuning
@@ -0,0 +1,31 @@
1
+ # Equinoxes and Solstice Times
2
+
3
+ The equinox and solstice are two precise events that each happen twice a year.
4
+
5
+ The equinox is the time when the Sun appears directly above the equator, the
6
+ solstice is the time when the Sun reaches its most northerly or southerly
7
+ excursion relative to the celestial equator on the celestial sphere.
8
+
9
+ Astronoby enables you to compute the time for each of these four events.
10
+
11
+ ```rb
12
+ ephem = Astronoby::Ephem.load("inpop19a.bsp")
13
+
14
+ Astronoby::EquinoxSolstice.march_equinox(2025, ephem)
15
+ # => 2025-03-20 09:01:29 UTC
16
+
17
+ Astronoby::EquinoxSolstice.june_solstice(2025, ephem)
18
+ # => 2025-06-21 02:42:19 UTC
19
+
20
+ Astronoby::EquinoxSolstice.september_equinox(2025, ephem)
21
+ # => 2025-09-22 18:19:22 UTC
22
+
23
+ Astronoby::EquinoxSolstice.december_solstice(2025, ephem)
24
+ # => 2025-12-21 15:03:03 UTC
25
+ ```
26
+
27
+ ## See also
28
+ - [Twilight Times](twilight_times.md) - for seasonal sun events
29
+ - [Moon Phases](moon_phases.md) - for lunar events
30
+ - [Ephemerides](ephem.md) - for data sources
31
+ - [Instant](instant.md) - for time handling