sac-format 0.6.0
C++20 SAC (Seismic Analysis Code) File Library
Loading...
Searching...
No Matches
sacfmt Namespace Reference

sac-format namespace More...

Namespaces

namespace  bitset_type
 bitset type-safety namespace.
 

Classes

class  coord
 Defines a geographic coordinant (degrees/radians) More...
 
class  io_error
 Class for generic I/O exceptions. More...
 
struct  point
 Defines a geographic point (latitude, longitude) More...
 
struct  read_spec
 Struct that specifies parameters for reading. More...
 
class  Trace
 The Trace class. More...
 
struct  word_pair
 Struct containing a pair of words. More...
 

Typedefs

using char_bit = std::bitset< bits_per_byte >
 One binary character (useful for building strings).
 
using word_one = std::bitset< binary_word_size >
 One binary word (useful for non-strings).
 
using word_two = std::bitset< static_cast< size_t >(2) *binary_word_size >
 Two binary words (useful for strings).
 
using word_four = std::bitset< static_cast< size_t >(4) *binary_word_size >
 Four binary words (kEvNm only).
 
template<class T >
using unsigned_int = typename bitset_type::uint< sizeof(T) *bits_per_byte >::type
 Convert variable to unsigned-integer using type-safe conversions.
 

Enumerations

enum class  name {
  depmin , depmax , odelta , resp0 ,
  resp1 , resp2 , resp3 , resp4 ,
  resp5 , resp6 , resp7 , resp8 ,
  resp9 , stel , stdp , evel ,
  evdp , mag , user0 , user1 ,
  user2 , user3 , user4 , user5 ,
  user6 , user7 , user8 , user9 ,
  dist , az , baz , gcarc ,
  depmen , cmpaz , cmpinc , xminimum ,
  xmaximum , yminimum , ymaximum , delta ,
  b , e , o , a ,
  t0 , t1 , t2 , t3 ,
  t4 , t5 , t6 , t7 ,
  t8 , t9 , f , stla ,
  stlo , evla , evlo , sb ,
  sdelta , nzyear , nzjday , nzhour ,
  nzmin , nzsec , nzmsec , nvhdr ,
  norid , nevid , npts , nsnpts ,
  nwfid , nxsize , nysize , iftype ,
  idep , iztype , iinst , istreg ,
  ievreg , ievtyp , iqual , isynth ,
  imagtyp , imagsrc , ibody , leven ,
  lpspol , lovrok , lcalda , kstnm ,
  kevnm , khole , ko , ka ,
  kt0 , kt1 , kt2 , kt3 ,
  kt4 , kt5 , kt6 , kt7 ,
  kt8 , kt9 , kf , kuser0 ,
  kuser1 , kuser2 , kcmpnm , knetwk ,
  kdatrd , kinst , data1 , data2
}
 Enumeration of all SAC fields. More...
 

Functions

std::streamoff word_position (const size_t word_number) noexcept
 Calculates position of word in SAC-file.
 
word_one uint_to_binary (uint num) noexcept
 Convert unsigned integer to 32-bit (one word) binary bitset.
 
word_one int_to_binary (int num) noexcept
 Convert integer to 32-bit (one word) binary bitset.
 
int binary_to_int (word_one bin) noexcept
 Convert 32-bit (one word) binary bitset to integer.
 
word_one float_to_binary (const float num) noexcept
 Convert floating-point value to 32-bit (one word) binary bitset.
 
float binary_to_float (const word_one &bin) noexcept
 Convert 32-bit (one word) binary bitset to a floating-point value.
 
word_two double_to_binary (const double num) noexcept
 Convert double-precision value to 64-bit (two words) binary bitset.
 
double binary_to_double (const word_two &bin) noexcept
 Convert 64-bit (two words) binary bitset to double-precision value.
 
void remove_leading_spaces (std::string *str) noexcept
 Remove all leading spaces from a string.
 
void remove_trailing_spaces (std::string *str) noexcept
 Remove all trailing spaces from a string.
 
std::string string_cleaning (const std::string &str) noexcept
 Remove leading/trailing spaces and control characters from a string.
 
void prep_string (std::string *str, const size_t str_size) noexcept
 Cleans string and then truncates/pads as necessary.
 
template<typename T >
void string_bits (T *bits, const std::string &str, const size_t str_size) noexcept
 Template function to convert string into binary bitset.
 
template<typename T >
std::string bits_string (const T &bits, const size_t num_words) noexcept
 Template function to convert binary bitset to string.
 
word_two string_to_binary (std::string str) noexcept
 Convert string to a 64-bit (two word) binary bitset.
 
std::string binary_to_string (const word_two &str) noexcept
 Convert a 64-bit (two word) binary bitset to a string.
 
word_four long_string_to_binary (std::string str) noexcept
 Convert a string to a 128-bit (four word) binary bitset.
 
std::string binary_to_long_string (const word_four &str) noexcept
 Convert a 128-bit (four word) binary bitset to a string.
 
word_one bool_to_binary (const bool flag) noexcept
 Convert a boolean to a 32-bit (one word) binary bitset.
 
bool binary_to_bool (const word_one &flag) noexcept
 Convert a 32-bit (one word) binary bitset to a boolean.
 
word_two concat_words (const word_pair< word_one > &pair_words) noexcept
 Concatenate two word_one binary strings into a single word_two string.
 
word_four concat_words (const word_pair< word_two > &pair_words) noexcept
 Concatenate two word_two binary strings into a single word_four string.
 
bool nwords_after_current (std::ifstream *sac, const read_spec &spec) noexcept
 Determine if the SAC-file has enough remaining data to read the requested amount of data.
 
void safe_to_read_header (std::ifstream *sac)
 Determine if the SAC-file is large enough to contain a complete header.
 
void safe_to_read_footer (std::ifstream *sac)
 Determines if the SAC-file has enough space remaining to contain a complete footer.
 
void safe_to_read_data (std::ifstream *sac, const size_t n_words, const bool data2)
 Determines if the SAC-file has enough space remaining to contain a complete data vector.
 
void safe_to_finish_reading (std::ifstream *sac)
 Determines if the SAC-file is finished.
 
word_one read_word (std::ifstream *sac)
 Read one word (32 bits, useful for non-strings) from a binary SAC-File.
 
word_two read_two_words (std::ifstream *sac)
 Read two words (64 bits, useful for most strings) from a binary SAC-file.
 
word_four read_four_words (std::ifstream *sac)
 Read four words (128 bits, kEvNm only) from a binary SAC-file.
 
std::vector< doubleread_data (std::ifstream *sac, const read_spec &spec)
 Reader arbitrary number of words (useful for vectors) from a binary SAC-file.
 
void write_words (std::ofstream *sac_file, const std::vector< char > &input)
 Write arbitrary number of words (useful for vectors) to a binary SAC-file.
 
template<typename T >
std::vector< charconvert_to_word (const T input) noexcept
 Template function to convert input value into a std::vector<char> for writing.
 
std::vector< charconvert_to_word (const double input) noexcept
 Convert double value into a std::vector<char> for writing.
 
template<size_t N>
std::array< char, Nconvert_to_words (const std::string &str, const size_t n_words) noexcept
 Template function to convert input string value into a std::array<char> for writing.
 
std::vector< charbool_to_word (const bool flag) noexcept
 Convert boolean to a word for writing.
 
bool equal_within_tolerance (const std::vector< double > &vector1, const std::vector< double > &vector2, const double tolerance) noexcept
 Check if two std::vector<double> are equal within a tolerance limit.
 
bool equal_within_tolerance (const double val1, const double val2, const double tolerance) noexcept
 Check if two double values are equal within a tolerance limit.
 
double degrees_to_radians (const double degrees) noexcept
 Convert decimal degrees to radians.
 
double radians_to_degrees (const double radians) noexcept
 Convert radians to decimal degrees.
 
double gcarc (const point location1, const point location2) noexcept
 Calculate great circle arc distance in decimal degrees between two points.
 
double azimuth (const point location1, const point location2) noexcept
 Calculate azimuth between two points.
 
double limit_360 (const double degrees) noexcept
 Takes a decimal degree value and constrains it to full circle using symmetry.
 
double limit_180 (const double degrees) noexcept
 Takes a decimal degree value and constrains it to a half circle using symmetry.
 
double limit_90 (const double degrees) noexcept
 Takes a decimal degree value and constrains it to a quarter circle using symmetry.
 
template std::vector< charconvert_to_word (const float input) noexcept
 
template std::vector< charconvert_to_word (const int x) noexcept
 
