sac-format 0.6.0 C++20 SAC (Seismic Analysis Code) File Library |
This section provides a brief overview of functionality and usage.
The Trace
class provides easy access to SAC-files in C++. Each SAC-file is a Trace
; therefore, each Trace
object is a seismic trace (seismogram).
SAC-files can be read in by using the parameterized constructor with a std::filesystem::path
(<filesystem>
) or a std::string
(<string>
) variable that corresponds to the location of the SAC-file.
For example:
Writing SAC files can be done using one of two write functions.
Use write
(for example trace.write(filename)
).
Use legacy_write
(for example trace.legacy_write(filename)
).
Every SAC variable is accessed via getters and setters of the same name.
trace.npts()
trace.data1()
trace.kstnm()
trace.kevnm("Event 1")
trace.evla(32.89)
trace.mag(3.21)
Most of the setters are only constrained by the parameter type (single-precision, double-precision, boolean, etc.). Some setters are constrained by additional rules.
Rules here are required because the sac-format library assumes them (not strictly required by the SAC format standard). For instance, the geometric functions assume certain bounds on latitudes and longitudes.
sac-format automatically imposes these rules.
stla(input)
Limited to [-90, 90] degrees, input that is outside that range is reduced using circular symmetry.
stlo(input)
Limited to [-180, 180] degrees, input that is outside that range is reduced using circular symmetry.
evla(input)
Limited to [-90, 90] degrees, input that is outside that range is reduced using circular symmetry.
evlo(input)
Limited to [-180, 180] degrees, input that is outside that range is reduced using circular symmetry.
Rules here are required by the SAC format standard. sac-format automatically imposes these rules to prevent the creation of corrupt sac-files.
npts(input)
Because npts
defines the size of the data vectors, changing this value will change the size of data1
and data2
∗. Increasing npts resizes the vectors (std::vector::resize) by placing zeros at the end of the vectors. Reducing npts resizes the vectors down to the first npts values.
Therefore, care must be taken to maintain separate copies of data1
and data2
∗ if you plan to manipulate the original data after resizing.
∗ data2 has npts
only if it is legal, otherwise it is of size 0.
leven(input)
Changing the value of leven
potentially changes the legality of data2
, it also potentially affects the value of iftype
.
If iftype>1, then leven must be true
(evenly sampled data). Therefore, if leven is made false
in this scenario (unevenly sampled data) then iftype becomes unset∗.
If changing leven makes data2 legal∗∗, then data2 is qresized to have npts
zeros.
∗ The SAC format defines the unset values for all data-types. For integers (like iftype) it is the integer value -12345
.
∗∗ If data2 was already legal, then it is unaffected.
iftype(input)
Changing the value of iftype
poentially changes the legality of data2
, it also potentially affects the value of leven
.
If leven is false
, then iftype must be either 1 or unset. Therefore, changing iftype to have a value >1 requires that leven becomes true
(evenly sampled data).
If changing iftype makes data2 legal∗, then data2 is resized to have npts
zeros.
∗ If data2 was already legal, then it is unaffected.
data1(input)
If the size of data1
is changed, then npts
must change to reflect the new size. If data2
is legal, this adjusts its size to match as well.
data2(input)
If the size of data2
is changed to be larger than 0 and it is illegal, it is made legal by setting iftype(2)
(spectral-data).
When the size of data2 changes, npts
is updated to the new size and data1
is resized to match.
If data2
is made illegal, its size is reduced to 0 while npts
and data1
are unaffected.
Calculate gcarc
, dist
, az
, and baz
assuming spherical Earth.
Calculate frequency from delta
.
Return std::string
formatted as YYYY-JJJ
from nzyear
and nzjday
.
Return std::string
formatted as HH:MM:SS.xxx
from nzhour
, nzmin
, nzsec
, and nzmsec
.
sac-format throws exceptions of type sacfmt::io_error
(inherits std::exception
) in the event of a failure to read/write a SAC-file.
Convert decimal degrees to radians.
Convert radians to decimal degrees.
Calculate great-circle arc distance (spherical planet).
Calculate azimuth between two points (spherical planet).
Take arbitrary value of degrees and unwrap to [0, 360].
Take arbitrary value of degrees and unwrap to [-180, 180]. Useful for longitude.
Take arbitrary value of degrees and unwrap to [-90, 90]. Useful for latitude.
Low-level I/O functions are discussed below.
Conversion pair for binary representation of integer values.
Conversion pair for binary representation of floating-point values.
Conversion pair for binary representation of double-precision values.
Conversion pair for binary representation of two-word (regular) string values.
Conversion pair for binary representation of four-word (only kstnm
string values.
NOTE that care must be taken when using them to ensure that safe input is provided; the Trace
class ensures safe I/O, low-level I/O functions do not necessarily ensure safety.
Functions to read one-, two-, and four-word variables (depending on the header) and an arbitrary amount of binary data (exclusive to data1
and data2
).
Takes objects and converts them into std::vector<char>
(convert_to_word
and bool_to_word
) or std::array<char, N>
(convert_to_words
, N = # of words).
Writes input words (as std::vector<char>
) to a binary SAC-file.
Concatenates words taking into account the system endianness.
Template function that performs conversion of binary strings of arbitrary length to an arbitrary number of words.
Remove leading and trailing blank spaces from strings assuming ASCII convention (space character is integer 32, below that value are control characters that also appear as blank spaces).
Ensures string does not contain an internal termination character (\0
) and removes it if present, then removes blank spaces.
Performs string_cleaning
followed by string truncation/padding to the necessary length.
Floating-point/double-precision equality within a provided tolerance (default is f_eps
, defined in sac_format.hpp
).
Unit- and integration-tests (using Catch2) are contained in the tests
folder. They include:
binary_conversions.cpp
confirms that conversion to/from binary functions correctly.constants.cpp
confirms constant values (e.g. SAC magic numbers) are correct.datetime.cpp
confirms date and time functions work correctly.geometry.cpp
confirms that geometric calculations are correct (azimuth, greater-circle arc-length, etc.).trace.cpp
confirms that the trace class is functioning correctly (I/O, exceptions, bounded headers, etc.).The tests compile to the following programs:
basic_tests
(binary conversions and constants).datetime_tests
geometry_tests
trace_tests
Test coverage details are visible on CodeCov.io and Codacy.com. All tests can be locally-run to ensure full functionality and compliance.
By default each test prints out a pass summary, without details unless an error is encountered.
By passing the --success
flag you can see the full results of all tests.
The full output is verbose, using the compact reporter will condense the test results (--reporter=compact
).
To see additional options, run -?
.
If you have CMake install, you can run the tests using ctest
.
benchmark.cpp
contains the benchmarks. Running it locally will provide information on how long each function takes; benchmarks start with the low-level I/O function and build up to Trace reading, writing, and equality comparison.
To view available optional flags, run becnhmark -?
.
The two core files are split in the standard interface (hpp)/implementation (cpp) format.
Interface: function declarations and constants.
Implementation: function details.
Utility functions and constants exclusive to testing and benchmarking. Not split into interface/implementation.