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

core-data-structures.mddocs/

0

# Core Data Structures

1

2

Fundamental data objects for seismological time series, event catalogs, and station metadata. These objects provide the foundation for all ObsPy functionality with automatic format detection and seamless integration across the seismological data ecosystem.

3

4

## Capabilities

5

6

### UTCDateTime Class

7

8

UTC-based datetime handling specifically designed for seismological timestamps with microsecond precision and specialized formatting for seismological standards.

9

10

```python { .api }

11

class UTCDateTime:

12

def __init__(self, *args, **kwargs):

13

"""

14

Create UTC datetime object.

15

16

Args:

17

*args: Various input formats (string, timestamp, datetime components)

18

**kwargs: Additional parameters

19

20

Examples:

21

UTCDateTime() # Current time

22

UTCDateTime("2023-01-01T00:00:00")

23

UTCDateTime(2023, 1, 1, 0, 0, 0)

24

UTCDateTime(1672531200.0) # Unix timestamp

25

"""

26

27

def strftime(self, fmt: str) -> str:

28

"""Format datetime as string using strftime format codes."""

29

30

def strptime(cls, date_string: str, format: str) -> 'UTCDateTime':

31

"""Parse string to UTCDateTime using format codes."""

32

33

def format_fissures(self) -> str:

34

"""Format for FISSURES/DHI web services."""

35

36

def format_arclink(self) -> str:

37

"""Format for ArcLink protocol."""

38

39

def format_seedlink(self) -> str:

40

"""Format for SeedLink protocol."""

41

42

def format_seed(self) -> str:

43

"""Format for SEED standard."""

44

45

def format_iris_web_service(self) -> str:

46

"""Format for IRIS web services."""

47

48

def now(cls) -> 'UTCDateTime':

49

"""Get current UTC time."""

50

51

def utcnow(cls) -> 'UTCDateTime':

52

"""Get current UTC time (alias for now())."""

53

54

@property

55

def matplotlib_date(self) -> float:

56

"""Get matplotlib-compatible date number."""

57

58

def replace(self, **kwargs) -> 'UTCDateTime':

59

"""Return datetime with specified components replaced."""

60

61

def timetuple(self) -> tuple:

62

"""Return time tuple compatible with time module."""

63

64

def utctimetuple(self) -> tuple:

65

"""Return UTC time tuple."""

66

67

def toordinal(self) -> int:

68

"""Return proleptic Gregorian ordinal."""

69

70

def isoformat(self) -> str:

71

"""Return ISO format string."""

72

73

def isoweekday(self) -> int:

74

"""Return day of week (1=Monday, 7=Sunday)."""

75

76

def isocalendar(self) -> tuple:

77

"""Return ISO calendar tuple (year, week, weekday)."""

78

```

79

80

### Trace Class

81

82

Single seismogram trace container with data array and metadata, providing the fundamental building block for seismological time series analysis.

83

84

