You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
6.3 KiB
Plaintext
192 lines
6.3 KiB
Plaintext
1 year ago
|
/**
|
||
|
@page page-tutorial Tutorial
|
||
|
|
||
|
@tableofcontents
|
||
|
|
||
|
@section common-usage Common usage
|
||
|
|
||
|
This page contains a description of basic library usage for the most
|
||
|
common usage cases.
|
||
|
|
||
|
Additionally, the @ref page-examples page contains full examples for
|
||
|
common use cases, which are also included in the 'examples' directory
|
||
|
of the source code distribution.
|
||
|
|
||
|
@subsection reading Reading miniSEED data
|
||
|
|
||
|
A common task is to read a file of miniSEED records and perform some
|
||
|
action based on the header values or apply some process to the data
|
||
|
samples. There are two patterns to support this in the library, one
|
||
|
to iterate over the file record-by-record and another to read all data
|
||
|
into a collection of continuous series.
|
||
|
|
||
|
@subsubsection reading-records Reading miniSEED records from files
|
||
|
|
||
|
The ms3_readmsr() routine will open a specified file and return
|
||
|
MS3Record structures for each miniSEED record it reads from the file.
|
||
|
Called iteratively in a loop, all records are returned in the order
|
||
|
discovered.
|
||
|
|
||
|
A code snippet for reading miniSEED from a file record-by-record:
|
||
|
@anchor msr3-readmsr-snippet
|
||
|
@code
|
||
|
int main ()
|
||
|
{
|
||
|
char *filename = "datafile.mseed";
|
||
|
MS3Record *msr = NULL;
|
||
|
uint32_t flags = MSF_SKIPNOTDATA & MSF_UNPACKDATA;
|
||
|
int verbose = 0;
|
||
|
int retcode;
|
||
|
|
||
|
while ((retcode = ms3_readmsr (&msr, filename, flags, verbose)) == MS_NOERROR)
|
||
|
{
|
||
|
/* Do something with the record here, e.g. print */
|
||
|
msr3_print (msr, verbose);
|
||
|
}
|
||
|
|
||
|
if (retcode != MS_ENDOFFILE)
|
||
|
ms_log (2, "Cannot read %s: %s\n", filename, ms_errorstr (retcode));
|
||
|
|
||
|
/* Cleanup memory and close file */
|
||
|
ms3_readmsr (&msr, NULL, flags, verbose);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
@endcode
|
||
|
|
||
|
It is important to call ms3_readmsr() for cleanup as illustrated to
|
||
|
free memory and close files.
|
||
|
|
||
|
There are more advanced versions of this routine. The ms3_readmsr_r()
|
||
|
function is a thread-safe version that can be used in threaded
|
||
|
programs to read files in parallel. The ms3_readmsr_selection()
|
||
|
function is a thread-safe version that can additionally accept @ref
|
||
|
data-selections to efficiently return only selected data.
|
||
|
|
||
|
@subsubsection reading-tracelists Reading miniSEED from files into traces lists
|
||
|
|
||
|
Another option is to read all miniSEED into a @ref trace-list without
|
||
|
any handling of records. This is done with ms3_readtraces(), which is
|
||
|
very useful for quickly reading data for processing. The data are
|
||
|
returned in ordered, continuous segments ready for processing.
|
||
|
|
||
|
A code snippet for reading miniSEED from a file into a @ref trace-list :
|
||
|
@anchor msr3-readtracelist-snippet
|
||
|
@code
|
||
|
int main ()
|
||
|
{
|
||
|
char *filename1 = "datafile1.mseed";
|
||
|
char *filename2 = "datafile2.mseed";
|
||
|
MS3TraceList *mstl = NULL;
|
||
|
MS3Tolerance tol = MS3Tolerance_INITIALIZER;
|
||
|
uint32_t flags = MSF_SKIPNOTDATA & MSF_UNPACKDATA;
|
||
|
int verbose = 0;
|
||
|
int retcode;
|
||
|
|
||
|
retcode = ms3_readtracelist (&mstl, filename1, &tol, 0, flags, verbose);
|
||
|
|
||
|
if (retcode != MS_NOERROR)
|
||
|
ms_log (2, "Cannot read %s: %s\n", filename1, ms_errorstr (retcode));
|
||
|
|
||
|
retcode = ms3_readtracelist (&mstl, filename2, &tol, 0, flags, verbose);
|
||
|
|
||
|
if (retcode != MS_NOERROR)
|
||
|
ms_log (2, "Cannot read %s: %s\n", filename2, ms_errorstr (retcode));
|
||
|
|
||
|
if (!mstl)
|
||
|
{
|
||
|
fprintf (stderr, "Error reading file\\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
/* Do something with the traces here, e.g. print */
|
||
|
mstl3_printtracelist (mstl, 0, verbose, 0, 0);
|
||
|
|
||
|
mstl3_free (&mstl, 1);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
@endcode
|
||
|
|
||
|
There are more advanced versions of this routine. The
|
||
|
ms3_readtracelist_timewin() function allows data to be limited to a
|
||
|
specific time range while reading. The ms3_readtracelist_selection()
|
||
|
can additionally accept @ref data-selections to efficiently return
|
||
|
only selected data.
|
||
|
|
||
|
@subsubsection reading-buffers Reading miniSEED from memory
|
||
|
|
||
|
If an application is not designed to read miniSEED from files the
|
||
|
library provides functions functionality to read data from memory.
|
||
|
The mstl3_readbuffer() function will read all data from a buffer into
|
||
|
a @ref trace-list. The low-level functions ms3_detect() and
|
||
|
msr3_parse() can be used to detect and parse miniSEED records in
|
||
|
memory buffers.
|
||
|
|
||
|
@subsection writing Writing miniSEED records
|
||
|
|
||
|
Another common task is to create miniSEED records. There are two
|
||
|
patterns to support this in the library: one is to write data from
|
||
|
library containers to files and another to create records and provide
|
||
|
them back to the caller in a memory buffer via a callback function.
|
||
|
|
||
|
@subsubsection callback Callback design
|
||
|
|
||
|
If not writing directly to files, the packing interfaces use a
|
||
|
callback design, where the caller specifies a function that will be
|
||
|
called for every record that is created. It is the responsibility of
|
||
|
the callback function to handle the record before returning. This
|
||
|
design allows a program to do whatever is needed with generated
|
||
|
miniSEED, i.e. write to files, send over the network, or even
|
||
|
injection of more information.
|
||
|
|
||
|
@subsubsection writing-files Writing miniSEED data to files
|
||
|
|
||
|
The library supports writing miniSEED directly to files from either
|
||
|
MS3Record or MS3TraceList containers using msr3_writemseed() or
|
||
|
mstl3_writemseed() respectively.
|
||
|
|
||
|
A code snippet for writing miniSEED to a file from an MS3Record using msr3_writemseed():
|
||
|
@anchor msr3-writemseed-snippet
|
||
|
@code
|
||
|
int main()
|
||
|
{
|
||
|
int packedrecords;
|
||
|
int verbose = 0;
|
||
|
char *msfile = "output.mseed";
|
||
|
int32_t datasamples[] = {0,1,2,3,4,5,6,7,8,9,10};
|
||
|
MS3Record *msr;
|
||
|
|
||
|
msr = msr3_init (NULL);
|
||
|
|
||
|
/* Populate MS3Record values */
|
||
|
strcpy (msr->sid, "XX_TEXT__B_H_E");
|
||
|
msr->formatversion = 3;
|
||
|
msr->reclen = 512;
|
||
|
msr->encoding = DE_STEIM2;
|
||
|
msr->starttime = ms_timestr2nstime ("2018-12-01T00:00:00.000000000");
|
||
|
msr->samprate = 20.0;
|
||
|
|
||
|
msr->datasamples = datasamples; /* pointer to 32-bit integer data samples */
|
||
|
msr->numsamples = 11;
|
||
|
msr->sampletype = 'i'; /* declare data type to be 32-bit integers */
|
||
|
|
||
|
/* Write all data in MS3Record to output file, using MSF_FLUSHDATA flag */
|
||
|
packedrecords = msr3_writemseed (msr, msfile, 1, MSF_FLUSHDATA, verbose);
|
||
|
|
||
|
ms_log (0, "Wrote %d records to %s\n", packedrecords, msfile);
|
||
|
|
||
|
/* Disconnect datasamples pointer, otherwise msr3_free() will attempt to free() it */
|
||
|
msr->datasamples = NULL;
|
||
|
|
||
|
msr3_free (&msr);
|
||
|
}
|
||
|
@endcode
|
||
|
|
||
|
@subsubsection creating-records Creating miniSEED records
|
||
|
|
||
|
Records can be generated from data in either MS3Record or MS3TraceList
|
||
|
containers using, respectively, msr3_pack() or and mstl3_pack().
|
||
|
|
||
|
*/
|