Skip to main content

Parsing IGS Sitelog files (supports version 2+3)

Project description

SitelogParser

A Python library and command-line tool for parsing, validating, and exporting IGS (International GNSS Service) sitelog files. SitelogParser converts sitelog text files into structured Python dataclasses, enables programmatic manipulation of sitelog data, and exports them back to the IGS sitelog v2.0 format.

Features

  • Parse IGS sitelog files into type-safe Python dataclasses
  • Export sitelog data back to IGS sitelog v2.0 format with automatic metadata updates
  • Generate Bernese files (.sta) from sitelog data with equipment history and time ranges
  • Generate SINEX files (.snx) in SINEX 2.02 format with coordinates and eccentricity data
  • Generate coordinate files (.crd) with ECEF coordinates in multiple reference frames
  • Merge multiple sitelogs into single station information, SINEX, or coordinate files
  • Command-line interface for validation, listing, preparing, and generating files
  • Type hints throughout for better IDE support and type checking
  • Automatic form metadata computation (latest modification dates and changed sections)
  • Timestamp handling with UTC timezone support
  • Glob pattern support for batch file processing

Installation

pip install sitelogparser

For development:

git clone <repository-url>
cd SitelogParser
pip install -e .

Command-Line Usage

The slp command provides several operations:

Validate a sitelog file

slp validate tests/AMST_20190705.txt

Output:

✓ Valid sitelog: tests/AMST_20190705.txt

📊 Statistics:
  Site: Amsterdam, Netherlands (AMST)
  DOMES: 13502M001
  Location: Amsterdam, Netherlands
  Receivers: 20
  Antennas: 6
  Last Modified: 2018-11-28
  Modified Sections: 3.19, 3.20

List receivers, antennas, or metadata

# List all receivers
slp list tests/AMST_20190705.txt --type receivers

# List all antennas
slp list tests/AMST_20190705.txt --type antennas

# Show site metadata
slp list tests/AMST_20190705.txt --type metadata

# Show everything (default)
slp list tests/AMST_20190705.txt

Example output (receivers):


📡 GNSS Receivers:
#    Type                      Serial          Installed            Removed
-------------------------------------------------------------------------------------
1    TRIMBLE NETRS             4439239154      2005-04-13T12:00Z    2005-12-15T10:00Z
2    TRIMBLE NETRS             4439239154      2005-12-15T10:00Z    2010-03-15T08:30Z
3    LEICA GRX1200+GNSS        495553          2010-03-15T08:30Z    2010-09-06T08:35Z
4    LEICA GRX1200+GNSS        495553          2010-09-06T08:35Z    2010-10-28T11:40Z
5    LEICA GRX1200+GNSS        495553          2010-10-28T11:50Z    2010-11-15T10:30Z
6    LEICA GRX1200+GNSS        495553          2010-11-15T10:30Z    2011-01-20T07:40Z
7    LEICA GRX1200+GNSS        495553          2011-01-20T07:50Z    2011-06-01T07:50Z
8    LEICA GRX1200+GNSS        495553          2011-06-01T07:50Z    2011-08-31T05:30Z
9    TRIMBLE NETR9             5106K73572      2011-08-31T05:30Z    2011-09-13T11:00Z
10   LEICA GRX1200+GNSS        495553          2011-09-13T11:00Z    2011-11-18T14:00Z
11   TPS GB-1000               8RXJKJ48V7K     2011-11-18T14:00Z    2012-08-22T07:30Z
12   TPS NET-G3A               618-00899       2012-08-22T07:30Z    2012-09-19T15:25Z
13   TPS NET-G3A               618-00899       2012-09-19T15:25Z    2013-10-31T15:23Z
14   TPS NET-G3A               618-00899       2013-10-31T15:34Z    2014-05-23T12:08Z
15   TPS NET-G3A               618-00899       2014-05-23T12:25Z    2017-03-17T13:12Z
16   LEICA GR30                1705298         2017-03-17T13:13Z    2017-10-10T05:17Z
17   TPS NET-G3A               618-00899       2017-10-10T06:07Z    2017-11-17T13:11Z
18   LEICA GR30                1705298         2017-11-17T14:24Z    2018-06-21T06:02Z
19   LEICA GR30                1705298         2018-06-21T06:04Z    2018-11-28T07:23Z
20   LEICA GR30                1705298         2018-11-28T07:25Z    (CCYY-MM-DDThh:mmZ)

Example output (antennas):


📶 GNSS Antennas:
#    Type                      Serial          Installed            Removed
-------------------------------------------------------------------------------------
1    TRM41249.00     TZGD      12696814        2005-04-13T12:00Z    2010-03-15T08:30Z
2    LEIAR25.R3      LEIT      09480032        2010-03-15T08:30Z    2011-08-31T05:30Z
3    TRM57971.00     TZGD      1441101374      2011-08-31T05:30Z    2011-09-13T11:00Z
4    LEIAR25.R3      LEIT      09470019        2011-09-13T11:00Z    2012-08-22T07:30Z
5    TPSCR.G3        TPSH      383-2172        2012-08-22T07:30Z    2017-10-10T06:07Z
6    LEIAR25.R4      LEIT      726448          2017-10-10T06:07Z    (CCYY-MM-DDThh:mmZ)

Example output (metadata):

📋 Site Metadata:

Site Name: Amsterdam, Netherlands
Four Character ID: AMST
DOMES Number: 13502M001
Location: Amsterdam, Netherlands
Coordinates:
  Latitude: +52.3712800855
  Longitude: +4.8563185513
  Elevation: 1.0 m

On-Site Agency: Technische Universiteit Delft
Responsible Agency: Technische Universiteit Delft

Prepare/export a sitelog file

# Read and export with auto-generated filename
slp prepare tests/AMST_20190705.txt

# Specify output file
slp prepare tests/AMST_20190705.txt -o output/AMST_prepared.log

Output:

✓ Parsed sitelog: tests/AMST_20190705.txt
✓ Exported to: output/AMST_prepared.log

The prepared file will be in IGS sitelog v2.0 format with:

  • Automatically updated form metadata (date prepared, modified sections)
  • Normalized formatting and field alignment
  • UTC timestamps in CCYY-MM-DDThh:mmZ format

Generate Bernese station information file (.sta)

Generate a Bernese GNSS Software 5.2 compatible station information file from one or more sitelogs:

# Generate from single file
slp generate_sta tests/AMST_20190705.txt

# Generate from multiple files (glob pattern)
slp generate_sta tests/testlogs/*.log -o stations.sta

# Generate from directory (finds all .txt and .log files)
slp generate_sta tests/testlogs/

# Custom output file
slp generate_sta tests/AMST_20190705.txt -o output/AMST.sta

Features:

  • Combines multiple sitelogs into a single station file
  • TYPE 001: Station renaming entries
  • TYPE 002: Combined receiver and antenna entries (overlapping time periods)
  • TYPE 003: Receiver equipment history
  • TYPE 004: Antenna equipment history
  • Automatic serial number replacement with "999999"
  • Time range overlap resolution (prevents overlapping periods)

Output example:

✓ Loaded: AMST_20190705.log (AMST)

✓ Generated Bernese station information file (.sta)
  Output: amst.sta
  Stations: 1
  Lines: 85
  Size: 5234 bytes

📋 Included stations:
  - AMST (11048M001): 20 RX, 6 ANT

Generate SINEX file (.snx)

Generate a SINEX 2.02 (Solution Independent Exchange) format file from one or more sitelogs:

# Generate from single file
slp generate_snx tests/AMST_20190705.txt

# Generate from multiple files (glob pattern)
slp generate_snx tests/testlogs/*.log -o stations.snx

# Generate from directory (finds all .txt and .log files)
slp generate_snx tests/testlogs/

# Custom output file
slp generate_snx tests/AMST_20190705.txt -o output/AMST.snx

Features:

  • Combines multiple sitelogs into a single SINEX file
  • +FILE/REFERENCE: File metadata and contact information
  • +SITE/ID: Station identification with coordinates
  • +SITE/RECEIVER: Receiver equipment history with time periods
  • +SITE/ANTENNA: Antenna equipment history with time periods
  • +SITE/ECCENTRICITY: Antenna offset information (Up, North, East)
  • +SOLUTION/ESTIMATE: ECEF coordinates (X, Y, Z) for each station
  • Automatic serial number replacement with "99999"
  • Time range overlap resolution (prevents overlapping periods)

Output example:

✓ Loaded: AMST_20190705.log (AMST)

✓ Generated SINEX file (.snx)
  Output: amst.snx
  Stations: 1
  Lines: 68
  Size: 4334 bytes

📋 Included stations:
  - AMST (11048M001): 20 RX, 6 ANT

Generate Bernese coordinate file (.crd)

Generate a Bernese GNSS Software coordinate list file from one or more sitelogs:

# Generate from single file with default ETRS89 frame
slp generate_crd tests/AMST_20190705.txt

# Generate with specific coordinate frame
slp generate_crd tests/AMST_20190705.txt --frame IGS20

# Generate from multiple files (glob pattern)
slp generate_crd tests/testlogs/*.log -o stations.crd

# Generate from directory (finds all .txt and .log files)
slp generate_crd tests/testlogs/

# Custom output file with coordinate frame
slp generate_crd tests/AMST_20190705.txt -o output/AMST.crd --frame ITRF2020

Features:

  • Combines multiple sitelogs into a single coordinate file
  • ECEF coordinates (X, Y, Z) in meters with 5 decimal precision
  • Supports multiple coordinate frames: ETRS89 (default), IGS20, IGS14, ITRF2020, etc.
  • Auto-determines datum name from coordinate frame
  • Stations sorted alphabetically by four-character ID
  • Skips stations with zero coordinates
  • Includes station names and DOMES numbers

Output example:

✓ Loaded: AMST_20190705.log (AMST)

✓ Generated Bernese coordinate file (.crd)
  Output: amst.crd
  Frame: ETRS89
  Stations: 1
  Lines: 8
  Size: 392 bytes

📋 Included stations:
  - AMST (13502M001)

Generated file format:

ETRS89: coordinate list                                          23-JAN-26 07:50
--------------------------------------------------------------------------------

LOCAL GEODETIC DATUM: ETRS89               EPOCH: 2005-04-13 12:00:00

NUM  STATION NAME           X (M)          Y (M)          Z (M)     FLAG     SYSTEM

  1  AMST 13502M001   3799725.65441  901944.13241  5028762.14325    ETRS89

Show version

slp --version
slp --version

API Usage

Basic Parsing

from sitelogparser.common.sitelog import SiteLogParser

# Parse a sitelog file
parser = SiteLogParser(sitelog_file="path/to/sitelog.txt")
sitelog = parser.sitelog

# Access site information
print(f"Site: {sitelog.site_identification.site_name}")
print(f"Four-char ID: {sitelog.site_identification.four_character_id}")
print(f"DOMES: {sitelog.site_identification.iers_domes_number}")

# Access location data
location = sitelog.site_location
print(f"Location: {location.city}, {location.country}")
print(f"Coordinates: {location.latitude}, {location.longitude}")

# Iterate over receivers
for receiver in sitelog.gnss_receivers:
    print(f"Receiver {receiver.number}: {receiver.receiver_type}")
    print(f"  Serial: {receiver.serial_number}")
    print(f"  Firmware: {receiver.firmware_version}")

# Iterate over antennas
for antenna in sitelog.gnss_antennas:
    print(f"Antenna {antenna.number}: {antenna.antenna_type}")
    print(f"  Serial: {antenna.serial_number}")
    print(f"  Radome: {antenna.antenna_radome_type}")

# Access agency information
print(f"On-site agency: {sitelog.on_site_agency.name}")
print(f"Primary contact: {sitelog.on_site_agency.primary_contact.name}")
print(f"Email: {sitelog.on_site_agency.primary_contact.email}")

Exporting Sitelog Data

from sitelogparser.common.sitelog import SiteLogParser

# Parse existing sitelog
parser = SiteLogParser(sitelog_file="input.txt")

# Modify data programmatically
parser.sitelog.site_identification.site_name = "Updated Site Name"

# Export to new file (automatically updates form metadata)
output_text = parser.export_sitelog()
with open("output.txt", "w") as f:
    f.write(output_text)

Creating a New Sitelog

from sitelogparser.common.models import (
    Sitelog, FormInformation, SiteIdentification, SiteLocation,
    GNSSReceiver, GNSSAntenna, Agency, Contact
)
from sitelogparser.common.sitelog import SiteLogParser
from datetime import datetime, timezone

# Create sitelog structure
sitelog = Sitelog()

# Fill form information
sitelog.form_information = FormInformation(
    prepared_by="John Doe",
    report_type="NEW"
)

# Fill site identification
sitelog.site_identification = SiteIdentification(
    site_name="Example Site",
    four_character_id="EXMP",
    iers_domes_number="12345M001",
    date_installed=datetime(2025, 1, 1, tzinfo=timezone.utc).timestamp()
)

# Fill location
sitelog.site_location = SiteLocation(
    city="Example City",
    country="Example Country",
    latitude="+12.3456789012",
    longitude="+123.4567890123",
    elevation="100.0"
)

# Add receivers
receiver = GNSSReceiver(
    number=1,
    receiver_type="EXAMPLE RECEIVER",
    satellite_system="GPS",
    serial_number="12345",
    firmware_version="1.0.0",
    elevation_cutoff_setting="0",
    date_installed=datetime(2025, 1, 1, tzinfo=timezone.utc).timestamp(),
    date_removed=0.0,  # 0.0 means not removed yet
    temperature_stabilization="none"
)
sitelog.gnss_receivers.append(receiver)

# Add antennas
antenna = GNSSAntenna(
    number=1,
    antenna_type="EXAMPLE ANTENNA",
    serial_number="ANT123",
    antenna_reference_point="BPA",
    marker_arp_up_ecc="0.0000",
    marker_arp_north_ecc="0.0000",
    marker_arp_east_ecc="0.0000",
    alignment_of_true_n="0",
    antenna_radome_type="NONE",
    radome_serial_number="",
    antenna_cable_type="",
    antenna_cable_length="",
    date_installed=datetime(2025, 1, 1, tzinfo=timezone.utc).timestamp(),
    date_removed=0.0
)
sitelog.gnss_antennas.append(antenna)

# Add agency information
sitelog.on_site_agency = Agency(
    section="11",
    name="Example Organization",
    abbreviation="EXORG",
    mail_address="123 Example St, Example City, Country",
    primary_contact=Contact(
        name="Jane Doe",
        phone1="+1-555-0100",
        email="jane.doe@example.org"
    )
)

# Export to sitelog format
parser = SiteLogParser(sitelog_text="")
parser.sitelog = sitelog
output_text = parser.export_sitelog()

with open("new_sitelog.txt", "w") as f:
    f.write(output_text)

Working with Timestamps

Dates in the dataclasses are stored as float timestamps (seconds since Unix epoch):

from datetime import datetime, timezone

# Convert datetime to timestamp (for setting dates)
dt = datetime(2025, 1, 15, 12, 30, tzinfo=timezone.utc)
timestamp = dt.timestamp()
receiver.date_installed = timestamp

# Convert timestamp to datetime (for reading dates)
from sitelogparser.common.sitelog import SiteLogParser
parser = SiteLogParser(sitelog_file="sitelog.txt")
receiver = parser.sitelog.gnss_receivers[0]

if receiver.date_installed > 0:
    dt = datetime.fromtimestamp(receiver.date_installed, tz=timezone.utc)
    print(f"Installed: {dt.strftime('%Y-%m-%d %H:%M:%S %Z')}")

# Dates are exported in IGS format: CCYY-MM-DDThh:mmZ
# Empty dates (0.0) are shown as: (CCYY-MM-DDThh:mmZ)

Data Models

The library uses Python dataclasses for type-safe data representation:

  • Sitelog: Top-level container for all sitelog data
  • FormInformation: Section 0 - Form metadata
  • SiteIdentification: Section 1 - Site identification
  • SiteLocation: Section 2 - Site location information
  • GNSSReceiver: Section 3.x - Individual receiver configuration
  • GNSSAntenna: Section 4.x - Individual antenna configuration
  • Agency: Sections 11-12 - Agency information with contacts
  • Contact: Contact person information

All dataclasses have full type hints and can be converted to dictionaries using the to_dict() method.

Requirements

  • Python >= 3.8
  • No external dependencies (uses only Python standard library)

Development

Run tests:

python -m unittest discover tests/ -v

Run specific test:

python -m unittest tests.test_parser
python -m unittest tests.test_generate

License

See LICENSE.txt for details.

Contributing

Contributions are welcome! Please ensure all tests pass before submitting pull requests.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sitelogparser-1.2.0.tar.gz (93.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sitelogparser-1.2.0-py2.py3-none-any.whl (68.3 kB view details)

Uploaded Python 2Python 3

File details

Details for the file sitelogparser-1.2.0.tar.gz.

File metadata

  • Download URL: sitelogparser-1.2.0.tar.gz
  • Upload date:
  • Size: 93.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for sitelogparser-1.2.0.tar.gz
Algorithm Hash digest
SHA256 48ab61efa9bdcc74ca7f79aef9f22280539ed9ae1e2318f4a8d4f5df920de8fd
MD5 0e3dbb18f5ddd6a26ca421d0f85a6126
BLAKE2b-256 cb17ee5f6810c49d6a55ceddb236051cf4ddd8f138a8481bb1e68bd043a89266

See more details on using hashes here.

File details

Details for the file sitelogparser-1.2.0-py2.py3-none-any.whl.

File metadata

  • Download URL: sitelogparser-1.2.0-py2.py3-none-any.whl
  • Upload date:
  • Size: 68.3 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for sitelogparser-1.2.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 1a29b93c0d2ca130fc7efbfb8219163a3ac02e6dbdc388471d730c273652ec0f
MD5 7629c123aa8ec2799f14f2e2479a54f0
BLAKE2b-256 29bfa567040a9b5530f0d7850883c8477dc2b8940906a834986806b0b2882442

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page