CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-spiceypy

A Python wrapper for the NAIF CSPICE Toolkit providing essential tools for spacecraft navigation and planetary science calculations

Overview
Eval results
Files

ck-orientation.mddocs/

CK (C-Kernels/Orientation Data)

Spacecraft and instrument attitude/pointing data management using C-kernels. CK files store time-ordered orientation information that describes how spacecraft, instruments, and reference frames are oriented in space, enabling precise pointing calculations for observations and navigation.

Capabilities

CK File Operations

Create, open, and manage CK files containing orientation data.

def ckopn(fname: str, ifname: str, ncomch: int) -> int:
    """
    Open new CK file for writing.
    
    Parameters:
    - fname: str, CK file name
    - ifname: str, internal file name
    - ncomch: int, number of comment characters
    
    Returns:
    int: file handle
    """

def ckcls(handle: int) -> None:
    """
    Close CK file.
    
    Parameters:
    - handle: int, file handle
    
    Returns:
    None
    """

Pointing Data Retrieval

Get spacecraft and instrument pointing information from CK files.

def ckgp(inst: int, sclkdp: float, tol: float, ref: str) -> Tuple[ndarray, float, bool]:
    """
    Get pointing (attitude matrix) from CK file.
    
    Parameters:
    - inst: int, instrument ID code
    - sclkdp: float, spacecraft clock time
    - tol: float, time tolerance
    - ref: str, reference frame
    
    Returns:
    Tuple[ndarray, float, bool]: (c_matrix, clkout, found)
    """

def ckgpav(inst: int, sclkdp: float, tol: float, ref: str) -> Tuple[ndarray, ndarray, float, bool]:
    """
    Get pointing and angular velocity from CK file.
    
    Parameters:
    - inst: int, instrument ID code
    - sclkdp: float, spacecraft clock time
    - tol: float, time tolerance
    - ref: str, reference frame
    
    Returns:
    Tuple[ndarray, ndarray, float, bool]: (c_matrix, av, clkout, found)
    """

Frame Transformations

Compute orientation transformations between reference frames.

def ckfrot(inst: int, et: float) -> Tuple[ndarray, str, bool]:
    """
    Get frame rotation from CK file using ET.
    
    Parameters:
    - inst: int, instrument ID code  
    - et: float, ephemeris time
    
    Returns:
    Tuple[ndarray, str, bool]: (rotate, ref, found)
    """

def ckfxfm(inst: int, et: float) -> Tuple[ndarray, str, bool]:
    """
    Get frame transformation (6x6 state matrix) from CK file.
    
    Parameters:
    - inst: int, instrument ID code
    - et: float, ephemeris time
    
    Returns:
    Tuple[ndarray, str, bool]: (xform, ref, found)
    """

CK Data Writing

Write various types of CK segments for different attitude parameterizations.

def ckw01(handle: int, begtim: float, endtim: float, inst: int, ref: str, avflag: bool, segid: str, nrec: int, sclkdp: ndarray, quats: ndarray, avvs: ndarray) -> None:
    """
    Write Type 1 CK segment (discrete pointing).
    
    Parameters:
    - handle: int, file handle
    - begtim: float, segment begin time
    - endtim: float, segment end time
    - inst: int, instrument ID
    - ref: str, reference frame
    - avflag: bool, angular velocity flag
    - segid: str, segment identifier
    - nrec: int, number of records
    - sclkdp: ndarray, spacecraft clock times
    - quats: ndarray, quaternions (4 x nrec)
    - avvs: ndarray, angular velocities (3 x nrec)
    
    Returns:
    None
    """

def ckw02(handle: int, begtim: float, endtim: float, inst: int, ref: str, segid: str, nrec: int, start: ndarray, stop: ndarray, quats: ndarray, avvs: ndarray, rates: ndarray) -> None:
    """
    Write Type 2 CK segment (linearly interpolated pointing).
    
    Parameters:
    - handle: int, file handle
    - begtim: float, segment begin time
    - endtim: float, segment end time
    - inst: int, instrument ID
    - ref: str, reference frame
    - segid: str, segment identifier
    - nrec: int, number of records
    - start: ndarray, interval start times
    - stop: ndarray, interval stop times
    - quats: ndarray, quaternions
    - avvs: ndarray, angular velocities
    - rates: ndarray, angular acceleration
    
    Returns:
    None
    """

def ckw03(handle: int, begtim: float, endtim: float, inst: int, ref: str, avflag: bool, segid: str, nrec: int, sclkdp: ndarray, quats: ndarray, avvs: ndarray, nints: int, starts: ndarray) -> None:
    """
    Write Type 3 CK segment (Chebyshev polynomials).
    
    Parameters:
    - handle: int, file handle
    - begtim: float, segment begin time
    - endtim: float, segment end time
    - inst: int, instrument ID
    - ref: str, reference frame
    - avflag: bool, angular velocity flag
    - segid: str, segment identifier
    - nrec: int, number of records
    - sclkdp: ndarray, spacecraft clock times
    - quats: ndarray, quaternions
    - avvs: ndarray, angular velocities
    - nints: int, number of intervals
    - starts: ndarray, interval start indices
    
    Returns:
    None
    """

def ckw05(handle: int, subtype: int, degree: int, begtim: float, endtim: float, inst: int, ref: str, avflag: bool, segid: str, n: int, sclkdp: ndarray, packts: ndarray, rate: float, nints: int, starts: ndarray) -> None:
    """
    Write Type 5 CK segment (MEX/Rosetta format).
    
    Parameters:
    - handle: int, file handle
    - subtype: int, subtype code
    - degree: int, polynomial degree
    - begtim: float, segment begin time
    - endtim: float, segment end time
    - inst: int, instrument ID
    - ref: str, reference frame
    - avflag: bool, angular velocity flag
    - segid: str, segment identifier
    - n: int, number of packets
    - sclkdp: ndarray, spacecraft clock times
    - packts: ndarray, data packets
    - rate: float, nominal tick rate
    - nints: int, number of intervals
    - starts: ndarray, interval start indices
    
    Returns:
    None
    """

CK Coverage Analysis

Analyze time coverage and data availability in CK files.

def ckcov(ck: str, idcode: int, needav: bool, level: str, tol: float, timsys: str, cover: SpiceCell) -> None:
    """
    Find time coverage windows for CK object.
    
    Parameters:
    - ck: str, CK file name
    - idcode: int, instrument/spacecraft ID
    - needav: bool, require angular velocity data
    - level: str, coverage level ("SEGMENT" or "INTERVAL")
    - tol: float, time tolerance
    - timsys: str, time system ("SCLK" or "TDB")
    - cover: SpiceCell, coverage window (modified)
    
    Returns:
    None (coverage window updated in place)
    """

def ckobj(ck: str) -> List[int]:
    """
    Get object ID codes for all objects in CK file.
    
    Parameters:
    - ck: str, CK file name
    
    Returns:
    List[int]: object ID codes
    """

Low-Level Profile Access

Access raw CK data at the segment level.

def cklpf(fname: str) -> int:
    """
    Load CK file, return handle.
    
    Parameters:
    - fname: str, CK file name
    
    Returns:
    int: file handle
    """

def ckupf(handle: int) -> None:
    """
    Unload CK file.
    
    Parameters:
    - handle: int, file handle
    
    Returns:
    None
    """

Segment Information

Query metadata and structure of CK segments.

def cknr02(handle: int, descr: SpiceDLADescr) -> int:
    """
    Get number of records in Type 2 CK segment.
    
    Parameters:
    - handle: int, CK file handle
    - descr: SpiceDLADescr, segment descriptor
    
    Returns:
    int: number of records
    """

def cknr03(handle: int, descr: SpiceDLADescr) -> int:
    """
    Get number of records in Type 3 CK segment.
    
    Parameters:
    - handle: int, CK file handle
    - descr: SpiceDLADescr, segment descriptor
    
    Returns:
    int: number of records
    """

def ckgr02(handle: int, descr: SpiceDLADescr, recno: int) -> Tuple[float, float, ndarray, ndarray, float]:
    """
    Get record from Type 2 CK segment.
    
    Parameters:
    - handle: int, CK file handle
    - descr: SpiceDLADescr, segment descriptor
    - recno: int, record number
    
    Returns:
    Tuple[float, float, ndarray, ndarray, float]: (start, stop, quat, av, rate)
    """

def ckgr03(handle: int, descr: SpiceDLADescr, recno: int) -> Tuple[float, ndarray, ndarray]:
    """
    Get record from Type 3 CK segment.
    
    Parameters:
    - handle: int, CK file handle
    - descr: SpiceDLADescr, segment descriptor
    - recno: int, record number
    
    Returns:
    Tuple[float, ndarray, ndarray]: (sclkdp, quat, av)
    """

CK Metadata

Get information about loaded CK files and instruments.

def ckmeta(ckid: int, meta: str) -> Union[str, int]:
    """
    Get metadata for CK instrument.
    
    Parameters: 
    - ckid: int, CK instrument ID
    - meta: str, metadata item ("SPK_ID", "FRAME_ID", "FRAME_NAME", etc.)
    
    Returns:
    Union[str, int]: metadata value
    """

Common Usage Patterns

Getting Spacecraft Attitude

import spiceypy as spice
import numpy as np

# Load CK file and other kernels
spice.furnsh("spacecraft_attitude.bc")
spice.furnsh("spacecraft_sclk.tsc")

# Convert time to spacecraft clock
et = spice.str2et("2023-01-01T12:00:00")
spacecraft_id = -123
sclk = spice.sce2s(spacecraft_id, et)