```python { .api }

85

class Trace:

86

def __init__(self, data=None, header=None):

87

"""

88

Create seismogram trace.

89

90

Args:

91

data: NumPy array containing seismic data

92

header: Dictionary or Stats object with metadata

93

"""

94

95

@property

96

def data(self):

97

"""NumPy array containing seismic data."""

98

99

@property

100

def stats(self) -> 'Stats':

101

"""Trace metadata (Stats object)."""

102

103

@property

104

def id(self) -> str:

105

"""Unique trace identifier (network.station.location.channel)."""

106

107

def plot(self, **kwargs):

108

"""

109

Plot trace waveform.

110

111

Args:

112

**kwargs: Matplotlib plotting options

113

"""

114

115

def spectrogram(self, **kwargs):

116

"""

117

Plot spectrogram of trace data.

118

119

Args:

120

**kwargs: Spectrogram parameters and plotting options

121

"""

122

123

def write(self, filename: str, format: str = None, **kwargs):

124

"""

125

Write trace to file.

126

127

Args:

128

filename: Output filename

129

format: Format (auto-detected if None)

130

**kwargs: Format-specific options

131

"""

132

133

def trim(self, starttime=None, endtime=None, **kwargs) -> 'Trace':

134

"""

135

Trim trace to time window.

136

137

Args:

138

starttime: Start time (UTCDateTime or None)

139

endtime: End time (UTCDateTime or None)

140

**kwargs: Additional trim options

141

142

Returns:

143

Modified trace (in-place)

144

"""

145

146

def slice(self, starttime=None, endtime=None) -> 'Trace':

147

"""

148

Return new trace with data sliced to time window.

149

150

Args:

151

starttime: Start time (UTCDateTime or None)

152

endtime: End time (UTCDateTime or None)

153

154

Returns:

155

New Trace object with sliced data

156

"""

157

158

def filter(self, type: str, **options) -> 'Trace':

159

"""

160

Apply digital filter to trace data.

161

162

Args:

163

type: Filter type ('bandpass', 'lowpass', 'highpass', etc.)

164

**options: Filter-specific parameters (frequencies, etc.)

165

166

Returns:

167

Modified trace (in-place)

168

"""

169

170

def trigger(self, type: str, **options):

171

"""

172

Apply triggering algorithm to trace data.

173

174

Args:

175

type: Trigger type ('recstalta', 'classicstalta', etc.)

176

**options: Trigger-specific parameters

177

178

Returns:

179

Trigger function or onset times

180

"""

181

182

def resample(self, sampling_rate: float, **kwargs) -> 'Trace':

183

"""

184

Resample trace to new sampling rate.

185

186

Args:

187

sampling_rate: Target sampling rate in Hz

188

**kwargs: Resampling options

189

190

Returns:

191

Modified trace (in-place)

192

"""

193

194

def decimate(self, factor: int, **kwargs) -> 'Trace':

195

"""

196

Decimate trace by integer factor.

197

198

Args:

199

factor: Decimation factor

200

**kwargs: Decimation options

201

202

Returns:

203

Modified trace (in-place)

204

"""

205

206

def simulate(self, paz_remove=None, paz_simulate=None, **kwargs) -> 'Trace':

207

"""

208

Simulate instrument response.

209

210

Args:

211

paz_remove: Poles and zeros to remove

212

paz_simulate: Poles and zeros to simulate

213

**kwargs: Simulation options

214

215

Returns:

216

Modified trace (in-place)

217

"""

218

219

def detrend(self, type: str = 'linear', **kwargs) -> 'Trace':

220

"""

221

Remove trend from trace data.

222

223

Args:

224

type: Detrend type ('linear', 'constant', 'polynomial', etc.)

225

**kwargs: Detrend-specific options

226

227

Returns:

228

Modified trace (in-place)

229

"""

230

231

def taper(self, max_percentage: float = 0.05, type: str = 'hann', **kwargs) -> 'Trace':

232

"""

233

Apply taper to trace data.

234

235

Args:

236

max_percentage: Taper length as fraction of trace

237

type: Taper type ('hann', 'cosine', etc.)

238

**kwargs: Taper options

239

240

Returns:

241

Modified trace (in-place)

242

"""

243

244

def normalize(self, norm: float = None) -> 'Trace':

245

"""

246

Normalize trace data.

247

248

Args:

249

norm: Normalization value (max absolute value if None)

250

251

Returns:

252

Modified trace (in-place)

253

"""

254

255

def differentiate(self, method: str = 'gradient') -> 'Trace':

256

"""

257

Differentiate trace data.

258

259

Args:

260

method: Differentiation method

261

262

Returns:

263

Modified trace (in-place)

264

"""

265

266

def integrate(self, method: str = 'cumtrapz') -> 'Trace':

267

"""

268

Integrate trace data.

269

270

Args:

271

method: Integration method

272

273

Returns:

274

Modified trace (in-place)

275

"""

276

277

def attach_response(self, response):

278

"""

279

Attach instrument response to trace.

280

281

Args:

282

response: Response object or filename

283

"""

284

285

def remove_response(self, **kwargs) -> 'Trace':

286

"""

287

Remove instrument response from trace data.

288

289

Args:

290

**kwargs: Response removal options

291

292

Returns:

293

Modified trace (in-place)

294

"""

295

296

def remove_sensitivity(self, **kwargs) -> 'Trace':

297

"""

298

Remove instrument sensitivity from trace data.

299

300

Args:

301

**kwargs: Sensitivity removal options

302

303

Returns:

304

Modified trace (in-place)

305

"""

306

307

def copy(self) -> 'Trace':

308

"""Return deep copy of trace."""

309

310

def split(self) -> list['Trace']:

311

"""Split trace at gaps, returning list of traces."""

312

313

def times(self, type: str = 'matplotlib') -> np.ndarray:

314

"""

315

Generate time array for trace data.

316

317

Args:

318

type: Time array type ('matplotlib', 'utcdatetime', 'timestamp')

319

320

Returns:

321

NumPy array of time values

322

"""

323

324

def max(self) -> float:

325

"""Return maximum absolute value of trace data."""

326

327

def std(self) -> float:

328

"""Return standard deviation of trace data."""

329

330

def verify(self) -> bool:

331

"""Verify trace integrity and consistency."""

332

```

