Skip to content

pysmo

Pysmo protocol classes and their minimal implementations.

The pysmo base namespace provides protocol classes used as type hints and a minimal reference implementation ("Mini class") for each protocol. The protocols define common seismological data structures such as locations, seismic events, stations, and seismograms.

Each Mini class is a concrete attrs class that implements exactly the attributes required by its protocol. Mini classes are named by prefixing "Mini" to the protocol name (e.g. MiniSeismogram implements the Seismogram protocol).

Classes, functions, and other tools that operate on pysmo types are provided by the pysmo.classes, pysmo.functions, and pysmo.tools subpackages.

Modules:

Name Description
classes

Classes compatible with pysmo types.

functions

Building-block functions for pysmo types.

lib

Internal utilities, validators, defaults, and I/O used by pysmo.

tools

Topic-specific tools that operate on pysmo types.

typing

Constrained type aliases used for runtime validation in pysmo.

Classes:

Name Description
Seismogram

Protocol class to define the Seismogram type.

Station

Protocol class to define the Station type.

Event

Protocol class to define the Event type.

Location

Protocol class to define the Location type.

LocationWithDepth

Protocol class to define the LocationWithDepth type.

MiniSeismogram

Minimal class for use with the Seismogram type.

MiniStation

Minimal class for use with the Station type.

MiniEvent

Minimal class for use with the Event type.

MiniLocation

Minimal class for use with the Location type.

MiniLocationWithDepth

Minimal class for use with the MiniLocationWithDepth type.

Seismogram

Bases: Protocol

Protocol class to define the Seismogram type.

Examples:

Usage for a function that takes a Seismogram compatible class instance as argument and returns the begin time in isoformat:

>>> from pysmo import Seismogram
>>> from pysmo.classes import SAC  # SAC is a class that "speaks" Seismogram
>>>
>>> def example_function(seis_in: Seismogram) -> str:
...     return seis_in.begin_time.isoformat()
...
>>> sac = SAC.from_file("example.sac")
>>> seismogram = sac.seismogram
>>> example_function(seismogram)
'2005-03-01T07:23:02.160000+00:00'
>>>

Attributes:

Name Type Description
begin_time Timestamp

Seismogram begin time.

data ndarray

Seismogram data.

delta Timedelta

The sampling interval.

end_time Timestamp

Seismogram end time.

Source code in src/pysmo/_types/_seismogram.py
@runtime_checkable
class Seismogram(Protocol):
    """Protocol class to define the `Seismogram` type.

    Examples:
        Usage for a function that takes a Seismogram compatible class instance as
        argument and returns the begin time in isoformat:

        ```python
        >>> from pysmo import Seismogram
        >>> from pysmo.classes import SAC  # SAC is a class that "speaks" Seismogram
        >>>
        >>> def example_function(seis_in: Seismogram) -> str:
        ...     return seis_in.begin_time.isoformat()
        ...
        >>> sac = SAC.from_file("example.sac")
        >>> seismogram = sac.seismogram
        >>> example_function(seismogram)
        '2005-03-01T07:23:02.160000+00:00'
        >>>
        ```
    """

    begin_time: Timestamp
    """Seismogram begin time."""

    data: np.ndarray
    """Seismogram data."""

    delta: Timedelta
    """The sampling interval.

    Should be a positive `Timedelta` instance.
    """

    @property
    def end_time(self) -> Timestamp:
        """Seismogram end time."""
        ...

begin_time instance-attribute

begin_time: Timestamp

Seismogram begin time.

data instance-attribute

data: ndarray

Seismogram data.

delta instance-attribute

delta: Timedelta

The sampling interval.

Should be a positive Timedelta instance.

end_time property

end_time: Timestamp

Seismogram end time.

Station

Bases: Location, Protocol

Protocol class to define the Station type.

Attributes:

Name Type Description
latitude float

Latitude in degrees.

longitude float

Longitude in degrees.

name str

Station name or identifier.

