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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +10 -0
- data/Guardfile +70 -0
- data/LICENSE.txt +21 -0
- data/README.md +103 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/eph_jpl.gemspec +33 -0
- data/exe/eph_jpl +14 -0
- data/lib/eph_jpl/argument.rb +87 -0
- data/lib/eph_jpl/binary.rb +270 -0
- data/lib/eph_jpl/const.rb +36 -0
- data/lib/eph_jpl/ephemeris.rb +195 -0
- data/lib/eph_jpl/version.rb +3 -0
- data/lib/eph_jpl.rb +14 -0
- metadata +105 -0
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
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
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
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
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
|
+
|
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: []
|