333

334

### Stats Class

335

336

Metadata container for trace information extending dictionary functionality with attribute access and seismological standards compliance.

337

338

```python { .api }

339

class Stats(AttribDict):

340

def __init__(self, header=None):

341

"""

342

Create trace metadata container.

343

344

Args:

345

header: Dictionary of metadata values

346

"""

347

348

# Standard SEED metadata attributes

349

sampling_rate: float # Sampling rate in Hz

350

delta: float # Sample interval in seconds

351

npts: int # Number of data points

352

network: str # Network code (SEED standard)

353

station: str # Station code (SEED standard)

354

location: str # Location code (SEED standard)

355

channel: str # Channel code (SEED standard)

356

starttime: UTCDateTime # Start time of trace

357

endtime: UTCDateTime # End time of trace

358

calib: float # Calibration factor

359

```

360

361

### Stream Class

362

363

Collection of Trace objects with ensemble processing capabilities for multi-channel and multi-station seismological data analysis.

364

365

```python { .api }

366

class Stream:

367

def __init__(self, traces=None):

368

"""

369

Create stream from traces.

370

371

Args:

372

traces: List of Trace objects or None for empty stream

373

"""

374

375

def __len__(self) -> int:

376

"""Return number of traces in stream."""

377

378

def __getitem__(self, index) -> Trace:

379

"""Get trace by index or slice."""

380

381

def __setitem__(self, index, trace: Trace):

382

"""Set trace at index."""

383

384

def append(self, trace: Trace):

385

"""Add trace to end of stream."""

386

387

def extend(self, trace_list: list[Trace]):

388

"""Extend stream with list of traces."""

389

390

def insert(self, index: int, trace: Trace):

391

"""Insert trace at specified index."""

392

393

def remove(self, trace: Trace):

394

"""Remove trace from stream."""

395

396

def pop(self, index: int = -1) -> Trace:

397

"""Remove and return trace at index."""

398

399

def reverse(self):

400

"""Reverse order of traces in stream."""

401

402

def sort(self, keys: list[str] = ['network', 'station', 'location', 'channel', 'starttime']):

403

"""

404

Sort traces by metadata keys.

405

406

Args:

407

keys: List of metadata keys for sorting priority

408

"""

409

410

def select(self, **kwargs) -> 'Stream':

411

"""

412

Select traces matching criteria.

413

414

Args:

415

**kwargs: Selection criteria (network, station, channel, etc.)

416

417

Returns:

418

New Stream with matching traces

419

"""

420

421

def plot(self, **kwargs):

422

"""

423

Plot all traces in stream.

424

425

Args:

426

**kwargs: Plotting options

427

"""

428

429

def spectrogram(self, **kwargs):

430

"""

431

Plot spectrograms of all traces.

432

433

Args:

434

**kwargs: Spectrogram parameters

435

"""

436

437

def write(self, filename: str, format: str = None, **kwargs):

438

"""

439

Write stream to file.

440

441

Args:

442

filename: Output filename

443

format: Format (auto-detected if None)

444

**kwargs: Format-specific options

445

"""

446

447

def trim(self, starttime=None, endtime=None, **kwargs) -> 'Stream':

448

"""

449

Trim all traces to time window.

450

451

Args:

452

starttime: Start time (UTCDateTime or None)

453

endtime: End time (UTCDateTime or None)

454

**kwargs: Trim options

455

456

Returns:

457

Modified stream (in-place)

458

"""

459

460

def cutout(self, starttime, endtime) -> 'Stream':

461

"""

462

Remove time window from all traces.

463

464

Args:

465

starttime: Start time of cutout window

466

endtime: End time of cutout window

467

468

Returns:

469

Modified stream (in-place)

470

"""

471

472

def slice(self, starttime=None, endtime=None) -> 'Stream':

473

"""

474

Return new stream with traces sliced to time window.

475

476

Args:

477

starttime: Start time (UTCDateTime or None)

478

endtime: End time (UTCDateTime or None)

479

480

Returns:

481

New Stream with sliced traces

482

"""

483

484

def slide(self, window_length: float, step: float, **kwargs):

485

"""

486

Generator yielding sliding time windows.

487

488

Args:

489

window_length: Window length in seconds

490

step: Step size in seconds

491

**kwargs: Additional options

492

493

Yields:

494

Stream objects for each time window

495

"""

496

497

def merge(self, method: int = -1, interpolation_samples: int = -1, **kwargs) -> 'Stream':

498

"""

499

Merge overlapping or adjacent traces.

500

501

Args:

502

method: Merge method (-1=auto, 0=sum, 1=overlap)

503

interpolation_samples: Interpolation gap limit

504

**kwargs: Merge options

505

506

Returns:

507

Modified stream (in-place)

508

"""

509

510

def get_gaps(self) -> list:

511

"""

512

Get list of gaps between traces.

513

514

Returns:

515

List of gap information tuples

516

"""

517

518

def print_gaps(self):

519

"""Print gap information to stdout."""

520

521

def verify(self) -> bool:

522

"""Verify stream integrity and trace consistency."""

523

524

def filter(self, type: str, **options) -> 'Stream':

525

"""

526

Apply filter to all traces.

527

528

Args:

529

type: Filter type

530

**options: Filter parameters

531

532

Returns:

533

Modified stream (in-place)

534

"""

535

536

def trigger(self, type: str, **options):

537

"""

538

Apply trigger to all traces.

539

540

Args:

541

type: Trigger type

542

**options: Trigger parameters

543

544

Returns:

545

Trigger results for all traces

546

"""

547

548

def resample(self, sampling_rate: float, **kwargs) -> 'Stream':

549

"""

550

Resample all traces.

551

552

Args:

553

sampling_rate: Target sampling rate

554

**kwargs: Resampling options

555

556

Returns:

557

Modified stream (in-place)

558

"""

559

560

def decimate(self, factor: int, **kwargs) -> 'Stream':

561

"""

562

Decimate all traces.

563

564

Args:

565

factor: Decimation factor

566

**kwargs: Decimation options

567

568

Returns:

569

Modified stream (in-place)

570

"""

571

572

def simulate(self, **kwargs) -> 'Stream':

573

"""

574

Simulate instrument response for all traces.

575

576

Args:

577

**kwargs: Simulation options

578

579

Returns:

580

Modified stream (in-place)

581

"""

582

583

def detrend(self, type: str = 'linear', **kwargs) -> 'Stream':

584

"""

585

Detrend all traces.

586

587

Args:

588

type: Detrend type

589

**kwargs: Detrend options

590

591

Returns:

592

Modified stream (in-place)

593

"""

594

595

def taper(self, max_percentage: float = 0.05, **kwargs) -> 'Stream':

596

"""

597

Taper all traces.

598

599

Args:

600

max_percentage: Taper length fraction

601

**kwargs: Taper options

602

603

Returns:

604

Modified stream (in-place)

605

"""

606

607

def normalize(self, **kwargs) -> 'Stream':

608

"""

609

Normalize all traces.

610

611

Args:

612

**kwargs: Normalization options

613

614

Returns:

615

Modified stream (in-place)

616

"""

617

618

def differentiate(self, **kwargs) -> 'Stream':

619

"""

620

Differentiate all traces.

621

622

Args:

623

**kwargs: Differentiation options

624

625

Returns:

626

Modified stream (in-place)

627

"""

628

629

def integrate(self, **kwargs) -> 'Stream':

630

"""

631

Integrate all traces.

632

633

Args:

634

**kwargs: Integration options

635

636

Returns:

637

Modified stream (in-place)

638

"""

639

640

def max(self) -> float:

641

"""Return maximum absolute value across all traces."""

642

643

def std(self) -> float:

644

"""Return standard deviation across all traces."""

645

646

def rotate(self, method: str, **kwargs) -> 'Stream':

647

"""

648

Rotate coordinate components.

649

650

Args:

651

method: Rotation method ('NE->RT', 'ZNE->LQT', etc.)

652

**kwargs: Rotation parameters (back_azimuth, inclination, etc.)

653

654

Returns:

655

Modified stream (in-place)

656

"""

657

658

def attach_response(self, response):

659

"""

660

Attach instrument response to all traces.

661

662

Args:

663

response: Response object or inventory

664

"""

665

666

def remove_response(self, **kwargs) -> 'Stream':

667

"""

668

Remove instrument response from all traces.

669

670

Args:

671

**kwargs: Response removal options

672

673

Returns:

674

Modified stream (in-place)

675

"""

676

677

def remove_sensitivity(self, **kwargs) -> 'Stream':

678

"""

679

Remove sensitivity from all traces.

680

681

Args:

682

**kwargs: Sensitivity removal options

683

684

Returns:

685

Modified stream (in-place)

686

"""

687

688

def stack(self, **kwargs) -> list[Trace]:

689

"""

690

Stack traces by metadata groups.

691

692

Args:

693

**kwargs: Stacking options

694

695

Returns:

696

List of stacked traces

697

"""

698

699

def copy(self, deep: bool = True) -> 'Stream':

700

"""

701

Return copy of stream.

702

703

Args:

704

deep: Create deep copy if True

705

706

Returns:

707

Copied Stream object

708

"""

709

710

def clear(self):

711

"""Remove all traces from stream."""

712

713

def split(self) -> 'Stream':

714

"""

715

Split traces at gaps.

716

717

Returns:

718

Modified stream with split traces (in-place)

719

"""

720

```

