Introduction

across-client is a library which provides functionality to access and manipulate the data products found on the ACROSS core-server. In this notebook, we will briefly demonstrate the main features of across-client, including fetching Observatory/Telescope/Instrument metadata, Schedules and Observations, and performing target visibility calculations.

Science Situational Awareness (SSA) Models

The ACROSS core-server records data about scientific instruments, their functionality, and their actions in Science Situational Awareness (SSA) models. At its most basic, these data can be broken down in Observatory, Telescope, and Instrument objects. An Observatory can have many Telescopes, which in turn can have many Instruments. All metadata about these SSA models can be retrieved using the across-client via a number of parameters, as demonstrated below:

[1]:
from across.client import Client

# Example: Retrieve an Observatory by name

client = Client()
observatories = client.observatory.get_many(name="HST")
print(f"Name: {observatories[0].name}")
Name: Hubble Space Telescope
[2]:
from across.client import Client

# Example: Retrieve a Telescope by its instrument name

client = Client()
telescopes = client.telescope.get_many(instrument_name="Advanced CCD Imaging Spectrometer")
print(f"Name: {telescopes[0].name}")
Name: Chandra X-ray Telescope
[3]:
from across.client import Client

# Example: Retrieve an Instrument by ID

client = Client()
telescopes = client.telescope.get_many(name="JWST")
instrument_id = telescopes[0].instruments[0].id

instrument = client.instrument.get(id=instrument_id)
print(f"Name: {instrument.name}")
Name: Near-Infrared Spectrograph

Schedule and Observation Data

The ACROSS core-server routinely ingests up-to-date planned and completed Observations from the Telescopes in its system. Observations are grouped into Schedules by their fidelity (either low or high) and status (planned, scheduled, and performed). The across-client can be used to retrieve any of these data:

[ ]:
from across.client import Client

# Example: Retrieve latest as-flown schedule for a telescope

client = Client()
schedules = client.schedule.get_many(
    telescope_names=["NuSTAR"],
    status="performed",
    include_observations=True,
)
print(f"NuSTAR schedule: {schedules.items[0].model_dump_json(indent=4)}")
NuSTAR schedule: {
    "telescope_id": "281a5a5d-3629-4aa3-a739-968bee65415f",
    "name": "nustar_as_flown_2025-11-11_2025-11-12",
    "date_range": {
        "begin": "2025-11-11T10:26:06.720000",
        "end": "2025-11-12T13:11:08.160000"
    },
    "status": "performed",
    "external_id": null,
    "fidelity": "high",
    "id": "925e8816-2339-4892-ab81-43eda52acac1",
    "observations": [
        {
            "instrument_id": "8e3f11f7-c943-4b45-b55e-59d475a4114f",
            "object_name": "AT2025aarm",
            "pointing_position": {
                "ra": 68.0937,
                "dec": -5.3722
            },
            "date_range": {
                "begin": "2025-11-11T11:16:13.440000",
                "end": "2025-11-12T13:11:08.160000"
            },
            "external_observation_id": "91101646002",
            "type": "timing",
            "status": "performed",
            "pointing_angle": 203.2945,
            "exposure_time": 93294.71875,
            "reason": null,
            "description": null,
            "proposal_reference": null,
            "object_position": {
                "ra": null,
                "dec": null
            },
            "depth": null,
            "bandpass": {
                "anyof_schema_1_validator": null,
                "anyof_schema_2_validator": null,
                "anyof_schema_3_validator": null,
                "actual_instance": {
                    "filter_name": "NuSTAR",
                    "min": 0.1581431102464288,
                    "max": 4.132806614440008,
                    "type": "WAVELENGTH",
                    "central_wavelength": 2.1454748623432183,
                    "peak_wavelength": null,
                    "bandwidth": 1.9873317520967895,
                    "unit": "angstrom"
                },
                "any_of_schemas": [
                    "EnergyBandpass",
                    "WavelengthBandpass",
                    "FrequencyBandpass"
                ]
            },
            "t_resolution": null,
            "em_res_power": null,
            "o_ucd": null,
            "pol_states": null,
            "pol_xel": null,
            "category": null,
            "priority": null,
            "tracking_type": null,
            "id": "2a13a6c3-ecd5-499e-b238-f6ac5ae3f602",
            "schedule_id": "925e8816-2339-4892-ab81-43eda52acac1",
            "created_on": "2025-11-18T02:53:03.104069",
            "created_by_id": null
        }
    ],
    "observation_count": 1,
    "created_on": "2025-11-18T02:53:03.022843",
    "created_by_id": "1022155f-f13d-4ade-ac73-3d1941f612da",
    "checksum": "d48fd1df8a6380c49f67345a9c2cee00ab231d2405af09747b2a84f959ac42184c028c8a8497379de4bdd1dc680db0c7509914f6befac140f03e33e94dead58a"
}
[ ]:
from across.client import Client

# Example: Retrieve all observations close to some coordinate

target_ra = 120.0
target_dec = 50.0

client = Client()
observations = client.observation.get_many(
    cone_search_ra=target_ra,
    cone_search_dec=target_dec,
    cone_search_radius=1,
)
print(f"There are {len(observations.items)} observations within our cone search.")
There are 9 observations within our cone search

Target Visibility Calculations

across-client also has functionality to perform calculations given the data hosted on the core-server. At the moment, the main functionality enabled is target visibility calculations for a single instrument. Given a target coordinate, a time range, and an Instrument ID, the core-server calculates time windows where that instrument is able to observe the target. It does so by using constraints, unique to each instrument, that are stored in the server. An example of such a constraint is a SunAngleConstraint–how close an instrument can point to the sun. Below is a demonstration of using the across-client to perform this calculation:

[15]:
from datetime import datetime
from across.client import Client

# Example: Calculate target visibility windows

client = Client()
# Retrieve the instrument ID
instruments = client.instrument.get_many(name="UVOT")
uvot_id = instruments[0].id

# Give some visibility calculation parameters
target_ra = 83.86662
target_dec = -69.26986
date_range_begin = datetime(2025, 12, 17, 0, 0, 0)
date_range_end = datetime(2025, 12, 18, 0, 0, 0)

# Calculate the visibility windows
visibility_result = client.visibility_calculator.calculate_windows(
    instrument_id=uvot_id,
    ra=target_ra,
    dec=target_dec,
    date_range_begin=date_range_begin,
    date_range_end=date_range_end,
)
for window in visibility_result.visibility_windows:
    print(f"  {window.window.begin.datetime} to {window.window.end.datetime}")
    print(f"    Duration: {window.max_visibility_duration} seconds")
    print(f"    Start reason: {window.constraint_reason.start_reason}")
    print(f"    End reason: {window.constraint_reason.end_reason}")
  2025-12-17 00:35:00 to 2025-12-17 00:38:00
    Duration: 179 seconds
    Start reason: Observatory Earth Limb
    End reason: Observatory South Atlantic Anomaly
  2025-12-17 01:02:00 to 2025-12-17 01:09:00
    Duration: 419 seconds
    Start reason: Observatory South Atlantic Anomaly
    End reason: Observatory Earth Limb
  2025-12-17 02:08:00 to 2025-12-17 02:17:00
    Duration: 539 seconds
    Start reason: Observatory Earth Limb
    End reason: Observatory South Atlantic Anomaly
  2025-12-17 02:39:00 to 2025-12-17 02:42:00
    Duration: 179 seconds
    Start reason: Observatory South Atlantic Anomaly
    End reason: Observatory Earth Limb
  2025-12-17 03:40:00 to 2025-12-17 03:55:00
    Duration: 899 seconds
    Start reason: Observatory Earth Limb
    End reason: Observatory South Atlantic Anomaly
  2025-12-17 05:13:00 to 2025-12-17 05:34:00
    Duration: 1259 seconds
    Start reason: Observatory Earth Limb
    End reason: Observatory South Atlantic Anomaly
  2025-12-17 06:46:00 to 2025-12-17 07:20:00
    Duration: 2040 seconds
    Start reason: Observatory Earth Limb
    End reason: Observatory Earth Limb
  2025-12-17 08:18:00 to 2025-12-17 08:53:00
    Duration: 2100 seconds
    Start reason: Observatory Earth Limb
    End reason: Observatory Earth Limb
  2025-12-17 09:51:00 to 2025-12-17 10:25:00
    Duration: 2040 seconds
    Start reason: Observatory Earth Limb
    End reason: Observatory Earth Limb
  2025-12-17 11:24:00 to 2025-12-17 11:58:00
    Duration: 2040 seconds
    Start reason: Observatory Earth Limb
    End reason: Observatory Earth Limb
  2025-12-17 12:56:00 to 2025-12-17 13:31:00
    Duration: 2100 seconds
    Start reason: Observatory Earth Limb
    End reason: Observatory Earth Limb
  2025-12-17 14:29:00 to 2025-12-17 15:03:00
    Duration: 2040 seconds
    Start reason: Observatory Earth Limb
    End reason: Observatory Earth Limb
  2025-12-17 16:02:00 to 2025-12-17 16:36:00
    Duration: 2039 seconds
    Start reason: Observatory Earth Limb
    End reason: Observatory Earth Limb
  2025-12-17 17:40:00 to 2025-12-17 18:09:00
    Duration: 1739 seconds
    Start reason: Observatory South Atlantic Anomaly
    End reason: Observatory Earth Limb
  2025-12-17 19:20:00 to 2025-12-17 19:41:00
    Duration: 1259 seconds
    Start reason: Observatory South Atlantic Anomaly
    End reason: Observatory Earth Limb
  2025-12-17 20:58:00 to 2025-12-17 21:14:00
    Duration: 959 seconds
    Start reason: Observatory South Atlantic Anomaly
    End reason: Observatory Earth Limb
  2025-12-17 22:34:00 to 2025-12-17 22:47:00
    Duration: 779 seconds
    Start reason: Observatory South Atlantic Anomaly
    End reason: Observatory Earth Limb
  2025-12-17 23:45:00 to 2025-12-17 23:46:00
    Duration: 59 seconds
    Start reason: Observatory Earth Limb
    End reason: Observatory South Atlantic Anomaly

Summary

This notebook gave an overview of the main features of across-client, namely:

  • Retrieving Observatory/Telescope/Instrument metadata from the ACROSS core-server;

  • Retrieving Schedule and Observation data for Telescopes and Instruments from the core-server; and

  • Performing target visibility calculations using the core-server

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