eph_jpl 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9b03b2d3373fd9bc0620fbf5872f3a6723b296af
4
+ data.tar.gz: c9ac3a034cea4f40a52f7da183f7db0a039a05f2
5
+ SHA512:
6
+ metadata.gz: b8581d2d5933ca5912540f400fbd799eaf7eee22e3dc59cf4f1e1e8a99b543424f4371215202840626bb62f3b099280d2b9872a98b069a71911d433174876368
7
+ data.tar.gz: 3f8521f73b9a180ae73f307bd00e80649c25c100c00f3e577b43da1cce8ffe709e26c4f61491595771a49645dec5cbd4976f93fb1ccd1a8d596600574b74410d
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.1
4
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in eph_jpl.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem "guard"
8
+ gem "guard-rspec", "~> 4.7.0"
9
+ end
10
+
data/Guardfile ADDED
@@ -0,0 +1,70 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features) \
6
+ # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
+
8
+ ## Note: if you are using the `directories` clause above and you are not
9
+ ## watching the project directory ('.'), then you will want to move
10
+ ## the Guardfile to a watched dir and symlink it back, e.g.
11
+ #
12
+ # $ mkdir config
13
+ # $ mv Guardfile config/
14
+ # $ ln -s config/Guardfile .
15
+ #
16
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
+
18
+ # Note: The cmd option is now required due to the increasing number of ways
19
+ # rspec may be run, below are examples of the most common uses.
20
+ # * bundler: 'bundle exec rspec'
21
+ # * bundler binstubs: 'bin/rspec'
22
+ # * spring: 'bin/rspec' (This will use spring if running and you have
23
+ # installed the spring binstubs per the docs)
24
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
25
+ # * 'just' rspec: 'rspec'
26
+
27
+ guard :rspec, cmd: "bundle exec rspec" do
28
+ require "guard/rspec/dsl"
29
+ dsl = Guard::RSpec::Dsl.new(self)
30
+
31
+ # Feel free to open issues for suggestions and improvements
32
+
33
+ # RSpec files
34
+ rspec = dsl.rspec
35
+ watch(rspec.spec_helper) { rspec.spec_dir }
36
+ watch(rspec.spec_support) { rspec.spec_dir }
37
+ watch(rspec.spec_files)
38
+
39
+ # Ruby files
40
+ ruby = dsl.ruby
41
+ dsl.watch_spec_files_for(ruby.lib_files)
42
+
43
+ ## Rails files
44
+ #rails = dsl.rails(view_extensions: %w(erb haml slim))
45
+ #dsl.watch_spec_files_for(rails.app_files)
46
+ #dsl.watch_spec_files_for(rails.views)
47
+
48
+ #watch(rails.controllers) do |m|
49
+ # [
50
+ # rspec.spec.call("routing/#{m[1]}_routing"),
51
+ # rspec.spec.call("controllers/#{m[1]}_controller"),
52
+ # rspec.spec.call("acceptance/#{m[1]}")
53
+ # ]
54
+ #end
55
+
56
+ ## Rails config changes
57
+ #watch(rails.spec_helper) { rspec.spec_dir }
58
+ #watch(rails.routes) { "#{rspec.spec_dir}/routing" }
59
+ #watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
60
+
61
+ ## Capybara features specs
62
+ #watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
63
+ #watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
64
+
65
+ ## Turnip features and steps
66
+ #watch(%r{^spec/acceptance/(.+)\.feature$})
67
+ #watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
68
+ # Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
69
+ #end
70
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Masaru Koizumi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # EphJpl
2
+
3
+ ## Introduction
4
+
5
+ This is the gem library which calculates ephemeris datas by JPL(NASA Jet Propulsion Laboratory) method.
6
+
7
+ This library calculates rectangular coordinates and velocities of a target astronomical body which made an astronomical body the center on a Julian Day.(Coordinate system is ICRS)
8
+
9
+ ### What's JPL?
10
+
11
+ Please refer the following link.
12
+
13
+ * [NASA Jet Propulsion Laboratory (JPL) - Space Mission and Science News, Videos and Images](http://www.jpl.nasa.gov/)
14
+
15
+ Please refer the following links about DE datas.
16
+
17
+ * [HORIZONS System](http://ssd.jpl.nasa.gov/?horizons)
18
+ * [ftp://ssd.jpl.nasa.gov/pub/eph/planets/](ftp://ssd.jpl.nasa.gov/pub/eph/planets/)
19
+
20
+ To understand this library's in-depth specification, you need to comprehend contents of the following link well.
21
+
22
+ * [testeph.f - JPL](ftp://ssd.jpl.nasa.gov/pub/eph/planets/fortran/testeph.f)
23
+
24
+ ### Supported DE Ver.
25
+
26
+ This library supports only DE430, now.
27
+
28
+ ### Settable astronomical bodies as target and center numbers.
29
+
30
+ 1. Mercury
31
+ 2. Venus
32
+ 3. Earth
33
+ 4. Mars
34
+ 5. Jupiter
35
+ 6. Saturn
36
+ 7. Uranus
37
+ 8. Neptune
38
+ 9. Pluto
39
+ 10. Moon
40
+ 11. Sun
41
+ 12. Solar system Barycenter
42
+ 13. Earth-Moon barycenter
43
+ 14. Earth Nutations
44
+ 15. Lunar mantle Librations
45
+
46
+ ## Installation
47
+
48
+ Add this line to your application's Gemfile:
49
+
50
+ ```ruby
51
+ gem 'eph_jpl'
52
+ ```
53
+
54
+ And then execute:
55
+
56
+ $ bundle
57
+
58
+ Or install it yourself as:
59
+
60
+ $ gem install eph_jpl
61
+
62
+ ## Usage
63
+
64
+ ``` ruby
65
+ obj = EphJpl.new("/path/to/JPLEPH", 11, 3, 2457465.5)
66
+
67
+ p obj.target #=> Target atronomical body No. (Integer)
68
+ p obj.target_name #=> Target atronomical body name (String)
69
+ p obj.center #=> Center atronomical body No. (Integer)
70
+ p obj.center_name #=> Center atronomical body name (String)
71
+ p obj.jd #=> Julian Day (Float)
72
+ p obj.km #=> KM flag (true: km unit, false: AU unit) (Boolean)
73
+ p obj.unit #=> UNIT of positions and velocities (String)
74
+ p obj.bin #=> Acquired data from binary file (Hash)
75
+ p obj.calc #=> [x, y, z-position, x, y, z-velocity]
76
+ ```
77
+
78
+ About arguments for target and center astronomical bodies.
79
+
80
+ * You can set a integer betweetn 1 and 15 as a target astronomical body.
81
+ * You can set a integer betweetn 0 and 13 as a center astronomical body.
82
+
83
+ About units.
84
+
85
+ * If a target astronomical body number < 14 and KM flag = false, units of position and velocity are au, au/day.
86
+ * If a target astronomical body number < 14 and KM flag = true, units of position and velocity are km, km/sec.
87
+ * If a target astronomical body number = 14 or 15, units of position and velocity are rad, rad/day.
88
+
89
+ ## Development
90
+
91
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. Run `bundle exec eph_jpl` to use the gem in this directory, ignoring other installed copies of this gem.
92
+
93
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
94
+
95
+ ## Contributing
96
+
97
+ Bug reports and pull requests are welcome on GitHub at https://github.com/komasaru/eph_jpl.
98
+
99
+
100
+ ## License
101
+
102
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
103
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "eph_jpl"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/eph_jpl.gemspec ADDED
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'eph_jpl/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "eph_jpl"
8
+ spec.version = EphJpl::VERSION
9
+ spec.authors = ["komasaru"]
10
+ spec.email = ["masaru@mk-mode.com"]
11
+
12
+ spec.summary = %q{Ephemeris calculation tool by JPL method.}
13
+ spec.description = %q{EphJcg is a ephemeris calculation tool by JPL method.}
14
+ spec.homepage = "https://github.com/komasaru/eph_jpl"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
+ # delete this section to allow pushing this gem to any host.
19
+ #if spec.respond_to?(:metadata)
20
+ # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
21
+ #else
22
+ # raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ #end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_development_dependency "bundler", "~> 1.11"
31
+ spec.add_development_dependency "rake", "~> 10.0"
32
+ spec.add_development_dependency "rspec", "~> 3.0"
33
+ end
data/exe/eph_jpl ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "eph_jpl"
4
+
5
+ # e.g. `bundle exec exe/eph_jpl ~/src/ephemeris_jpl/JPLEPH 11 3 2457465.5` # 2016-03-18
6
+ o = EphJpl.new(*ARGV)
7
+ str = "TARGET = #{o.target} (#{o.target_name})\n"
8
+ str << "CENTER = #{o.center} (#{o.center_name})\n"
9
+ str << " JD = #{o.jd}\n"
10
+ str << " UNIT = #{o.unit}"
11
+ puts str
12
+ #p o.bin
13
+ p o.calc
14
+
@@ -0,0 +1,87 @@
1
+ module EphJpl
2
+ class Argument
3
+ def initialize(*args)
4
+ @args = *args
5
+ end
6
+
7
+ #=========================================================================
8
+ # 引数取得
9
+ #
10
+ # @return: [BIN_PATH, TARGET, CENTER, JD, KM]
11
+ #=========================================================================
12
+ def get_args
13
+ bin_path = get_binpath
14
+ target = get_target
15
+ center = get_center
16
+ jd = get_jd
17
+ km = get_km
18
+ check_bin_path(bin_path)
19
+ check_target_center(target, center)
20
+ return [bin_path, target, center, jd, km]
21
+ rescue => e
22
+ raise
23
+ end
24
+
25
+ def get_binpath
26
+ raise unless bin_path = @args.shift
27
+ return bin_path
28
+ rescue => e
29
+ raise Const::MSG_ERR_1
30
+ end
31
+
32
+ def get_target
33
+ raise unless target = @args.shift
34
+ raise unless target.to_s =~ /^\d+$/
35
+ raise if target.to_i < 1 || 15 < target.to_i
36
+ return target.to_i
37
+ rescue => e
38
+ raise Const::MSG_ERR_3
39
+ end
40
+
41
+ def get_center
42
+ raise unless center = @args.shift
43
+ raise unless center.to_s =~ /^\d+$/
44
+ raise if center.to_i < 0 || 13 < center.to_i
45
+ return center.to_i
46
+ rescue => e
47
+ raise Const::MSG_ERR_4
48
+ end
49
+
50
+ def get_jd
51
+ raise unless jd = @args.shift
52
+ if jd.to_s !~ /^[\d\.]+$/ || \
53
+ jd.to_f < Const::EPOCH_PERIOD[0] || \
54
+ Const::EPOCH_PERIOD[1] < jd.to_f
55
+ raise
56
+ end
57
+ return jd.to_f
58
+ rescue => e
59
+ raise Const::MSG_ERR_7
60
+ end
61
+
62
+ def get_km
63
+ km = @args.shift
64
+ km ||= Const::KM
65
+ raise unless km.to_s =~ /^true|false|[01]$/
66
+ km = km.to_s =~ /0|false/ ? false : true
67
+ return km
68
+ rescue => e
69
+ raise Const::MSG_ERR_8
70
+ end
71
+
72
+ def check_target_center(target, center)
73
+ case
74
+ when target == center
75
+ raise Const::MSG_ERR_5
76
+ when target < 14 && center == 0,
77
+ target > 13 && center != 0
78
+ raise Const::MSG_ERR_6
79
+ end
80
+ end
81
+
82
+ def check_bin_path(bin_path)
83
+ raise Const::MSG_ERR_2 unless File.exist?(bin_path)
84
+ end
85
+ end
86
+ end
87
+
@@ -0,0 +1,270 @@
1
+ module EphJpl
2
+ class Binary
3
+ def initialize(*args)
4
+ @bin_path, @target, @center, @jd = *args
5
+ @pos = 0
6
+ end
7
+
8
+ def get_binary
9
+ begin
10
+ ttl = get_ttl # TTL
11
+ cnams = get_cnams # CNAM
12
+ sss = get_sss # SS
13
+ ncon = get_ncon # NCON
14
+ au = get_au # AU
15
+ emrat = get_emrat # EMRAT
16
+ ipts = get_ipts # IPT
17
+ numde = get_numde # NUMDE
18
+ ipts << get_ipts_13 # IPT(Month's libration)
19
+ cvals = get_cvals(ncon) # CVAL(定数値)
20
+ jdepoc = cvals[4] # JDEPOC
21
+ coeffs, jds_cheb = get_coeffs(sss, ipts) # Coefficient, JDs(for Chebyshev polynomial)
22
+ return {
23
+ ttl: ttl, cnams: cnams, sss: sss, ncon: ncon, au: au, emrat: emrat,
24
+ numde: numde, ipts: ipts, cvals: cvals, jdepoc: jdepoc,
25
+ coeffs: coeffs, jds_cheb: jds_cheb
26
+ }
27
+ rescue => e
28
+ raise
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ #=========================================================================
35
+ # TTL
36
+ #
37
+ # @param: <none>
38
+ # @return: TTL
39
+ #=========================================================================
40
+ def get_ttl
41
+ recl = 84
42
+
43
+ begin
44
+ ttl = (0..2).map do |i|
45
+ File.binread(@bin_path, recl, @pos + recl * i).unpack("A*")[0]
46
+ end.join("\n")
47
+ @pos += recl * 3
48
+ return ttl
49
+ rescue => e
50
+ raise
51
+ end
52
+ end
53
+
54
+ #=========================================================================
55
+ # CNAM
56
+ #
57
+ # @param: <none>
58
+ # @return: Array of CNAM
59
+ #=========================================================================
60
+ def get_cnams
61
+ recl = 6
62
+
63
+ begin
64
+ cnams = (0..399).map do |i|
65
+ File.binread(@bin_path, recl, @pos + recl * i).unpack("A*")[0]
66
+ end
67
+ @pos += recl * 400
68
+ return cnams
69
+ rescue => e
70
+ raise
71
+ end
72
+ end
73
+
74
+ #=========================================================================
75
+ # SS
76
+ #
77
+ # @param: <none>
78
+ # @return: Array of SS
79
+ #=========================================================================
80
+ def get_sss
81
+ recl = 8
82
+
83
+ begin
84
+ sss = (0..2).map do |i|
85
+ File.binread(@bin_path, recl, @pos + recl * i).unpack("d*")[0]
86
+ end
87
+ @pos += recl * 3
88
+ return sss
89
+ rescue => e
90
+ raise
91
+ end
92
+ end
93
+
94
+ #=========================================================================
95
+ # NCON
96
+ #
97
+ # @param: <none>
98
+ # @return: NCON
99
+ #=========================================================================
100
+ def get_ncon
101
+ recl = 4
102
+
103
+ begin
104
+ ncon = File.binread(@bin_path, recl, @pos).unpack("I*")[0]
105
+ @pos += recl
106
+ return ncon
107
+ rescue => e
108
+ raise
109
+ end
110
+ end
111
+
112
+ #=========================================================================
113
+ # AU
114
+ #
115
+ # @param: <none>
116
+ # @return: AU
117
+ #=========================================================================
118
+ def get_au
119
+ recl = 8
120
+
121
+ begin
122
+ au = File.binread(@bin_path, recl, @pos).unpack("d*")[0]
123
+ @pos += recl
124
+ return au
125
+ rescue => e
126
+ raise
127
+ end
128
+ end
129
+
130
+ #=========================================================================
131
+ # EMRAT
132
+ #
133
+ # @param: <none>
134
+ # @return: <none>
135
+ #=========================================================================
136
+ def get_emrat
137
+ recl = 8
138
+
139
+ begin
140
+ emrat = File.binread(@bin_path, recl, @pos).unpack("d*")[0]
141
+ @pos += recl
142
+ return emrat
143
+ rescue => e
144
+ raise
145
+ end
146
+ end
147
+
148
+ #=========================================================================
149
+ # IPT
150
+ #
151
+ # @param: <none>
152
+ # @return: Array of IPT
153
+ #=========================================================================
154
+ def get_ipts
155
+ recl = 4
156
+
157
+ begin
158
+ ipts = (0..11).map do |i|
159
+ ary = (0..2).map do |j|
160
+ File.binread(@bin_path, recl, @pos + recl * j).unpack("I*")[0]
161
+ end
162
+ @pos += recl * 3
163
+ ary
164
+ end
165
+ return ipts
166
+ rescue => e
167
+ raise
168
+ end
169
+ end
170
+
171
+ #=========================================================================
172
+ # NUMDE
173
+ #
174
+ # * If NUMDE != 430, raise error!
175
+ #
176
+ # @param: <none>
177
+ # @return: NUMDE
178
+ #=========================================================================
179
+ def get_numde
180
+ recl = 4
181
+
182
+ begin
183
+ numde = File.binread(@bin_path, recl, @pos).unpack("I*")[0]
184
+ raise Const::MSG_ERR_8 unless numde == 430
185
+ @pos += recl
186
+ return numde
187
+ rescue => e
188
+ raise
189
+ end
190
+ end
191
+
192
+ #=========================================================================
193
+ # IPT_13(Month's libration)
194
+ #
195
+ # @param: <none>
196
+ # @return: Array of IPT
197
+ #=========================================================================
198
+ def get_ipts_13
199
+ recl = 4
200
+
201
+ begin
202
+ ipts = (0..2).map do |i|
203
+ File.binread(@bin_path, recl, @pos + recl * i).unpack("I*")[0]
204
+ end
205
+ @pos += recl * 3
206
+ return ipts
207
+ rescue => e
208
+ raise
209
+ end
210
+ end
211
+
212
+ #=========================================================================
213
+ # CVAL
214
+ #
215
+ # @param: NCON
216
+ # @return: Array of CVAL
217
+ #=========================================================================
218
+ def get_cvals(ncon)
219
+ pos = Const::KSIZE * Const::RECL
220
+ recl = 8
221
+
222
+ begin
223
+ return (0..ncon - 1).map do |i|
224
+ File.binread(@bin_path, recl, pos + recl * i).unpack("d*")[0]
225
+ end
226
+ rescue => e
227
+ raise
228
+ end
229
+ end
230
+
231
+ #=========================================================================
232
+ # COEFF
233
+ #
234
+ # * Set JD(start, end) for Chebyshev polynomial to the array @jd_cheb
235
+ #
236
+ # @param: Array of SS
237
+ # @param: Array of IPT
238
+ # @return: <none>
239
+ #=========================================================================
240
+ def get_coeffs(sss, ipts)
241
+ idx = ((@jd - sss[0]) / sss[2]).floor # レコードインデックス
242
+ pos = Const::KSIZE * Const::RECL * (2 + idx)
243
+ recl = 8
244
+ coeffs = Array.new
245
+
246
+ begin
247
+ items = (0..(Const::KSIZE / 2) - 1).map do |i|
248
+ File.binread(@bin_path, recl, pos + recl * i).unpack("d*")[0]
249
+ end
250
+ jd_cheb = [items.shift, items.shift]
251
+ ipts.each_with_index do |ipt, i|
252
+ n = i == 11 ? 2 : 3 # 要素数
253
+ ary_1 = Array.new
254
+ ipt[2].times do |j|
255
+ ary_0 = Array.new
256
+ n.times do |k|
257
+ ary_0 << items.shift(ipt[1])
258
+ end
259
+ ary_1 << ary_0
260
+ end
261
+ coeffs << ary_1
262
+ end
263
+ return [coeffs, jd_cheb]
264
+ rescue => e
265
+ raise
266
+ end
267
+ end
268
+ end
269
+ end
270
+
@@ -0,0 +1,36 @@
1
+ module EphJpl
2
+ module Const
3
+ USAGE = <<-EOS
4
+ [USAGE] EphJpl.new(BIN_PATH, TARGET, CENTER, JD)
5
+ [ASTRO NO] (TARGET: 1 - 15, CENTER: 0 - 13)
6
+ 1: Mercury, 2: Venus, 3: Earth, 4: Mars, 5: Jupiter,
7
+ 6: Saturn, 7: Uranus, 8: Neptune, 9: Pluto, 10: Moon,
8
+ 11: Sun, 12: Solar system Barycenter, 13: Earth-Moon barycenter,
9
+ 14: Earth Nutations, 15: Lunar mantle Librations
10
+ * If TARGET = 14 or 15, CENTER = 0
11
+ * TARGET != CENTER
12
+ * 2287184.5 <= JD <= 2688976.5
13
+ EOS
14
+ MSG_ERR_1 = "Binary file path is invalid!"
15
+ MSG_ERR_2 = "Binary file is not found!"
16
+ MSG_ERR_3 = "TARGET is invalid!"
17
+ MSG_ERR_4 = "CENTER is invalid!"
18
+ MSG_ERR_5 = "TARGET == CENTER ?"
19
+ MSG_ERR_6 = "TARGET or CENTER is invalid!"
20
+ MSG_ERR_7 = "JD is invalid!"
21
+ MSG_ERR_8 = "KM flag is invalid!"
22
+ MSG_ERR_9 = "This library is supporting only DE430!"
23
+ EPOCH_PERIOD = [2287184.5, 2688976.5]
24
+ KSIZE = 2036
25
+ RECL = 4
26
+ ASTRS = [
27
+ "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus",
28
+ "Neptune", "Pluto", "Moon", "Sun", "Solar system Barycenter",
29
+ "Earth-Moon barycenter", "Earth Nutations", "Lunar mantle Librations"
30
+ ]
31
+ KIND = 2
32
+ BARY = true
33
+ KM = false
34
+ end
35
+ end
36
+
@@ -0,0 +1,195 @@
1
+ module EphJpl
2
+ class Ephemeris
3
+ attr_reader :target, :center, :jd, :bin, :km,
4
+ :target_name, :center_name, :unit
5
+
6
+ def initialize(target, center, jd, bin, km = false)
7
+ @target, @center, @jd, @km = target, center, jd, km
8
+ @target_name = Const::ASTRS[@target - 1]
9
+ @center_name = Const::ASTRS[@center - 1]
10
+ @unit = @target > 13 ? "rad, rad/day" : @km ? "km, km/sec" : "AU, AU/day"
11
+ @bin = bin
12
+ @list = get_list
13
+ end
14
+
15
+ def calc
16
+ pvs = Array.new(11).map { |a| Array.new(6, 0.0) } # for position, velocity
17
+ pvs_tmp = Array.new(13) # Temporary array for position, velocity of target and center
18
+ rrds = Array.new(6, 0.0) # for calculated data (difference between target and center)
19
+
20
+ begin
21
+ # Interpolate (11:Sun)
22
+ pv_sun = interpolate(11)
23
+ # Interpolate (1:Mercury - 10:Moon)
24
+ 0.upto(9) do |i|
25
+ next if @list[i] == 0
26
+ pvs[i] = interpolate(i + 1)
27
+ next if i > 8
28
+ next if Const::BARY
29
+ pvs[i] = pvs[i].map.with_index do |pv, j|
30
+ pv - pv_sun[j]
31
+ end
32
+ end
33
+ # Interpolate (14:Nutation)
34
+ if @list[10] > 0 && @bin[:ipts][11][1] > 0
35
+ p_nut = interpolate(14)
36
+ end
37
+ # Interpolate (15:Libration)
38
+ if @list[11] > 0 && @bin[:ipts][12][1] > 0
39
+ pvs[10] = interpolate(15)
40
+ end
41
+
42
+ # Difference between target and center
43
+ case
44
+ when @target == 14
45
+ rrds = p_nut if @bin[:ipts][11][1] > 0
46
+ when @target == 15
47
+ rrds = pvs[10] if @bin[:ipts][12][1] > 0
48
+ else
49
+ 0.upto(9) { |i| pvs_tmp[i] = pvs[i] }
50
+ pvs_tmp[10] = pv_sun if [@target, @center].include?(11)
51
+ pvs_tmp[11] = Array.new(6, 0.0) if [@target, @center].include?(12)
52
+ pvs_tmp[12] = pvs[2] if [@target, @center].include?(13)
53
+ if @target * @center == 30 || @target + @center == 13
54
+ pvs_tmp[2] = Array.new(6, 0.0)
55
+ else
56
+ pvs_tmp[2] = pvs[2].map.with_index do |pv, i|
57
+ pv - pvs[9][i] / (1.0 + @bin[:emrat])
58
+ end unless @list[2] == 0
59
+ pvs_tmp[9] = pvs_tmp[2].map.with_index do |pv, i|
60
+ pv + pvs[9][i]
61
+ end unless @list[9] == 0
62
+ end
63
+ 0.upto(5) do |i|
64
+ rrds[i] = pvs_tmp[@target - 1][i] - pvs_tmp[@center - 1][i]
65
+ end
66
+ end
67
+ return rrds
68
+ rescue => e
69
+ raise
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ #=========================================================================
76
+ # Computation target list
77
+ #
78
+ # @param: <none>
79
+ # @return: Array
80
+ #=========================================================================
81
+ def get_list
82
+ list = Array.new(12, 0)
83
+
84
+ begin
85
+ if @target == 14
86
+ list[10] = Const::KIND if @bin[:ipts][11][1] > 0
87
+ return list
88
+ end
89
+ if @target == 15
90
+ list[11] = Const::KIND if @bin[:ipts][12][1] > 0
91
+ return list
92
+ end
93
+ [@target, @center].each do |k|
94
+ list[k - 1] = Const::KIND if k <= 10
95
+ list[2] = Const::KIND if k == 10
96
+ list[9] = Const::KIND if k == 3
97
+ list[2] = Const::KIND if k == 13
98
+ end
99
+ return list
100
+ rescue => e
101
+ raise
102
+ end
103
+ end
104
+
105
+ #=========================================================================
106
+ # Interpolate by Chebyshev's Polynomial
107
+ #
108
+ # * Case astro-no
109
+ # 1 ... 13: Position and velocity of x, y, z (6 items)
110
+ # 14: Angular position and volocity of delta Psi, delta Epsilon (4 items)
111
+ # 15: Angular position and volocity of Phi, Theta, Psi (6 items)
112
+ # * If astro-no = 12, then location and volocity of x, y, z are all 0.0.
113
+ #
114
+ # @param: astr (= astronomical no)
115
+ # @return: pvs = [
116
+ # x-position, y-position, z-position,
117
+ # x-velocity, y-velocity, z-velocity
118
+ # ]
119
+ # Case: 14:Nutation
120
+ # pvs = [
121
+ # delta-psi-angular-position, delta-epsilon-angular-position,
122
+ # delta-psi-angular-velocity, delta-epsilon-angular-velocity
123
+ # ]
124
+ # Case: 15:Libration
125
+ # pvs = [
126
+ # phi-angular-position, theta-angular-position, psi-angular-position,
127
+ # phi-angular-velocity, theta-angular-velocity, psi-angular-velocity
128
+ # ]
129
+ #=========================================================================
130
+ def interpolate(astr)
131
+ pvs = Array.new
132
+
133
+ begin
134
+ tc, idx_sub = norm_time(astr)
135
+ n_item = astr == 14 ? 2 : 3 # 要素数
136
+ i_ipt = astr > 13 ? astr - 3 : astr - 1
137
+ i_coef = astr > 13 ? astr - 3 : astr - 1
138
+
139
+ # 位置
140
+ ary_p = [1, tc]
141
+ 2.upto(@bin[:ipts][i_ipt][1] - 1) do |i|
142
+ ary_p << 2 * tc * ary_p[-1] - ary_p[-2]
143
+ end # 各項
144
+ 0.upto(n_item - 1) do |i|
145
+ val = 0
146
+ 0.upto(@bin[:ipts][i_ipt][1] - 1) do |j|
147
+ val += @bin[:coeffs][i_coef][idx_sub][i][j] * ary_p[j]
148
+ end
149
+ val /= @bin[:au] if !@km && astr < 14
150
+ pvs << val
151
+ end # 値
152
+
153
+ # 速度
154
+ ary_v = [0, 1, 2 * 2 * tc]
155
+ 3.upto(@bin[:ipts][i_ipt][1] - 1) do |i|
156
+ ary_v << 2 * tc * ary_v[-1] + 2 * ary_p[i - 1] - ary_v[-2]
157
+ end # 各項
158
+ 0.upto(n_item - 1) do |i|
159
+ val = 0
160
+ 0.upto(@bin[:ipts][i_ipt][1] - 1) do |j|
161
+ val += @bin[:coeffs][i_coef][idx_sub][i][j] * ary_v[j] * 2 * @bin[:ipts][i_ipt][2] / @bin[:sss][2].to_f
162
+ end
163
+ if astr < 14
164
+ val /= @bin[:au] unless @km
165
+ val /= 86400.0 if @km
166
+ end
167
+ pvs << val
168
+ end # 値
169
+
170
+ return pvs
171
+ rescue => e
172
+ raise
173
+ end
174
+ end
175
+
176
+ #=========================================================================
177
+ # Time normalization, sub-period's index calculation for Chebyshev's Polynomial
178
+ #
179
+ # @param: astr (= atronomical no)
180
+ # @return: [chebyshev-time, sub-index]
181
+ #=========================================================================
182
+ def norm_time(astr)
183
+ idx = astr > 13 ? astr - 2 : astr
184
+ jd_start = @bin[:jds_cheb][0]
185
+ tc = (@jd - jd_start) / @bin[:sss][2].to_f
186
+ temp = tc * @bin[:ipts][idx - 1][2]
187
+ idx = (temp - tc.floor).floor # サブ区間のインデックス
188
+ tc = (temp % 1.0 + tc.floor) * 2 - 1 # チェビシェフ時間
189
+ return [tc, idx]
190
+ rescue => e
191
+ raise
192
+ end
193
+ end
194
+ end
195
+
@@ -0,0 +1,3 @@
1
+ module EphJpl
2
+ VERSION = "0.1.0"
3
+ end
data/lib/eph_jpl.rb ADDED
@@ -0,0 +1,14 @@
1
+ require "eph_jpl/version"
2
+ require "eph_jpl/argument"
3
+ require "eph_jpl/binary"
4
+ require "eph_jpl/const"
5
+ require "eph_jpl/ephemeris"
6
+
7
+ module EphJpl
8
+ def self.new(*args)
9
+ bin_path, target, center, jd, km = Argument.new(*args).get_args
10
+ bin = Binary.new(bin_path, target, center, jd).get_binary
11
+ return EphJpl::Ephemeris.new(target, center, jd, bin, km)
12
+ end
13
+ end
14
+
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eph_jpl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - komasaru
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-06-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: EphJcg is a ephemeris calculation tool by JPL method.
56
+ email:
57
+ - masaru@mk-mode.com
58
+ executables:
59
+ - eph_jpl
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - ".travis.yml"
66
+ - Gemfile
67
+ - Guardfile
68
+ - LICENSE.txt
69
+ - README.md
70
+ - Rakefile
71
+ - bin/console
72
+ - bin/setup
73
+ - eph_jpl.gemspec
74
+ - exe/eph_jpl
75
+ - lib/eph_jpl.rb
76
+ - lib/eph_jpl/argument.rb
77
+ - lib/eph_jpl/binary.rb
78
+ - lib/eph_jpl/const.rb
79
+ - lib/eph_jpl/ephemeris.rb
80
+ - lib/eph_jpl/version.rb
81
+ homepage: https://github.com/komasaru/eph_jpl
82
+ licenses:
83
+ - MIT
84
+ metadata: {}
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 2.6.4
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: Ephemeris calculation tool by JPL method.
105
+ test_files: []