Introduction

The across-tools library provides functionality for:

  • Ephemeris Calculation: Generate positions for spacecraft and ground observatories

  • Visibility Computation: Determine when targets are observable given various constraints

  • Footprint Analysis: Work with instrument fields of view projected on the sky

Let’s explore each of these capabilities.

Core Data Types

The library uses several core data types for representing astronomical coordinates and regions.

[1]:
from across.tools import Coordinate, Polygon

# Create a coordinate representing a position on the sky
coord = Coordinate(ra=180.0, dec=45.0)
print(f"Coordinate: RA={coord.ra}°, Dec={coord.dec}°")

# Create a polygon region on the sky
polygon = Polygon(
    coordinates=[
        Coordinate(ra=0.0, dec=0.0),
        Coordinate(ra=1.0, dec=0.0),
        Coordinate(ra=1.0, dec=1.0),
        Coordinate(ra=0.0, dec=1.0),
        Coordinate(ra=0.0, dec=0.0),  # Close the polygon
    ]
)
print(f"Polygon with {len(polygon.coordinates)} vertices")
Coordinate: RA=180.0°, Dec=45.0°
Polygon with 5 vertices

Ephemeris Calculation

The ephemeris module provides classes for computing spacecraft and observatory positions. Different ephemeris sources are supported:

  • TLEEphemeris: Two-Line Element sets for Earth-orbiting spacecraft

  • JPLEphemeris: JPL Horizons service for solar system bodies

  • SPICEEphemeris: SPICE kernels for precise spacecraft trajectories

  • GroundEphemeris: Fixed ground observatory locations

[2]:
from datetime import datetime

from across.tools.ephemeris import compute_ground_ephemeris

# Example: Compute ephemeris for a ground observatory
# Let's use the coordinates of a fictional observatory
ephem = compute_ground_ephemeris(
    begin=datetime(2024, 6, 21),
    end=datetime(2024, 6, 22),
    step_size=3600,  # 1 hour steps
    latitude=34.0,  # Latitude in degrees
    longitude=-118.0,  # Longitude in degrees
    height=100.0,  # Height in meters
)

print(f"Ephemeris computed from {ephem.begin.iso} to {ephem.end.iso}")
print(f"Number of time steps: {len(ephem.timestamp)}")
Ephemeris computed from 2024-06-21 00:00:00.000 to 2024-06-22 00:00:00.000
Number of time steps: 25

Visibility Constraints

The visibility module provides various constraints that can be applied to determine when a target is observable:

  • SunAngleConstraint: Minimum/maximum angle from the Sun

  • MoonAngleConstraint: Minimum/maximum angle from the Moon

  • EarthLimbConstraint: Minimum angle from Earth’s limb (for space observatories)

  • SAAPolygonConstraint: Avoidance of the South Atlantic Anomaly

  • AltAzConstraint: Altitude and azimuth limits (for ground observatories)

[3]:
from across.tools.visibility.constraints import (
    AltAzConstraint,
    MoonAngleConstraint,
    SunAngleConstraint,
)

# Sun angle constraint: target must be at least 45° from the Sun
sun_constraint = SunAngleConstraint(min_angle=45, max_angle=180)
print(f"Sun constraint: {sun_constraint.min_angle}° - {sun_constraint.max_angle}°")

# Moon angle constraint: target must be at least 15° from the Moon
moon_constraint = MoonAngleConstraint(min_angle=15, max_angle=180)
print(f"Moon constraint: {moon_constraint.min_angle}° - {moon_constraint.max_angle}°")

# Altitude constraint for ground observatories: target must be above horizon
alt_constraint = AltAzConstraint(altitude_max=90, altitude_min=0)
print(f"Altitude constraint: {alt_constraint.altitude_min}° - {alt_constraint.altitude_max}°")
Sun constraint: 45.0° - 180.0°
Moon constraint: 15.0° - 180.0°
Altitude constraint: 0.0° - 90.0°

Footprint Analysis

The footprint module allows you to work with instrument fields of view. You can define detector shapes, project them onto the sky, and query which HEALPix pixels they cover.

[4]:
from across.tools import Coordinate, Polygon
from across.tools.footprint import Footprint

# Define a simple square detector footprint (in detector coordinates)
# Coordinates are offsets from the boresight in degrees
detector = Polygon(
    coordinates=[
        Coordinate(ra=-0.5, dec=-0.5),
        Coordinate(ra=0.5, dec=-0.5),
        Coordinate(ra=0.5, dec=0.5),
        Coordinate(ra=-0.5, dec=0.5),
        Coordinate(ra=-0.5, dec=-0.5),
    ]
)

footprint = Footprint(detectors=[detector])
print(f"Footprint with {len(footprint.detectors)} detector(s)")
Footprint with 1 detector(s)
[5]:
# Project the footprint onto a specific sky position
target = Coordinate(ra=180.0, dec=45.0)
roll_angle = 0.0  # degrees

projected = footprint.project(coordinate=target, roll_angle=roll_angle)
print(f"Projected footprint centered at RA={target.ra}°, Dec={target.dec}°")

# Query HEALPix pixels covered by the footprint
pixels = projected.query_pixels(order=8)
print(f"Footprint covers {len(pixels)} HEALPix pixels at order 8")
Projected footprint centered at RA=180.0°, Dec=45.0°
Footprint covers 28 HEALPix pixels at order 8

Summary

This notebook demonstrated the core capabilities of across-tools:

  1. Core data types (Coordinate, Polygon) for representing sky positions and regions

  2. Ephemeris calculation for determining observatory positions over time

  3. Visibility constraints for filtering when targets are observable

  4. Footprint analysis for working with instrument fields of view

For more detailed information, see the API Reference and additional example notebooks.