Skip to content

Minimal Classes#

Pysmo includes minimal implementations of a class for each type. They serve as reference classes to be used with the corresponding types, and where applicable, are used as output objects in functions. The classes are all named using the pattern Mini<Type>. Thus the Seismogram type has a corresponding MiniSeismogram class.

MiniEvent #

Bases: MiniHypocenter

Minimal class for events.

The MiniEvent class provides a minimal implementation of class that is compatible with the Event type. The class is a subclass of MiniHypocenter, and therefore also matches the Location and Hypocenter types.

Attributes:

Name Type Description
depth float

Hypocenter depth.

longitude float

Event longitude.

latitude float

Event latitude.

time datetime

Event origin time.

Examples:

>>> from pysmo import MiniEvent, Event, Hypocenter, Location
>>> from datetime import datetime, timezone
>>> now = datetime.now(timezone.utc)
>>> my_event = MiniEvent(latitude=-24.68, longitude=-26.73,
                         depth=15234.0, time=now)
>>> isinstance(my_event, Event)
True
>>> isinstance(my_event, Hypocenter)
True
>>> isinstance(my_event, Location)
True
Source code in pysmo/classes/mini.py
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
@define(kw_only=True)
class MiniEvent(MiniHypocenter):
    """Minimal class for events.

    The `MiniEvent` class provides a minimal implementation of class that is
    compatible with the [`Event`][pysmo.types.Event] type. The class is a
    subclass of [`MiniHypocenter`][pysmo.classes.mini.MiniHypocenter], and
    therefore also matches the [`Location`][pysmo.types.Location] and
    [`Hypocenter`][pysmo.types.Hypocenter] types.

    Attributes:
        depth (float): Hypocenter depth.
        longitude (float): Event longitude.
        latitude (float): Event latitude.
        time: Event origin time.

    Examples:
        >>> from pysmo import MiniEvent, Event, Hypocenter, Location
        >>> from datetime import datetime, timezone
        >>> now = datetime.now(timezone.utc)
        >>> my_event = MiniEvent(latitude=-24.68, longitude=-26.73,
                                 depth=15234.0, time=now)
        >>> isinstance(my_event, Event)
        True
        >>> isinstance(my_event, Hypocenter)
        True
        >>> isinstance(my_event, Location)
        True
    """

    time: datetime = field(validator=type_validator())

MiniHypocenter #

Bases: MiniLocation

Minimal class for hypocententers.

The MiniHypocenter class provides a minimal implementation of class that is compatible with the Hypocenter type. The class is a subclass of MiniLocation, and therefore also matches the Location type.

Attributes:

Name Type Description
depth float

Hypocenter depth.

longitude float

Event longitude.

latitude float

Event latitude.

Examples:

>>> from pysmo import MiniHypocenter, Hypocenter, Location
>>> my_hypo = MiniHypocenter(latitude=-24.68, longitude=-26.73, depth=15234.0)
>>> isinstance(my_hypo, Hypocenter)
True
>>> isinstance(my_hypo, Location)
True
Source code in pysmo/classes/mini.py
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
@define(kw_only=True)
class MiniHypocenter(MiniLocation):
    """Minimal class for hypocententers.

    The `MiniHypocenter` class provides a minimal implementation of class that
    is compatible with the [`Hypocenter`][pysmo.types.Hypocenter] type. The
    class is a subclass of [`MiniLocation`][pysmo.classes.mini.MiniLocation],
    and therefore also matches the [`Location`][pysmo.types.Location] type.

    Attributes:
        depth: Hypocenter depth.
        longitude (float): Event longitude.
        latitude (float): Event latitude.

    Examples:
        >>> from pysmo import MiniHypocenter, Hypocenter, Location
        >>> my_hypo = MiniHypocenter(latitude=-24.68, longitude=-26.73, depth=15234.0)
        >>> isinstance(my_hypo, Hypocenter)
        True
        >>> isinstance(my_hypo, Location)
        True
    """

    depth: float = field(converter=float, validator=type_validator())

MiniLocation #

Minimal class for geographical locations.

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

Attributes:

Name Type Description
latitude float

The latitude of an object from -90 to 90 degrees.

longitude float

The longitude of an object from -180 to 180 degrees.

Examples:

>>> from pysmo import MiniLocation, Location
>>> my_location = MiniLocation(latitude=41.8781, longitude=-87.6298)
>>> isinstance(my_location, Location)
True
Source code in pysmo/classes/mini.py
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
@define(kw_only=True)
class MiniLocation:
    """Minimal class for geographical locations.

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

    Attributes:
        latitude: The latitude of an object from -90 to 90 degrees.
        longitude: The longitude of an object from -180 to 180 degrees.

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

    latitude: float = field(
        converter=float,
        validator=[validators.ge(-90), validators.le(90), type_validator()],
    )
    longitude: float = field(
        converter=float,
        validator=[validators.gt(-180), validators.le(180), type_validator()],
    )

MiniSeismogram #

Minimal class for seismogram data.

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

Attributes:

Name Type Description
begin_time datetime

Seismogram begin time.

end_time datetime

Seismogram end time.

delta float

Seismogram sampling interval.

data ndarray

Seismogram data.

Examples:

>>> from pysmo import MiniSeismogram, Seismogram
>>> from datetime import datetime, timezone
>>> import numpy as np
>>> now = datetime.now(timezone.utc)
>>> my_seismogram = MiniSeismogram(begin_time=now, delta=0.1,
                                   data=np.random.rand(100), id='myseis')
>>> isinstance(my_seismogram, Seismogram)
True
Source code in pysmo/classes/mini.py
 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
@define(kw_only=True)
class MiniSeismogram:
    """Minimal class for seismogram data.

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

    Attributes:
        begin_time: Seismogram begin time.
        end_time: Seismogram end time.
        delta: Seismogram sampling interval.
        data: Seismogram data.

    Examples:
        >>> from pysmo import MiniSeismogram, Seismogram
        >>> from datetime import datetime, timezone
        >>> import numpy as np
        >>> now = datetime.now(timezone.utc)
        >>> my_seismogram = MiniSeismogram(begin_time=now, delta=0.1,
                                           data=np.random.rand(100), id='myseis')
        >>> isinstance(my_seismogram, Seismogram)
        True
    """

    begin_time: datetime = field(
        default=SEISMOGRAM_DEFAULTS.begin_time, validator=type_validator()
    )
    delta: float = field(
        default=SEISMOGRAM_DEFAULTS.delta,
        converter=float,
        validator=type_validator(),
    )
    data: np.ndarray = field(factory=lambda: np.array([]), validator=type_validator())

    def __len__(self) -> int:
        return np.size(self.data)

    @property
    def end_time(self) -> datetime:
        if len(self) == 0:
            return self.begin_time
        return self.begin_time + timedelta(seconds=self.delta * (len(self) - 1))

    @classmethod
    def clone(cls, seismogram: Seismogram, skip_data: bool = False) -> Self:
        """Create a new MiniSeismogram instance from an existing
        [Seismogram][pysmo.types.Seismogram] object.

        Attributes:
            seismogram: The Seismogram to be cloned.
            skip_data: Create clone witout copying data.

        Returns:
            A copy of the original Seismogram object.

        Examples:
            Create a copy of a [SAC][pysmo.classes.sac.SAC] object without data:

            >>> from pysmo import SAC, MiniSeismogram
            >>> original_seis = SAC.from_file('testfile.sac').seismogram
            >>> cloned_seis = MiniSeismogram.clone(original_seis, skip_data=True)
            >>> print(cloned_seis.data)
            []

            Create a copy of a [SAC][pysmo.classes.sac.SAC] object with data:

            >>> from pysmo import SAC, MiniSeismogram
            >>> from numpy.testing import assert_allclose
            >>> original_seis = SAC.from_file('testfile.sac').seismogram
            >>> cloned_seis = MiniSeismogram.clone(original_seis)
            >>> assert_allclose(original_seis.data, cloned_seis.data)
            True
            >>> print(cloned_seis.data)
            [2302. 2313. 2345. ... 2836. 2772. 2723.]
        """
        cloned_seismogram = cls()
        cloned_seismogram.begin_time = copy.copy(seismogram.begin_time)
        cloned_seismogram.delta = seismogram.delta
        if not skip_data:
            cloned_seismogram.data = copy.copy(seismogram.data)
        return cloned_seismogram

    def normalize(self) -> None:
        """Normalize the seismogram data with its absolute max value.

        Examples:
            >>> import numpy as np
            >>> from pysmo import MiniSeismogram
            >>> my_seis = MiniSeismogram(data=np.array([5, 3, 7]))
            >>> my_seis.normalize()
            >>> my_seis.data
            array([0.71428571, 0.42857143, 1.        ])
        """
        self.data = _normalize(self)

    def detrend(self) -> None:
        """Remove linear and/or constant trends from a seismogram.

        Examples:
            >>> import numpy as np
            >>> import pytest
            >>> from pysmo import MiniSeismogram
            >>> my_seis = MiniSeismogram(data=np.array([5, 3, 7]))
            >>> my_seis.detrend()
            >>> np.mean(my_seis.data)
            >>> assert 0 == pytest.approx(np.mean(my_seis.data))
            True
        """
        self.data = _detrend(self)

    def resample(self, delta: float) -> None:
        """Resample Seismogram object data using the Fourier method.

        Parameters:
            delta: New sampling interval.

        Examples:
            >>> from pysmo import MiniSeismogram
            >>> my_seis = MiniSeismogram(data=np.random.rand(10000))
            >>> len(my_seis)
            10000
            >>> new_delta = my_seis.delta * 2
            >>> my_seis.resample(new_delta)
            >>> len(my_seis)
            5000
        """
        self.data, self.delta = _resample(self, delta), delta

clone(seismogram, skip_data=False) classmethod #

Create a new MiniSeismogram instance from an existing Seismogram object.

Attributes:

Name Type Description
seismogram

The Seismogram to be cloned.

skip_data

Create clone witout copying data.

Returns:

Type Description
Self

A copy of the original Seismogram object.

Examples:

Create a copy of a SAC object without data:

>>> from pysmo import SAC, MiniSeismogram
>>> original_seis = SAC.from_file('testfile.sac').seismogram
>>> cloned_seis = MiniSeismogram.clone(original_seis, skip_data=True)
>>> print(cloned_seis.data)
[]

Create a copy of a SAC object with data:

>>> from pysmo import SAC, MiniSeismogram
>>> from numpy.testing import assert_allclose
>>> original_seis = SAC.from_file('testfile.sac').seismogram
>>> cloned_seis = MiniSeismogram.clone(original_seis)
>>> assert_allclose(original_seis.data, cloned_seis.data)
True
>>> print(cloned_seis.data)
[2302. 2313. 2345. ... 2836. 2772. 2723.]
Source code in pysmo/classes/mini.py
 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
@classmethod
def clone(cls, seismogram: Seismogram, skip_data: bool = False) -> Self:
    """Create a new MiniSeismogram instance from an existing
    [Seismogram][pysmo.types.Seismogram] object.

    Attributes:
        seismogram: The Seismogram to be cloned.
        skip_data: Create clone witout copying data.

    Returns:
        A copy of the original Seismogram object.

    Examples:
        Create a copy of a [SAC][pysmo.classes.sac.SAC] object without data:

        >>> from pysmo import SAC, MiniSeismogram
        >>> original_seis = SAC.from_file('testfile.sac').seismogram
        >>> cloned_seis = MiniSeismogram.clone(original_seis, skip_data=True)
        >>> print(cloned_seis.data)
        []

        Create a copy of a [SAC][pysmo.classes.sac.SAC] object with data:

        >>> from pysmo import SAC, MiniSeismogram
        >>> from numpy.testing import assert_allclose
        >>> original_seis = SAC.from_file('testfile.sac').seismogram
        >>> cloned_seis = MiniSeismogram.clone(original_seis)
        >>> assert_allclose(original_seis.data, cloned_seis.data)
        True
        >>> print(cloned_seis.data)
        [2302. 2313. 2345. ... 2836. 2772. 2723.]
    """
    cloned_seismogram = cls()
    cloned_seismogram.begin_time = copy.copy(seismogram.begin_time)
    cloned_seismogram.delta = seismogram.delta
    if not skip_data:
        cloned_seismogram.data = copy.copy(seismogram.data)
    return cloned_seismogram

detrend() #

Remove linear and/or constant trends from a seismogram.

Examples:

>>> import numpy as np
>>> import pytest
>>> from pysmo import MiniSeismogram
>>> my_seis = MiniSeismogram(data=np.array([5, 3, 7]))
>>> my_seis.detrend()
>>> np.mean(my_seis.data)
>>> assert 0 == pytest.approx(np.mean(my_seis.data))
True
Source code in pysmo/classes/mini.py
119
120
121
122
123
124
125
126
127
128
129
130
131
132
def detrend(self) -> None:
    """Remove linear and/or constant trends from a seismogram.

    Examples:
        >>> import numpy as np
        >>> import pytest
        >>> from pysmo import MiniSeismogram
        >>> my_seis = MiniSeismogram(data=np.array([5, 3, 7]))
        >>> my_seis.detrend()
        >>> np.mean(my_seis.data)
        >>> assert 0 == pytest.approx(np.mean(my_seis.data))
        True
    """
    self.data = _detrend(self)

normalize() #

Normalize the seismogram data with its absolute max value.

Examples:

>>> import numpy as np
>>> from pysmo import MiniSeismogram
>>> my_seis = MiniSeismogram(data=np.array([5, 3, 7]))
>>> my_seis.normalize()
>>> my_seis.data
array([0.71428571, 0.42857143, 1.        ])
Source code in pysmo/classes/mini.py
106
107
108
109
110
111
112
113
114
115
116
117
def normalize(self) -> None:
    """Normalize the seismogram data with its absolute max value.

    Examples:
        >>> import numpy as np
        >>> from pysmo import MiniSeismogram
        >>> my_seis = MiniSeismogram(data=np.array([5, 3, 7]))
        >>> my_seis.normalize()
        >>> my_seis.data
        array([0.71428571, 0.42857143, 1.        ])
    """
    self.data = _normalize(self)

resample(delta) #

Resample Seismogram object data using the Fourier method.

Parameters:

Name Type Description Default
delta float

New sampling interval.

required

Examples:

>>> from pysmo import MiniSeismogram
>>> my_seis = MiniSeismogram(data=np.random.rand(10000))
>>> len(my_seis)
10000
>>> new_delta = my_seis.delta * 2
>>> my_seis.resample(new_delta)
>>> len(my_seis)
5000
Source code in pysmo/classes/mini.py
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
def resample(self, delta: float) -> None:
    """Resample Seismogram object data using the Fourier method.

    Parameters:
        delta: New sampling interval.

    Examples:
        >>> from pysmo import MiniSeismogram
        >>> my_seis = MiniSeismogram(data=np.random.rand(10000))
        >>> len(my_seis)
        10000
        >>> new_delta = my_seis.delta * 2
        >>> my_seis.resample(new_delta)
        >>> len(my_seis)
        5000
    """
    self.data, self.delta = _resample(self, delta), delta

MiniStation #

Bases: MiniLocation

Minimal class for seismic stations.

The MiniStation class provides a minimal implementation of class that is compatible with the Station type. The class is a subclass of MiniLocation, and therefore also matches the Location type.

Attributes:

Name Type Description
name str

Station name.

network str | None

Network name.

elevation float | None

Station elevation.

longitude float

Station longitude.

latitude float

Station latitude.

Examples:

>>> from pysmo import MiniStation, Station, Location
>>> my_station = MiniStation(latitude=-21.680301, longitude=-46.732601,
                             name="CACB", network="BL")
>>> isinstance(my_station, Station)
True
>>> isinstance(my_station, Location)
True
Source code in pysmo/classes/mini.py
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
@define(kw_only=True)
class MiniStation(MiniLocation):
    """Minimal class for seismic stations.

    The `MiniStation` class provides a minimal implementation of class that
    is compatible with the `Station` type. The class is a subclass of
    `MiniLocation`, and therefore also matches the `Location` type.

    Attributes:
        name: Station name.
        network: Network name.
        elevation: Station elevation.
        longitude (float): Station longitude.
        latitude (float): Station latitude.

    Examples:
        >>> from pysmo import MiniStation, Station, Location
        >>> my_station = MiniStation(latitude=-21.680301, longitude=-46.732601,
                                     name="CACB", network="BL")
        >>> isinstance(my_station, Station)
        True
        >>> isinstance(my_station, Location)
        True
    """

    name: str = field(validator=type_validator())
    network: str | None = field(default=None, validator=type_validator())
    elevation: float | None = field(
        default=None,
        converter=converters.optional(float),
        validator=validators.optional(
            [validators.gt(-180), validators.le(180), type_validator()]
        ),
    )