# Get spacecraft pointing matrix
inst_id = -123000  # instrument ID
tolerance = 1.0    # 1 second tolerance
ref_frame = "J2000"

c_matrix, clkout, found = spice.ckgp(inst_id, sclk, tolerance, ref_frame)

if found:
    print(f"Attitude matrix at SCLK {clkout}:")
    print(c_matrix)
    
    # Convert to Euler angles if needed
    angles = spice.m2eul(c_matrix, 3, 1, 3)  # Z-X-Z sequence
    print(f"Euler angles (Z-X-Z): {np.degrees(angles)} degrees")

Getting Attitude with Angular Velocity

# Get both attitude and angular velocity
c_matrix, av, clkout, found = spice.ckgpav(inst_id, sclk, tolerance, ref_frame)

if found:
    print(f"Attitude matrix:\n{c_matrix}")
    print(f"Angular velocity: {av} rad/sec")
    
    # Angular velocity magnitude
    av_magnitude = spice.vnorm(av)
    print(f"Angular velocity magnitude: {av_magnitude} rad/sec")

Creating CK File

import numpy as np

# Open new CK file
handle = spice.ckopn("spacecraft_attitude.bc", "Spacecraft Attitude Data", 0)

# Define attitude data
inst_id = -123000
ref_frame = "J2000"
segment_id = "Attitude Segment 1"

# Time range and data
begin_time = spice.str2et("2023-01-01T00:00:00")  
end_time = spice.str2et("2023-01-02T00:00:00")

# Convert times to spacecraft clock
sclk_times = []
for i in range(24):  # hourly data points
    et = begin_time + i * 3600.0  # hours to seconds
    sclk = spice.sce2s(spacecraft_id, et)
    sclk_times.append(sclk)

sclk_array = np.array(sclk_times)

# Generate quaternions (example: slow rotation about Z-axis)
quaternions = []
angular_velocities = []

for i, sclk in enumerate(sclk_times):
    # Rotation angle increases linearly with time  
    angle = 2 * np.pi * i / len(sclk_times)  # one full rotation per day
    
    # Quaternion for rotation about Z-axis
    quat = np.array([
        np.cos(angle/2), 0, 0, np.sin(angle/2)  # [w, x, y, z]
    ])
    quaternions.append(quat)
    
    # Angular velocity (constant rotation about Z)
    av = np.array([0, 0, 2*np.pi/(24*3600)])  # rad/sec
    angular_velocities.append(av)

quats_array = np.array(quaternions).T  # 4 x N
avs_array = np.array(angular_velocities).T  # 3 x N

# Write Type 1 CK segment
spice.ckw01(
    handle, begin_time, end_time, inst_id, ref_frame,
    True,  # include angular velocity
    segment_id, len(sclk_times), sclk_array, quats_array, avs_array
)

# Close CK file
spice.ckcls(handle)

Analyzing CK Coverage

# Create time window for coverage analysis
coverage = spice.cell_double(1000)

# Find coverage for specific instrument
ck_file = "spacecraft_attitude.bc"
spice.ckcov(
    ck_file,
    inst_id,
    False,      # don't require angular velocity
    "INTERVAL", # interval-level coverage
    0.0,        # no tolerance
    "SCLK",     # spacecraft clock time
    coverage
)

# Display coverage intervals
num_intervals = spice.wncard(coverage)
print(f"Found {num_intervals} coverage intervals:")

for i in range(num_intervals):
    start_sclk, stop_sclk = spice.wnfetd(coverage, i)
    
    # Convert back to ET for display
    start_et = spice.scs2e(spacecraft_id, start_sclk)
    stop_et = spice.scs2e(spacecraft_id, stop_sclk) 
    
    start_utc = spice.et2utc(start_et, "C", 0)
    stop_utc = spice.et2utc(stop_et, "C", 0)
    
    print(f"  Interval {i}: {start_utc} to {stop_utc}")

Querying CK File Contents

# Get all objects in CK file  
object_ids = spice.ckobj("spacecraft_attitude.bc")
print(f"Objects in CK file: {object_ids}")

# Get metadata for each object
for obj_id in object_ids:
    try:
        frame_name = spice.ckmeta(obj_id, "FRAME_NAME")
        frame_id = spice.ckmeta(obj_id, "FRAME_ID")
        print(f"Object {obj_id}: Frame {frame_name} (ID {frame_id})")
    except:
        print(f"Object {obj_id}: Unable to retrieve metadata")

Install with Tessl CLI

npx tessl i tessl/pypi-spiceypy

docs

ck-orientation.md

coordinate-systems.md

data-structures.md

dsk-shape-models.md

e-kernels.md

ephemeris-trajectories.md

error-handling.md

event-finding.md

geometry-surface.md

index.md

kernel-management.md

low-level-file-access.md

physical-constants.md

reference-frames.md

spacecraft-clock.md

time-systems.md

vector-matrix.md

tile.json