DATRW++ library: seismic data I/O with multiple formats
mseedread.cc
Go to the documentation of this file.
1 /*! \file mseedread.cc
2  * \brief read mini-SEED files (implementation)
3  *
4  * ----------------------------------------------------------------------------
5  *
6  * \author Thomas Forbriger
7  * \date 15/07/2004
8  *
9  * read mini-SEED files (implementation)
10  *
11  * ----
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25  * ----
26  *
27  * Copyright (c) 2004 by Thomas Forbriger (BFO Schiltach)
28  *
29  * REVISIONS and CHANGES
30  * - 15/07/2004 V1.0 Thomas Forbriger (thof)
31  * - 04/04/2006 V1.1 use Motorola byte order for header fields as
32  * standard byte order
33  * - 28/04/2006 V1.2 - long int appears to be of
34  * implementation dependent size
35  * - provide explicit conversion of BTIME fields
36  * - 09/05/2006 V1.3 use general Steim 1 and 2 code
37  * - 07/07/2006 V1.4 provide debug function when reading MiniSEED record
38  * - 10/07/2006 V1.5 skip special words within data stream
39  * - 29/06/2007 V1.6 no longer use libtfxx
40  * - 11/09/2007 V1.7 added help function
41  * - 11/11/2009 V1.8 requires header cstring
42  * - 13/09/2011 V1.9 silently skip ASCII blocks
43  * - 07/05/2014 V1.10 accept all type field indicators in the fixed
44  * section of data header as defined by SEED V2.4
45  * - 08/05/2014 V1.11 add format modifier ttolerance to help
46  * check for consistent number of frames
47  * - 12/05/2014 V1.12 do not read more than the indicated number of frames
48  * or samples
49  * - 22/07/2014 V1.13 thof:
50  * - move member fucntions
51  * MiniSEEDRecord::readheader and MiniSEEDRecord::read
52  * to dedicated compilation units
53  * - support new format modifier: estimateNframes
54  * - 23/06/2016 V1.14 thof:
55  * - move member functions of MiniSEEDRecord to
56  * separate compilation units
57  * - 05/07/2016 V1.15 thof:
58  * - move help function to separate compilation unit
59  * - do not provide stand-alone help function in
60  * namespace mseed
61  *
62  * ============================================================================
63  */
64 #define DATRW_MSEEDREAD_CC_VERSION \
65  "DATRW_MSEEDREAD_CC V1.15"
66 
67 #include <string>
68 #include <cstring>
69 #include <string.h>
70 #include <datrwxx/mseedread.h>
71 #include <datrwxx/mseed.h>
72 #include <datrwxx/bytesex.h>
73 
74 namespace datrw {
75 
76  /*!
77  * \section sec_mseed_concept Concept of reading MiniSEED files
78  *
79  * This module is designed to read data from SeisComP an there from the
80  * old version used in the GRSN (with comserv client datalog) as well as
81  * the new version (using seedlink). Further it will read EDL (Earth Data
82  * Logger) MiniSEED files. Their formats differ in block size and MiniSEED
83  * data files that are written by comserv contain telemetry volume headers
84  * additionally.
85  *
86  * If we provide a stream like class, that is constructed from an istream
87  * object and returns a full data block at once (containing fixed data
88  * header, blockette 1000 and blockette 1001 and time series samples; the
89  * latter preferably in an STL vector), we can hide all bytesex and
90  * blocksize stuff inside this class.
91  *
92  * This stream class has to skip the telemetry volume header if the file
93  * starts with one. And it has to check the bytesex of the data, which is
94  * coded therein, but which is only available from blockette 1000, which
95  * is only available after some reading. The data record length is also
96  * only available from blockette 1000. Thus reading this informations
97  * would already require to know this information. Thus there will be some
98  * guessing and testing be involved and in particular some strong
99  * assumptions about the blockette structure used in the file.
100  * Fortunately the SEED manual defines on page 12, that the common byte
101  * order for all SEED header fields is big-endian (Motorola). Only SEED
102  * data fields my by different. Their byte order is specified in the Data
103  * Only SEED Blockette in the case of MiniSEED data.
104  *
105  * Notice: Data written by EarthDataLoggers is not consistent with the
106  * definition of the byte order of header fields in SEED data. EDL prefer
107  * to write everything in Intel byte order :-( The code has to check for
108  * this, which is done in member function
109  * datrw::mseed::MiniSEEDRecord::readheader(std::istream& is)
110  * as well as in the test program provided in file mseedtest.cc
111  *
112  * We will use the basic structures defined in namespace SEED to hold the
113  * data. However, it will be necessary to put some envelope around these
114  * structure in particular to indicate if a blockette was actually read
115  * from a dataset or not (because it will be present in the returned data
116  * block structure in any case).
117  *
118  * \section sec_mseed_ascii Howto handle ASCII data
119  * In data streamed directly from Q330HR data acquisition systems,
120  * there may ASCII blocks be present containing system logs.
121  * This ASCII data is handled in
122  * datrw::mseed::MiniSEEDRecord::readheader(std::istream& is)
123  * which just skips the ASCII block and reads until the next binary data
124  * block.
125  * If it reaches EOF datrw::mseed::MiniSEEDRecord::Mvalid is turned to
126  * false as usual with all other reading operations.
127  *
128  * \date 13.9.2011
129  */
130  namespace mseed {
131 
132  namespace util {
133 
134  /*! \brief Return a maximum of \p l characters.
135  *
136  * \param[in] s input string (character array)
137  * \param[in] l maximum number of characters to return
138  * \return string object containing not more than \p l characters of
139  * the input sequence
140  */
141  std::string extractstring(const char* s, const int& l)
142  {
143  int slen=std::strlen(s);
144  slen = slen < 0 ? l : slen;
145  slen = slen < l ? slen : l;
146  return(std::string(s, slen));
147  } // std::string extractstring(const char* s, const int& l)
148 
149  } // namespace util
150 
151  /*! contructor of MiniSEEDblock allocates memory of requested block size.
152  * In case this fails, an exception is thrown.
153  */
154  MiniSEEDblock::MiniSEEDblock(const unsigned int& blocksize):
155  Mblocksize(blocksize)
156  {
157  try { Mblock=Theap(blocksize); }
158  catch (std::bad_alloc) {
159  DATRW_abort("MiniSEEDblock: could not allocate memory!");
160  }
161  } // MiniSEEDblock::MiniSEEDblock
162 
163  /*----------------------------------------------------------------------*/
164 
165  //! convert BTIME structure to libtime structure
166  libtime::TAbsoluteTime convert(const SEED::BTIME& t)
167  {
168  int milsec=int(int(t.tmilsec)/10);
169  int micsec=100*(int(t.tmilsec)-milsec*10);
170  libtime::TAbsoluteTime retval(int(t.year), 1, 1,
171  int(t.hour), int(t.min), int(t.sec),
172  int(milsec), int(micsec));
173  retval.setdoy(int(t.doy));
174  return(retval);
175  } // libtime::TAbsoluteTime convert(const SEED::BTIME& t)
176 
177  /*----------------------------------------------------------------------*/
178 
179  //! calculate sampling interval from srate and smult
180  double samplinginterval(const short int& srate,
181  const short int& srmult)
182  {
183  double fac1 = srate < 0 ? -double(srate) : 1./double(srate);
184  double fac2 = srmult < 0 ? -double(srmult) : 1./double(srmult);
185  return(fac1*fac2);
186  } // double samplinginterval(const short int& srate,
187  // const short int& smult);
188 
189  /*----------------------------------------------------------------------*/
190 
191  //! check bytesex
192  bool needswap(const unsigned char& bytesex)
193  {
194  // my CPU type
196  // file type
198  // file type
199  SEED::EByteOrder byteorder=SEED::EByteOrder(int(bytesex));
200  if (byteorder == SEED::vax8086)
201  { filesex=datrw::util::cpu_Intel; }
202  else if (byteorder == SEED::sparc68000)
203  { filesex=datrw::util::cpu_Motorola; }
204  bool retval=(filesex != mysex);
205  return(retval);
206  } // needswap(const unsigned char& bytesex)
207 
208  } // namespace mseed
209 
210 } // namespace datrw
211 
212 /* ----- END OF mseedread.cc ----- */
aff::Series< Tvalue > Theap
use aff shared heap to store and copy block
Definition: mseedread.h:82
unsigned short int tmilsec
Definition: seedstructs.h:225
unsigned short int year
Definition: seedstructs.h:219
Ecpu_type cpu()
check for my CPU model
Definition: bytesex.cc:73
Ecpu_type
Define different CPU type that are recognized.
Definition: bytesex.h:88
std::string extractstring(const char *s, const int &l)
Return a maximum of l characters.
Definition: mseedread.cc:141
double samplinginterval(const short int &srate, const short int &srmult)
calculate sampling interval from srate and smult
Definition: mseedread.cc:180
bool needswap(const unsigned char &bytesex)
check bytesex
Definition: mseedread.cc:192
A copy of bytesex.h from libtfxx (prototypes)
MiniSEEDblock(const unsigned int &blocksize=standard_block_size)
Definition: mseedread.cc:154
unknown CPU
Definition: bytesex.h:94
Root namespace of library.
Definition: aalibdatrwxx.cc:16
libtime::TAbsoluteTime convert(const SEED::BTIME &t)
convert BTIME structure to libtime structure
Definition: mseedread.cc:166
unsigned int blocksize() const
Definition: mseedread.h:88
Motorola CPU.
Definition: bytesex.h:92
unsigned short int doy
Definition: seedstructs.h:220
#define DATRW_abort(M)
Abort and give a message.
Definition: error.h:101
provide mini-SEED data (prototypes)
SPARC or 68000 byte order.
Definition: seedstructs.h:127
Intel CPU.
Definition: bytesex.h:90
VAX or 8086 byte order.
Definition: seedstructs.h:126