DATRW++ library: seismic data I/O with multiple formats
mseedread_mseedrecord_readheader.cc
Go to the documentation of this file.
1 /*! \file mseedread_mseedrecord_readheader.cc
2  * \brief MiniSEEDRecord::readheader read and parse information contained therein (implementation)
3  *
4  * ----------------------------------------------------------------------------
5  *
6  * \author Thomas Forbriger
7  * \date 22/07/2014
8  *
9  * MiniSEEDRecord::readheader read and parse information contained therein
10  * (implementation)
11  *
12  * Copyright (c) 2014 by Thomas Forbriger (BFO Schiltach)
13  *
14  * ----
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28  * ----
29  *
30  * REVISIONS and CHANGES
31  * - 22/07/2014 V1.0 Thomas Forbriger
32  * copied from mseed/mseedread.cc
33  *
34  * ============================================================================
35  */
36 #define TF_MSEEDREAD_MSEEDRECORD_READHEADER_CC_VERSION \
37  "TF_MSEEDREAD_MSEEDRECORD_READHEADER_CC V1.0"
38 
39 #include <string>
40 #include <cstring>
41 #include <string.h>
42 #include <datrwxx/mseedread.h>
43 #include <datrwxx/mseed.h>
44 #include<datrwxx/bytesex.h>
45 #include<aff/subarray.h>
46 
47 namespace datrw {
48 
49  namespace mseed {
50 
51  /*----------------------------------------------------------------------*/
52  // extract header from MiniSEED data
53 
55  {
56  // create block to read MiniSEED
57  MiniSEEDblock block;
58  // count blocks
59  int iblock=0;
60  // reset blockette indicators
61  Mhasblockette1000=false;
62  Mhasblockette1001=false;
63 
64  /* read first block and extract essential header fields
65  * ----------------------------------------------------
66  * Look for data control header
67  * This initial sequence is required to skip the telemetry volume header
68  * if present.
69  *
70  * See chapter 8, page 108: "Fixed Section of Data Header (48 bytes)"
71  * in recent SEED V2.4 Manual for changes in the type field definition.
72  *
73  * Data header/quality indicator. Previously, this field was only
74  * allowed to be “D” and was only used to indicate that this is a data
75  * header. As of SEED version 2.4 the meaning of this field has been
76  * extended to also indicate the level of quality control that has been
77  * applied to the record.
78  *
79  * With SEED version 2.4 the type field may contain the following
80  * indicators:
81  *
82  * D — The state of quality control of the data is indeterminate.
83  * R — Raw Waveform Data with no Quality Control
84  * Q — Quality Controlled Data, some processes have been applied to the
85  * data.
86  * M — Data center modified, time-series values have not been changed.
87  */
88  bool nodataheader=true;
89  while (nodataheader && is.good()) {
90  is >> block;
91  SEED::ControlHeader controlheader(block.block());
92  if ((controlheader.type == 'D')
93  || (controlheader.type == 'R')
94  || (controlheader.type == 'Q')
95  || (controlheader.type == 'M'))
96  { nodataheader=false; }
97  }
98 
99  if (nodataheader)
100  {
101  // trapped if EOF is reached before a valid controlheader
102  // of type 'D' is found
103  Mvalid=false;
104  }
105  else
106  {
107  // Flag which will be set true, if we have met a header in front
108  // of valid sample block from which time series data can be extracted.
109  // Alternative blocks are ASCII log data block, which will be skipped.
110  bool seriesheader=false;
111  while ((!seriesheader) && is.good())
112  {
113  // data header is present
114  ++iblock;
115  // SEED defines Motorola (big-endian) to be the standard byte order
116  // for all headers
117  // check our CPU type
120  "ERROR (reading MiniSEED record): "
121  "cannot identify CPU type");
122  bool doswap = (mysex == datrw::util::cpu_Intel);
124  // extract essential header fields
125  // Blockette1000 is essential to determine bytesex
126  if (Mrecordheader.fblock > block.bytesize())
127  {
128  // try it the other way
129  doswap = !doswap;
132  "ERROR (reading MiniSEED record): "
133  "cannot find first blockette");
134  }
135  // read Blockettes
136  unsigned int blocketteadr=Mrecordheader.fblock;
137  for (int i=0; i<Mrecordheader.numblock; i++)
138  {
140  bh(block.block(blocketteadr), doswap);
141  if (bh.type == 1000)
142  {
143  Mhasblockette1000=true;
145  SEED::DataOnlySEEDBlockette(block.block(blocketteadr), doswap);
146  }
147  else if (bh.type == 1001)
148  {
149  Mhasblockette1001=true;
151  SEED::DataExtensionBlockette(block.block(blocketteadr), doswap);
152  }
153  blocketteadr=bh.next;
154  }
156  "ERROR (reading MiniSEED record): "
157  "Data Only SEED Blockette is essential");
158  // check bytesex integrity
160  "ERROR (reading MiniSEED record): "
161  "swapping is not consistent");
162  // check for possible ASCII data and skip ASCII data
164  {
165  unsigned int totalreclen=Mblockette1000.reclenbytes();
166  unsigned int bytecount=Mrecordheader.dbeg;
167  unsigned int pframe=Mrecordheader.dbeg;
169  {
170  std::cout << this->date().hierarchicalstring() << " ASCII data block:"
171  << std::endl;
172  std::cout << ">>";
173  }
174  while ((bytecount < totalreclen) && is.good())
175  {
176  if (pframe >= block.bytesize())
177  {
178  is >> block;
179  pframe=0;
180  iblock++;
181  }
182  while (pframe < block.bytesize())
183  {
184  char c=block[pframe];
185  if (isprint(c))
186  {
188  {
189  std::cout << c;
190  }
191  }
192  else if (c == 0x0d)
193  {
195  {
196  std::cout << std::endl << ">>";
197  }
198  }
199  ++pframe;
200  ++bytecount;
201  } // while (pframe < block.bytesize())
202  } // while ((bytecount < totalreclen) && is.good())
204  {
205  std::cout << std::endl;
206  }
207  is >> block;
208  iblock++;
209  } // if (Mblockette1000.format == datrw::mseed::SEED::ascii)
210  else
211  {
212  // we expect to have met a valid series header
213  seriesheader=true;
214  }
215  } // while ((!seriesheader) && is.good())
216  // finished successfully
217  if (is.good()) { Mvalid=true; }
218  }
219  return(block);
220  } // MiniSEEDblock MiniSEEDRecord::readheader(std::istream& is)
221 
222  } // namespace mseed
223 
224 } // namespace datrw
225 
226 /* ----- END OF mseedread_mseedrecord_readheader.cc ----- */
#define DATRW_assert(C, M)
Check an assertion and report by throwing an exception.
Definition: error.h:92
MiniSEEDblock readheader(std::istream &is)
read header and return block
SEED::DataExtensionBlockette Mblockette1001
Data Extension Blockette.
Definition: mseedread.h:241
unsigned short int dbeg
beginning of data
Definition: seedstructs.h:320
Ecpu_type cpu()
check for my CPU model
Definition: bytesex.cc:73
unsigned short int fblock
first blockette
Definition: seedstructs.h:321
unsigned int bytesize() const
Definition: mseedread.h:90
Ecpu_type
Define different CPU type that are recognized.
Definition: bytesex.h:88
bool Mhasblockette1001
Data Extension Blockette is present.
Definition: mseedread.h:231
bool needswap(const unsigned char &bytesex)
check bytesex
Definition: mseedread.cc:192
A copy of bytesex.h from libtfxx (prototypes)
unknown CPU
Definition: bytesex.h:94
Root namespace of library.
Definition: aalibdatrwxx.cc:16
bool Mhasblockette1000
Data Only SEED Blockette is present.
Definition: mseedread.h:229
SEED::FixedDataRecordHeader Mrecordheader
Fixed Data Record Header.
Definition: mseedread.h:237
unsigned char format
Encoding Format.
Definition: seedstructs.h:355
libtime::TAbsoluteTime date() const
return time of first sample
provide mini-SEED data (prototypes)
bool report_ascii_data_to_stdout
report ASCII lines
Definition: mseedread.h:136
SEED::DataOnlySEEDBlockette Mblockette1000
Data Only SEED Blockette.
Definition: mseedread.h:239
Debug Mdebug
debug options
Definition: mseedread.h:225
bool Mvalid
contains valid data
Definition: mseedread.h:227
Intel CPU.
Definition: bytesex.h:90
Tvalue * block() const
Definition: mseedread.h:93
unsigned char bytesex
Word order.
Definition: seedstructs.h:356
unsigned char numblock
number of blockettes that follow
Definition: seedstructs.h:317