network str

Network name or identifier.

location str

Location ID.

channel str

Channel code.

elevation float | None

Station elevation in metres.

Source code in src/pysmo/_types/_station.py
@runtime_checkable
class Station(Location, Protocol):
    """Protocol class to define the `Station` type."""

    name: str
    """Station name or identifier.

    A 1-5 character identifier for the station recording the data.
    """

    network: str
    """Network name or identifier.

    A 1-2 character code identifying the network/owner of the data.
    """

    location: str
    """Location ID.

    A two character code used to uniquely identify different data streams
    at a single stationa.
    """

    channel: str
    """Channel code.

    A three character combination used to identify:

    1. Band and general sample rate.
    2. Instrument type.
    3. Orientation of the sensor.
    """

    elevation: float | None
    """Station elevation in metres."""

latitude instance-attribute

latitude: float

Latitude in degrees.

longitude instance-attribute

longitude: float

Longitude in degrees.

name instance-attribute

name: str

Station name or identifier.

A 1-5 character identifier for the station recording the data.

network instance-attribute

network: str

Network name or identifier.

A 1-2 character code identifying the network/owner of the data.

location instance-attribute

location: str

Location ID.

A two character code used to uniquely identify different data streams at a single stationa.

channel instance-attribute

channel: str

Channel code.

A three character combination used to identify:

  1. Band and general sample rate.
  2. Instrument type.
  3. Orientation of the sensor.

elevation instance-attribute

elevation: float | None

Station elevation in metres.

Event

Bases: LocationWithDepth, Protocol

Protocol class to define the Event type.

Attributes:

Name Type Description
latitude float

Latitude in degrees.

longitude float

Longitude in degrees.

depth float

Location depth in metres.

time Timestamp

Event origin time.

Source code in src/pysmo/_types/_event.py
@runtime_checkable
class Event(LocationWithDepth, Protocol):
    """Protocol class to define the `Event` type."""

    time: Timestamp
    """Event origin time."""

latitude instance-attribute

latitude: float

Latitude in degrees.

longitude instance-attribute

longitude: float

Longitude in degrees.

depth instance-attribute

depth: float

Location depth in metres.

time instance-attribute

time: Timestamp

Event origin time.

Location

Bases: Protocol

Protocol class to define the Location type.

Attributes:

Name Type Description
latitude float

Latitude in degrees.

longitude float

Longitude in degrees.

Source code in src/pysmo/_types/_location.py
@runtime_checkable
class Location(Protocol):
    """Protocol class to define the `Location` type."""

    latitude: float
    """Latitude in degrees."""

    longitude: float
    """Longitude in degrees."""

latitude instance-attribute

latitude: float

Latitude in degrees.

longitude instance-attribute

longitude: float

Longitude in degrees.

LocationWithDepth

Bases: Location, Protocol

Protocol class to define the LocationWithDepth type.

Attributes:

Name Type Description
latitude float

Latitude in degrees.

longitude float

Longitude in degrees.

depth float

Location depth in metres.

Source code in src/pysmo/_types/_location_with_depth.py
@runtime_checkable
class LocationWithDepth(Location, Protocol):
    """Protocol class to define the `LocationWithDepth` type."""

    depth: float
    """Location depth in metres."""

latitude instance-attribute

latitude: float

Latitude in degrees.

longitude instance-attribute

longitude: float

Longitude in degrees.

depth instance-attribute

depth: float

Location depth in metres.

MiniSeismogram

Bases: SeismogramEndtimeMixin

Minimal class for use with the Seismogram type.

The MiniSeismogram class provides a minimal implementation of class that is compatible with the Seismogram type.

Examples:

>>> from pysmo import MiniSeismogram, Seismogram
>>> from pandas import Timestamp, Timedelta
>>> from datetime import timezone
>>> import numpy as np
>>> now = Timestamp.now(timezone.utc)
>>> delta = Timedelta(seconds=0.1)
>>> seismogram = MiniSeismogram(begin_time=now, delta=delta, data=np.random.rand(100))
>>> isinstance(seismogram, Seismogram)
True
>>>

