0
# Data Center Clients
1
2
Standardized clients for accessing 67+ global seismological data centers including IRIS, GEOFON, NCEDC, SCEDC, and others through FDSN web services with unified interfaces for waveforms, events, and station metadata. These clients provide seamless access to the global seismological data ecosystem with automatic format handling and error recovery.
3
4
## Capabilities
5
6
### FDSN Web Service Client
7
8
Primary client for accessing seismological data centers using the International Federation of Digital Seismograph Networks (FDSN) web service standards.
9
10
```python { .api }
11
# Import from obspy.clients.fdsn
12
class Client:
13
def __init__(self, base_url: str = "IRIS", user: str = None, password: str = None,
14
user_agent: str = None, debug: bool = False, timeout: int = 120,
15
**kwargs):
16
"""
17
FDSN web service client.
18
19
Args:
20
base_url: Data center identifier or full URL
21
user: Username for restricted data access
22
password: Password for restricted data access
23
user_agent: Custom user agent string
24
debug: Enable debug output
25
timeout: Request timeout in seconds
26
**kwargs: Additional client options
27
28
Available data centers:
29
IRIS, GEOFON, NCEDC, SCEDC, USGS, EMSC, ISC, ORFEUS, RESIF, INGV,
30
BGR, KOERI, NOA, LMU, ETHZ, NIEP, GEONET, GA, IPGP, and 50+ others
31
"""
32
33
def get_waveforms(self, network: str, station: str, location: str, channel: str,
34
starttime, endtime, quality: str = "B", minimumlength: float = None,
35
longestonly: bool = False, **kwargs) -> Stream:
36
"""
37
Request waveform data.
38
39
Args:
40
network: Network code (e.g., "IU", "II", "G")
41
station: Station code (e.g., "ANMO", "BFO")
42
location: Location code (e.g., "00", "10", "--")
43
channel: Channel code (e.g., "BHZ", "HHE", "LHN")
44
starttime: Start time (UTCDateTime)
45
endtime: End time (UTCDateTime)
46
quality: Data quality ("D", "R", "Q", "M", "B")
47
minimumlength: Minimum trace length in seconds
48
longestonly: Return only longest continuous segment
49
**kwargs: Additional service parameters
50
51
Returns:
52
Stream object with requested waveforms
53
54
Raises:
55
FDSNException: Service error or no data found
56
"""
57
58
def get_waveforms_bulk(self, bulk, quality: str = "B", minimumlength: float = None,
59
longestonly: bool = False, **kwargs) -> Stream:
60
"""
61
Request multiple waveform segments efficiently.
62
63
Args:
64
bulk: List of (network, station, location, channel, starttime, endtime) tuples
65
quality: Data quality preference
66
minimumlength: Minimum trace length in seconds
67
longestonly: Return only longest segments
68
**kwargs: Additional parameters
69
70
Returns:
71
Stream object with all requested waveforms
72
"""
73
74
def get_events(self, starttime=None, endtime=None, minlatitude: float = None,
75
maxlatitude: float = None, minlongitude: float = None,
76
maxlongitude: float = None, latitude: float = None,
77
longitude: float = None, minradius: float = None,
78
maxradius: float = None, mindepth: float = None,
79
maxdepth: float = None, minmagnitude: float = None,
80
maxmagnitude: float = None, magnitudetype: str = None,
81
includeallorigins: bool = None, includeallmagnitudes: bool = None,
82
includearrivals: bool = None, eventid: str = None,
83
limit: int = None, offset: int = None, orderby: str = "time",
84
catalog: str = None, contributor: str = None, **kwargs):
85
"""
86
Request earthquake event data.
87
88
Args:
89
starttime: Earliest event origin time
90
endtime: Latest event origin time
91
minlatitude: Southern boundary in degrees
92
maxlatitude: Northern boundary in degrees
93
minlongitude: Western boundary in degrees
94
maxlongitude: Eastern boundary in degrees
95
latitude: Center latitude for radial search
96
longitude: Center longitude for radial search
97
minradius: Minimum radius from center in degrees
98
maxradius: Maximum radius from center in degrees
99
mindepth: Minimum depth in km
100
maxdepth: Maximum depth in km
101
minmagnitude: Minimum magnitude
102
maxmagnitude: Maximum magnitude
103
magnitudetype: Magnitude type preference
104
includeallorigins: Include all origins per event
105
includeallmagnitudes: Include all magnitudes per event
106
includearrivals: Include phase arrival data
107
eventid: Specific event identifier
108
limit: Maximum number of events
109
offset: Number of events to skip
110
orderby: Sort order ("time", "magnitude", "time-asc")
111
catalog: Preferred event catalog
112
contributor: Preferred data contributor
113
**kwargs: Additional query parameters
114
115
Returns:
116
Catalog object containing matching events
117
"""
118
119
def get_events_bulk(self, bulk, **kwargs):
120
"""
121
Request multiple event queries efficiently.
122
123
Args:
124
bulk: List of event query parameter dictionaries
125
**kwargs: Common parameters for all queries
126
127
Returns:
128
Catalog object with all matching events
129
"""
130
131
def get_stations(self, network=None, station=None, location=None, channel=None,
132
starttime=None, endtime=None, startbefore=None, startafter=None,
133
endbefore=None, endafter=None, minlatitude: float = None,
134
maxlatitude: float = None, minlongitude: float = None,
135
maxlongitude: float = None, latitude: float = None,
136
longitude: float = None, minradius: float = None,
137
maxradius: float = None, level: str = "station",
138
includerestricted: bool = None, includeavailability: bool = None,
139
updatedafter=None, matchtimeseries: bool = None, **kwargs):
140
"""
141
Request station metadata.
142
143
Args:
144
network: Network code(s) or pattern
145
station: Station code(s) or pattern
146
location: Location code(s) or pattern
147
channel: Channel code(s) or pattern
148
starttime: Earliest station start time
149
endtime: Latest station end time
150
startbefore: Stations starting before this time
151
startafter: Stations starting after this time
152
endbefore: Stations ending before this time
153
endafter: Stations ending after this time
154
minlatitude: Southern boundary in degrees
155
maxlatitude: Northern boundary in degrees
156
minlongitude: Western boundary in degrees
157
maxlongitude: Eastern boundary in degrees
158
latitude: Center latitude for radial search
159
longitude: Center longitude for radial search
160
minradius: Minimum radius from center in degrees
161
maxradius: Maximum radius from center in degrees
162
level: Detail level ("network", "station", "channel", "response")
163
includerestricted: Include restricted stations
164
includeavailability: Include data availability
165
updatedafter: Stations updated after this time
166
matchtimeseries: Match to available time series
167
**kwargs: Additional query parameters
168
169
Returns:
170
Inventory object containing station metadata
171
"""
172
173
def get_stations_bulk(self, bulk, **kwargs):
174
"""
175
Request multiple station queries efficiently.
176
177
Args:
178
bulk: List of station query parameter dictionaries
179
**kwargs: Common parameters for all queries
180
181
Returns:
182
Inventory object with all matching stations
183
"""
184
185
def get_waveform_availability(self, network=None, station=None, location=None,
186
channel=None, starttime=None, endtime=None, **kwargs):
187
"""
188
Get waveform data availability information.
189
190
Args:
191
network: Network code(s) or pattern
192
station: Station code(s) or pattern
193
location: Location code(s) or pattern
194
channel: Channel code(s) or pattern
195
starttime: Earliest time window
196
endtime: Latest time window
197
**kwargs: Additional parameters
198
199
Returns:
200
List of availability information dictionaries
201
"""
202
```
203
204
### Multi-Center Routing Client
205
206
Advanced client that automatically routes requests to appropriate data centers based on network-station combinations and data availability.
207
208
```python { .api }
209
class RoutingClient:
210
def __init__(self, routing_type: str = "eida-routing",
211
eida_token: str = None, include_providers: list = None,
212
exclude_providers: list = None, debug: bool = False,
213
timeout: int = 120, **kwargs):
214
"""
215
Multi-data center routing client.
216
217
Args:
218
routing_type: Routing service type ("eida-routing", "iris-federator")
219
eida_token: EIDA authentication token for restricted data
220
include_providers: List of data centers to include
221
exclude_providers: List of data centers to exclude
222
debug: Enable debug output
223
timeout: Request timeout in seconds
224
**kwargs: Additional client options
225
"""
226
227
def get_waveforms(self, network: str, station: str, location: str, channel: str,
228
starttime, endtime, **kwargs) -> Stream:
229
"""
230
Request waveforms with automatic routing.
231
232
Automatically determines appropriate data center and handles
233
cross-center data assembly for complex requests.
234
235
Args:
236
network: Network code
237
station: Station code
238
location: Location code
239
channel: Channel code
240
starttime: Start time
241
endtime: End time
242
**kwargs: Additional parameters
243
244
Returns:
245
Stream object with waveforms from appropriate data centers
246
"""
247
248
def get_waveforms_bulk(self, bulk, **kwargs) -> Stream:
249
"""
250
Bulk waveform request with intelligent routing.
251
252
Args:
253
bulk: List of waveform request tuples
254
**kwargs: Additional parameters
255
256
Returns:
257
Stream object with data from multiple centers
258
"""
259
260
def get_stations(self, **kwargs):
261
"""
262
Request station metadata with routing.
263
264
Args:
265
**kwargs: Station query parameters
266
267
Returns:
268
Inventory object from appropriate data centers
269
"""
270
271
def get_availability(self, **kwargs):
272
"""
273
Get data availability across multiple centers.
274
275
Args:
276
**kwargs: Availability query parameters
277
278
Returns:
279
Comprehensive availability information
280
"""
281
```
282
283
### Mass Downloader
284
285
Automated bulk data download system for large-scale seismological studies with intelligent request management and error handling.
286
287
```python { .api }
288
# Import from obspy.clients.fdsn.mass_downloader
289
class MassDownloader:
290
def __init__(self, providers: list = None, debug: bool = False,
291
configure_logging: bool = True, **kwargs):
292
"""
293
Automated mass data download system.
294
295
Args:
296
providers: List of FDSN data center identifiers
297
debug: Enable debug logging
298
configure_logging: Set up logging automatically
299
**kwargs: Additional downloader options
300
"""
301
302
def download(self, domain, restrictions, mseed_storage: str,
303
stationxml_storage: str = None, threads_per_client: int = 3,
304
download_chunk_size_in_mb: int = 20, **kwargs):
305
"""
306
Download seismological data for specified domain and restrictions.
307
308
Args:
309
domain: Spatial domain for download (Domain object)
310
restrictions: Download restrictions (Restrictions object)
311
mseed_storage: Directory for MiniSEED files
312
stationxml_storage: Directory for StationXML files
313
threads_per_client: Concurrent downloads per data center
314
download_chunk_size_in_mb: Maximum chunk size for downloads
315
**kwargs: Additional download options
316
"""
317
318
def get_availability(self, domain, restrictions, **kwargs):
319
"""
320
Get data availability for domain without downloading.
321
322
Args:
323
domain: Spatial domain
324
restrictions: Time and channel restrictions
325
**kwargs: Additional options
326
327
Returns:
328
Availability summary information
329
"""
330
331
class Restrictions:
332
def __init__(self, starttime, endtime, chunklength_in_sec: int = 86400,
333
network: str = None, station: str = None, location: str = None,
334
channel: str = None, exclude_networks: list = None,
335
exclude_stations: list = None, minimum_length: float = 0.0,
336
minimum_interstation_distance_in_m: float = 0.0,
337
channel_priorities: list = None, location_priorities: list = None,
338
reject_channels_with_gaps: bool = False,
339
sanitize: bool = True, **kwargs):
340
"""
341
Download restrictions and data selection criteria.
342
343
Args:
344
starttime: Download start time (UTCDateTime)
345
endtime: Download end time (UTCDateTime)
346
chunklength_in_sec: File chunk length in seconds
347
network: Network code pattern
348
station: Station code pattern
349
location: Location code pattern
350
channel: Channel code pattern
351
exclude_networks: Networks to exclude
352
exclude_stations: Stations to exclude
353
minimum_length: Minimum trace length fraction
354
minimum_interstation_distance_in_m: Station spacing filter
355
channel_priorities: Preferred channel order
356
location_priorities: Preferred location order
357
reject_channels_with_gaps: Reject gapped channels
358
sanitize: Clean up file naming
359
**kwargs: Additional restrictions
360
"""
361
362
class Domain:
363
"""Base class for spatial domains."""
364
pass
365
366
class RectangularDomain(Domain):
367
def __init__(self, minlatitude: float, maxlatitude: float,
368
minlongitude: float, maxlongitude: float, **kwargs):
369
"""
370
Rectangular geographic domain.
371
372
Args:
373
minlatitude: Southern boundary in degrees
374
maxlatitude: Northern boundary in degrees
375
minlongitude: Western boundary in degrees
376
maxlongitude: Eastern boundary in degrees
377
**kwargs: Additional domain options
378
"""
379
380
class CircularDomain(Domain):
381
def __init__(self, latitude: float, longitude: float, minradius: float,
382
maxradius: float, **kwargs):
383
"""
384
Circular geographic domain.
385
386
Args:
387
latitude: Center latitude in degrees
388
longitude: Center longitude in degrees
389
minradius: Inner radius in degrees
390
maxradius: Outer radius in degrees
391
**kwargs: Additional domain options
392
"""
393
394
class GlobalDomain(Domain):
395
def __init__(self, **kwargs):
396
"""
397
Global domain (all available stations).
398
399
Args:
400
**kwargs: Additional domain options
401
"""
402
```
403
404
### Specialized Clients
405
406
Additional clients for accessing specific seismological services and data types.
407
408
```python { .api }
409
# IRIS-specific services
410
# Import from obspy.clients.iris
411
class Client:
412
def __init__(self, user: str = None, password: str = None, timeout: int = 120,
413
debug: bool = False, **kwargs):
414
"""
415
IRIS Data Management Center client.
416
417
Args:
418
user: Username for restricted access
419
password: Password for restricted access
420
timeout: Request timeout in seconds
421
debug: Enable debug output
422
**kwargs: Additional options
423
"""
424
425
def distaz(self, stalat: float, stalon: float, evtlat: float, evtlon: float):
426
"""
427
Calculate distance and azimuth using IRIS web service.
428
429
Args:
430
stalat: Station latitude in degrees
431
stalon: Station longitude in degrees
432
evtlat: Event latitude in degrees
433
evtlon: Event longitude in degrees
434
435
Returns:
436
Dictionary with distance, azimuth, and back-azimuth
437
"""
438
439
def flinnengdahl(self, lat: float, lon: float):
440
"""
441
Get Flinn-Engdahl region number and name.
442
443
Args:
444
lat: Latitude in degrees
445
lon: Longitude in degrees
446
447
Returns:
448
Dictionary with region information
449
"""
450
451
def traveltime(self, model: str, phases: list, evdepth: float,
452
distdeg: float = None, distkm: float = None):
453
"""
454
Calculate travel times using IRIS TauP service.
455
456
Args:
457
model: Earth model name
458
phases: List of seismic phases
459
evdepth: Event depth in km
460
distdeg: Distance in degrees (or use distkm)
461
distkm: Distance in km (or use distdeg)
462
463
Returns:
464
List of travel time dictionaries
465
"""
466
467
# Syngine synthetic seismogram service
468
# Import from obspy.clients.syngine
469
class Client:
470
def __init__(self, base_url: str = "http://service.iris.edu",
471
user_agent: str = None, debug: bool = False, **kwargs):
472
"""
473
Syngine synthetic seismogram client.
474
475
Args:
476
base_url: Syngine service URL
477
user_agent: Custom user agent
478
debug: Enable debug output
479
**kwargs: Additional options
480
"""
481
482
def get_waveforms(self, model: str, network: str, station: str,
483
starttime, endtime, eventid: str = None, **kwargs) -> Stream:
484
"""
485
Generate synthetic seismograms.
486
487
Args:
488
model: Earth model for synthetics
489
network: Network code
490
station: Station code
491
starttime: Start time
492
endtime: End time
493
eventid: Event identifier
494
**kwargs: Source parameters (lat, lon, depth, magnitude, etc.)
495
496
Returns:
497
Stream with synthetic seismograms
498
"""
499
500
def get_available_models(self):
501
"""
502
Get list of available Earth models.
503
504
Returns:
505
List of model names and descriptions
506
"""
507
508
# Real-time SeedLink client
509
# Import from obspy.clients.seedlink
510
class EasySeedLinkClient:
511
def __init__(self, server_url: str, autoconnect: bool = True, **kwargs):
512
"""
513
SeedLink real-time streaming client.
514
515
Args:
516
server_url: SeedLink server URL
517
autoconnect: Connect automatically
518
**kwargs: Connection options
519
"""
520
521
def select_stream(self, net: str, station: str, selector: str = "BHZ"):
522
"""
523
Select data stream.
524
525
Args:
526
net: Network code
527
station: Station code
528
selector: Channel selector
529
"""
530
531
def run(self):
532
"""Start real-time data streaming."""
533
534
def on_data(self, trace: Trace):
535
"""
536
Callback for incoming data (override in subclass).
537
538
Args:
539
trace: Real-time trace data
540
"""
541
pass
542
543
# Nominal Response Library client
544
# Import from obspy.clients.nrl
545
class NRL:
546
def __init__(self, root: str = None, **kwargs):
547
"""
548
Nominal Response Library client.
549
550
Args:
551
root: Local NRL path or None for online access
552
**kwargs: Additional options
553
"""
554
555
def get_response(self, sensor_keys: list, datalogger_keys: list, **kwargs):
556
"""
557
Get instrument response from NRL.
558
559
Args:
560
sensor_keys: Sensor identification path
561
datalogger_keys: Datalogger identification path
562
**kwargs: Additional parameters
563
564
Returns:
565
Response object
566
"""
567
568
def get_sensors(self):
569
"""Get available sensors list."""
570
571
def get_dataloggers(self):
572
"""Get available dataloggers list."""
573
```
574
575
## Usage Examples
576
577
### Basic FDSN Client Usage
578
579
```python
580
from obspy.clients.fdsn import Client
581
from obspy import UTCDateTime
582
583
# Create client for IRIS data center
584
client = Client("IRIS")
585
586
# Alternative: use specific data center URL
587
# client = Client("http://service.iris.edu")
588
589
# Download waveform data
590
starttime = UTCDateTime("2023-01-15T10:00:00")
591
endtime = UTCDateTime("2023-01-15T12:00:00")
592
593
st = client.get_waveforms("IU", "ANMO", "00", "BHZ", starttime, endtime)
594
print(f"Downloaded {len(st)} traces")
595
596
# Download earthquake catalog
597
events = client.get_events(starttime=starttime, endtime=endtime,
598
minmagnitude=5.0, maxmagnitude=8.0)
599
print(f"Found {len(events)} events")
600
601
# Download station metadata
602
inventory = client.get_stations(network="IU", station="ANMO",
603
level="response")
604
print(f"Got metadata for {len(inventory.networks)} networks")
605
```
606
607
### Bulk Data Downloads
608
609
```python
610
from obspy.clients.fdsn import Client
611
from obspy import UTCDateTime
612
613
client = Client("IRIS")
614
615
# Define bulk waveform request
616
starttime = UTCDateTime("2023-01-01")
617
endtime = UTCDateTime("2023-01-02")
618
619
bulk_list = [
620
("IU", "ANMO", "00", "BHZ", starttime, endtime),
621
("IU", "ANMO", "00", "BHN", starttime, endtime),
622
("IU", "ANMO", "00", "BHE", starttime, endtime),
623
("IU", "COLA", "00", "BHZ", starttime, endtime),
624
("IU", "COLA", "00", "BHN", starttime, endtime),
625
("IU", "COLA", "00", "BHE", starttime, endtime),
626
]
627
628
# Download all traces efficiently
629
st = client.get_waveforms_bulk(bulk_list)
630
print(f"Downloaded {len(st)} traces from bulk request")
631
632
# Process by station
633
for net_sta in set([f"{tr.stats.network}.{tr.stats.station}" for tr in st]):
634
st_station = st.select(network=net_sta.split('.')[0],
635
station=net_sta.split('.')[1])
636
print(f"Station {net_sta}: {len(st_station)} traces")
637
```
638
639
### Mass Downloader for Large Studies
640
641
```python
642
from obspy.clients.fdsn.mass_downloader import (
643
RectangularDomain, Restrictions, MassDownloader
644
)
645
from obspy import UTCDateTime
646
647
# Define spatial domain (Southern California)
648
domain = RectangularDomain(minlatitude=32.0, maxlatitude=37.0,
649
minlongitude=-122.0, maxlongitude=-115.0)
650
651
# Define temporal and channel restrictions
652
restrictions = Restrictions(
653
starttime=UTCDateTime("2023-01-01"),
654
endtime=UTCDateTime("2023-01-07"),
655
chunklength_in_sec=86400, # 1-day files
656
channel_priorities=["HH[ZNE]", "BH[ZNE]", "EH[ZNE]"],
657
location_priorities=["", "00", "10"],
658
minimum_length=0.8, # Require 80% data coverage
659
reject_channels_with_gaps=False,
660
minimum_interstation_distance_in_m=1000.0 # 1 km minimum spacing
661
)
662
663
# Create downloader
664
mdl = MassDownloader(providers=["IRIS", "NCEDC", "SCEDC"])
665
666
# Download data
667
mdl.download(domain, restrictions,
668
mseed_storage="waveforms",
669
stationxml_storage="stations")
670
```
671
672
### Multi-Center Routing
673
674
```python
675
from obspy.clients.fdsn import RoutingClient
676
from obspy import UTCDateTime
677
678
# Create routing client (automatically finds best data center)
679
client = RoutingClient("eida-routing")
680
681
# Request data that may be distributed across multiple centers
682
starttime = UTCDateTime("2023-01-01")
683
endtime = UTCDateTime("2023-01-02")
684
685
# EIDA network data (will route to appropriate European centers)
686
st = client.get_waveforms("FR", "SJAF", "00", "HHZ", starttime, endtime)
687
688
# Get station information from multiple centers
689
inventory = client.get_stations(network="FR,G,IU", station="*",
690
level="station")
691
692
print(f"Got data from {len(set([tr.stats.network for tr in st]))} networks")
693
print(f"Inventory has {sum([len(net.stations) for net in inventory.networks])} stations")
694
```
695
696
### Real-time Data Streaming
697
698
```python
699
from obspy.clients.seedlink.easyseedlink import create_client
700
from obspy import UTCDateTime
701
702
def handle_data(trace):
703
"""Process incoming real-time data."""
704
print(f"Received: {trace.id} - {trace.stats.starttime}")
705
706
# Apply real-time processing
707
trace.detrend('linear')
708
trace.filter('bandpass', freqmin=1.0, freqmax=10.0)
709
710
# Check for events (example)
711
if trace.max() > 1000: # Simple amplitude threshold
712
print(f"Possible event detected on {trace.id}")
713
714
# Connect to SeedLink server
715
client = create_client("rtserve.iris.washington.edu", on_data=handle_data)
716
717
# Select streams
718
client.select_stream("IU", "ANMO", "BHZ.D")
719
client.select_stream("IU", "COLA", "BHZ.D")
720
721
# Start streaming (runs indefinitely)
722
client.run()
723
```
724
725
### Synthetic Seismograms with Syngine
726
727
```python
728
from obspy.clients.syngine import Client
729
from obspy import UTCDateTime
730
731
client = Client()
732
733
# Get available models
734
models = client.get_available_models()
735
print("Available models:", [m['name'] for m in models])
736
737
# Generate synthetic seismograms for earthquake
738
starttime = UTCDateTime("2023-01-01T00:00:00")
739
endtime = UTCDateTime("2023-01-01T01:00:00")
740
741
st = client.get_waveforms(
742
model="ak135f_5s",
743
network="XX",
744
station="SYN",
745
starttime=starttime,
746
endtime=endtime,
747
# Source parameters
748
sourcelocation="2023-01-01T00:10:00,-10.0,30.0,10000", # time,lat,lon,depth_m
749
sourcemagnitude=6.5,
750
sourcedepthinmeters=10000
751
)
752
753
print(f"Generated {len(st)} synthetic traces")
754
st.plot()
755
```
756
757
## Types
758
759
```python { .api }
760
# Exception classes
761
class FDSNException(Exception):
762
"""Base exception for FDSN client errors."""
763
pass
764
765
class FDSNNoDataException(FDSNException):
766
"""No data available for request."""
767
pass
768
769
class FDSNTimeoutException(FDSNException):
770
"""Request timeout exceeded."""
771
pass
772
773
class FDSNBadRequestException(FDSNException):
774
"""Invalid request parameters."""
775
pass
776
777
# Data center information structure
778
DataCenter = {
779
'name': str, # Data center name
780
'website': str, # Website URL
781
'services': list[str], # Available services
782
'waveform_url': str, # Waveform service URL
783
'event_url': str, # Event service URL
784
'station_url': str # Station service URL
785
}
786
787
# Availability information structure
788
Availability = {
789
'network': str, # Network code
790
'station': str, # Station code
791
'location': str, # Location code
792
'channel': str, # Channel code
793
'starttime': UTCDateTime, # Earliest available data
794
'endtime': UTCDateTime, # Latest available data
795
'samplerate': float, # Sampling rate
796
'quality': str # Data quality indicator
797
}
798
```