or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-data-structures.mddata-center-clients.mdfile-format-io.mdgeodetic-calculations.mdindex.mdsignal-processing.mdtravel-time-calculations.mdvisualization-imaging.md

data-center-clients.mddocs/

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

```