Attributes:

Name Type Description
end_time Timestamp

Seismogram end time.

begin_time Timestamp

Seismogram begin time.

delta PositiveTimedelta

Seismogram sampling interval.

data ndarray

Seismogram data.

Source code in src/pysmo/_types/_seismogram.py
@beartype
@define(kw_only=True, slots=True)
class MiniSeismogram(SeismogramEndtimeMixin):
    """Minimal class for use with the [`Seismogram`][pysmo.Seismogram] type.

    The `MiniSeismogram` class provides a minimal implementation of class that
    is compatible with the [`Seismogram`][pysmo.Seismogram] type.

    Examples:
        ```python
        >>> from pysmo import MiniSeismogram, Seismogram
        >>> from pandas import Timestamp, Timedelta
        >>> from datetime import timezone
        >>> import numpy as np
        >>> now = Timestamp.now(timezone.utc)
        >>> delta = Timedelta(seconds=0.1)
        >>> seismogram = MiniSeismogram(begin_time=now, delta=delta, data=np.random.rand(100))
        >>> isinstance(seismogram, Seismogram)
        True
        >>>
        ```
    """

    begin_time: Timestamp = field(
        default=SEISMOGRAM_DEFAULTS.begin_time.value, validator=datetime_is_utc
    )
    """Seismogram begin time."""

    delta: PositiveTimedelta = SEISMOGRAM_DEFAULTS.delta.value
    """Seismogram sampling interval."""

    data: np.ndarray = field(factory=lambda: np.array([]))
    """Seismogram data."""

end_time property

end_time: Timestamp

Seismogram end time.

begin_time class-attribute instance-attribute

begin_time: Timestamp = field(
    default=begin_time.value, validator=datetime_is_utc
)

Seismogram begin time.

delta class-attribute instance-attribute

delta: PositiveTimedelta = delta.value

Seismogram sampling interval.

data class-attribute instance-attribute

data: ndarray = field(factory=lambda: array([]))

Seismogram data.

MiniStation

Minimal class for use with the Station type.

The MiniStation class provides a minimal implementation of class that is compatible with the Station type.

Examples:

>>> from pysmo import MiniStation, Station, Location
>>> station = MiniStation(latitude=-21.680301, longitude=-46.732601, name="CACB", network="BL", channel="BHZ", location="00")
>>> isinstance(station, Station)
True
>>> isinstance(station, Location)
True
>>>

Attributes:

Name Type Description
name str

Station name.

network str

Network name.

location str

Location ID.

channel str

Channel code.

latitude float

Station latitude from -90 to 90 degrees.

longitude float

Station longitude from -180 to 180 degrees.

elevation float | None

Station elevation.

Source code in src/pysmo/_types/_station.py
@define(kw_only=True, slots=True)
class MiniStation:
    """Minimal class for use with the Station type.

    The `MiniStation` class provides a minimal implementation of class that
    is compatible with the `Station` type.

    Examples:
        ```python
        >>> from pysmo import MiniStation, Station, Location
        >>> station = MiniStation(latitude=-21.680301, longitude=-46.732601, name="CACB", network="BL", channel="BHZ", location="00")
        >>> isinstance(station, Station)
        True
        >>> isinstance(station, Location)
        True
        >>>
        ```
    """

    name: str = field(validator=[validators.min_len(1), validators.max_len(5)])
    """Station name.

    See [`Station.name`][pysmo.Station.name] for more details.
    """

    network: str = field(validator=[validators.min_len(1), validators.max_len(2)])
    """Network name.

    See [`Station.network`][pysmo.Station.network] for more details.
    """

    location: str = field(
        default="  ",
        validator=[validators.min_len(2), validators.max_len(2)],
        converter=_pad_string,
    )
    """Location ID.

    See [`Station.location`][pysmo.Station.location] for more details.
    """

    channel: str = field(validator=[validators.min_len(3), validators.max_len(3)])
    """Channel code.

    See [`Station.channel`][pysmo.Station.channel] for more details.
    """

    latitude: float = field(validator=[validators.ge(-90), validators.le(90)])
    """Station latitude from -90 to 90 degrees."""

    longitude: float = field(validator=[validators.gt(-180), validators.le(180)])
    """Station longitude from -180 to 180 degrees."""

    elevation: float | None = field(
        default=None, validator=validators.optional(validators.instance_of(float | int))
    )
    """Station elevation."""