template std::array< char, word_lengthconvert_to_words (const std::string &str, const size_t n_words) noexcept
 

Variables

constexpr size_t word_length {4}
 Size (bytes) of fundamental data-chunk.
 
constexpr size_t bits_per_byte {8}
 Size (bits) of binary character.
 
constexpr size_t binary_word_size {word_length * bits_per_byte}
 Size (bits) of funamental data-chunk.
 
constexpr std::streamoff data_word {158}
 First word of (first) data-section (stream offset).
 
constexpr int unset_int {-12345}
 Integer unset value (SAC Magic).
 
constexpr float unset_float {-12345.0F}
 Float-point unset value (SAC Magic).
 
constexpr double unset_double {-12345.0}
 Double-precision unset value (SAC Magic).
 
constexpr bool unset_bool {false}
 Boolean unset value (SAC Magic).
 
const std::string unset_word {"-12345"}
 String unset value (SAC Magic).
 
constexpr float f_eps {2.75e-6F}
 Accuracy precision expected of SAC floating-point values.
 
constexpr int ascii_space {32}
 ASCII-code of 'space' character.
 
constexpr int num_float {39}
 Number of float-poing header values in SAC format.
 
constexpr int num_double {22}
 Number of double-precision header values in SAC format.
 
constexpr int num_int {26}
 Number of integer header values in SAC format.
 
constexpr int num_bool {4}
 Number of boolean header values in SAC format.
 
constexpr int num_string {23}
 Number of string header values in SAC format.
 
constexpr int num_data {2}
 Number of data arrays in SAC format.
 
constexpr int num_footer {22}
 Number of double-precision footer values in SAC format (version 7).
 
constexpr int modern_hdr_version {7}
 nVHdr value for newest SAC format (2020+).
 
constexpr int old_hdr_version {6}
 nVHdr value for historic SAC format (pre-2020).
 
constexpr int common_skip_num {7}
 Extremely common number of 'internal use' headers in SAC format.
 
constexpr double rad_per_deg {std::numbers::pi_v<double> / 180.0}
 Radians per degree.
 
constexpr double deg_per_rad {1.0 / rad_per_deg}
 Degrees per radian.
 
constexpr double circle_deg {360.0}
 Degrees in a circle.
 
constexpr double earth_radius {6378.14}
 Average radius of Earth (kilometers).
 
const std::unordered_map< name, const size_tsac_map
 Lookup table for variable locations.
 

Detailed Description

sac-format namespace

Typedef Documentation

◆ char_bit

One binary character (useful for building strings).

◆ unsigned_int

Convert variable to unsigned-integer using type-safe conversions.

◆ word_four

Four binary words (kEvNm only).

◆ word_one

One binary word (useful for non-strings).

◆ word_two

Two binary words (useful for strings).

Enumeration Type Documentation

◆ name

Enumeration of all SAC fields.

Additional information can be found at SAC-file format

Enumerator
depmin 

Float, pre-data word 001.

Minimum value of the dependent variable (displacement/velocity/acceleration/volts/counts).

depmax 

Float, pre-data word 002.

Maximum value of the dependent variable.

odelta 

Float, pre-data word 004.

Modified (observational) value of delta.

resp0 

Float, pre-data word 021.

Instrument response parameter (poles, zeros, and a constant).

Not used by SAC - free for other purposes.

resp1 

See resp0, pre-data word 022.

resp2 

See resp0, pre-data word 023.

resp3 

See resp0, pre-data word 024.

resp4 

See resp0, pre-data word 025.

resp5 

See resp0, pre-data word 026.

resp6 

See resp0, pre-data word 027.

resp7 

See resp0, pre-data word 028.

resp8 

See resp0, pre-data word 029.

resp9 

See resp0, pre-data word 030.

stel 

Float, pre-data word 033.

Station elevation in meters above sea level (m.a.s.l.).

Not used by SAC - free for other purposes.

stdp 

Float, pre-data word 034.

Station depth in meters below surface (borehole/buried vault).

Not used by SAC - free for other purposes.

evel 

Float, pre-data word 037.

Event elevation m.a.s.l.

Not used by SAC - free for other purposes.

evdp 

Float, pre-data word 038.

Event depth in kilometers (previous meters) below surface.

mag 

Float, pre-data word 039.

Event magnitude.

user0 

Float, pre-data word 040.

Storage for user-defined values.

user1 

See user0, pre-data word 041.

user2 

See user0, pre-data word 042.

user3 

See user0, pre-data word 043.

user4 

See user0, pre-data word 044.

user5 

See user0, pre-data word 045.

user6 

See user0, pre-data word 046.

user7 

See user0, pre-data word 047.

user8 

See user0, pre-data word 048.

user9 

See user0, pre-data word 049.

dist 

Float, pre-data word 050.

Station-Event distance in kilometers.

az 

Float, pre-data word 051.

Azimuth $\color{orange}Station\rightarrow Event$ in decimal degrees from North.

baz 

Float, pre-data word 052.

Back-Azimuth $\color{orange}Event\rightarrow Station$ in decimal degrees from North.

gcarc 

Float, pre-data word 053.

Great-circle arc-distance between station and event in decimal degrees.

depmen 

Float, pre-data word 056.

Mean value of dependent variable.

cmpaz 

Float, pre-data word 057.

Instrument measurement azimuth, decimal degrees from North.

cmpinc 

Float, pre-data word 058.

Instrument measurement incidence angle, decimal degrees from upward vertical (incident 0 = dip -90).

Note: SEED/MINISEED use dip angle, decimal degrees from horizontal (dip 0 = incident 90).

xminimum 

Float, pre-data word 059.

Spectral-only equivalent of depmin ( $\color{orange}f_{0}$ or $\color{orange}\omega_{0}$).

xmaximum 

Float, pre-data word 060.

Spectral-only equivalent of depman ( $\color{orange}f_{max}$ or $\color{orange}\omega_{max}$).

yminimum 

Float, pre-data word 061.

Spectral-only equivalent of b.

ymaximum 

Float, pre-data word 062.

Spectral-only equivalent of e.

delta 

Double, pre-data word 000; post-data words 00-01.

Increment between evenly-spaced samples ( $\color{orange}\Delta t$ for timeseries, $\color{orange}\Delta f$ or $\color{orange}\Delta\omega$ for spectral).

Double, pre-data word 005; post-data words 02-03.

First value (beginning) of independent variable ( $\color{orange}t_{0}$).

Double, pre-data word 006; post-data words 04-05.

Final value (ending) of the independent variable ( $\color{orange}t_{max}$).

Double, pre-data word 007; post-data words 06-07.

Event origin time, in seconds relative to the reference time.

Double, pre-data word 008; post-data words 08-09.

Event first arrival time, in seconds relative to the reference time.

t0 

Double, pre-data word 010; post-data words 10-11.

User defined time value, in seconds relative to the reference time.

t1 

See t0, pre-data word 011; post-data words 12-13.

t2 

See t0, pre-data word 012; post-data words 14-15.

t3 

See t0, pre-data word 013; post-data words 16-17.

t4 

See t0, pre-data word 014; post-data words 18-19.

t5 

See t0, pre-data word 015; post-data words 20-21.

t6 

See t0, pre-data word 016; post-data words 22-23.

t7 

See t0, pre-data word 017; post-data words 24-25.

t8 

See t0, pre-data word 018; post-data words 26-27.

t9 

See t0, pre-data word 019; post-data words 28-29.

Double, pre-data word 020; post-data words 30-31.

Event end (fini) time, in seconds relative to the reference time.

stla 

Double, pre-data word 031; post-data words 36-37.

Station latitude in decimal degrees, N/S is positive/negative.

sac-format automatically enforces $\color{orange}\phi\in [-90,90]$.

stlo 

Double, pre-data word 032; post-data words 38-39.

Station longitude in decimal degrees, E/W is positive/negative.

sac-format automaticall enforces $\color{orange}\lambda\in [-180,180]$.

evla 

Double, pre-data word 035; post-data words 32-33.

Event latitude in decimal degrees, N/S is positive/negative.

sac-format automatically enforces $\color{orange}\phi\in [-90,90]$.

evlo 

Double, pre-data word 036; post-data words 34-35.

Event longitude in decimal degrees, E/W is positive/negative.

sac-format automatically enforces $\color{orange}\lambda\in [-180,180]$.

sb 

Double, pre-data word 054; post-data words 40-41.

Original (saved) value of b (beginning).

sdelta 

Double, pre-data word 055; post-data words 42-43.

