eph_jpl 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []