MS_READMSR(3)

πŸ“¦
version 2.19.8 Β· 2 versions
  • 2.19.8 Β· debian bookworm, debian trixie, ubuntu jammy, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking (latest)
  • 2.19.5 Β· fedora 43, fedora 44
, in debian bookworm, debian trixie, ubuntu jammy, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸ’– MS_READMSR β€” bestie, let's read some Mini-SEED πŸ’–

okay so this is a page from the Library Functions Manual and it's literally all about pulling Mini-SEED data out of files. buckle up πŸŽ€


✨ NAME ✨

ms_readmsr β€” Read Mini-SEED data from files πŸ¦‹


✨ SYNOPSIS ✨

#include <libmseed.h>

int ms_readmsr ( MSRecord **ppmsr, char *msfile, int reclen,
                 off_t *fpos, int *last, flag skipnotdata,
                 flag dataflag,flag verbose );

int ms_readmsr_r ( MSFileParam **ppmsfp, MSRecord **ppmsr, char *msfile,
                    int reclen, off_t *fpos, int *last,
                    flag skipnotdata, flag dataflag,flag verbose );

int ms_readtraces ( MSTraceGroup **ppmstg, char *msfile, int reclen,
                    double timetol, double sampratetol,
                    flag dataquality, flag skipnotdata,
                    flag dataflag, flag verbose );

int ms_readtraces_timewin ( MSTraceGroup **ppmstg, char *msfile,
                    int reclen,  double timetol, double sampratetol,
                    hptime_t starttime, hptime_t endtime,
                    flag dataquality, flag skipnotdata,
                    flag dataflag, flag verbose );

int ms_readtraces_selection ( MSTraceGroup **ppmstg, char *msfile,
                    int reclen,  double timetol, double sampratetol,
                    Selections *selections, flag dataquality,
                    flag skipnotdata, flag dataflag, flag verbose );

int ms_readtracelist ( MSTraceList **ppmstl, char *msfile, int reclen,
                       double timetol, double sampratetol,
                       flag dataquality, flag skipnotdata,
                       flag dataflag, flag verbose );

int ms_readtracelist_timewin ( MSTraceList **ppmstl, char *msfile,
                       int reclen, double timetol, double sampratetol,
                       hptime_t starttime, hptime_t endtime,
                       flag dataquality, flag skipnotdata,
                       flag dataflag, flag verbose );

int ms_readtracelist_selection ( MSTraceList **ppmstl, char *msfile,
                       int reclen, double timetol, double sampratetol,
                       Selections *selections, flag dataquality,
                       flag skipnotdata, flag dataflag, flag verbose );

✨ DESCRIPTION ✨

so ms_readmsr and ms_readmsr_r? they open a file and then, over and over with each call, read every single Mini-SEED record out of it. πŸ’… and if msfile is "-" (just a dash, the loneliest string), standard input gets opened instead. iconic.

every record that comes through gets unpacked using msr_unpack(3) β€” that's the glow-up step. ✨ and if the MSRecord struct at *ppmsr hasn't been initialized yet, you gotta set it to NULL and it will initialize it automatically for you. it's giving "don't worry bestie, I got you" 🫢

now the tea β˜•: the ms_readmsr version is not thread safe. the reentrant ms_readmsr_r version is thread safe and can read more than one file in parallel β€” multitasking queen πŸ‘‘. ms_readmsr_r stores all its static file reading params in an MSFileParam struct, and a pointer to that struct must be supplied by you, the caller (ppmsfp). memory will be allocated on the initial call if the pointer is NULL.

if reclen is 0 or negative, the length of every record is automatically detected. πŸ” for auto length detection, records are first searched for a Blockette 1000, and if none is found a search is conducted for the next valid record header (where the existence of the next record or end-of-file implies the length of the current record). detective work, fr fr πŸ•΅οΈβ€β™€οΈ

if the fpos pointer is not NULL, the value will be set to the file position (offset from the beginning in bytes) from where the returned record was read. and here's the special case, pay attention bestie: if fpos is not NULL and the value it points to is less than zero, it gets interpreted as the (positive) offset in the file at which to begin reading data. 🎯 but β€” this feature does not work with packed files. noted. πŸ’€

if the last pointer is not NULL, the value will be set to 1 when the record at the end of the file is being returned, otherwise it'll be 0. but heads up: this indicator will not be set when the last valid record in the file is followed by padding. sneaky.

if the skipnotdata flag is true (not 0), any data chunks read that don't have valid data record indicators (i.e. D, R, or Q) will be skipped. bye felicia πŸ‘‹

the dataflag argument is passed directly to msr_unpack(3) and controls whether data samples get unpacked.

after reading all the input records, the controlling program should call it one last time with msfile set to NULL. 🧹 that closes the file and cleans up allocated memory. the farewell call. 😭

if ms_readmsr or ms_readmsr_r are called with a different file than the one they currently have open, they will close the currently open file, open the new file, and print an error message. properly coded applications should reset the function when the end of file has been reached as described above and not rely on this behavior. don't be messy, bestie. πŸ™ˆ

🌸 the traces/tracelist crew 🌸

the ms_readtraces and ms_readtracelist routines read all Mini-SEED records from a file using ms_readmsr_r and add each one to either a MSTraceGroup or MSTraceList using mst_addmsrtogroup(3) and mstl_addmsr(3) respectively. the msfile, reclen, skipnotdata and dataflag arguments are passed directly to ms_readmsr_r. the timetol, sampratetol and dataquality arguments are passed directly to mst_addmsrtogroup(3) or mstl_addmsr(3).

if the pointer to the MSTraceGroup or MSTraceList struct hasn't been initialized, it must be set to NULL and it will be initialize automatically. ✨ the MSTraceGroup or MSTraceList structures may already contain entries and will be added to by these routines. and these routines are thread safe. slay. πŸ’…


πŸ¦‹ the timewin girlies πŸ¦‹

the ms_readtraces_timewin and ms_readtracelist_timewin routines do the same thing as ms_readtraces and ms_readtracelist but will limit the data to records containing samples between the specified starttime and endtime. it's giving ✨boundaries✨


πŸŽ€ the selection girlies πŸŽ€

the ms_readtraces_selection and ms_readtracelist_selection routines do the same thing as ms_readtraces and ms_readtracelist but will limit the data to records that match the specified selections. Selections include criteria for source name and time window parameters β€” see ms_selection(3) for more info, iykyk. πŸ’œ


✨ RETURN VALUES ✨

on the successful read and parsing of a record, ms_readmsr and ms_readmsr_r return MS_NOERROR and populate the MSRecord struct at *ppmsr. πŸŽ‰ upon reaching the end of the input file these routines return MS_ENDOFFILE. on error these routines return a libmseed error code (defined in libmseed.h).

on the successful read and parsing of a file, ms_readtraces and ms_readtracelist return MS_NOERROR and populate the MSTraceGroup or MSTraceList struct. on error these routines return a libmseed error code (defined in libmseed.h).


✨ PACKED FILES ✨

ms_readmsr, ms_readtraces and ms_readtracelist will read packed Mini-SEED files. packed Mini-SEED is the indexed archive format used internally at the IRIS Data Management Center and probably not used anywhere else. πŸ’€ niche.


✨ EXAMPLE ✨

skeleton code for reading a file with ms_readmsr(3), bestie edition:

main() {
  MSRecord *msr = NULL;
  int retcode;

  while ( (retcode = ms_readmsr (&msr, filename, 0, NULL, NULL, 1, 0, verbose)) == MS_NOERROR )
    {
       /* Do something with the record here, e.g. print */
       msr_print (msr, verbose);
    }

  if ( retcode != MS_ENDOFFILE )
    ms_log (2, "Error reading input file %s: %s\n", filename, ms_errorstr(retcode));

  /* Cleanup memory and close file */
  ms_readmsr (&msr, NULL, 0, NULL, NULL, 0, 0, verbose);
}

for reading a file with the thread safe ms_readmsr_r(3):

main() {
  MSRecord *msr = NULL;
  MSFileParam *msfp = NULL;
  int retcode;

  while ( (retcode = ms_readmsr_r (&msfp, &msr, filename, 0, NULL, NULL, 1, 0, verbose)) == MS_NOERROR )
    {
       /* Do something with the record here, e.g. print */
       msr_print (msr, verbose);
    }

  if ( retcode != MS_ENDOFFILE )
    ms_log (2, "Error reading input file %s: %s\n", filename, ms_errorstr(retcode));

  /* Cleanup memory and close file */
  ms_readmsr_r (&msfp, &msr, NULL, 0, NULL, NULL, 0, 0, verbose);
}

for reading a file with ms_readtraces(3):

main() {
  MSTraceList *mstl = NULL;
  int retcode;

  retcode = ms_readtracelist (&mstl, filename, 0, -1.0, -1.0, 0, 1, 0, verbose);

  if ( retcode != MS_NOERROR )
    ms_log (2, "Error reading input file %s: %s\n", filename, ms_errorstr(retcode));

  retcode = ms_readtracelist (&mstl, filename2, 0, -1.0, -1.0, 0, 1, 0, verbose);

  if ( retcode != MS_NOERROR )
    ms_log (2, "Error reading input file %s: %s\n", filename2, ms_errorstr(retcode));

  if ( ! mstl )
    {
      ms_log (2, "Error reading file\n");
      return -1;
    }

  /* Do something with the traces here, e.g. print */
  mstl_printtracelist (mstl, 0, verbose, 0);

  mstl_free (&mstl);
}

✨ SEE ALSO ✨

ms_intro(3), msr_unpack(3), mst_addmsrtogroup(3), mstl_addmsr(3), ms_log(3) and ms_errorstr(3). go read those too, they're part of the friend group 🫢


✨ AUTHOR ✨

Chad Trabant IRIS Data Management Center


and that's the whole page bestie πŸ’œ this one came from the Libmseed API, dated 2011/01/06 β€” yes she's an elder but she still ate. periodt. πŸ’…βœ¨