name class-attribute instance-attribute

name: str = field(validator=[min_len(1), max_len(5)])

Station name.

See Station.name for more details.

network class-attribute instance-attribute

network: str = field(validator=[min_len(1), max_len(2)])

Network name.

See Station.network for more details.

location class-attribute instance-attribute

location: str = field(
    default="  ",
    validator=[min_len(2), max_len(2)],
    converter=_pad_string,
)

Location ID.

See Station.location for more details.

channel class-attribute instance-attribute

channel: str = field(validator=[min_len(3), max_len(3)])

Channel code.

See Station.channel for more details.

latitude class-attribute instance-attribute

latitude: float = field(validator=[ge(-90), le(90)])

Station latitude from -90 to 90 degrees.

longitude class-attribute instance-attribute

longitude: float = field(validator=[gt(-180), le(180)])

Station longitude from -180 to 180 degrees.

elevation class-attribute instance-attribute

elevation: float | None = field(
    default=None,
    validator=optional(instance_of(float | int)),
)

Station elevation.

MiniEvent

Minimal class for use with the Event type.

The MiniEvent class provides a minimal implementation of class that is compatible with the Event type.

Examples:

>>> from pysmo import MiniEvent, Event, LocationWithDepth, Location
>>> from pandas import Timestamp
>>> from datetime import timezone
>>> now = Timestamp.now(timezone.utc)
>>> event = MiniEvent(latitude=-24.68, longitude=-26.73, depth=15234.0, time=now)
>>> isinstance(event, Event)
True
>>> isinstance(event, Location)
True
>>> isinstance(event, LocationWithDepth)
True
>>>

Attributes:

Name Type Description
time Timestamp

Event origin time.

latitude float

Event atitude from -90 to 90 degrees.

longitude float

Event longitude from -180 to 180 degrees.

depth float

Event depth in metres.

Source code in src/pysmo/_types/_event.py
@define(kw_only=True, slots=True)
class MiniEvent:
    """Minimal class for use with the [`Event`][pysmo.Event] type.

    The `MiniEvent` class provides a minimal implementation of class that is
    compatible with the [`Event`][pysmo.Event] type.

    Examples:
        ```python
        >>> from pysmo import MiniEvent, Event, LocationWithDepth, Location
        >>> from pandas import Timestamp
        >>> from datetime import timezone
        >>> now = Timestamp.now(timezone.utc)
        >>> event = MiniEvent(latitude=-24.68, longitude=-26.73, depth=15234.0, time=now)
        >>> isinstance(event, Event)
        True
        >>> isinstance(event, Location)
        True
        >>> isinstance(event, LocationWithDepth)
        True
        >>>
        ```
    """

    time: Timestamp = field(validator=datetime_is_utc)
    """Event origin time."""

    latitude: float = field(validator=[validators.ge(-90), validators.le(90)])
    """Event atitude from -90 to 90 degrees."""

    longitude: float = field(validator=[validators.gt(-180), validators.le(180)])
    """Event longitude from -180 to 180 degrees."""

    depth: float
    """Event depth in metres."""

time class-attribute instance-attribute

time: Timestamp = field(validator=datetime_is_utc)

Event origin time.

latitude class-attribute instance-attribute

latitude: float = field(validator=[ge(-90), le(90)])

Event atitude from -90 to 90 degrees.

