stationxml-rs
Pure Rust FDSN StationXML and SeisComP SC3ML reader/writer. Zero unsafe, zero C dependencies.
What is StationXML?
FDSN StationXML is the standard XML format for seismic station metadata, used by earthquake monitoring networks worldwide (IRIS, FDSN, BMKG, etc.). It describes station locations, instrument responses, poles & zeros, and data logger configurations.
SeisComP SC3ML is an alternative XML format used by the SeisComP earthquake monitoring system. It stores the same information in a flat, reference-based structure rather than FDSN's nested hierarchy.
This crate provides a format-agnostic inventory model with pluggable backends for both formats, enabling read, write, and cross-format conversion.
Features
- FDSN StationXML 1.2 read and write
- SeisComP SC3ML 0.6--0.13 read and write
- Cross-format conversion: FDSN <-> SC3ML via shared inventory model
- Auto-detect format from root XML element
- Full instrument response: poles & zeros, FIR coefficients, stage gains, sensitivity
- Builder pattern for constructing inventories programmatically
- Sensor library: embedded database of common seismometers (GS-11D, Trillium, etc.)
- ADC conversion helpers: counts <-> voltage <-> physical units
- Zero unsafe -- no FFI, no transmute, no raw pointers
- Zero C dependencies -- pure Rust, compiles anywhere
rustcruns
Quick Start
Add to your Cargo.toml:
[]
= "0.2"
Read with auto-detection
use read_from_file;
// Auto-detects FDSN or SC3ML from the XML content
let inv = read_from_file.unwrap;
for net in &inv.networks
Read and write with explicit format
use ;
// Read FDSN StationXML
let inv = read_from_str.unwrap;
// Write as SC3ML (cross-format conversion)
let sc3ml_xml = write_to_string.unwrap;
Build an inventory from scratch
use ;
let inv = new
.network
.build;
let xml = .unwrap;
API Overview
use ;
| Type | Description |
|---|---|
Inventory |
Top-level container for all station metadata |
Network |
Seismic network (e.g. "IU", "GE") with stations |
Station |
Station with location, site info, and channels |
Channel |
Channel with orientation, sample rate, and response |
Response |
Instrument response with sensitivity and stage chain |
ResponseStage |
Single response stage (poles/zeros, coefficients, or FIR) |
PolesZeros |
Analog/digital transfer function (Laplace or Z-transform) |
FIR |
Finite Impulse Response filter coefficients |
Coefficients |
Gain-only stage (e.g. ADC stage) |
Equipment |
Sensor or data logger description |
Fdsn |
FDSN StationXML 1.2 format backend |
Sc3ml |
SeisComP SC3ML 0.6--0.13 format backend |
InventoryBuilder |
Fluent builder for constructing inventories |
AdcConversion |
ADC conversion helpers (counts, voltage, physical) |
Supported Formats
| Format | Namespace | Read | Write |
|---|---|---|---|
| FDSN StationXML 1.2 | http://www.fdsn.org/xml/station/1 |
Yes | Yes |
| SeisComP SC3ML 0.6--0.13 | http://geofon.gfz-potsdam.de/ns/seiscomp3-schema/* |
Yes | Yes |
SC3ML Reference Resolution
SC3ML uses a flat structure with publicID references. The reader automatically resolves:
<Inventory>
<sensor publicID="Sensor#GS11D" response="ResponsePAZ#GS11D"> --> Channel.sensor
<datalogger publicID="Datalogger#PB24"> --> Channel.data_logger
<responsePAZ publicID="ResponsePAZ#GS11D"> --> Response stage 1
<responseFIR publicID="ResponseFIR#DECIM2"> --> Response FIR stage
<network>
<station>
<sensorLocation>
<stream sensor="Sensor#GS11D" datalogger="Datalogger#PB24"> (references above)
The writer reverses this: deduplicating shared sensors/responses into top-level definitions.
Architecture
src/
lib.rs -- crate root, re-exports, top-level read/write functions
inventory.rs -- core types: Inventory, Network, Station, Channel, Response
format.rs -- StationXmlFormat trait, Format enum, detect_format()
error.rs -- StationXmlError enum (thiserror)
datetime.rs -- shared ISO 8601 datetime parsing/formatting
builder.rs -- InventoryBuilder fluent API
sensor.rs -- embedded sensor database (GS-11D, Trillium, etc.)
conversion.rs -- ADC conversion helpers
fdsn/
mod.rs -- pub struct Fdsn; impl StationXmlFormat
types.rs -- FDSN-specific XML serde structs
reader.rs -- FDSN XML -> Inventory
writer.rs -- Inventory -> FDSN XML
sc3ml/
mod.rs -- pub struct Sc3ml; impl StationXmlFormat
types.rs -- SC3ML-specific XML serde structs
reader.rs -- SC3ML XML -> Inventory (reference resolution)
writer.rs -- Inventory -> SC3ML XML (deduplication)
Design Decisions
- Format-agnostic core:
Inventorytypes don't depend on any XML format - Trait-based backends:
StationXmlFormattrait for each format (Fdsn, Sc3ml) - Auto-detect:
detect_format()inspects root XML element name - Roundtrip-safe: read -> write -> read produces identical
Inventory - ObsPy-compatible: output XML is parseable by
obspy.read_inventory() - Embedded sensor DB:
data/sensors.jsoncompiled into binary viainclude_str!
TDD with ObsPy
Test vectors are generated by Python/ObsPy scripts, ensuring compatibility with the de facto reference implementation:
&&
Development
References
Sister Projects
- miniseed-rs -- Pure Rust miniSEED v2/v3 decoder/encoder
- seedlink-rs -- Pure Rust SeedLink client
License
Apache-2.0