721

722

### Universal Read Functions

723

724

Format-agnostic functions for reading seismological data files with automatic format detection and unified interfaces.

725

726

```python { .api }

727

def read(pathname_or_url, format=None, headonly=False, starttime=None,

728

endtime=None, nearest_sample=True, dtype=None, apply_calib=False,

729

check_compression=True, **kwargs) -> Stream:

730

"""

731

Read waveform files into Stream object.

732

733

Args:

734

pathname_or_url: File path, URL, or file-like object

735

format: Format hint (auto-detected if None)

736

headonly: Read metadata only, skip data

737

starttime: Start time for reading window

738

endtime: End time for reading window

739

nearest_sample: Align times to nearest sample

740

dtype: Data type for conversion

741

apply_calib: Apply calibration factor

742

check_compression: Verify compressed data integrity

743

**kwargs: Format-specific options

744

745

Returns:

746

Stream object containing traces

747

748

Supported formats: MiniSEED, SAC, GSE2, SEG-Y, WIN, CSS, SEISAN,

749

AH, WAV, GCF, RefTek, PDAS, Y, SEG-2, SH,

750

Kinemetrics, NIED, RG16, DMX, ALSEP, and others

751

"""

752

753

def read_events(pathname_or_url, format=None, **kwargs):

754

"""

755

Read earthquake event files into Catalog object.

756

757

Args:

758

pathname_or_url: File path, URL, or file-like object

759

format: Format hint (auto-detected if None)

760

**kwargs: Format-specific options

761

762

Returns:

763

Catalog object containing events

764

765

Supported formats: QuakeML, NDK, CMTSOLUTION, Nordic, NonLinLoc,

766

SC3ML, ZMAP, JSON, MCHEDR, CNV, FOCMEC,

767

HypoDD, SCARDEC, GSE2, IMS1.0, and others

768

"""

769

770

def read_inventory(pathname_or_url, format=None, **kwargs):

771

"""

772

Read station metadata files into Inventory object.

773

774

Args:

775

pathname_or_url: File path, URL, or file-like object

776

format: Format hint (auto-detected if None)

777

**kwargs: Format-specific options

778

779

Returns:

780

Inventory object containing station metadata

781

782

Supported formats: StationXML, SEED/XSEED, SACPZ, CSS,

783

Station text, SC3ML, ArcLink XML, and others

784

"""

785

```

