Skip to content

haisamido/UTDFpy

Repository files navigation

UTDFpy

A Python library for reading and manipulating Universal Tracking Data Format (UTDF) satellite tracking data.

A direct conversion of https://github.com/trwyant/perl-Astro-UTDF. Thanks go to https://github.com/trwyant for creating the Perl module.

Binary Format

UTDF records are 75-byte big-endian binary structures. The library uses explicit big-endian unpacking (struct format >), so it produces identical results on any architecture (arm64, amd64, etc.).

Prerequisites

  • Task (task runner)
  • Docker (or Podman)

Development

All development tasks run inside a Docker container via Taskfile.yaml. To use Podman instead of Docker:

task tests CONTAINER_BIN=podman

Available tasks

task tests          # Run lint, format check, typecheck, unit tests, then example
task unit_tests     # Run unit tests (pytest inside Docker)
task tests:cov      # Run tests with coverage report
task lint           # Run ruff linter
task lint:fix       # Run ruff linter with auto-fix (modifies host files)
task format         # Run ruff formatter (modifies host files)
task format:check   # Check formatting without changes
task typecheck      # Run mypy type checking
task check          # Run all checks (lint, format, typecheck, tests)
task build          # Build distribution packages
task publish        # Build and publish package to PyPI
task utdfpy:install            # Install utdfpy from PyPI into local venv
task utdfpy:install:from:local # Install utdfpy from local source (editable)
task example_utdf              # Run read_utdf.py example against test data
task utdf-cli                  # Run interactive UTDF query tool
task ci:test:locally                   # Run both GitHub Actions and GitLab CI locally
task github:ci:test:locally            # Run GitHub Actions locally with act
task gitlab:ci:test:locally            # Run GitLab CI locally with gitlab-ci-local
task rebuild                    # Clean everything and run full test suite from scratch
task clean                     # Remove build artifacts and caches
task clean:all                 # Remove everything including Docker image

Task dependency chain

tests depends on lint, format:check, typecheck, unit_tests, and example_utdf, each of which depends on docker:build. Running task tests will automatically build the Docker image, run the linter, check formatting, run mypy, execute the unit test suite, and run the example script. publish depends on tests, so it runs the full check suite before uploading to PyPI.

Installation

pip install utdfpy

Or for development:

pip install -e '.[dev]'

Usage

from utdfpy import UTDFRecord

# Read all records from a UTDF file
records = UTDFRecord.slurp("tracking_data.utd")

for record in records:
    print(record.sic, record.vid, record.decode("measurement_time"))
    print(f"  azimuth:  {record.azimuth}")
    print(f"  elevation: {record.elevation}")
    print(f"  range:    {record.range}")

Example script

$ .venv/bin/python examples/read_utdf.py tests/data/data.utd
Read 2 records from tests/data/data.utd

Record 0:
  SIC:             86
  VID:             99
  Time:            2010-03-19T01:01:30+00:00
  Azimuth:         5.839702317578685
  Azimuth (deg):   334.5397498011498
  Elevation:       0.9403839735099665
  Elevation (deg): 53.877694653498
  Range (km):      425.12365727401914

Record 1:
  SIC:             86
  VID:             99
  Time:            2010-03-19T01:01:31+00:00
  Azimuth:         5.852690026751761
  Azimuth (deg):   335.28364953218365
  Elevation:       0.9534989112054779
  Elevation (deg): 54.62862629867479
  Range (km):      421.4236702842119

Reading an arbitrary UTDF file

Use the utdf-cli task to read any UTDF file by passing the path via CLI_ARGS:

task utdf-cli -- /path/to/your/file.utd

Or run the example script directly:

.venv/bin/python examples/read_utdf.py /path/to/your/file.utd

Both require a local venv. Run task utdfpy:install:from:local first if you haven't already.

CLI tool

An interactive query tool is included:

utdf-cli tracking_data.utd

Commands: load, count, select, next, list, or type any field name to inspect it.

Running CI locally

GitHub Actions via act. On macOS, Docker Desktop fails due to its containerd image store, so use Podman instead:

task github:ci:test:locally CONTAINER_BIN=podman

GitLab CI via gitlab-ci-local:

task gitlab:ci:test:locally

CI/CD

  • GitHub Actions (.github/workflows/ci.yaml): runs lint and typecheck in parallel, then unit tests on push/PR; auto-creates a release and publishes to PyPI when the version in pyproject.toml changes.
  • GitLab CI (.gitlab-ci.yaml): runs lint and typecheck in parallel, then unit tests; auto-creates a release and publishes to PyPI when the version in pyproject.toml changes.

License

Artistic-2.0 OR GPL-1.0-or-later (same as the original Perl module).

Architecture

classDiagram
    class UTDFRecord {
        -bytes _front
        -str _router
        -int _year
        -int _sic
        -int _vid
        -int _seconds_of_year
        -int _microseconds_of_year
        -float _transponder_latency
        -bool _enforce_validity
        -UTDFRecord _prior_record
        -float _factor_K
        -float _factor_M
        +azimuth() float
        +elevation() float
        +range_delay() float
        +doppler_count() float
        +doppler_shift() float
        +range() float
        +range_rate() float
        +measurement_time() float
        +transmit_frequency() int
        +raw_record() bytes
        +hex_record() str
        +clone() UTDFRecord
        +slurp(file) list~UTDFRecord~
        +iter_file(file) Iterator~UTDFRecord~
        +decode(field_name) str
    }

    class UTDFError {
        <<exception>>
    }

    class InvalidRecordError {
        <<exception>>
    }

    class FrequencyBand {
        <<IntEnum>>
        UNSPECIFIED
        VHF
        UHF
        S_BAND
        C_BAND
        X_BAND
        KU_BAND
        VISIBLE
    }

    class TransmissionType {
        <<IntEnum>>
        TEST
        SIMULATED
        RESUBMIT
        REAL_TIME
        PLAYBACK
    }

    class TrackingMode {
        <<IntEnum>>
        AUTOTRACK
        PROGRAM_TRACK
        MANUAL
        SLAVED
    }

    class TrackerType {
        <<IntEnum>>
        C_BAND_PULSE
        SRE
        SGLS
        TDRSS
    }

    class AntennaGeometry {
        <<IntEnum>>
        AZ_EL
        XY_SOUTH
        XY_EAST
        RA_DEC
        HR_DEC
    }

    Exception <|-- UTDFError
    UTDFError <|-- InvalidRecordError
    UTDFRecord --> UTDFRecord : prior_record
    UTDFRecord ..> InvalidRecordError : raises
    UTDFRecord ..> parsing : uses
    UTDFRecord ..> decode : uses
Loading

About

Universal Tracking Data Format (UTDF) is a 75-byte binary format used by NASA Ground Stations

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors