Class: Ephem::SPK

Inherits:
Object
  • Object
show all
Defined in:
lib/ephem/spk.rb

Overview

The SPK class represents a SPICE Kernel (SPK) file, which contains ephemeris data for solar system bodies. It manages segments of trajectory data and provides methods to access and manipulate this data.

SPK files contain segments of ephemeris data, where each segment represents the motion of one body (target) with respect to another body (center) over a specific time period.

Examples:

Opening and using an SPK file

spk = Ephem::SPK.open("de421.bsp")
segment = spk[0, 10]
spk.close

Constant Summary collapse

TYPES =
[
  INPOP = "IMCCE INPOP",
  JPL_DE = "JPL DE"
].freeze
INPOP_REGEXP =
/^\s+\d{4}\.\d{5}0+$/
DE_REGEXP =
/^[A-Z]E-(\d{4})LE-\1$/
DE_FILENAME =
"NIO2SPK"
DATA_TYPE_IDENTIFIER =
5
SEGMENT_CLASSES =
{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(daf:) ⇒ SPK

Creates a new SPK instance with the given DAF.

Parameters:

  • daf (Ephem::IO::DAF)

    The DAF (Double precision Array File) containing SPK data

Raises:

  • (ArgumentError)

    If the DAF is nil



37
38
39
40
41
42
43
# File 'lib/ephem/spk.rb', line 37

def initialize(daf:)
  raise ArgumentError, "DAF cannot be nil" if daf.nil?

  @daf = daf
  @segments = load_segments
  @pairs = build_pairs
end

Instance Attribute Details

#pairsObject (readonly)

Returns the value of attribute pairs.



30
31
32
# File 'lib/ephem/spk.rb', line 30

def pairs
  @pairs
end

#segmentsObject (readonly)

Returns the value of attribute segments.



30
31
32
# File 'lib/ephem/spk.rb', line 30

def segments
  @segments
end

Class Method Details

.open(path) ⇒ SPK

Opens an SPK file at the specified path.

Parameters:

  • path (String)

    Path to the SPK file

Returns:

  • (SPK)

    A new SPK instance

Raises:

  • (ArgumentError)

    If the file cannot be accessed due to permissions



50
51
52
53
54
55
# File 'lib/ephem/spk.rb', line 50

def self.open(path)
  daf = IO::DAF.new(File.open(path, "rb"))
  new(daf: daf)
rescue Errno::EACCES => e
  raise ArgumentError, "File permission denied: #{path} (#{e.message})"
end

Instance Method Details

#[](center, target) ⇒ Segments::BaseSegment

Retrieves the segment for a specific center-target pair.

Parameters:

  • center (Integer)

    NAIF ID of the center body

  • target (Integer)

    NAIF ID of the target body

Returns:

Raises:

  • (KeyError)

    If no segment is found for the given center-target pair



83
84
85
86
87
88
# File 'lib/ephem/spk.rb', line 83

def [](center, target)
  @pairs.fetch([center, target]) do
    raise KeyError,
      "No segment found for center: #{center}, target: #{target}"
  end
end

#closevoid

This method returns an undefined value.

Closes the SPK file and cleans up resources. This method should be called when you’re done using the SPK file.



61
62
63
64
# File 'lib/ephem/spk.rb', line 61

def close
  @daf&.close
  @segments&.each(&:clear_data)
end

#commentsString

Returns the comments stored in the SPK file.

Returns:

  • (String)

    The comments from the DAF file



105
106
107
# File 'lib/ephem/spk.rb', line 105

def comments
  @daf.comments
end

#each_segment {|segment| ... } ⇒ Enumerator, void

Iterates through all segments in the SPK file.

Yields:

  • (segment)

    Gives each segment to the block

Yield Parameters:

Returns:

  • (Enumerator)

    If no block is given

  • (void)

    If a block is given



115
116
117
118
119
# File 'lib/ephem/spk.rb', line 115

def each_segment(&block)
  return enum_for(:each_segment) unless block_given?

  @segments.each(&block)
end

#excerpt(output_path:, start_jd:, end_jd:, target_ids: nil, debug: false) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
# File 'lib/ephem/spk.rb', line 121

def excerpt(output_path:, start_jd:, end_jd:, target_ids: nil, debug: false)
  Excerpt
    .new(self)
    .extract(
      output_path: output_path,
      start_jd: start_jd,
      end_jd: end_jd,
      target_ids: target_ids,
      debug: debug
    )
end

#to_sString

Returns a string representation of the SPK file.

Returns:

  • (String)

    A description of the SPK file and its segments



69
70
71
72
73
74
# File 'lib/ephem/spk.rb', line 69

def to_s
  <<~DESCRIPTION
    SPK file with #{@segments.size} segments:
    #{@segments.map(&:to_s).join("\n")}
  DESCRIPTION
end

#typeString?

Type of SPK file to make the difference between JPL DE and IMCCE INPOP

Returns:

  • (String, nil)

    The type of the SPK file



93
94
95
96
97
98
99
100
# File 'lib/ephem/spk.rb', line 93

def type
  @type ||= if @daf.record_data.internal_filename.match?(INPOP_REGEXP)
    INPOP
  elsif @daf.record_data.internal_filename == DE_FILENAME ||
      segments.first&.source&.match?(DE_REGEXP)
    JPL_DE
  end
end