Original (saved) value of delta (sample-spacing).

nzyear 

Integer, pre-data word 070.

Reference time GMT year.

nzjday 

Integer, pre-data word 071.

Reference time GMT day-of-year (often called Julian Date).

1-366 Not enforced.

nzhour 

Integer, pre-data word 072.

Reference time GMT hour.

00-23 Not enforced.

nzmin 

Integer, pre-data word 073.

Reference time GMT minute.

00-59 Not enforced.

nzsec 

Integer, pre-data word 074.

Reference time GMT second.

00-59 Not enforced.

nzmsec 

Integer, pre-data word 075.

Reference time GMT millisecond.

0-999 not enforced.

nvhdr 

Integer, pre-data word 076.

SAC-file version.

7 = 2020+, sac 102.0+, has a Footer. 6 = pre-2020, sac 101.6a-, no Footer.

norid 

Integer, pre-data word 077.

Origin ID.

nevid 

Integer, pre-data word 078.

Event ID.

npts 

Integer, pre-data word 079.

Number of points in data.

nsnpts 

Integer, pre-data word 080.

Original (saved) npts.

nwfid 

Integer, pre-data word 081.

Waveform ID.

nxsize 

Integer, pre-data word 082.

Spectral-only equivalent of npts (length of spectrum).

nysize 

Integer, pre-data word 083.

Spectral-only; width of spectrum.

iftype 

Integer, pre-data word 085.

File type.

idep 

Integer, pre-data word 086.

Dependent variable type.

iztype 

Integer, pre-data word 087.

Reference time equivalent.

iinst 

Integer, pre-data word 089.

Recording instrument type.

Not used by SAC - free for other purposes.

istreg 

Integer, pre-data word 090.

Station geographic region.

Not used by SAC - free for other purposes.

ievreg 

Integer, pre-data word 091.

Event geographic region.

Not used by SAC - free for other purposes.

ievtyp 

Integer, pre-data word 092.

Event type.

Not used by SAC - free for other purposes.

iqual 

Integer, pre-data word 093.

Quality of data.

Not used by SAC - free for other purposes.

isynth 

Integer, pre-data word 094.

Synthetic data flag.

Not used by SAC - free for other purposes.

imagtyp 

Integer, pre-data word 095.

Magnitude type.

imagsrc 

Integer, pre-data word 096.

Magnitude information source.

ibody 

Integer, pre-data word 097.

Body/spheroid definition used to calculate distances.

Not currently-used by sac-format (SAC does used it).

leven 

Boolean, pre-data word 105.

REQUIRED

Evenly-spaced data flag. True = even.

lpspol 

Boolean, pre-data word 106.

Station polarity flag.

True = positive (left-handed, e.g. North-East-Up).

lovrok 

Boolean, pre-data word 107.

File overwrite flag.

If true, okay to overwrite file.

Not used by sac-format.

lcalda 

Boolean, pre-data word 108.

Calculate geometry flag.

Not used by sac-format.

kstnm 

String (2 words), pre-data words 110–111.

Station name.

kevnm 

String (4 words), pre-data words 112–115.

Event name.

khole 

String (2 words), pre-data words 116–117.

Nuclear-Hole identifier.

Other-Location identifier (LOCID).

ko 

String (2 words), pre-data words 118–119.

Text for o.

ka 

String (2 words), pre-data words 120–121.

Text for a.

kt0 

String (2 words), pre-data words 122–123.

Text for t0

kt1 

See kt0, pre-data words 124–125.

kt2 

See kt0, pre-data words 126–127.

kt3 

See kt0, pre-data words 128–129.

kt4 

See kt0, pre-data words 130–131.

kt5 

See kt0, pre-data words 132–133.

kt6 

See kt0, pre-data words 134–135.

kt7 

See kt0, pre-data words 136–137.

kt8 

See kt0, pre-data words 138–139.

kt9 

See kt0, pre-data words 140–141.

kf 

String (2 words), pre-data words 142–143.

Text for f.

kuser0 

String (2 words), pre-data words 144–145.

Text for user0.

kuser1 

See kuser0, pre-data words 146–147.

kuser2 

See kuser0, pre-data words 148–149.

kcmpnm 

String (2 words), pre-data words 150-151.

Component name.

knetwk 

String (2 words), pre-data words 152-153.

Network name.

kdatrd 

String (2 words), pre-data words 154-155.

Date the data was read onto a computer.

kinst 

String (2 words), pre-data words 156-157.

Instrument name.

data1 

std::vector<double>, words 158–(158 + npts)

First data vector. ALWAYS present, ALWAYS begins at word 158.

data2 

std::vector<double>, words (158 + 1 + npts)–(159 + (2 * npts))

Second data vector. CONDITIONAL present. IF PRESENT, begins at end of data1.

Required if leven is false (uneven sampling), or if iftype is spectral/XY/XYZ.

316 {
317 // Floats
324 depmin,
330 depmax,
336 odelta,
344 resp0,
346 resp1,
348 resp2,
350 resp3,
352 resp4,
354 resp5,
356 resp6,
358 resp7,
360 resp8,
362 resp9,
370 stel,
378 stdp,
386 evel,
392 evdp,
398 mag,
404 user0,
406 user1,
408 user2,
410 user3,
412 user4,
414 user5,
416 user6,
418 user7,
420 user8,
422 user9,
428 dist,
435 az,
442 baz,
448 gcarc,
454 depmen,
460 cmpaz,
470 cmpinc,
497 // Doubles
506 delta,
512 b,
519 e,
525 o,
531 a,
537 t0,
539 t1,
541 t2,
543 t3,
545 t4,
547 t5,
549 t6,
551 t7,
553 t8,
555 t9,
561 f,
569 stla,
577 stlo,
585 evla,
593 evlo,
599 sb,
605 sdelta,
606 // Ints
612 nzyear,
620 nzjday,
628 nzhour,
636 nzmin,
644 nzsec,
652 nzmsec,
661 nvhdr,
667 norid,
673 nevid,
679 npts,
685 nsnpts,
691 nwfid,
697 nxsize,
703 nysize,
709 iftype,
715 idep,
721 iztype,
729 iinst,
737 istreg,
745 ievreg,
753 ievtyp,
761 iqual,
769 isynth,
775 imagtyp,
781 imagsrc,
789 ibody,
790 // Bools
798 leven,
806 lpspol,
816 lovrok,
824 lcalda,
825 // Strings
831 kstnm,
837 kevnm,
845 khole,
851 ko,
857 ka,
863 kt0,
865 kt1,
867 kt2,
869 kt3,
871 kt4,
873 kt5,
875 kt6,
877 kt7,
879 kt8,
881 kt9,
887 kf,
893 kuser0,
895 kuser1,
897 kuser2,
903 kcmpnm,
909 knetwk,
915 kdatrd,
921 kinst,
922 // Data
928 data1,
937 data2
938};
@ kuser2
See kuser0, pre-data words 148–149.
@ kt2
See kt0, pre-data words 126–127.
@ user5
See user0, pre-data word 045.
@ t3
See t0, pre-data word 013; post-data words 16-17.
@ t2
See t0, pre-data word 012; post-data words 14-15.
@ t4
See t0, pre-data word 014; post-data words 18-19.
@ user1
See user0, pre-data word 041.
@ resp7
See resp0, pre-data word 028.
@ t7
See t0, pre-data word 017; post-data words 24-25.
@ user7
See user0, pre-data word 047.
@ user4
See user0, pre-data word 044.
@ resp4
See resp0, pre-data word 025.
@ t8
See t0, pre-data word 018; post-data words 26-27.
@ resp3
See resp0, pre-data word 024.
@ resp9
See resp0, pre-data word 030.
@ user8
See user0, pre-data word 048.
@ user2
See user0, pre-data word 042.
@ t9
See t0, pre-data word 019; post-data words 28-29.
@ kt7
See kt0, pre-data words 136–137.
@ t1
See t0, pre-data word 011; post-data words 12-13.
@ user9
See user0, pre-data word 049.
@ resp5
See resp0, pre-data word 026.
@ user3
See user0, pre-data word 043.
@ kt1
See kt0, pre-data words 124–125.
@ resp1
See resp0, pre-data word 022.
@ t6
See t0, pre-data word 016; post-data words 22-23.
@ user6
See user0, pre-data word 046.
@ resp2
See resp0, pre-data word 023.
@ kt5
See kt0, pre-data words 132–133.
@ resp8
See resp0, pre-data word 029.
@ kt6
See kt0, pre-data words 134–135.
@ kuser1
See kuser0, pre-data words 146–147.
@ t5
See t0, pre-data word 015; post-data words 20-21.
@ kt8
See kt0, pre-data words 138–139.
@ kt4
See kt0, pre-data words 130–131.
@ kt9
See kt0, pre-data words 140–141.
@ resp6
See resp0, pre-data word 027.
@ kt3
See kt0, pre-data words 128–129.
double gcarc(point location1, point location2) noexcept
Calculate great circle arc distance in decimal degrees between two points.
Definition sac_format.cpp:735

