Skip to content

Conventions

Trust your data

Type annotations form a contract between different parts of a program, not between the code and the data it processes. Pysmo does not use annotations to validate data. Instead, it assumes the data arriving at a function are correct and in the expected format. Validate once, at the point of ingestion, and trust the data afterwards. At the class level this is straightforward with a library such as attrs, which pysmo uses throughout.

SI units

Mismatched units are a common source of errors and tedious format conversions. Pysmo assumes SI units throughout, even where other conventions are common in seismology. This is also consistent with scipy.constants, for example. A notable case is depth, which is in metres, positive downwards, where many seismological tools use kilometres instead.

Time

Pysmo uses pandas datetime types throughout rather than the built-in datetime module. Unlike datetime, pandas timestamps and time intervals are backed by the same array machinery as numpy. An operation across many values at once (shifting every pick time in an array by a fixed offset, say) then runs as a single array operation rather than a Python loop over individual objects, and is correspondingly faster. pysmo.tools.noise.NoiseModel stores its period axis this way, as a pandas.TimedeltaIndex built in one call to pandas.to_timedelta rather than one pandas.Timedelta at a time.

Points in time are always pandas.Timestamp objects with tzinfo set to UTC. All times are absolute; relative offsets from some reference point are avoided. Time intervals such as the sampling interval are always pandas.Timedelta objects, not bare floats: a float has no fixed unit attached (seconds? samples? days?), and converting between units or across calendar boundaries by hand (leap years, variable month lengths, leap seconds) is a common source of bugs. pandas.Timestamp and pandas.Timedelta handle that arithmetic internally, storing values as integer nanoseconds and avoiding the rounding error that floating-point seconds accumulate under repeated arithmetic.

Many seismological data formats and tools store absolute times without recording a timezone, even though the values are effectively UTC. In keeping with "trust your data" above, a naive timestamp arriving at a pysmo type is therefore assumed to represent UTC and is converted accordingly, not rejected. This conversion happens once, at the class level; functions that accept timestamps do not repeat it.

SciPy and NumPy parameters

Where scipy or numpy functions are used, pysmo follows their parameter definitions and ranges rather than seismology conventions. For example, scipy.signal.windows.tukey defines alpha between 0 and 1, whereas taper functions in seismology typically use 0 to 0.5. Pysmo uses the SciPy definition. Default parameter values follow SciPy and NumPy as well, which may produce different results from equivalent functions in other programs such as SAC.

Types are always complete

Pysmo types are semantically complete: a Location without a latitude or longitude is not a location at all. For this reason, optional attributes (those that could be None) are avoided unless strictly necessary. Every attribute a type defines is always present and meaningful. This is one of the advantages of pysmo's protocol-based approach over monolithic classes: because each type represents exactly one concept, code that receives a Location can use its attributes directly, without first checking that they have a value.

Prefer functions over methods

Functions are preferred over methods. Methods on a type create coupling between the type and specific behaviour, which works against reusability. Pysmo types therefore contain almost no methods.

The same applies to Python's special methods, those with double-underscore names such as __len__. Pysmo types are data containers, and giving them special behaviour this way would be ambiguous. If Seismogram had a __len__ method, len(seismogram) could mean the number of samples or something else. len(seismogram.data) is unambiguous.