786

787

## Usage Examples

788

789

### Basic Trace Operations

790

791

```python

792

from obspy import Trace, UTCDateTime

793

import numpy as np

794

795

# Create trace with synthetic data

796

data = np.random.randn(1000)

797

trace = Trace(data=data)

798

trace.stats.sampling_rate = 100.0

799

trace.stats.starttime = UTCDateTime("2023-01-01T00:00:00")

800

trace.stats.network = "XX"

801

trace.stats.station = "TEST"

802

trace.stats.channel = "HHZ"

803

804

# Basic processing

805

trace.detrend('linear')

806

trace.filter('bandpass', freqmin=1.0, freqmax=10.0)

807

trace.taper(0.05)

808

809

# Get trace information

810

print(f"Trace ID: {trace.id}")

811

print(f"Duration: {trace.stats.endtime - trace.stats.starttime} seconds")

812

print(f"Max amplitude: {trace.max()}")

813

```

814

815

### Stream Processing Workflow

816

817

```python

818

from obspy import read

819

820

# Read seismic data file

821

st = read('seismic_data.mseed')

822

823

# Pre-processing

824

st.detrend('linear')

825

st.taper(0.05)

826

st.filter('bandpass', freqmin=1.0, freqmax=20.0)

827

828

# Merge overlapping traces and remove gaps

829

st.merge(method=1, interpolation_samples=10)

830

831

# Select specific components

832

st_z = st.select(channel="*Z") # Vertical components

833

st_n = st.select(channel="*N") # North components

834

st_e = st.select(channel="*E") # East components

835

836

# Rotate horizontal components to radial-transverse

837

st_horizontal = st_n + st_e # Combine N and E components

838

st_horizontal.rotate('NE->RT', back_azimuth=45.0)

839

840

# Time window extraction

841

event_time = UTCDateTime("2023-01-15T10:30:00")

842

st_event = st.slice(event_time, event_time + 300) # 5-minute window

843

```

844

845

## Types

846

847

```python { .api }

848

class AttribDict(dict):

849

"""Dictionary with attribute-style access to keys."""

850

851

def __init__(self, *args, **kwargs):

852

"""Initialize with dictionary data."""

853

854

def __getattr__(self, name):

855

"""Get dictionary value as attribute."""

856

857

def __setattr__(self, name, value):

858

"""Set dictionary value as attribute."""

859

860

def __delattr__(self, name):

861

"""Delete dictionary key as attribute."""

862

```