longitude class-attribute instance-attribute

longitude: float = field(validator=[gt(-180), le(180)])

Event longitude from -180 to 180 degrees.

depth instance-attribute

depth: float

Event depth in metres.

MiniLocation

Minimal class for use with the Location type.

The MiniLocation class provides a minimal implementation of class that is compatible with the Location type.

Examples:

>>> from pysmo import MiniLocation, Location
>>> location = MiniLocation(latitude=41.8781, longitude=-87.6298)
>>> isinstance(location, Location)
True
>>>

Attributes:

Name Type Description
latitude float

Latitude from -90 to 90 degrees.

longitude float

Longitude from -180 to 180 degrees.

Source code in src/pysmo/_types/_location.py
@define(kw_only=True, slots=True)
class MiniLocation:
    """Minimal class for use with the [`Location`][pysmo.Location] type.

    The `MiniLocation` class provides a minimal implementation of class that
    is compatible with the [`Location`][pysmo.Location] type.

    Examples:
        ```python
        >>> from pysmo import MiniLocation, Location
        >>> location = MiniLocation(latitude=41.8781, longitude=-87.6298)
        >>> isinstance(location, Location)
        True
        >>>
        ```
    """

    latitude: float = field(validator=[validators.ge(-90), validators.le(90)])
    """Latitude from -90 to 90 degrees."""

    longitude: float = field(validator=[validators.gt(-180), validators.le(180)])
    """Longitude from -180 to 180 degrees."""

latitude class-attribute instance-attribute

latitude: float = field(validator=[ge(-90), le(90)])

Latitude from -90 to 90 degrees.

longitude class-attribute instance-attribute

longitude: float = field(validator=[gt(-180), le(180)])

Longitude from -180 to 180 degrees.

MiniLocationWithDepth

Minimal class for use with the MiniLocationWithDepth type.

The MiniLocationWithDepth class provides a minimal implementation of class that is compatible with the MiniLocationWithDepth type.

Examples:

>>> from pysmo import MiniLocationWithDepth, LocationWithDepth, Location
>>> hypo = MiniLocationWithDepth(latitude=-24.68, longitude=-26.73, depth=15234.0)
>>> isinstance(hypo, LocationWithDepth)
True
>>> isinstance(hypo, Location)
True
>>>

Attributes:

Name Type Description
latitude float

Location latitude from -90 to 90 degrees.

longitude float

Location longitude from -180 to 180 degrees.

depth float

Location depth in metres.

Source code in src/pysmo/_types/_location_with_depth.py
@define(kw_only=True, slots=True)
class MiniLocationWithDepth:
    """Minimal class for use with the [`MiniLocationWithDepth`][pysmo.MiniLocationWithDepth] type.

    The `MiniLocationWithDepth` class provides a minimal implementation of class that
    is compatible with the [`MiniLocationWithDepth`][pysmo.MiniLocationWithDepth] type.

    Examples:
        ```python
        >>> from pysmo import MiniLocationWithDepth, LocationWithDepth, Location
        >>> hypo = MiniLocationWithDepth(latitude=-24.68, longitude=-26.73, depth=15234.0)
        >>> isinstance(hypo, LocationWithDepth)
        True
        >>> isinstance(hypo, Location)
        True
        >>>
        ```
    """

    latitude: float = field(validator=[validators.ge(-90), validators.le(90)])
    """Location latitude from -90 to 90 degrees."""

    longitude: float = field(validator=[validators.gt(-180), validators.le(180)])
    """Location longitude from -180 to 180 degrees."""

    depth: float
    """Location depth in metres."""

latitude class-attribute instance-attribute

latitude: float = field(validator=[ge(-90), le(90)])

Location latitude from -90 to 90 degrees.

longitude class-attribute instance-attribute

longitude: float = field(validator=[gt(-180), le(180)])

Location longitude from -180 to 180 degrees.

depth instance-attribute

depth: float

Location depth in metres.