Class: Ephem::Segments::Segment

Inherits:
BaseSegment show all
Defined in:
lib/ephem/segments/segment.rb

Overview

Manages data segments within SPICE kernel (SPK) files, providing methods to compute positions and velocities of celestial bodies using Chebyshev polynomial approximations.

Each segment contains data for a specific celestial body (target) relative to another body (center) within a specific time range. The data is stored as Chebyshev polynomial coefficients that can be evaluated to obtain position and velocity vectors.

The class provides thread-safe data loading and caching mechanisms to optimize performance while ensuring data consistency in multithreaded environments.

Examples:

Computing position at a specific time

segment = Ephem::Segments::Segment.new(
  daf: daf_object,
  source: "DE440.bsp",
  descriptor: [...]
)
position = segment.compute(time)  # returns Vector

Computing position and velocity

state = segment.compute_and_differentiate(time)  # returns State
position = state.position  # Vector
velocity = state.velocity  # Vector

See Also:

Constant Summary collapse

COMPONENT_COUNTS =
{
  2 => 3,  # Type 2: position (x, y, z)
  3 => 6   # Type 3: position (x, y, z) and velocity (vx, vy, vz)
}.freeze

Constants inherited from BaseSegment

BaseSegment::TARGET_NAMES

Instance Attribute Summary

Attributes inherited from BaseSegment

#center, #daf, #source, #target

Instance Method Summary collapse

Methods inherited from BaseSegment

#describe, #to_s

Methods included from Core::CalendarCalculations

format_date, julian_to_gregorian

Constructor Details

#initialize(daf:, source:, descriptor:) ⇒ Segment

Returns a new instance of Segment.

Parameters:

  • daf (Ephem::IO::DAF)

    DAF file object containing the segment data

  • source (String)

    Name of the source SPK file

  • descriptor (Array)

    Array containing segment metadata:

    • start_second [Float] Start time in seconds from J2000

    • end_second [Float] End time in seconds from J2000

    • target [Integer] NAIF ID of target body

    • center [Integer] NAIF ID of center body

    • frame [Integer] Reference frame ID

    • data_type [Integer] Type of data (2 for position, 3 for pos/vel)

    • start_i [Integer] Start index in DAF array

    • end_i [Integer] End index in DAF array



51
52
53
54
55
# File 'lib/ephem/segments/segment.rb', line 51

def initialize(daf:, source:, descriptor:)
  super
  @data_loaded = false
  @data_lock = Mutex.new
end

Instance Method Details

#clear_datavoid

This method returns an undefined value.

Clears cached coefficient data, forcing reload on next computation.

This method is thread-safe and can be used to free memory or force fresh data loading if needed.



121
122
123
124
125
126
127
128
# File 'lib/ephem/segments/segment.rb', line 121

def clear_data
  @data_lock.synchronize do
    @data_loaded = false
    @midpoints = nil
    @radii = nil
    @coefficients = nil
  end
end

#compute(tdb, tdb2 = 0.0) ⇒ Ephem::Core::Vector Also known as: position_at

Computes the position of the target body relative to the center body at the specified time.

Uses Chebyshev polynomial approximation to interpolate the position from stored coefficients. The computation is thread-safe and uses cached data when available.

Examples:

Computing Earth’s position relative to Solar System Barycenter

position = segment.compute(2451545.0)  # J2000 epoch

Parameters:

  • tdb (Numeric, Array<Numeric>)

    Time(s) in TDB Julian Date

  • tdb2 (Numeric) (defaults to: 0.0)

    Optional fractional part of TDB date

Returns:

Raises:



71
72
73
# File 'lib/ephem/segments/segment.rb', line 71

def compute(tdb, tdb2 = 0.0)
  Core::Vector.new(*generate(tdb, tdb2).first)
end

#compute_and_differentiate(tdb, tdb2 = 0.0) ⇒ Ephem::Core::State+ Also known as: state_at

Computes both position and velocity vectors at the specified time.

Uses Chebyshev polynomial approximation and its derivative to compute both position and velocity. The computation is thread-safe and uses cached data when available.

Examples:

Computing Earth’s state vector

state = segment.compute_and_differentiate(2451545.0)
position = state.position  # in kilometers
velocity = state.velocity  # in kilometers/second

Parameters:

  • tdb (Numeric, Array<Numeric>)

    Time(s) in TDB Julian Date

  • tdb2 (Numeric) (defaults to: 0.0)

    Optional fractional part of TDB date

Returns:

Raises:



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/ephem/segments/segment.rb', line 93

def compute_and_differentiate(tdb, tdb2 = 0.0)
  load_data
  tdb_seconds = convert_to_seconds(tdb, tdb2)

  case tdb_seconds
  when Numeric
    pos_array, vel_array = generate_single(tdb_seconds)
    Core::State.new(
      Core::Vector.new(pos_array[0], pos_array[1], pos_array[2]),
      Core::Vector.new(vel_array[0], vel_array[1], vel_array[2])
    )
  else
    generate_multiple(tdb_seconds).map do |pos_array, vel_array|
      Core::State.new(
        Core::Vector.new(pos_array[0], pos_array[1], pos_array[2]),
        Core::Vector.new(vel_array[0], vel_array[1], vel_array[2])
      )
    end
  end
end