Function Documentation

◆ azimuth()

double sacfmt::azimuth(const point location1,
const point location2 
)
noexcept

Calculate azimuth between two points.

Assumes spherical Earth (in future may update to solve on a more general body).

$\color{orange}\phi$ is latitude. $\color{orange}\lambda$ is longitude. $\color{orange}\theta$ is azimuth.

\[\color{orange}
\theta=tan^{-1}\left(
\frac{sin(\delta\lambda)cos(\phi_{2})}{cos(\phi_{1})sin(\phi_{2})
- sin(\phi_{1})cos(\phi_{2})cos(\delta\lambda)}
\right)
\]

Parameters
[in]location1point of first location.
[in]location2point of second location.
Returns
double The azimuth from the first location to the second location.
766 {
767 const double numerator{
768 std::sin(location2.longitude.radians() - location1.longitude.radians()) *
769 std::cos(location2.latitude.radians())};
770 const double denominator{(std::cos(location1.latitude.radians()) *
771 std::sin(location2.latitude.radians())) -
772 (std::sin(location1.latitude.radians()) *
773 std::cos(location2.latitude.radians()) *
774 std::cos(location2.longitude.radians() -
775 location1.longitude.radians()))};
776 double result{radians_to_degrees(std::atan2(numerator, denominator))};
777 while (result < 0.0) {
778 result += circle_deg;
779 }
780 return result;
781}
double radians() const noexcept
Get coordinate value in radians.
Definition sac_format.hpp:271
constexpr double circle_deg
Degrees in a circle.
Definition sac_format.hpp:116
double radians_to_degrees(double radians) noexcept
Convert radians to decimal degrees.
Definition sac_format.cpp:673
coord longitude
Longitude of point.
Definition sac_format.hpp:287
coord latitude
Latitude of point.
Definition sac_format.hpp:286
Struct containing a pair of words.
Definition sac_format.hpp:191
Here is the call graph for this function:
Here is the caller graph for this function:

◆ binary_to_bool()

bool sacfmt::binary_to_bool(const word_oneflag)
noexcept

Convert a 32-bit (one word) binary bitset to a boolean.

Parameters
[in]flagword_one binary bitset to be converted (takes zeroth element).
Returns
boolean Converted boolean value.
357{ return flag[0]; }
Here is the caller graph for this function:

◆ binary_to_double()

double sacfmt::binary_to_double(const word_twobin)
noexcept

Convert 64-bit (two words) binary bitset to double-precision value.

Converts bitset to unsigned long long then to double.

Parameters
[in]binword_two Binary value to be converted.
Returns
double Converted value.
159 {
160 const auto val = bin.to_ullong();
161 double result{};
162 // flawfinder: ignore
163 memcpy(&result, &val, sizeof(double));
164 return result;
165}
Here is the caller graph for this function:

◆ binary_to_float()

float sacfmt::binary_to_float(const word_onebin)
noexcept

Convert 32-bit (one word) binary bitset to a floating-point value.

Converts bitset to unsigned long then to float.

Parameters
[in]binword_one Binary value to be converted.
Returns
float Converted value.
127 {
128 const auto val = bin.to_ulong();
129 float result{};
130 // flawfinder: ignore
131 memcpy(&result, &val, sizeof(float));
132 return result;
133}
Here is the caller graph for this function:

◆ binary_to_int()

int sacfmt::binary_to_int(word_one bin)
noexcept

Convert 32-bit (one word) binary bitset to integer.

Uses two's complement to convert a binary value into an integer.

Parameters
[in]binBinary value to be converted.
Returns
int Converted value.
88 {
89 int result{};
90 if (bin.test(binary_word_size - 1)) {
91 // Complement
92 bin.flip();
93 result = static_cast<int>(bin.to_ulong());
94 result += 1;
95 // Change sign to make it negative
96 result *= -1;
97 } else {
98 result = static_cast<int>(bin.to_ulong());
99 }
100 return result;
101}
Here is the caller graph for this function:

◆ binary_to_long_string()

std::string sacfmt::binary_to_long_string(const word_fourstr)
noexcept

Convert a 128-bit (four word) binary bitset to a string.

Exclusively used to work with the kEvNm header.

Parameters
[in]strword_four to be converted to a string.
Returns
std::string Converted string.
332 {
333 std::string result{bits_string(str, 4)};
334 return string_cleaning(result);
335}
std::string bits_string(const T &bits, size_t num_words) noexcept
Template function to convert binary bitset to string.
Definition sac_format.cpp:258
Here is the call graph for this function:
Here is the caller graph for this function:

◆ binary_to_string()

std::string sacfmt::binary_to_string(const word_twostr)
noexcept

Convert a 64-bit (two word) binary bitset to a string.

Parameters
[in]strword_two to be converted to a string.
Returns
std::string Converted string.
298 {
299 std::string result{bits_string(str, 2)};
300 return string_cleaning(result);
301}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ bits_string()

template<typename T >
std::string sacfmt::bits_string(const Tbits,
const size_t num_words 
)
noexcept

Template function to convert binary bitset to string.

Parameters
[in]bitsSource bitset for the string.
[in]num_wordsLength of string in words (4 chars = 1 word)
Returns
std::string String converted from bitset.
258 {
259 std::string result{};
260 result.reserve(num_words * word_length);
261 constexpr size_t char_size{bits_per_byte};
262 char_bit byte{};
263 for (size_t i{0}; i < num_words * binary_word_size; i += char_size) {
264 for (size_t j{0}; j < char_size; ++j) [[likely]] {
265 byte[j] = bits[i + j];
266 }
267 result.push_back(static_cast<char>(byte.to_ulong()));
268 }
269 return result;
270}
std::bitset< bits_per_byte > char_bit
One binary character (useful for building strings).
Definition sac_format.hpp:82
constexpr size_t binary_word_size
Size (bits) of funamental data-chunk.
Definition sac_format.hpp:66
Here is the caller graph for this function:

◆ bool_to_binary()

word_one sacfmt::bool_to_binary(const bool flag)
noexcept

Convert a boolean to a 32-bit (one word) binary bitset.

Parameters
[in]flagBoolean value to be converted to a bitset (sets zeroth element).
Returns
word_one Converted binary bitset.
344 {
346 result[0] = flag;
347 return result;
348}
std::bitset< binary_word_size > word_one
One binary word (useful for non-strings).
Definition sac_format.hpp:84

◆ bool_to_word()

std::vector< char > sacfmt::bool_to_word(const bool flag)
noexcept

Convert boolean to a word for writing.

Parameters
[in]flagBoolean to be converted.
Returns
std::vector<char> Prepared value for writing.
598 {
599 std::vector<char> result;
600 result.resize(word_length);
601 std::fill(result.begin() + 1, result.end(), 0);
602 result[0] = static_cast<char>(flag ? 1 : 0);
603 return result;
604}
Here is the caller graph for this function:

◆ concat_words() [1/2]

word_two sacfmt::concat_words(const word_pair< word_one > & pair_words)
noexcept

Concatenate two word_one binary strings into a single word_two string.

Useful for reading strings from SAC-files.

Parameters
[in]pair_wordsword_pair Words to be concatenated.
Returns
word_two Concatenated words.
368 {
370 for (size_t i{0}; i < binary_word_size; ++i) [[likely]] {
371 result[i] = pair_words.first[i];
372 result[i + binary_word_size] = pair_words.second[i];
373 }
374 return result;
375}
std::bitset< static_cast< size_t >(2) *binary_word_size > word_two
Two binary words (useful for strings).
Definition sac_format.hpp:86
T first
First 'word' in the pair.
Definition sac_format.hpp:192
T second
Second 'word' in the pair.
Definition sac_format.hpp:193
Here is the caller graph for this function:

◆ concat_words() [2/2]

word_four sacfmt::concat_words(const word_pair< word_two > & pair_words)
noexcept

Concatenate two word_two binary strings into a single word_four string.

Exclusively used to read kEvNm header from SAC-file.

