equationoftime 4.1.2 → 4.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.ruby-version +1 -1
- data/Gemfile +6 -4
- data/Gemfile.lock +21 -14
- data/Guardfile +4 -21
- data/Manifest.txt +18 -52
- data/README.rdoc +6 -6
- data/Rakefile +53 -92
- data/equationoftime.gemspec +48 -49
- data/examples/my_lst.rb +9 -0
- data/examples/use_addr.rb +20 -0
- data/examples/use_ajd.rb +40 -0
- data/ext/eot/ceot.c +18 -14
- data/ext/eot/extconf.rb +4 -5
- data/lib/eot/angle_displays.rb +95 -0
- data/lib/eot/angles.rb +160 -291
- data/lib/eot/constants.rb +78 -81
- data/lib/eot/deltas.rb +40 -0
- data/lib/eot/geo_lat_lng_smt.rb +30 -57
- data/lib/eot/init.rb +86 -124
- data/lib/eot/time_displays.rb +105 -0
- data/lib/eot/times.rb +118 -121
- data/lib/eot/trigometric.rb +51 -0
- data/lib/eot/utilities.rb +49 -50
- data/lib/eot/version.rb +3 -2
- data/lib/eot.rb +11 -5
- data/test/eot/aliased_angles_spec.rb +291 -0
- data/test/eot/aliased_displays_spec.rb +126 -0
- data/test/{aliased_utilities_spec.rb → eot/aliased_utilities_spec.rb} +32 -36
- data/test/eot/angles_spec.rb +261 -0
- data/test/eot/constants_spec.rb +17 -0
- data/test/eot/displays_spec.rb +111 -0
- data/test/eot/geo_spec.rb +40 -0
- data/test/eot/init_spec.rb +45 -0
- data/test/eot/times_spec.rb +137 -0
- data/wiki.md +55 -0
- data/wiki2.md +4 -0
- data.tar.gz.sig +0 -0
- metadata +55 -69
- metadata.gz.sig +0 -0
- data/.settings/org.eclipse.ltk.core.refactoring.prefs +0 -2
- data/examples/analemma_data_generator.rb +0 -58
- data/examples/check_date_type.rb +0 -60
- data/examples/compare_geoc_long_ra.rb +0 -44
- data/examples/data_table_for_astro_dog.rb +0 -45
- data/examples/earth_rotation.rb +0 -42
- data/examples/eot_methods_list.rb +0 -48
- data/examples/eot_plot.r +0 -57
- data/examples/eot_suntimes.rb +0 -149
- data/examples/equation_of_time.py +0 -186
- data/examples/figure_1.jpg +0 -0
- data/examples/file_converter.rb +0 -31
- data/examples/from_readme.rb +0 -14
- data/examples/from_wiki.rb +0 -46
- data/examples/geo_locator.rb +0 -16
- data/examples/getjd.rb +0 -45
- data/examples/gmst_gast_non_sofa.rb +0 -406
- data/examples/input_suntimes.rb +0 -24
- data/examples/julian_day_formula.rb +0 -29
- data/examples/julian_day_formula.txt +0 -12
- data/examples/my_time_conversion.rb +0 -21
- data/examples/nutation_series.txt +0 -678
- data/examples/nutation_table5_3a.txt +0 -682
- data/examples/ptime.rb +0 -162
- data/examples/suntimes.rb +0 -30
- data/examples/suntimes_test.rb +0 -50
- data/examples/t_sofa.rb +0 -8228
- data/examples/test_celes.rb +0 -51
- data/examples/test_ceot.rb +0 -55
- data/examples/test_poly_eval.rb +0 -32
- data/examples/time_scales.rb +0 -29
- data/examples/times_year.rb +0 -53
- data/examples/usage_example.rb +0 -26
- data/examples/use_angles.rb +0 -222
- data/lib/eot/displays.rb +0 -216
- data/lib/eot/eot.so +0 -0
- data/lib/eot/nutation.rb +0 -78
- data/run_tests_eclipse.rb +0 -1
- data/test/aliased_angles_spec.rb +0 -239
- data/test/aliased_displays_spec.rb +0 -105
- data/test/angles_spec.rb +0 -264
- data/test/constants_spec.rb +0 -20
- data/test/displays_spec.rb +0 -110
- data/test/geo_spec.rb +0 -38
- data/test/init_spec.rb +0 -44
- data/test/nutation_spec.rb +0 -37
- data/test/spec_config.rb +0 -8
- data/test/times_spec.rb +0 -133
- data/test/utilities_spec.rb +0 -35
@@ -1,186 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python
|
2
|
-
"""
|
3
|
-
https://bitbucket.org/cmcqueen1975/sundials/src/26a0f54a7c18?at=default
|
4
|
-
Calculation of "equation of time".
|
5
|
-
|
6
|
-
References:
|
7
|
-
http://en.wikipedia.org/wiki/Equation_of_time
|
8
|
-
http://www.sundials.co.uk/equation.htm
|
9
|
-
|
10
|
-
Calculations have been done according to the Wikipedia reference.
|
11
|
-
|
12
|
-
Dependencies:
|
13
|
-
- Python 2.x
|
14
|
-
- NumPy
|
15
|
-
- SciPy (only strictly needed for the more accurate calculation)
|
16
|
-
- matplotlib to plot the graph
|
17
|
-
"""
|
18
|
-
|
19
|
-
import datetime
|
20
|
-
from collections import namedtuple
|
21
|
-
|
22
|
-
import numpy as np
|
23
|
-
import scipy # only strictly needed for the more accurate calculation in equation_of_time_accurate()
|
24
|
-
import scipy.optimize
|
25
|
-
|
26
|
-
# Named tuple to hold geographic location
|
27
|
-
Location = namedtuple('Location', 'latitude, longitude')
|
28
|
-
|
29
|
-
|
30
|
-
# If a location is given, a longitude correction is calculated and included in the graph.
|
31
|
-
# If the sundial itself includes the longitude correction, just use the 0 value here.
|
32
|
-
LOCATION = Location(0, 0)
|
33
|
-
#LOCATION = Location(51.3809, -2.3603) # Bath, England
|
34
|
-
#LOCATION = Location(35.10, 138.86) # Numazu, Japan
|
35
|
-
#LOCATION = Location(-37.81, 144.96) # Melbourne, Victoria, Australia
|
36
|
-
|
37
|
-
|
38
|
-
DAYS_PER_TROPICAL_YEAR = 365.242
|
39
|
-
SUN_ECCENTRICITY = 0.01671
|
40
|
-
|
41
|
-
# The angle from the vernal equinox to the periapsis in the plane of the ecliptic.
|
42
|
-
SUN_ANGLE_OFFSET = 4.9358
|
43
|
-
|
44
|
-
# Angle of tilt of earth's axis--about 23.44 degrees
|
45
|
-
SUN_OBLIQUITY = 0.40910
|
46
|
-
|
47
|
-
|
48
|
-
# Date range for drawing a graph.
|
49
|
-
DATE_START = datetime.date(2009, 1, 1)
|
50
|
-
DATE_END = datetime.date(2010, 1, 1)
|
51
|
-
# Periapsis occurs on a slightly different date each year--varying by a couple
|
52
|
-
# of days. 4th of January is about the average.
|
53
|
-
DATE_PERIAPSIS = datetime.date(2009, 1, 4)
|
54
|
-
|
55
|
-
|
56
|
-
def longitude_offset(location):
|
57
|
-
"""Given a location, return the offset due to longitude, in degrees
|
58
|
-
Location's longitude is used. Latitude isn't needed.
|
59
|
-
"""
|
60
|
-
longitude = location.longitude
|
61
|
-
longitude_per_hour = (360. / 24)
|
62
|
-
longitude_offset = longitude % longitude_per_hour
|
63
|
-
if longitude_offset > longitude_per_hour / 2:
|
64
|
-
longitude_offset -= longitude_per_hour
|
65
|
-
return longitude_offset
|
66
|
-
|
67
|
-
|
68
|
-
def longitude_offset_min(location):
|
69
|
-
minute_per_longitude = 24 * 60 / 360.
|
70
|
-
return longitude_offset(location) * minute_per_longitude
|
71
|
-
|
72
|
-
|
73
|
-
def mean_anomaly(day_number_n):
|
74
|
-
"""day_number_n is the number of days from periapsis."""
|
75
|
-
return day_number_n * (2 * np.pi / DAYS_PER_TROPICAL_YEAR)
|
76
|
-
|
77
|
-
|
78
|
-
@np.vectorize
|
79
|
-
def eccentric_anomaly(mean_anomaly_value):
|
80
|
-
local_sun_eccentricity = SUN_ECCENTRICITY
|
81
|
-
|
82
|
-
def eccentric_anomaly_function(eccentric_anomaly_value):
|
83
|
-
return eccentric_anomaly_value - local_sun_eccentricity * np.sin(eccentric_anomaly_value) - mean_anomaly_value
|
84
|
-
|
85
|
-
# eccentric_anomaly_value = scipy.optimize.brentq(eccentric_anomaly_function, 0 - 0.0001, 2 * np.pi + 0.0001)
|
86
|
-
eccentric_anomaly_value = scipy.optimize.fsolve(eccentric_anomaly_function, mean_anomaly_value)
|
87
|
-
return eccentric_anomaly_value
|
88
|
-
|
89
|
-
|
90
|
-
def true_anomaly(eccentric_anomaly_value):
|
91
|
-
local_sun_eccentricity = SUN_ECCENTRICITY
|
92
|
-
|
93
|
-
half_eccentric_anomaly = eccentric_anomaly_value / 2
|
94
|
-
a_x = np.cos(half_eccentric_anomaly)
|
95
|
-
a_y = np.sin(half_eccentric_anomaly)
|
96
|
-
a_y *= np.sqrt((1 + local_sun_eccentricity) / (1 - local_sun_eccentricity))
|
97
|
-
return 2 * np.arctan2(a_y, a_x)
|
98
|
-
|
99
|
-
|
100
|
-
def right_ascension(sun_angle):
|
101
|
-
"""sun_angle is the angle from the vernal equinox to the Sun in the plane of the ecliptic.
|
102
|
-
It is the true_anomaly value plus the SUN_ANGLE_OFFSET."""
|
103
|
-
a_x = np.cos(sun_angle)
|
104
|
-
a_y = np.sin(sun_angle)
|
105
|
-
return np.arctan2(a_y * np.cos(SUN_OBLIQUITY), a_x)
|
106
|
-
|
107
|
-
|
108
|
-
def equation_of_time_accurate(day_number_n):
|
109
|
-
"""Calculate the equation of time (in min), given a day number.
|
110
|
-
|
111
|
-
day_number_n is the number of days from periapsis.
|
112
|
-
Returns the difference between solar time and clock time, in minutes.
|
113
|
-
This uses a more accurate calculation.
|
114
|
-
"""
|
115
|
-
mean_anomaly_value = mean_anomaly(day_number_n)
|
116
|
-
eccentric_anomaly_value = eccentric_anomaly(mean_anomaly_value)
|
117
|
-
true_anomaly_value = true_anomaly(eccentric_anomaly_value)
|
118
|
-
right_ascension_value = right_ascension(true_anomaly_value + SUN_ANGLE_OFFSET)
|
119
|
-
eot = mean_anomaly_value + SUN_ANGLE_OFFSET - right_ascension_value
|
120
|
-
# Get the angles into the range we want--that is, -pi to +pi
|
121
|
-
eot = (eot + np.pi) % (2 * np.pi) - np.pi
|
122
|
-
return eot * (24 * 60 / 2 / np.pi)
|
123
|
-
|
124
|
-
|
125
|
-
def equation_of_time_simple(day_number_n):
|
126
|
-
"""Calculate the equation of time (in min), given a day number.
|
127
|
-
|
128
|
-
day_number_n is the number of days from periapsis.
|
129
|
-
Returns the difference between solar time and clock time, in minutes.
|
130
|
-
This uses a simple, approximate calculation.
|
131
|
-
"""
|
132
|
-
mean_anomaly_value = mean_anomaly(day_number_n)
|
133
|
-
return -7.655 * np.sin(mean_anomaly_value) + 9.873 * np.sin(2 * mean_anomaly_value + 3.588)
|
134
|
-
|
135
|
-
|
136
|
-
#equation_of_time = equation_of_time_simple
|
137
|
-
equation_of_time = equation_of_time_accurate
|
138
|
-
|
139
|
-
|
140
|
-
def main():
|
141
|
-
import matplotlib
|
142
|
-
#matplotlib.use('pdf')
|
143
|
-
#matplotlib.use('svg')
|
144
|
-
from matplotlib import pyplot as plt
|
145
|
-
|
146
|
-
|
147
|
-
date_range = np.arange(matplotlib.dates.date2num(DATE_START), matplotlib.dates.date2num(DATE_END), 0.1)
|
148
|
-
day_numbers = date_range - matplotlib.dates.date2num(DATE_PERIAPSIS)
|
149
|
-
|
150
|
-
# Calculate the accurate and simple calculations of equation of time.
|
151
|
-
solar_offset_accurate_min = equation_of_time_accurate(day_numbers) + longitude_offset_min(LOCATION)
|
152
|
-
solar_offset_simple_min = equation_of_time_simple(day_numbers) + longitude_offset_min(LOCATION)
|
153
|
-
|
154
|
-
# Plot the graph, either solar vs clock, or vice-versa.
|
155
|
-
if 1:
|
156
|
-
# Solar time vs clock time
|
157
|
-
plt.plot_date(date_range, solar_offset_accurate_min, '-')
|
158
|
-
# plt.plot_date(date_range, solar_offset_simple_min, '--')
|
159
|
-
plt.ylabel('solar time - clock time (min)')
|
160
|
-
else:
|
161
|
-
# Clock time vs solar time
|
162
|
-
plt.plot_date(date_range, -solar_offset_accurate_min, '-')
|
163
|
-
# plt.plot_date(date_range, -solar_offset_simple_min, '--')
|
164
|
-
plt.ylabel('clock time - solar time (min)')
|
165
|
-
|
166
|
-
# Set month lines
|
167
|
-
ax = plt.subplot(111)
|
168
|
-
ax.xaxis.set_major_locator(matplotlib.dates.MonthLocator())
|
169
|
-
ax.xaxis.set_major_formatter(matplotlib.ticker.NullFormatter())
|
170
|
-
# Set month labels centred in the middle (actually on day 15) of each month.
|
171
|
-
ax.xaxis.set_minor_locator(matplotlib.dates.MonthLocator(bymonthday=15))
|
172
|
-
ax.xaxis.set_minor_formatter(matplotlib.dates.DateFormatter('%b'))
|
173
|
-
for tick in ax.xaxis.get_minor_ticks():
|
174
|
-
tick.tick1line.set_markersize(0)
|
175
|
-
tick.tick2line.set_markersize(0)
|
176
|
-
|
177
|
-
plt.grid(True)
|
178
|
-
|
179
|
-
plt.show()
|
180
|
-
# plt.savefig('equation_of_time.pdf')
|
181
|
-
# plt.savefig('equation_of_time.svg')
|
182
|
-
# plt.savefig('equation_of_time.png')
|
183
|
-
|
184
|
-
|
185
|
-
if __name__ == '__main__':
|
186
|
-
main()
|
data/examples/figure_1.jpg
DELETED
Binary file
|
data/examples/file_converter.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
# the file this data comes from 'Circular_179.pdf' IAU 2000A Nutation Series
|
2
|
-
# the first 678 lines are for lunisolar data
|
3
|
-
|
4
|
-
require 'safe_yaml'
|
5
|
-
|
6
|
-
# make array elements from each line of the file
|
7
|
-
filename = "nutation_table5_3a.txt"
|
8
|
-
temp_array = []
|
9
|
-
data = File.readlines(filename)
|
10
|
-
|
11
|
-
# clean out whitespace and new line breaks
|
12
|
-
data.each {|i| temp_array << i.strip}
|
13
|
-
|
14
|
-
# make new muti-dimensional data array
|
15
|
-
data = []
|
16
|
-
temp_array.each {|i| data << i.split}
|
17
|
-
|
18
|
-
# save the array in a yaml file
|
19
|
-
File::open( "nutation_table5_3a.yaml", "w" ) do |f|
|
20
|
-
YAML.dump( data, f )
|
21
|
-
end
|
22
|
-
|
23
|
-
# show the new data file contents as an array.
|
24
|
-
data = []
|
25
|
-
File.open( "nutation_table5_3a.yaml" ) do |f|
|
26
|
-
YAML.load_documents( f ) do |doc|
|
27
|
-
data = doc
|
28
|
-
p data
|
29
|
-
end
|
30
|
-
p f
|
31
|
-
end
|
data/examples/from_readme.rb
DELETED
data/examples/from_wiki.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
# from_wiki.rb
|
2
|
-
|
3
|
-
begin
|
4
|
-
require 'eot'
|
5
|
-
rescue LoadError
|
6
|
-
lib = File.expand_path('../../lib', __FILE__)
|
7
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
8
|
-
require 'eot'
|
9
|
-
end
|
10
|
-
|
11
|
-
eot = Eot.new()
|
12
|
-
# Wiki 1:
|
13
|
-
|
14
|
-
loop do
|
15
|
-
puts "#{Time.now} #{eot.show_minutes(eot.now)}"
|
16
|
-
sleep 11
|
17
|
-
end
|
18
|
-
|
19
|
-
# Wiki 2:
|
20
|
-
|
21
|
-
latitude, longitude, date = 41.9474, -88.74467, "2013-12-25"
|
22
|
-
eot.latitude = latitude; eot.longitude = longitude; eot.ajd = Date.parse(date).jd
|
23
|
-
p eot.sunrise_dt().to_time
|
24
|
-
p eot.sunset_dt().to_time
|
25
|
-
|
26
|
-
# Wiki 3:
|
27
|
-
|
28
|
-
loop do
|
29
|
-
eot.ajd = DateTime.now.to_time.utc.to_datetime.ajd
|
30
|
-
puts eot.string_time(eot.tl_Aries() / 15.0)
|
31
|
-
sleep 0.73
|
32
|
-
end
|
33
|
-
|
34
|
-
# Wiki 4:
|
35
|
-
|
36
|
-
puts "There are #{Eot::SM * 6} hours in a sidereal day."
|
37
|
-
puts "That is why on the next day the stars are about 4 minutes earlier."
|
38
|
-
p obtime0 = Time.now
|
39
|
-
p obtime1 = obtime0 + Eot::SM * 6 * 3600
|
40
|
-
puts "Now you know when to look next time."
|
41
|
-
|
42
|
-
# Wiki 5:
|
43
|
-
|
44
|
-
p DateTime.jd(eot.sunrise_jd + 0.5)
|
45
|
-
p DateTime.jd(eot.sunset_jd + 0.5)
|
46
|
-
|
data/examples/geo_locator.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
# geo_locator.rb
|
2
|
-
|
3
|
-
begin
|
4
|
-
require 'eot'
|
5
|
-
rescue LoadError
|
6
|
-
lib = File.expand_path('../../lib', __FILE__)
|
7
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
8
|
-
require 'eot'
|
9
|
-
end
|
10
|
-
|
11
|
-
|
12
|
-
geo = GeoLatLng.new
|
13
|
-
geo.addr = "8000 South Michigan Ave., Chicago, IL"
|
14
|
-
geo.get_coordinates_from_address
|
15
|
-
p geo.lat
|
16
|
-
p geo.lng
|
data/examples/getjd.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'date'
|
4
|
-
include Math
|
5
|
-
|
6
|
-
def calc_time_julian_centurey(t)
|
7
|
-
# Julian Day Number j(2000) subtracted
|
8
|
-
(t - 2451545.0) / 36525.0
|
9
|
-
# Time in fractional centurey
|
10
|
-
end
|
11
|
-
|
12
|
-
# Truncate large angles
|
13
|
-
def mod_360(x)
|
14
|
-
360.0 * ( x / 360.0 - Integer( x / 360.0))
|
15
|
-
end
|
16
|
-
|
17
|
-
def calc_mean_long_aries(t)
|
18
|
-
|
19
|
-
mod_360(280.46061666 + t * 36525.0 * 360.98564736629 + t * (t * 0.000387933 - t * (t / 38710000.0)))
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
puts "outputs data every 5 seconds"
|
24
|
-
loop do
|
25
|
-
time = Time.now.utc
|
26
|
-
theDate = Date.new(time.year, time.month, time.day)
|
27
|
-
# puts time
|
28
|
-
# puts theDate
|
29
|
-
# puts "#{theDate.ajd} = Astronomical Julian Day"
|
30
|
-
# puts "#{theDate.jd - 0.5} = Astronomical Julian Day"
|
31
|
-
# puts "#{theDate.jd} = Julian Day"
|
32
|
-
t = time
|
33
|
-
theDayFraction = (t.usec / (1000000.0 * 3600.0) + t.min / 60.0 + t.hour + t.sec / 3600.0) / 24.0
|
34
|
-
# puts "#{theDayFraction} = Day Fraction time now"
|
35
|
-
|
36
|
-
theTotal = theDate.ajd + theDayFraction
|
37
|
-
# puts "#{theTotal} = Astronomical Julian Day + Day Fraction time now"
|
38
|
-
|
39
|
-
tjc = calc_time_julian_centurey(theTotal)
|
40
|
-
gmst = calc_mean_long_aries(tjc)
|
41
|
-
|
42
|
-
puts "#{gmst.round 3} = (GHA) Mean Hour Angle First Point of Aries (Vernal Equinox)"
|
43
|
-
puts "#{(gmst/15.0).round 3} = Mean Greenwich Siderial Time (GMST)"
|
44
|
-
sleep 5
|
45
|
-
end
|