pysmo.classes
Concrete classes compatible with pysmo types.
The pysmo.classes module provides classes that implement one or more
pysmo protocol types. These classes can be used directly with any
pysmo function or tool that operates on pysmo types.
Classes:
| Name | Description |
|---|---|
GeoCsvSeismogram |
Import class for seismograms in the GeoCSV timeseries format. |
SAC |
Access and modify data stored in SAC files. |
SacEvent |
Helper class for SAC event attributes. |
SacPZ |
Import class for SAC PZ (pole-zero) files. |
SacSeismogram |
Helper class for SAC seismogram attributes. |
SacStation |
Helper class for SAC station attributes. |
SacTimestamps |
Helper class to access times stored in SAC headers as |
StationXML |
Import class for FDSN StationXML response metadata. |
GeoCsvSeismogram
Bases: SeismogramEndtimeMixin
Import class for seismograms in the GeoCSV timeseries format.
Reads a waveform from the timeseries flavour of
GeoCSV and exposes
it as a Seismogram-compatible object.
This class is intended as a data-ingestion step. Once loaded, use
clone_to_mini to convert the
waveform to a MiniSeismogram, which can then
be passed to copy_from_mini to
populate another object such as a SAC instance.
Instances can be modified in memory but there is no write-back to
GeoCSV.
Examples:
>>> from pysmo import Seismogram
>>> from pysmo.classes import GeoCsvSeismogram
>>> text = '''\
... # dataset: GeoCSV 2.0
... # delimiter: ,
... # field_unit: UTC, Counts
... # field_type: datetime, INTEGER
... # SID: IU_ANMO_00_LHZ
... # sample_count: 3
... # sample_rate_hz: 1.0
... # start_time: 2010-02-27T06:30:00Z
... Time, Sample
... 2010-02-27T06:30:00Z, -47297
... 2010-02-27T06:30:01Z, -47298
... 2010-02-27T06:30:02Z, -47299'''
>>> seismogram = GeoCsvSeismogram.from_text(text)
>>> isinstance(seismogram, Seismogram)
True
>>> seismogram.sid
'IU_ANMO_00_LHZ'
>>> seismogram.data
array([-47297., -47298., -47299.])
>>> seismogram.end_time
Timestamp('2010-02-27 06:30:02+0000', tz='UTC')
>>>
Methods:
| Name | Description |
|---|---|
fetch |
Fetch and parse a seismogram from the EarthScope FDSN dataselect |
from_text |
Create a new instance from a GeoCSV text body. |
Attributes:
| Name | Type | Description |
|---|---|---|
begin_time |
UtcTimestamp
|
Seismogram begin time. |
data |
ndarray
|
Seismogram data. |
delta |
PositiveTimedelta
|
Seismogram sampling interval. |
sample_count |
int
|
Number of samples, always equal to |
sid |
str
|
FDSN source identifier of the parsed GeoCSV data (e.g. |
Source code in src/pysmo/classes/_geocsv.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | |
begin_time
class-attribute
instance-attribute
begin_time: UtcTimestamp = field(
converter=convert_to_utc_timestamp,
on_setattr=setters.convert,
)
Seismogram begin time.
data
class-attribute
instance-attribute
data: ndarray = field(
converter=convert_to_ndarray,
validator=validators.instance_of(np.ndarray),
on_setattr=setters.pipe(
setters.convert, setters.validate
),
)
Seismogram data.
delta
class-attribute
instance-attribute
delta: PositiveTimedelta = field(
converter=convert_to_timedelta,
validator=[
validators.instance_of(pd.Timedelta),
validators.gt(pd.Timedelta(0)),
],
on_setattr=setters.pipe(
setters.convert, setters.validate
),
)
Seismogram sampling interval.
sid
class-attribute
instance-attribute
sid: str = field(
validator=validators.instance_of(str),
on_setattr=setters.validate,
)
FDSN source identifier of the parsed GeoCSV data (e.g. IU_ANMO_00_LHZ).
This is parse-time metadata: it describes the GeoCSV data the instance was created from and is not updated when other attributes change.
fetch
classmethod
Fetch and parse a seismogram from the EarthScope FDSN dataselect web service, for an absolute time window.
For a window relative to a predicted phase arrival instead, compute
the window yourself (e.g. with pysmo.tools.web.fetch_travel_times,
which shows exactly this in its own Examples) and pass the
resulting starttime/endtime here.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
station
|
Station
|
Any object satisfying the |
required |
starttime
|
Timestamp
|
Start of the requested time window (UTC). |
required |
endtime
|
Timestamp
|
End of the requested time window (UTC). |
required |
Returns:
| Type | Description |
|---|---|
Self
|
A new GeoCsvSeismogram instance. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no waveform data is returned for the given window, or the returned segments cannot be merged into a continuous trace (data gaps, differing channels or sample rates). |
ResponseError
|
If the dataselect web service returns an HTTP error. |
Examples:
>>> import pandas as pd
>>> from pysmo import MiniStation
>>> from pysmo.classes import GeoCsvSeismogram
>>> station = MiniStation(
... name="ANMO", network="IU", location="00", channel="LHZ",
... latitude=34.945981, longitude=-106.457133,
... )
>>> seismogram = GeoCsvSeismogram.fetch(
... station=station,
... starttime=pd.Timestamp("2010-02-27T06:44:00Z"),
... endtime=pd.Timestamp("2010-02-27T06:54:00Z"),
... ) # doctest: +SKIP
>>>
Source code in src/pysmo/classes/_geocsv.py
from_text
classmethod
Create a new instance from a GeoCSV text body.
The text may contain several timeseries datasets (the EarthScope dataselect service returns one dataset per contiguous segment); they are merged into a single continuous waveform.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
GeoCSV text containing one or more timeseries datasets. |
required |
Returns:
| Type | Description |
|---|---|
Self
|
A new GeoCsvSeismogram instance. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the text contains no GeoCSV datasets, a dataset is not a valid timeseries, or the datasets cannot be merged into a continuous waveform (data gaps, differing channels or sample rates). |
Source code in src/pysmo/classes/_geocsv.py
SAC
Bases: SacIO
Access and modify data stored in SAC files.
The SAC class inherits all attributes and methods
of the SacIO class, and extends it with attributes
that allow using pysmo types. The extra attributes are themselves instances
of "helper" classes that shouldn't be instantiated directly.
Examples:
SAC instances are typically created by reading a SAC file. Users familiar with the SAC file format can access header and data using the names they are used to:
>>> from pysmo.classes import SAC
>>> sac = SAC.from_file("example.sac")
>>> sac.delta
0.019999999552965164
>>> sac.data
array([2302., 2313., 2345., ..., 2836., 2772., 2723.], shape=(180000,))
>>> sac.evla
-31.465999603271484
>>>
Presenting the data in the above way is not compatible with pysmo
types. For example, event coordinates are stored in the
evla and evlo
attributes, which do not match the pysmo Location
type. Renaming or aliasing evla to latitude and evlo to
longitude would solve the problem for the event coordinates, but
since the SAC format also specifies station coordinates
(stla, stlo)
we still run into compatibility issues.
In order to map these incompatible attributes to ones that can be used with pysmo types, we use helper classes as a way to access the attributes under different names that are compatible with pysmo types:
>>> # Import the Seismogram type to check if the nested class is compatible:
>>> from pysmo import Seismogram
>>>
>>> # First verify that a SAC instance is not a pysmo Seismogram:
>>> isinstance(sac, Seismogram)
False
>>> # The sac.seismogram object is, however:
>>> isinstance(sac.seismogram, Seismogram)
True
>>>
Because the SAC file format defines a large amount of header fields for
metadata, it needs to allow for many of these to be optional. Since the
helper classes are more specific (and intended to be used with pysmo
types), their attributes typically may not be None:
Tip
The SAC class directly inherits from the
SacIO class. This gives access to all
SAC headers, ability to load from a file, download data, and so on.
Using SAC is therefore almost always
preferred over using SacIO.
Attributes:
| Name | Type | Description |
|---|---|---|
event |
SacEvent
|
Access data stored in the SAC object compatible with the |
seismogram |
SacSeismogram
|
Access data stored in the SAC object compatible with the |
station |
SacStation
|
Access data stored in the SAC object compatible with the |
timestamps |
SacTimestamps
|
Maps a SAC times such as B, E, O, T0-T9 to Timestamp objects. |
Source code in src/pysmo/classes/_sac.py
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 | |
event
class-attribute
instance-attribute
Access data stored in the SAC object compatible with the Event type.
seismogram
class-attribute
instance-attribute
seismogram: SacSeismogram = field(init=False)
Access data stored in the SAC object compatible with the Seismogram type.
station
class-attribute
instance-attribute
station: SacStation = field(init=False)
Access data stored in the SAC object compatible with the Station type.
timestamps
class-attribute
instance-attribute
timestamps: SacTimestamps = field(init=False)
Maps a SAC times such as B, E, O, T0-T9 to Timestamp objects.
SacEvent
Bases: _SacNested
Helper class for SAC event attributes.
The SacEvent class is used to map SAC attributes in a way that
matches pysmo types. An instance of this class is created for each
new (parent) SAC instance to enable pysmo
types compatibility.
Examples:
Checking if a SacEvent matches the pysmo
Event type:
>>> from pysmo.classes import SAC
>>> from pysmo import Event
>>> sac = SAC.from_file("example.sac")
>>> isinstance(sac.event, Event)
True
>>>
Note
Not all SAC files contain event information.
Attributes:
| Name | Type | Description |
|---|---|---|
depth |
int | float
|
Event depth in metres (positive downward from the surface). |
latitude |
int | float
|
Event Latitude. |
longitude |
int | float
|
Event Longitude. |
time |
UtcTimestamp
|
Event origin time (UTC). |
Source code in src/pysmo/classes/_sac.py
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | |
depth
property
writable
Event depth in metres (positive downward from the surface).
time
property
writable
time: UtcTimestamp
Event origin time (UTC).
Important
This property uses the SacIO.o time
header. If SacIO.iztype is set to
"o", then this is also the "Reference time equivalance" and
SacIO.o cannot be changed (it is always
0). Changing the time directly
is not possible if this is the case.
SacPZ
Import class for SAC PZ (pole-zero) files.
Reads an analog instrument response from a
SAC PZ
file (as produced by e.g. the EarthScope SACPZ web service) and exposes
it as a Response-compatible object. SacPZ only ever
satisfies Response, never
StagedResponse — the SAC PZ format has no
digital-stage fields to parse.
Examples:
>>> from pysmo import Response
>>> from pysmo.classes import SacPZ
>>> text = '''\
... * NETWORK (KNETWK): IU
... * STATION (KSTNM): ANMO
... * LOCATION (KHOLE): 00
... * CHANNEL (KCMPNM): BHZ
... * START : 2018-07-09T20:45:00
... * END :
... * INPUT UNIT : M
... ZEROS 2
... \t+0.000000e+00\t+0.000000e+00
... \t+0.000000e+00\t+0.000000e+00
... POLES 1
... \t-1.000000e-02\t+0.000000e+00
... CONSTANT 1.0e+09
... '''
>>> response = SacPZ.from_text(text)
>>> isinstance(response, Response)
True
>>> response.network, response.station
('IU', 'ANMO')
>>>
Methods:
| Name | Description |
|---|---|
all_from_text |
Create one instance per record in a bulk/concatenated SAC PZ text body. |
fetch |
Fetch and parse an instrument response from the EarthScope SACPZ |
from_text |
Create a new instance from a single-record SAC PZ text body. |
Attributes:
| Name | Type | Description |
|---|---|---|
channel |
str
|
Channel code parsed from the SAC PZ file's comment header. |
end_date |
Timestamp | None
|
End of the epoch this response applies to, or |
input_units |
str
|
Physical units produced by removing this response via full spectral |
location |
str
|
Location code parsed from the SAC PZ file's comment header. |
network |
str
|
Network code parsed from the SAC PZ file's comment header. |
overall_sensitivity |
NonZeroNumber
|
Total system sensitivity (the SAC PZ file's |
poles |
list[complex]
|
Response poles. |
reference_sensitivity |
NonZeroNumber | None
|
Total system sensitivity at the reference frequency, |
start_date |
Timestamp
|
Start of the epoch this response applies to. |
station |
str
|
Station code parsed from the SAC PZ file's comment header. |
zeros |
list[complex]
|
Response zeros. |
Source code in src/pysmo/classes/_sacpz.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | |
channel
class-attribute
instance-attribute
channel: str = field(validator=validators.instance_of(str))
Channel code parsed from the SAC PZ file's comment header.
end_date
class-attribute
instance-attribute
End of the epoch this response applies to, or None if still open.
input_units
class-attribute
instance-attribute
input_units: str = field(
validator=validators.instance_of(str)
)
Physical units produced by removing this response via full spectral
deconvolution — not necessarily via the sensitivity-only path, see
remove_response for why.
See Response.input_units for more details.
location
class-attribute
instance-attribute
location: str = field(validator=validators.instance_of(str))
Location code parsed from the SAC PZ file's comment header.
network
class-attribute
instance-attribute
network: str = field(validator=validators.instance_of(str))
Network code parsed from the SAC PZ file's comment header.
overall_sensitivity
class-attribute
instance-attribute
overall_sensitivity: NonZeroNumber = field(
converter=float, validator=validate_nonzero
)
Total system sensitivity (the SAC PZ file's CONSTANT).
See Response.overall_sensitivity
for more details.
poles
class-attribute
instance-attribute
reference_sensitivity
class-attribute
instance-attribute
reference_sensitivity: NonZeroNumber | None = field(
default=None,
converter=_convert_optional_float,
validator=validators.optional(validate_nonzero),
)
Total system sensitivity at the reference frequency, A0 excluded
(the SAC PZ file's SENSITIVITY header, if present).
See
Response.reference_sensitivity
for more details.
start_date
class-attribute
instance-attribute
Start of the epoch this response applies to.
station
class-attribute
instance-attribute
station: str = field(validator=validators.instance_of(str))
Station code parsed from the SAC PZ file's comment header.
zeros
class-attribute
instance-attribute
all_from_text
classmethod
Create one instance per record in a bulk/concatenated SAC PZ text body.
Unlike from_text, this does not
require (or merge to) a single record — a SACPZ retrieval that is
not pinned to a single channel epoch returns multiple concatenated
records, each with its own network/station/location/channel/
start_date/end_date provenance, which callers can filter
themselves.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
SAC PZ text containing one or more records. |
required |
Returns:
| Type | Description |
|---|---|
list[Self]
|
One SacPZ instance per record found, in order of appearance. |
Source code in src/pysmo/classes/_sacpz.py
fetch
classmethod
Fetch and parse an instrument response from the EarthScope SACPZ web service, selecting one epoch.
Unlike StationXML.fetch, epoch
selection happens server-side: the SACPZ web service's own time
parameter is passed through, so exactly one record is returned
(the epoch active at time if given, otherwise the one currently
open) without needing to fetch the full response history first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
station
|
Station
|
Any object satisfying the |
required |
time
|
Timestamp | None
|
Timestamp used to select the response epoch. If |
None
|
Returns:
| Type | Description |
|---|---|
Self
|
A new SacPZ instance for the response epoch active at time |
Self
|
(or currently open, if |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the web service's response does not contain exactly one SAC PZ record. |
ResponseError
|
If the web service returns an HTTP error. |
Tip
When fetching live from EarthScope rather than reading an
existing SAC PZ file, prefer
StationXML.fetch: the
StationXML response also captures digital FIR/IIR stages, so it
always satisfies StagedResponse, unlike
SacPZ.
Examples:
>>> from pysmo import MiniStation
>>> from pysmo.classes import SacPZ
>>> station = MiniStation(
... name="ANMO", network="IU", location="00", channel="BHZ",
... latitude=34.945981, longitude=-106.457133,
... )
>>> response = SacPZ.fetch(station=station) # doctest: +SKIP
>>>
Source code in src/pysmo/classes/_sacpz.py
from_text
classmethod
Create a new instance from a single-record SAC PZ text body.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
SAC PZ text containing exactly one record (the common
sidecar-file case, e.g. one |
required |
Returns:
| Type | Description |
|---|---|
Self
|
A new SacPZ instance. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the text contains zero or more than one SAC PZ record. |
See Also
SacPZ.all_from_text: Parse
a bulk/concatenated multi-record text body.
Examples:
Reading a SAC PZ file already saved to disk — the common case for
archived/legacy data, e.g. extracted from an old SEED volume with
rdseed -p, rather than fetched live from EarthScope:
>>> from pathlib import Path
>>> from pysmo import Response
>>> from pysmo.classes import SacPZ
>>> text = Path("SACPZ.IU.ANMO.00.BHZ").read_text()
>>> response = SacPZ.from_text(text)
>>> isinstance(response, Response)
True
>>> response.network, response.station
('IU', 'ANMO')
>>>
Source code in src/pysmo/classes/_sacpz.py
SacSeismogram
Bases: _SacNested, SeismogramEndtimeMixin
Helper class for SAC seismogram attributes.
The SacSeismogram class is used to map SAC attributes in a way that
matches pysmo types. An instance of this class is created for each new
(parent) SAC instance to enable pysmo types
compatibility.
Examples:
Checking if a SacSeismogram matches the pysmo
Seismogram type:
>>> from pysmo import Seismogram
>>> from pysmo.classes import SAC
>>> sac = SAC.from_file("example.sac")
>>> isinstance(sac.seismogram, Seismogram)
True
>>>
Timing operations in a SAC file use a reference time, and all times
(begin time, event origin time, picks, etc.) are relative to this
reference time. In pysmo only absolute times are used. The example
below shows the begin_time is the absolute time (in UTC) of the first
data point:
Attributes:
| Name | Type | Description |
|---|---|---|
begin_time |
UtcTimestamp
|
Seismogram begin time. |
data |
ndarray
|
Seismogram data. |
delta |
Timedelta
|
Sampling interval. |
Source code in src/pysmo/classes/_sac.py
SacStation
Bases: _SacNested
Helper class for SAC station attributes.
The SacStation class is used to map SAC attributes in a way that
matches pysmo types. An instance of this class is created for each
new (parent) SAC instance to enable pysmo
types compatibility.
Examples:
Checking if a SacStation matches the pysmo
Station type:
>>> from pysmo.classes import SAC
>>> from pysmo import Station
>>> sac = SAC.from_file("example.sac")
>>> isinstance(sac.station, Station)
True
>>>
Attributes:
| Name | Type | Description |
|---|---|---|
channel |
str
|
Channel code. |
elevation |
int | float | None
|
Station elevation in metres. |
latitude |
int | float
|
Station latitude. |
location |
str
|
Location code. |
longitude |
int | float
|
Station longitude. |
name |
str
|
Station name or code. |
network |
str
|
Network name or code. |
Source code in src/pysmo/classes/_sac.py
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | |
SacTimestamps
Bases: _SacNested
Helper class to access times stored in SAC headers as Timestamp objects.
The SacTimestamps class is used to map SAC attributes in a way that
matches pysmo types. An instance of this class is created for each
new (parent) SAC instance to enable pysmo
types compatibility.
Examples:
Relative seismogram begin time as a float vs absolute begin time
as a Timestamp object.
>>> from pysmo.classes import SAC
>>> sac = SAC.from_file("example.sac")
>>>
>>> # SAC header "B" as stored in a SAC file
>>> sac.b
-63.34000015258789
>>>
>>> # the output above is the number of seconds relative
>>> # to the reference time and date:
>>> sac.kzdate , sac.kztime
('2005-03-01', '07:24:05.500')
>>>
>>> # Accessing the same SAC header via a `SacTimestamps` object
>>> # yields a corresponding Timestamp object with the absolute time:
>>> sac.timestamps.b
Timestamp('2005-03-01 07:23:02.159999848+0000', tz='UTC')
>>>
Changing timestamp values:
>>> import pandas as pd
>>> sac = SAC.from_file("example.sac")
>>>
>>> # Original value of the "B" SAC header:
>>> sac.b
-63.34000015258789
>>>
>>> # Add 30 seconds to the absolute time:
>>> sac.timestamps.b += pd.Timedelta(seconds=30)
>>>
>>> # The relative time also changes by the same amount:
>>> sac.b
-33.34
>>>
>>> # Changing b to None is not allowed (it is a required time header):
>>> sac.timestamps.b = None
Traceback (most recent call last):
...
TypeError: ...
>>>
Attributes:
| Name | Type | Description |
|---|---|---|
a |
OptionalSacTimestamp
|
First arrival time. |
b |
RequiredSacTimestamp
|
Beginning time of the independent variable. |
e |
RequiredSacTimestamp
|
Ending time of the independent variable (read-only). |
f |
OptionalSacTimestamp
|
Fini or end of event time. |
o |
OptionalSacTimestamp
|
Event origin time. |
t0 |
OptionalSacTimestamp
|
User defined time pick or marker 0. |
t1 |
OptionalSacTimestamp
|
User defined time pick or marker 1. |
t2 |
OptionalSacTimestamp
|
User defined time pick or marker 2. |
t3 |
OptionalSacTimestamp
|
User defined time pick or marker 3. |
t4 |
OptionalSacTimestamp
|
User defined time pick or marker 4. |
t5 |
OptionalSacTimestamp
|
User defined time pick or marker 5. |
t6 |
OptionalSacTimestamp
|
User defined time pick or marker 6. |
t7 |
OptionalSacTimestamp
|
User defined time pick or marker 7. |
t8 |
OptionalSacTimestamp
|
User defined time pick or marker 8. |
t9 |
OptionalSacTimestamp
|
User defined time pick or marker 9. |
Source code in src/pysmo/classes/_sac.py
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 | |
a
class-attribute
instance-attribute
First arrival time.
b
class-attribute
instance-attribute
Beginning time of the independent variable.
e
class-attribute
instance-attribute
Ending time of the independent variable (read-only).
f
class-attribute
instance-attribute
Fini or end of event time.
o
class-attribute
instance-attribute
Event origin time.
t0
class-attribute
instance-attribute
User defined time pick or marker 0.
t1
class-attribute
instance-attribute
User defined time pick or marker 1.
t2
class-attribute
instance-attribute
User defined time pick or marker 2.
t3
class-attribute
instance-attribute
User defined time pick or marker 3.
t4
class-attribute
instance-attribute
User defined time pick or marker 4.
t5
class-attribute
instance-attribute
User defined time pick or marker 5.
t6
class-attribute
instance-attribute
User defined time pick or marker 6.
t7
class-attribute
instance-attribute
User defined time pick or marker 7.
t8
class-attribute
instance-attribute
User defined time pick or marker 8.
StationXML
Import class for FDSN StationXML response metadata.
Reads an instrument response from a
FDSN StationXML document (as
returned by e.g. the EarthScope station web service with
level=response) and exposes it as a
Response-compatible object. Unlike
SacPZ, StationXML always satisfies
StagedResponse too — stages is simply empty
if the document has no digital FIR/IIR decimation stages.
A StationXML document commonly covers a channel's full instrument
history, i.e. several response epochs (e.g. after a sensor swap).
from_bytes narrows this to a
single epoch (matching a given time, or the currently-open one);
all_from_bytes returns
every epoch found, for callers who want to do their own selection.
Examples:
>>> from pysmo import Response, StagedResponse
>>> from pysmo.classes import StationXML
>>> xml = b'''\
... <?xml version="1.0"?>
... <FDSNStationXML xmlns="http://www.fdsn.org/xml/station/1">
... <Network code="IU">
... <Station code="ANMO">
... <Channel code="BHZ" locationCode="00"
... startDate="2018-07-09T20:45:00.0000">
... <Response>
... <InstrumentSensitivity>
... <Value>1.98475E9</Value>
... <Frequency>0.02</Frequency>
... <InputUnits><Name>m/s</Name></InputUnits>
... <OutputUnits><Name>counts</Name></OutputUnits>
... </InstrumentSensitivity>
... <Stage number="1">
... <PolesZeros>
... <InputUnits><Name>m/s</Name></InputUnits>
... <OutputUnits><Name>V</Name></OutputUnits>
... <PzTransferFunctionType>LAPLACE (RADIANS/SECOND)</PzTransferFunctionType>
... <NormalizationFactor>5.03773E14</NormalizationFactor>
... <NormalizationFrequency>0.02</NormalizationFrequency>
... <Zero number="0"><Real>0.0</Real><Imaginary>0.0</Imaginary></Zero>
... <Pole number="0"><Real>-0.037</Real><Imaginary>0.037</Imaginary></Pole>
... </PolesZeros>
... <Decimation>
... <InputSampleRate>40.0</InputSampleRate>
... <Factor>1</Factor>
... </Decimation>
... <StageGain><Value>1183.0</Value><Frequency>0.02</Frequency></StageGain>
... </Stage>
... </Response>
... </Channel>
... </Station>
... </Network>
... </FDSNStationXML>'''
>>> response = StationXML.from_bytes(xml)
>>> isinstance(response, Response)
True
>>> isinstance(response, StagedResponse)
True
>>> response.network, response.station
('IU', 'ANMO')
>>>
Methods:
| Name | Description |
|---|---|
all_from_bytes |
Create one instance per response epoch in a StationXML document. |
fetch |
Fetch and parse an instrument response from the EarthScope FDSN |
from_bytes |
Create a new instance from a StationXML document, selecting one epoch. |
Attributes:
| Name | Type | Description |
|---|---|---|
channel |
str
|
Channel code parsed from the StationXML document. |
end_date |
Timestamp | None
|
End of the epoch this response applies to, or |
input_units |
str
|
Physical units produced by removing this response. |
location |
str
|
Location code parsed from the StationXML document. |
network |
str
|
Network code parsed from the StationXML document. |
overall_sensitivity |
NonZeroNumber
|
Scale factor combined with |
poles |
list[complex]
|
Response poles. |
reference_sensitivity |
NonZeroNumber | None
|
Total system sensitivity at the reference frequency, |
stages |
list[ResponseStage]
|
Digital decimation stages, in signal order. Empty if the document has |
start_date |
Timestamp
|
Start of the epoch this response applies to. |
station |
str
|
Station code parsed from the StationXML document. |
zeros |
list[complex]
|
Response zeros. |
Source code in src/pysmo/classes/_stationxml.py
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | |
channel
class-attribute
instance-attribute
channel: str = field(validator=validators.instance_of(str))
Channel code parsed from the StationXML document.
end_date
class-attribute
instance-attribute
End of the epoch this response applies to, or None if still open.
input_units
class-attribute
instance-attribute
input_units: str = field(
validator=validators.instance_of(str)
)
location
class-attribute
instance-attribute
location: str = field(validator=validators.instance_of(str))
Location code parsed from the StationXML document.
network
class-attribute
instance-attribute
network: str = field(validator=validators.instance_of(str))
Network code parsed from the StationXML document.
overall_sensitivity
class-attribute
instance-attribute
overall_sensitivity: NonZeroNumber = field(
converter=float, validator=validate_nonzero
)
Scale factor combined with poles/zeros to reconstruct H(f)
(NormalizationFactor * InstrumentSensitivity).
See Response.overall_sensitivity
for more details.
poles
class-attribute
instance-attribute
reference_sensitivity
class-attribute
instance-attribute
reference_sensitivity: NonZeroNumber | None = field(
default=None,
converter=_convert_optional_float,
validator=validators.optional(validate_nonzero),
)
Total system sensitivity at the reference frequency, A0 excluded
(StationXML's InstrumentSensitivity/Value).
See
Response.reference_sensitivity
for more details.
stages
class-attribute
instance-attribute
stages: list[ResponseStage] = field(factory=list)
Digital decimation stages, in signal order. Empty if the document has no digital stages.
See StagedResponse.stages for more details.
start_date
class-attribute
instance-attribute
Start of the epoch this response applies to.
station
class-attribute
instance-attribute
station: str = field(validator=validators.instance_of(str))
Station code parsed from the StationXML document.
zeros
class-attribute
instance-attribute
all_from_bytes
classmethod
Create one instance per response epoch in a StationXML document.
Unlike from_bytes, this
does not narrow to a single epoch — a document covering a channel's
full instrument history returns several, each with its own
network/station/location/channel/start_date/end_date
provenance, which callers can filter themselves.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
xml
|
bytes
|
Raw StationXML document bytes. |
required |
Returns:
| Type | Description |
|---|---|
list[Self]
|
One StationXML instance per response epoch found, in document |
list[Self]
|
order. |
Source code in src/pysmo/classes/_stationxml.py
fetch
classmethod
Fetch and parse an instrument response from the EarthScope FDSN station web service, selecting one epoch.
A channel's instrument response usually has several epochs (e.g.
after a sensor swap), so the request is narrowed to a single one:
the epoch active at time if given, otherwise the one currently
open (no endDate). Fetches the full response history in one
request and narrows client-side (like
from_bytes); to fetch once
and interpret later (e.g. offline, or without repeating the network
request), use pysmo.tools.web.fetch_stationxml and
from_bytes /
all_from_bytes directly
instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
station
|
Station
|
Any object satisfying the |
required |
time
|
Timestamp | None
|
Timestamp used to select the response epoch. If |
None
|
Returns:
| Type | Description |
|---|---|
Self
|
A new StationXML instance for the response epoch active at |
Self
|
time (or currently open, if |
Raises:
| Type | Description |
|---|---|
ValueError
|
If zero or more than one response epoch matches
time (or "currently open", if |
ResponseError
|
If the station web service returns an HTTP error. |
Examples:
>>> from pysmo import MiniStation
>>> from pysmo.classes import StationXML
>>> station = MiniStation(
... name="ANMO", network="IU", location="00", channel="BHZ",
... latitude=34.945981, longitude=-106.457133,
... )
>>> response = StationXML.fetch(station=station) # doctest: +SKIP
>>>
Source code in src/pysmo/classes/_stationxml.py
from_bytes
classmethod
from_bytes(
xml: bytes,
*,
time: Timestamp | None = None,
location: str | None = None,
channel: str | None = None
) -> Self
Create a new instance from a StationXML document, selecting one epoch.
A document is not guaranteed to cover a single channel — a
station-level query (or one saved for later, offline use) commonly
returns every location/channel combination on record, each with its
own epoch history. location/channel narrow to one before time
is applied; without them, a multi-channel document raises the same
"more than one epoch" error as an ambiguous time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
xml
|
bytes
|
Raw StationXML document bytes (as returned by the FDSN
station web service with |
required |
time
|
Timestamp | None
|
Timestamp used to select the response epoch. If |
None
|
location
|
str | None
|
Location code to narrow to, if |
None
|
channel
|
str | None
|
Channel code to narrow to, if |
None
|
Returns:
| Type | Description |
|---|---|
Self
|
A new StationXML instance for the response epoch active at |
Self
|
time (or currently open, if |
Raises:
| Type | Description |
|---|---|
ValueError
|
If, after narrowing by |
See Also
StationXML.all_from_bytes:
Parse every epoch in the document without narrowing to one.