Parameters
[in]pair_wordsword_pair Words to be concatenated.
Returns
word_four Concatenated words.
386 {
388 constexpr size_t two_words{2 * binary_word_size};
389 for (size_t i{0}; i < two_words; ++i) [[likely]] {
390 result[i] = pair_words.first[i];
391 result[i + two_words] = pair_words.second[i];
392 }
393 return result;
394}
std::bitset< static_cast< size_t >(4) *binary_word_size > word_four
Four binary words (kEvNm only).
Definition sac_format.hpp:88

◆ convert_to_word() [1/4]

std::vector< char > sacfmt::convert_to_word(const double input)
noexcept

Convert double value into a std::vector<char> for writing.

Parameters
[in]inputInput value to convert (double).
Returns
std::vector<char> Prepared for writing to binary SAC-file.
549 {
550 constexpr size_t n_words{static_cast<size_t>(2) * word_length};
551 std::array<char, n_words> tmp{};
552 // Copy bytes from input into the tmp array
553 // flawfinder: ignore
554 std::memcpy(tmp.data(), &input, n_words);
555 std::vector<char> word{};
556 word.reserve(n_words);
557 std::for_each(tmp.begin(), tmp.end(),
558 [&word](const char &character) { word.push_back(character); });
559 return word;
560}

◆ convert_to_word() [2/4]

template std::vector< char > sacfmt::convert_to_word(const float input)
noexcept

◆ convert_to_word() [3/4]

template std::vector< char > sacfmt::convert_to_word(const int x)
noexcept

◆ convert_to_word() [4/4]

template<typename T >
std::vector< char > sacfmt::convert_to_word(const T input)
noexcept

Template function to convert input value into a std::vector<char> for writing.

Parameters
[in]inputInput value (float or int) to convert.
Returns
std::vector<char> Prepared for writing to binary SAC-file.
527 {
528 std::array<char, word_length> tmp{};
529 // Copy bytes from input into the tmp array
530 // flawfinder: ignore
531 std::memcpy(tmp.data(), &input, word_length);
532 std::vector<char> word{};
533 word.reserve(word_length);
534 std::for_each(tmp.begin(), tmp.end(),
535 [&word](const char &character) { word.push_back(character); });
536 return word;
537}
Here is the caller graph for this function:

◆ convert_to_words() [1/2]

template<size_t N>
template std::array< char, 4 *word_length > sacfmt::convert_to_words(const std::string & str,
size_t n_words 
)
noexcept

Template function to convert input string value into a std::array<char> for writing.

Parameters
[in]strInput string to convert.
[in]n_wordsNumber of words
Returns
std::array<char, N> Prepared for writing to a binary SAC-file.
573 {
574 std::vector<char> tmp{};
575 tmp.reserve(n_words);
576 std::for_each(str.begin(), str.end(),
577 [&tmp](const char &character) { tmp.push_back(character); });
578 std::array<char, N> all_words{};
579 // Move vector to array
580 std::move(tmp.begin(), tmp.end(), all_words.begin());
581 return all_words;
582}

◆ convert_to_words() [2/2]

template std::array< char, word_length > sacfmt::convert_to_words(const std::string & str,
const size_t n_words 
)
noexcept

◆ degrees_to_radians()

double sacfmt::degrees_to_radians(const double degrees)
noexcept

Convert decimal degrees to radians.

\[\color{orange}
r=d\cdot\frac{\pi}{180^{\circ}}
\]

Parameters
[in]degreesAngle in decimal degrees to be converted.
Returns
double Angle in radians.
659 {
660 return rad_per_deg * degrees;
661}
constexpr double rad_per_deg
Radians per degree.
Definition sac_format.hpp:112
Here is the caller graph for this function:

◆ double_to_binary()

word_two sacfmt::double_to_binary(const double num)
noexcept

Convert double-precision value to 64-bit (two words) binary bitset.

Converts double to unsigned-integer of same size for storage in bitset.

Parameters
[in]numDouble value to be converted.
Returns
word_two Converted value.
143 {
145 // flawfinder: ignore
146 std::memcpy(&num_as_uint, &num, sizeof(double));
147 word_two result{num_as_uint};
148 return result;
149}

◆ equal_within_tolerance() [1/2]

bool sacfmt::equal_within_tolerance(const double val1,
const double val2,
const double tolerance 
)
noexcept

Check if two double values are equal within a tolerance limit.

Default tolerance is f_eps.

Parameters
[in]val1First double in comparison.
[in]val2Second double in comparison.
[in]toleranceNumerical equality tolerance (default f_eps).
Returns
bool Boolean equality value.
645 {
646 return std::abs(val1 - val2) < tolerance;
647}

◆ equal_within_tolerance() [2/2]

bool sacfmt::equal_within_tolerance(const std::vector< double > & vector1,
const std::vector< double > & vector2,
const double tolerance 
)
noexcept

Check if two std::vector<double> are equal within a tolerance limit.

Default tolerance is f_eps.

Parameters
[in]vector1First data vector in comparison.
[in]vector2Second data vector in comparison.
[in]toleranceNumerical equality tolerance (default f_eps).
Returns
bool Boolean equality value.
622 {
623 if (vector1.size() != vector2.size()) {
624 return false;
625 }
626 for (size_t i{0}; i < vector1.size(); ++i) [[likely]] {
627 if (!equal_within_tolerance(vector1[i], vector2[i], tolerance)) {
628 return false;
629 }
630 }
631 return true;
632}
bool equal_within_tolerance(const std::vector< double > &vector1, const std::vector< double > &vector2, double tolerance=f_eps) noexcept
Check if two std::vector<double> are equal within a tolerance limit.
Definition sac_format.cpp:620
Here is the call graph for this function:
Here is the caller graph for this function:

◆ float_to_binary()

word_one sacfmt::float_to_binary(const float num)
noexcept

Convert floating-point value to 32-bit (one word) binary bitset.

Converts float to unsigned-integer of same size for storage in bitset.

Parameters
[in]numFloat value to be converted.
Returns
word_one Converted value.
111 {
113 // flawfinder: ignore
114 std::memcpy(&num_as_uint, &num, sizeof(float));
115 word_one result{num_as_uint};
116 return result;
117}

◆ gcarc()

double sacfmt::gcarc(const point location1,
const point location2 
)
noexcept

Calculate great circle arc distance in decimal degrees between two points.

Assumes spherical Earth (in future will include flatenning and adjustable radius for other bodies/greater accuracy).

$\color{orange}\phi$ is latitude. $\color{orange}\lambda$ is longitude. $\color{orange}\Delta$ is great circle arc distance (gcarc).

\[\color{orange}
\Delta = cos^{-1}\left(
sin(\phi_{1})sin(\phi_{2}) + cos(\phi_{1})cos(\phi_{2})
cos(\lambda_{2}-\lambda_{1})
\right)
\]

Parameters
[in]location1point of first location.
[in]location2point of second location
Returns
double The great circle arc distance in decimal degrees.
735 {
736 return radians_to_degrees(
737 std::acos(std::sin(location1.latitude.radians()) *
738 std::sin(location2.latitude.radians()) +
739 std::cos(location1.latitude.radians()) *
740 std::cos(location2.latitude.radians()) *
741 std::cos(location2.longitude.radians() -
742 location1.longitude.radians())));
743}
Here is the call graph for this function:

◆ int_to_binary()

word_one sacfmt::int_to_binary(int num)
noexcept

Convert integer to 32-bit (one word) binary bitset.

Uses two's complement to convert an integer into a binary value.

Parameters
[in]numNumber to be converted.
Returns
word_one Converted value.
67 {
69 if (num >= 0) {
70 bits = uint_to_binary(static_cast<uint>(num));
71 } else {
72 bits = uint_to_binary(static_cast<uint>(-num));
73 // Complement
74 bits.flip();
75 bits = bits.to_ulong() + 1;
76 }
77 return bits;
78}
word_one uint_to_binary(uint num) noexcept
Convert unsigned integer to 32-bit (one word) binary bitset.
Definition sac_format.cpp:44
Here is the call graph for this function:

◆ limit_180()

double sacfmt::limit_180(const double degrees)
noexcept

Takes a decimal degree value and constrains it to a half circle using symmetry.

\[\color{orange}
\left[-\infty,\infty\right]\rightarrow (-180,180]
\]

Parameters
[in]degreesDecimal degrees to be constrained.
Returns
double Value within limits.
820 {
821 double result{limit_360(degrees)};
822 constexpr double hemi{180.0};
823 if (result > hemi) {
824 result = result - circle_deg;
825 }
826 return result;
827}
double limit_360(double degrees) noexcept
Takes a decimal degree value and constrains it to full circle using symmetry.
Definition sac_format.cpp:794
Here is the call graph for this function:
Here is the caller graph for this function:

◆ limit_360()

double sacfmt::limit_360(const double degrees)
noexcept

Takes a decimal degree value and constrains it to full circle using symmetry.

\[\color{orange}
\left[-\infty,\infty\right]\rightarrow\left[0, 360\right]
\]

Parameters
[in]degreesDecimal degrees to be constrained.
Returns
double Value within limits.
794 {
795 double result{degrees};
796 while (std::abs(result) > circle_deg) {
797 if (result > circle_deg) {
798 result -= circle_deg;
799 } else {
800 result += circle_deg;
801 }
802 }
803 if (result < 0) {
804 result += circle_deg;
805 }
806 return result;
807}
Here is the caller graph for this function:

◆ limit_90()

double sacfmt::limit_90(const double degrees)
noexcept

Takes a decimal degree value and constrains it to a quarter circle using symmetry.

\[\color{orange}
\left[-\infty,\infty\right]\rightarrow\left[-90,90\right]
\]

Parameters
[in]degreesDecimal degrees to be constrained.
Returns
double Value within limits.
840 {
841 double result{limit_180(degrees)};
842 constexpr double quarter{90.0};
843 if (result > quarter) {
844 result = (2 * quarter) - result;
845 } else if (result < -quarter) {
846 result = (-2 * quarter) - result;
847 }
848 return result;
849}
double limit_180(double degrees) noexcept
Takes a decimal degree value and constrains it to a half circle using symmetry.
Definition sac_format.cpp:820
Here is the call graph for this function:
Here is the caller graph for this function:

◆ long_string_to_binary()

word_four sacfmt::long_string_to_binary(std::string str)
noexcept

Convert a string to a 128-bit (four word) binary bitset.

If the string is longer than 16 characters, then only the first 16 characters are kept. If the string is less than 16 characters long, it is right-padded with spaces.

Exclusively used to work with the kEvNm header.

Parameters
[in]strString to be converted to a bitset.
Returns
word_four Converted binary bitset.
315 {
316 constexpr size_t string_size{4 * word_length};
317 prep_string(&str, string_size);
318 // Four words (16 characters)
319 word_four bits{};
320 string_bits(&bits, str, string_size);
321 return bits;
322}
constexpr size_t word_length
Size (bytes) of fundamental data-chunk.
Definition sac_format.hpp:62
void string_bits(T *bits, const std::string &str, size_t str_size) noexcept
Template function to convert string into binary bitset.
Definition sac_format.cpp:237
Here is the call graph for this function:

◆ nwords_after_current()

bool sacfmt::nwords_after_current(std::ifstream * sac,
const read_specspec 
)
noexcept

Determine if the SAC-file has enough remaining data to read the requested amount of data.

Parameters
[in]sacstd::ifstream* SAC-file to read.
[in]specread_spec reading specification.
Returns
bool Truth value (true = safe to read).
1669 {
1670 bool result{false};
1671 if (sac->good()) {
1672 sac->seekg(0, std::ios::end);
1673 const std::size_t final_pos{static_cast<size_t>(sac->tellg())};
1674 // Doesn't like size_t since it wants to allow
1675 // the possibility of negative offsets (not how I use it)
1676 sac->seekg(static_cast<std::streamoff>(spec.start_word));
1677 const std::size_t diff{final_pos - spec.start_word};
1678 result = (diff >= (spec.num_words * word_length));
1679 }
1680 return result;
1681}
size_t num_words
Number of words to read.
Definition sac_format.hpp:211
size_t start_word
Word to start reading from.
Definition sac_format.hpp:213
Here is the caller graph for this function:

◆ prep_string()

void sacfmt::prep_string(std::string * str,
const size_t str_size 
)
noexcept

Cleans string and then truncates/pads as necessary.

This edits the string in-place.

Parameters
[in,out]strstd::string* String to be prepared.
[in]str_sizeDesired string length.
218 {
220 if (str->length() > str_size) {
221 str->resize(str_size);
222 } else if (str->length() < str_size) {
223 *str = str->append(str_size - str->length(), ' ');
224 }
225}
std::string string_cleaning(const std::string &str) noexcept
Remove leading/trailing spaces and control characters from a string.
Definition sac_format.cpp:199
Here is the call graph for this function:
Here is the caller graph for this function:

◆ radians_to_degrees()

double sacfmt::radians_to_degrees(const double radians)
noexcept

Convert radians to decimal degrees.

\[\color{orange}
d=r\cdot\frac{180^{\circ}}{\pi}
\]

Parameters
[in]radiansAngle in radians to be converted.
Returns
double Angle in decimal degrees.
673 {
674 return deg_per_rad * radians;
675}
constexpr double deg_per_rad
Degrees per radian.
Definition sac_format.hpp:114
Here is the caller graph for this function:

◆ read_data()

std::vector< double > sacfmt::read_data(std::ifstream * sac,
const read_specspec 
)

Reader arbitrary number of words (useful for vectors) from a binary SAC-file.

Note that this modifies the position of the reader within the stream (to the end of the read words).

Parameters
[in,out]sacstd::ifstream* Input binary SAC-file.
[in]specread_spec Reading specification.
Returns
std::vector<double> Data vector read in.
487 {
488 sac->seekg(word_position(spec.start_word));
489 std::vector<double> result{};
490 result.resize(spec.num_words);
491 std::for_each(result.begin(), result.end(), [&sac](double &value) {
492 value = static_cast<double>(binary_to_float(read_word(sac)));
493 });
494 return result;
495}
std::streamoff word_position(size_t word_number) noexcept
Calculates position of word in SAC-file.
Definition sac_format.cpp:31
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_four_words()

word_four sacfmt::read_four_words(std::ifstream * sac)

Read four words (128 bits, kEvNm only) from a binary SAC-file.

Note that this modifies the position of the reader within the stream (to the end of the read words).

Parameters
[in,out]sacstd::ifstream* Input binary SAC-file.
Returns
word_four Binary bitset representation of four words.
462 {
464 const word_two second_words{read_two_words(sac)};
465 word_pair<word_two> pair_words{};
466 if constexpr (std::endian::native == std::endian::little) {
467 pair_words.first = first_words;
468 pair_words.second = second_words;
469 } else {
470 pair_words.first = second_words;
471 pair_words.second = first_words;
472 }
473 return concat_words(pair_words);
474}
word_two read_two_words(std::ifstream *sac)
Read two words (64 bits, useful for most strings) from a binary SAC-file.
Definition sac_format.cpp:439
word_two concat_words(const word_pair< word_one > &pair_words) noexcept
Concatenate two word_one binary strings into a single word_two string.
Definition sac_format.cpp:368
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_two_words()

word_two sacfmt::read_two_words(std::ifstream * sac)

Read two words (64 bits, useful for most strings) from a binary SAC-file.

Note that this modifies the position of the reader within the stream (to the end of the read words).

Parameters
[in,out]sacstd::ifstream* Input binary SAC-file.
Returns
word_two Binary bitset representation of two words.
439 {
441 const word_one second_word{read_word(sac)};
442 word_pair<word_one> pair_words{};
443 if constexpr (std::endian::native == std::endian::little) {
444 pair_words.first = first_word;
445 pair_words.second = second_word;
446 } else {
447 pair_words.first = second_word;
448 pair_words.second = first_word;
449 }
450 return concat_words(pair_words);
451}
word_one read_word(std::ifstream *sac)
Read one word (32 bits, useful for non-strings) from a binary SAC-File.
Definition sac_format.cpp:407
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_word()

word_one sacfmt::read_word(std::ifstream * sac)

Read one word (32 bits, useful for non-strings) from a binary SAC-File.

Note that this modifies the position of the reader within the stream (to the end of the read word).

Parameters
[in,out]sacstd::ifstream* Input binary SAC-file.
Returns
word_one Binary bitset representation of single word.
407 {
408 word_one bits{};
409 constexpr size_t char_size{bits_per_byte};
410 // Where we will store the characters
411 std::array<char, word_length> word{};
412 // Read to our character array
413 // This can always hold the source due to careful typing/sizing
414 // flawfinder: ignore
415 if (sac->read(word.data(), word_length)) {
416 // Take each character
417 for (size_t i{0}; i < word_length; ++i) [[likely]] {
418 uint character{static_cast<uint>(word[i])};
419 char_bit byte{character};
420 // bit-by-bit
421 for (size_t j{0}; j < char_size; ++j) [[likely]] {
422 bits[(i * char_size) + j] = byte[j];
423 }
424 }
425 }
426 return bits;
427}
Here is the caller graph for this function:

◆ remove_leading_spaces()

void sacfmt::remove_leading_spaces(std::string * str)
noexcept

Remove all leading spaces from a string.

This edits the string in-place.

Parameters
[in,out]strstd::string* String to have spaces removed.
174 {
175 while ((static_cast<int>(str->front()) <= ascii_space) && (!str->empty())) {
176 str->erase(0, 1);
177 }
178}
Here is the caller graph for this function:

◆ remove_trailing_spaces()

void sacfmt::remove_trailing_spaces(std::string * str)
noexcept

Remove all trailing spaces from a string.

This edits the string in-place.

Parameters
[in,out]strstd::string* String to have spaces removed.
187 {
188 while ((static_cast<int>(str->back()) <= ascii_space) && (!str->empty())) {
189 str->pop_back();
190 }
191}
Here is the caller graph for this function:

◆ safe_to_finish_reading()

void sacfmt::safe_to_finish_reading(std::ifstream * sac)

Determines if the SAC-file is finished.

This must run after reading the header, data vector(s), and footer (if applicable). This checks to ensure there is no additional data in the SAC-file (there shouldn't be, and out of safety it throws an io_error to inform the user if there are shenanigans).

Parameters
[in]sacstd::ifstream* SAC-file to be checked.
Exceptions
io_errorIf the file is not finished.
1749 {
1750 const std::streamoff current_pos{sac->tellg()};
1751 sac->seekg(0, std::ios::end);
1752 const std::streamoff end_pos{sac->tellg()};
1753 sac->seekg(current_pos, std::ios::beg);
1754 // How far are we from the end of the file?
1755 const std::streamoff diff{end_pos - current_pos};
1756 // If there is more, something weird happened...
1757 if (diff != 0) {
1758 std::ostringstream oss{};
1759 oss << "Filesize exceeds data specification with ";
1760 oss << diff;
1761 oss << " bytes excess. Data corruption suspected.";
1762 throw io_error(oss.str());
1763 }
1764}
Here is the caller graph for this function:

◆ safe_to_read_data()

void sacfmt::safe_to_read_data(std::ifstream * sac,
const size_t n_words,
const bool data2 
)

Determines if the SAC-file has enough space remaining to contain a complete data vector.

This must be run after reading the header (and first data vector if applicable) and before the footer (if applicable).

Parameters
[in]sacstd::ifstream* SAC-file to read.
[in]n_wordsNumber of values in data vector.
[in]data2bool True if reading data2, false (default) if reading data1.
Exceptions
io_errorIf unsafe to read.
1730 {
1731 const std::string data{data2 ? "data2" : "data1"};
1732 const read_spec spec{n_words, static_cast<size_t>(sac->tellg())};
1733 if (!nwords_after_current(sac, spec)) {
1734 throw io_error("Insufficient filesize for " + data + '.');
1735 }
1736}
bool nwords_after_current(std::ifstream *sac, const read_spec &spec) noexcept
Determine if the SAC-file has enough remaining data to read the requested amount of data.
Definition sac_format.cpp:1669
Here is the call graph for this function:
Here is the caller graph for this function:

◆ safe_to_read_footer()

void sacfmt::safe_to_read_footer(std::ifstream * sac)

Determines if the SAC-file has enough space remaining to contain a complete footer.

This must be run after reading the header and data vector(s), not before.

Parameters
[in]sacstd::ifstream* SAC-file to read.
Exceptions
io_errorIf unsafe to read.
1708 {
1709 // doubles are two words long
1710 const read_spec spec{static_cast<size_t>(num_footer) * 2,
1711 static_cast<size_t>(sac->tellg())};
1712 if (!nwords_after_current(sac, spec)) {
1713 throw io_error("Insufficient filesize for footer.");
1714 }
1715}
constexpr int num_footer
Number of double-precision footer values in SAC format (version 7).
Definition sac_format.hpp:104
Struct that specifies parameters for reading.
Definition sac_format.hpp:209
Here is the call graph for this function:
Here is the caller graph for this function:

◆ safe_to_read_header()

void sacfmt::safe_to_read_header(std::ifstream * sac)

Determine if the SAC-file is large enough to contain a complete header.

This must be run prior to reading the data vector(s) and footer (if applicable), not after.

Parameters
[in]sacstd::ifstream* SAC-file to read.
Exceptions
io_errorIf unsafe to read.
1692 {
1693 const read_spec spec{data_word, 0};
1694 if (!nwords_after_current(sac, spec)) {
1695 throw io_error("Insufficient filesize for header.");
1696 }
1697}
constexpr std::streamoff data_word
First word of (first) data-section (stream offset).
Definition sac_format.hpp:68
Here is the call graph for this function:
Here is the caller graph for this function:

◆ string_bits()

template<typename T >
void sacfmt::string_bits(Tbits,
const std::string & str,
const size_t str_size 
)
noexcept

Template function to convert string into binary bitset.

Note that this edits the bitset in place.

Parameters
[out]bitsDestintation bitset for the string (result).
[in]strString to undergo conversion.
[in]str_sizeDesired string size in words (4 chars = 1 word).
238 {
239 constexpr size_t char_size{bits_per_byte};
240 char_bit byte{};
241 for (size_t i{0}; i < str_size; ++i) {
242 size_t character{static_cast<size_t>(str[i])};
243 byte = char_bit(character);
244 for (size_t j{0}; j < char_size; ++j) {
245 (*bits)[(i * char_size) + j] = byte[j];
246 }
247 }
248}
constexpr size_t bits_per_byte
Size (bits) of binary character.
Definition sac_format.hpp:64
Here is the caller graph for this function:

◆ string_cleaning()

std::string sacfmt::string_cleaning(const std::string & str)
noexcept

Remove leading/trailing spaces and control characters from a string.

Parameters
[in]strstd::string String to be cleaned.
Returns
std::string Cleaned string.
199 {
200 std::string result{str};
201 size_t null_position{str.find('\0')};
202 if (null_position != std::string::npos) {
203 result.erase(null_position);
204 }
205 remove_leading_spaces(&result);
207 return result;
208}
void remove_leading_spaces(std::string *str) noexcept
Remove all leading spaces from a string.
Definition sac_format.cpp:174
void remove_trailing_spaces(std::string *str) noexcept
Remove all trailing spaces from a string.
Definition sac_format.cpp:187
Here is the call graph for this function:
Here is the caller graph for this function:

◆ string_to_binary()

word_two sacfmt::string_to_binary(std::string str)
noexcept

Convert string to a 64-bit (two word) binary bitset.

If the string is longer than 8 characters, then only the first 8 characters are kept. If the string is less than 8 characters long, it is right-padded with spaces.

Parameters
[in]strString to be converted to a bitset.
Returns
word_two Converted binary bitset.
282 {
283 constexpr size_t string_size{2 * word_length};
284 // 1 byte per character
285 prep_string(&str, string_size);
286 // Two words (8 characters)
287 word_two bits{};
288 string_bits(&bits, str, string_size);
289 return bits;
290}
Here is the call graph for this function:

◆ uint_to_binary()

word_one sacfmt::uint_to_binary(uint num)
noexcept

Convert unsigned integer to 32-bit (one word) binary bitset.

This sets the current bit using bitwise and, updates the bit to manipulate and performs a right-shift (division by 2) until the number is zero.

Parameters
[in]numNumber to be converted.
Returns
word_one Converted value.
44 {
46 for (size_t pos{0}; pos < bits.size(); ++pos) {
47 if (num > 0) {
48 // Bitwise and to set flag.
49 bits.set(pos, static_cast<bool>(num & 1));
50 // Right-shift bits by 1, same as division by 2
51 num >>= 1;
52 } else {
53 break;
54 }
55 }
56 return bits;
57}
Here is the caller graph for this function:

◆ word_position()

std::streamoff sacfmt::word_position(const size_t word_number)
noexcept

Calculates position of word in SAC-file.

Multiplies given word number by the word-length in bytes (defined by the SAC format.)

Parameters
[in]word_numberNumber of desired word in file stream.
Returns
std::streamoff Position in SAC-file of desired word (in bytes).
31 {
32 return static_cast<std::streamoff>(word_number * word_length);
33}
Here is the caller graph for this function:

◆ write_words()

void sacfmt::write_words(std::ofstream * sac_file,
const std::vector< char > & input 
)

Write arbitrary number of words (useful for vectors) to a binary SAC-file.

Note that this modifies the position of the writer within the stream (to the end of the written words).

Parameters
[in,out]sac_filestd::ofstream* Output binary SAC-file.
[in]inputstd::vector<char> Character vector representation of data for writing.
510 {
511 std::ofstream &sac = *sac_file;
512 if (sac.is_open()) {
513 std::for_each(input.begin(), input.end(), [&sac](const char &character) {
514 sac.write(&character, sizeof(char));
515 });
516 }
517}
Here is the caller graph for this function:

Variable Documentation

◆ ascii_space

constexpr int sacfmt::ascii_space {32}
constexpr

ASCII-code of 'space' character.

90{32};

◆ binary_word_size

constexpr size_t sacfmt::binary_word_size {word_length * bits_per_byte}
constexpr

Size (bits) of funamental data-chunk.

◆ bits_per_byte

constexpr size_t sacfmt::bits_per_byte {8}
constexpr

Size (bits) of binary character.

64{8};

◆ circle_deg

constexpr double sacfmt::circle_deg {360.0}
constexpr

Degrees in a circle.

116{360.0};

◆ common_skip_num

constexpr int sacfmt::common_skip_num {7}
constexpr

Extremely common number of 'internal use' headers in SAC format.

110{7};

◆ data_word

constexpr std::streamoff sacfmt::data_word {158}
constexpr

First word of (first) data-section (stream offset).

68{158};

◆ deg_per_rad

constexpr double sacfmt::deg_per_rad {1.0 / rad_per_deg}
constexpr

Degrees per radian.

114{1.0 / rad_per_deg};

◆ earth_radius

constexpr double sacfmt::earth_radius {6378.14}
constexpr

Average radius of Earth (kilometers).

118{6378.14};

◆ f_eps

constexpr float sacfmt::f_eps {2.75e-6F}
constexpr

Accuracy precision expected of SAC floating-point values.

80{2.75e-6F};

◆ modern_hdr_version

constexpr int sacfmt::modern_hdr_version {7}
constexpr

nVHdr value for newest SAC format (2020+).

106{7};

◆ num_bool

constexpr int sacfmt::num_bool {4}
constexpr

Number of boolean header values in SAC format.

98{4};

◆ num_data

constexpr int sacfmt::num_data {2}
constexpr

Number of data arrays in SAC format.

102{2};

◆ num_double

constexpr int sacfmt::num_double {22}
constexpr

Number of double-precision header values in SAC format.

94{22};

◆ num_float

constexpr int sacfmt::num_float {39}
constexpr

Number of float-poing header values in SAC format.

92{39};

◆ num_footer

constexpr int sacfmt::num_footer {22}
constexpr

Number of double-precision footer values in SAC format (version 7).

104{22};

◆ num_int

constexpr int sacfmt::num_int {26}
constexpr

Number of integer header values in SAC format.

96{26};

◆ num_string

constexpr int sacfmt::num_string {23}
constexpr

Number of string header values in SAC format.

100{23};

◆ old_hdr_version

constexpr int sacfmt::old_hdr_version {6}
constexpr

nVHdr value for historic SAC format (pre-2020).

108{6};

◆ rad_per_deg

constexpr double sacfmt::rad_per_deg {std::numbers::pi_v<double> / 180.0}
constexpr

Radians per degree.

112{std::numbers::pi_v<double> / 180.0};

◆ sac_map

const std::unordered_map<name, const size_t> sacfmt::sac_map

Lookup table for variable locations.

Maps SAC variables (headers and data) to their internal locations in the Trace class.

946 {
947 // Floats
948 {name::depmin, 0},
949 {name::depmax, 1},
950 {name::odelta, 2},
951 {name::resp0, 3},
952 {name::resp1, 4},
953 {name::resp2, 5},
954 {name::resp3, 6},
955 {name::resp4, 7},
956 {name::resp5, 8},
957 {name::resp6, 9},
958 {name::resp7, 10},
959 {name::resp8, 11},
960 {name::resp9, 12},
961 {name::stel, 13},
962 {name::stdp, 14},
963 {name::evel, 15},
964 {name::evdp, 16},
965 {name::mag, 17},
966 {name::user0, 18},
967 {name::user1, 19},
968 {name::user2, 20},
969 {name::user3, 21},
970 {name::user4, 22},
971 {name::user5, 23},
972 {name::user6, 24},
973 {name::user7, 25},
974 {name::user8, 26},
975 {name::user9, 27},
976 {name::dist, 28},
977 {name::az, 29},
978 {name::baz, 30},
979 {name::gcarc, 31},
980 {name::depmen, 32},
981 {name::cmpaz, 33},
982 {name::cmpinc, 34},
983 {name::xminimum, 35},
984 {name::xmaximum, 36},
985 {name::yminimum, 37},
986 {name::ymaximum, 38},
987 // Doubles
988 {name::delta, 0},
989 {name::b, 1},
990 {name::e, 2},
991 {name::o, 3},
992 {name::a, 4},
993 {name::t0, 5},
994 {name::t1, 6},
995 {name::t2, 7},
996 {name::t3, 8},
997 {name::t4, 9},
998 {name::t5, 10},
999 {name::t6, 11},
1000 {name::t7, 12},
1001 {name::t8, 13},
1002 {name::t9, 14},
1003 {name::f, 15},
1004 {name::stla, 16},
1005 {name::stlo, 17},
1006 {name::evla, 18},
1007 {name::evlo, 19},
1008 {name::sb, 20},
1009 {name::sdelta, 21},
1010 // Ints
1011 {name::nzyear, 0},
1012 {name::nzjday, 1},
1013 {name::nzhour, 2},
1014 {name::nzmin, 3},
1015 {name::nzsec, 4},
1016 {name::nzmsec, 5},
1017 {name::nvhdr, 6},
1018 {name::norid, 7},
1019 {name::nevid, 8},
1020 {name::npts, 9},
1021 {name::nsnpts, 10},
1022 {name::nwfid, 11},
1023 {name::nxsize, 12},
1024 {name::nysize, 13},
1025 {name::iftype, 14},
1026 {name::idep, 15},
1027 {name::iztype, 16},
1028 {name::iinst, 17},
1029 {name::istreg, 18},
1030 {name::ievreg, 19},
1031 {name::ievtyp, 20},
1032 {name::iqual, 21},
1033 {name::isynth, 22},
1034 {name::imagtyp, 23},
1035 {name::imagsrc, 24},
1036 {name::ibody, 25},
1037 // Bools
1038 {name::leven, 0},
1039 {name::lpspol, 1},
1040 {name::lovrok, 2},
1041 {name::lcalda, 3},
1042 // Strings
1043 {name::kstnm, 0},
1044 {name::kevnm, 1},
1045 {name::khole, 2},
1046 {name::ko, 3},
1047 {name::ka, 4},
1048 {name::kt0, 5},
1049 {name::kt1, 6},
1050 {name::kt2, 7},
1051 {name::kt3, 8},
1052 {name::kt4, 9},
1053 {name::kt5, 10},
1054 {name::kt6, 11},
1055 {name::kt7, 12},
1056 {name::kt8, 13},
1057 {name::kt9, 14},
1058 {name::kf, 15},
1059 {name::kuser0, 16},
1060 {name::kuser1, 17},
1061 {name::kuser2, 18},
1062 {name::kcmpnm, 19},
1063 {name::knetwk, 20},
1064 {name::kdatrd, 21},
1065 {name::kinst, 22},
1066 // Data
1067 {name::data1, 0},
1068 {name::data2, 1}};

◆ unset_bool

constexpr bool sacfmt::unset_bool {false}
constexpr

Boolean unset value (SAC Magic).

76{false};

◆ unset_double

constexpr double sacfmt::unset_double {-12345.0}
constexpr

Double-precision unset value (SAC Magic).

74{-12345.0};

◆ unset_float

constexpr float sacfmt::unset_float {-12345.0F}
constexpr

Float-point unset value (SAC Magic).

72{-12345.0F};

◆ unset_int

constexpr int sacfmt::unset_int {-12345}
constexpr

Integer unset value (SAC Magic).

70{-12345};

◆ unset_word

const std::string sacfmt::unset_word {"-12345"}

String unset value (SAC Magic).

78{"-12345"};

◆ word_length

constexpr size_t sacfmt::word_length {4}
constexpr

Size (bytes) of fundamental data-chunk.

62{4};