DATRW++ library: seismic data I/O with multiple formats
seedstructs.cc
Go to the documentation of this file.
1 /*! \file seedstructs.cc
2  * \brief provide memeber functions for SEED structs (implementation)
3  *
4  * ----------------------------------------------------------------------------
5  *
6  * \author Thomas Forbriger
7  * \date 10/03/2006
8  *
9  * provide memeber functions for SEED structs (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) 2006 by Thomas Forbriger (BFO Schiltach)
28  *
29  * REVISIONS and CHANGES
30  * - 10/03/2006 V1.0 Thomas Forbriger
31  * - 09/05/2006 V1.1 introduced Steim 2 code
32  * - 11/05/2006 V1.2 correction for reading bytes in Steim 2 Word
33  * - 29/06/2007 V1.3 no longer use libtfxx
34  *
35  * ============================================================================
36  */
37 #define DATRW_SEEDSTRUCTS_CC_VERSION \
38  "DATRW_SEEDSTRUCTS_CC V1.3"
39 
40 #include<datrwxx/seedstructs.h>
41 #include<datrwxx/error.h>
42 #include<datrwxx/bytesex.h>
43 
44 #include<iostream>
45 #include<iomanip>
46 
47 namespace datrw {
48 
49  namespace mseed {
50 
51  namespace SEED {
52 
53 #define SWAPIT( A ) A=datrw::util::swap(A)
54 
55  void BTIME::swap()
56  {
57  SWAPIT(year);
58  SWAPIT(doy);
59  SWAPIT(hour);
60  SWAPIT(min);
61  SWAPIT(sec);
62  SWAPIT(zero);
63  SWAPIT(tmilsec);
64  } // void BTIME::swap()
65 
67  {
68  stime.swap();
69  SWAPIT(nsamp);
70  SWAPIT(srate);
71  SWAPIT(srmult);
72  SWAPIT(tcorr);
73  SWAPIT(dbeg);
74  SWAPIT(fblock);
75  } // void FixedDataRecordHeader::swap()
76 
78  {
79  SWAPIT(type);
80  SWAPIT(next);
81  } // void DataRecordBlocketteHeader::swap()
82 
84  {
86  } // void DataOnlySEEDBlockette::swap()
87 
89  {
91  } // void DataExtensionBlockette::swap()
92 
93  /*======================================================================*/
94 
96  {
97  unsigned int code = ((this->control() >> ((nwords-i-1)*2)) & 0x03);
98  return(ESteimControl(code));
99  } // SteimFrame::ESteimControl SteimFrame::ctrl(const int& i) const
100 
101  /*======================================================================*/
102 
104  {
105  Steim1Word w;
106  SWAPIT(this->Mdata.control);
107  for (int i=0; i<nwords; ++i)
108  {
109  w.fw=this->Mdata.word[i];
110  switch(this->ctrl(i)) {
111  case Fspecial:
112  case Ffw:
113  SWAPIT(w.fw);
114  break;
115  case Fbyte:
116  SWAPIT(w.byte[0]);
117  SWAPIT(w.byte[1]);
118  SWAPIT(w.byte[2]);
119  SWAPIT(w.byte[3]);
120  break;
121  case Fhw:
122  SWAPIT(w.hw[0]);
123  SWAPIT(w.hw[1]);
124  break;
125  default:
126  DATRW_abort("ERROR (Steim1Frame::swap()): illegal code");
127  }
128  this->Mdata.word[i]=w.fw;
129  }
130  } // virtual void Steim1Frame::swap()
131 
132  /*======================================================================*/
133 
135  {
136  Steim1Word w;
137  SWAPIT(this->Mdata.control);
138  for (int i=0; i<nwords; ++i)
139  {
140  w.fw=this->Mdata.word[i];
141  switch(this->ctrl(i)) {
142  case Fspecial:
143  case Fdnib1:
144  case Fdnib2:
145  SWAPIT(w.fw);
146  break;
147  case Fbyte:
148  SWAPIT(w.byte[0]);
149  SWAPIT(w.byte[1]);
150  SWAPIT(w.byte[2]);
151  SWAPIT(w.byte[3]);
152  break;
153  default:
154  DATRW_abort("ERROR (Steim2Frame::swap()): illegal code");
155  }
156  this->Mdata.word[i]=w.fw;
157  }
158  } // virtual void Steim2Frame::swap()
159 
160  /*----------------------------------------------------------------------*/
161 
163  {
164  Miword=0;
165  Midiff=0;
166  Mvalid=true;
167  setn();
168  } // void SteimFrame::reset()
169 
170  /*----------------------------------------------------------------------*/
171 
173  {
174  ++Midiff;
175  if (Midiff == Mn) { ++Miword; Midiff=0; }
176  if (Miword == Steim1Frame::nwords) { Mvalid=false; }
177  if (Mvalid) { setn(); }
178  } // void SteimFrame::next()
179 
180  /*======================================================================*/
181  /* Steim 1 Reader code
182  * -------------------
183  */
184 
186  {
187  switch(this->ctrl()) {
189  Mn=1;
190  break;
191  case SteimFrame::Fbyte:
192  Mn=4;
193  break;
194  case SteimFrame::Fhw:
195  Mn=2;
196  break;
197  case SteimFrame::Ffw:
198  Mn=1;
199  break;
200  default:
201  DATRW_abort("ERROR (Steim1Frame::setn()): illegal code");
202  }
203  } // void Steim1Frame::setn()
204 
205  /*----------------------------------------------------------------------*/
206 
207  int Steim1Frame::diff() const
208  {
209  int retval=0;
210  Steim1Word w;
211  w.fw=this->word();
212  if (this->valid())
213  {
214  switch(this->ctrl()) {
216  retval=w.fw;
217  break;
218  case SteimFrame::Fbyte:
219  retval=int(w.byte[this->idiff()]);
220  break;
221  case SteimFrame::Fhw:
222  retval=w.hw[this->idiff()];
223  break;
224  case SteimFrame::Ffw:
225  retval=w.fw;
226  break;
227  default:
228  DATRW_abort("ERROR (Steim1Reader::diff()): illegal code");
229  }
230  }
231  // std::cout << " ** diff is " << retval << std::endl;
232  return(retval);
233  } // int Steim1Frame::diff()
234 
235  /*======================================================================*/
236  /* Steim 2 Reader code
237  * -------------------
238  */
239 
241  {
242  Steim2Word w(Steim2Word::ESteim2Control(this->ctrl()), this->word());
243  Mn=w.nval();
244  } // void Steim2Frame::setn()
245 
246  /*----------------------------------------------------------------------*/
247 
248  int Steim2Frame::diff() const
249  {
250  Steim2Word w(Steim2Word::ESteim2Control(this->ctrl()), this->word());
251  int retval=w.value(this->idiff());
252  return(retval);
253  } // int Steim2Frame::diff()
254 
255  /*======================================================================*/
256  /* Steim 2 Word code
257  * -----------------
258  */
259 
260  int Steim2Word::dnib() const
261  {
262  return(int((Mword >> 30) & 0x03));
263  } // int Steim2Word::dnib() const
264 
265  /*----------------------------------------------------------------------*/
266 
267  int Steim2Word::nval() const
268  {
269  int retval=0;
270  switch (Mctrl) {
272  retval=1;
273  break;
274  case Steim2Word::Fbyte:
275  retval=4;
276  break;
277  case Steim2Word::Fdnib1:
278  switch (this->dnib()) {
279  case Steim2Word::Fdnib01:
280  retval=1;
281  break;
282  case Steim2Word::Fdnib10:
283  retval=2;
284  break;
285  case Steim2Word::Fdnib11:
286  retval=3;
287  break;
288  default:
289  DATRW_abort("ERROR (Steim2Word::value): "
290  "illegal decode nibble");
291  }
292  break;
293  case Steim2Word::Fdnib2:
294  switch (this->dnib()) {
295  case Steim2Word::Fdnib00:
296  retval=5;
297  break;
298  case Steim2Word::Fdnib01:
299  retval=6;
300  break;
301  case Steim2Word::Fdnib10:
302  retval=7;
303  break;
304  default:
305  DATRW_abort("ERROR (Steim2Word::value): "
306  "illegal decode nibble");
307  }
308  break;
309  default:
310  DATRW_abort("ERROR (Steim2Word::value): illegal ctrl code");
311  }
312  return(retval);
313  } // int Steim2Word::nval() const
314 
315  /*----------------------------------------------------------------------*/
316 
317  int Steim2Word::value(const int& i) const
318  {
319  int nval=this->nval();
320  DATRW_assert((i<nval),
321  "ERROR (Steim2Word::value): "
322  "illegal value index");
323  int retval=0;
324  --nval;
325  switch (Mctrl) {
327  retval=Mword;
328  break;
329  case Steim2Word::Fbyte:
330  // bytes must be read in a different order
331  // since we do not swap this word
332  // which is consistent with decode_steim2.c in rdseed
333  retval=this->extract(8,i);
334  break;
335  case Steim2Word::Fdnib1:
336  switch (this->dnib()) {
337  case Steim2Word::Fdnib01:
338  retval=this->extract(30,0);
339  break;
340  case Steim2Word::Fdnib10:
341  retval=this->extract(15,nval-i);
342  break;
343  case Steim2Word::Fdnib11:
344  retval=this->extract(10,nval-i);
345  break;
346  default:
347  DATRW_abort("ERROR (Steim2Word::value): "
348  "illegal decode nibble");
349  }
350  break;
351  case Steim2Word::Fdnib2:
352  switch (this->dnib()) {
353  case Steim2Word::Fdnib00:
354  retval=this->extract(6,nval-i);
355  break;
356  case Steim2Word::Fdnib01:
357  retval=this->extract(5,nval-i);
358  break;
359  case Steim2Word::Fdnib10:
360  retval=this->extract(4,nval-i);
361  break;
362  default:
363  DATRW_abort("ERROR (Steim2Word::value): "
364  "illegal decode nibble");
365  }
366  break;
367  default:
368  DATRW_abort("ERROR (Steim2Word::value): illegal ctrl code");
369  }
370  return(retval);
371  } // int Steim2Word::value(const int& p) const
372 
373  /*----------------------------------------------------------------------*/
374 
375  int Steim2Word::extract(const int& b, const int& p) const
376  {
377  DATRW_assert((b>0), "ERROR (Steim2Word::extract): "
378  "use at least 1 byte");
379  DATRW_assert((p>=0), "ERROR (Steim2Word::extract): "
380  "illegal position");
381  DATRW_assert((p<int(32/b)), "ERROR (Steim2Word::extract): "
382  "illegal position");
383  int signmask=int(1 << (b-1));
384  int valmask=signmask - 1;
385  int nshift=b*p;
386  // extract sign bit
387  int sign=int((Mword >> nshift) & signmask);
388  // extract value bit code
389  int value=int((Mword >> nshift) & valmask);
390  // construct 32-bit (int size) two's complement value
391  int retval= sign ? (value | ~valmask) : value;
392  return(retval);
393  } // int Steim2Word::extract(const int& p) const
394 
395  } // namespace SEED
396 
397  } // namespace mseed
398 
399 } // namespace datrw
400 
401 #undef SWAPIT
402 
403 /* ----- END OF seedstructs.cc ----- */
int idiff() const
return current difference index
Definition: seedstructs.h:517
virtual void swap()
swapping must be performed differently for Steim1 and Steim2
Definition: seedstructs.cc:134
int fw
1 4-byte difference (fullword)
Definition: seedstructs.h:396
unsigned short int tmilsec
Definition: seedstructs.h:225
#define DATRW_assert(C, M)
Check an assertion and report by throwing an exception.
Definition: error.h:92
virtual void swap()
swapping must be performed differently for Steim1 and Steim2
Definition: seedstructs.cc:103
virtual int diff() const
return current difference value
Definition: seedstructs.cc:207
unsigned short int year
Definition: seedstructs.h:219
unsigned short int dbeg
beginning of data
Definition: seedstructs.h:320
short int srate
sample rate factor
Definition: seedstructs.h:312
int nval() const
return number of values in this word
Definition: seedstructs.cc:267
unsigned short int fblock
first blockette
Definition: seedstructs.h:321
void reset()
step to first difference value
Definition: seedstructs.cc:162
unsigned int control() const
return control word
Definition: seedstructs.h:490
virtual void setn()
set Mn for current word (compression type specific)
Definition: seedstructs.cc:185
SteimFrame::ESteimControl ctrl() const
return control code for current word
Definition: seedstructs.h:508
unsigned int control
control flags
Definition: seedstructs.h:482
short int srmult
sample rate multiplier
Definition: seedstructs.h:313
int dnib() const
return dnib
Definition: seedstructs.cc:260
ESteimControl
possible control codes
Definition: seedstructs.h:468
unsigned short int nsamp
number of samples
Definition: seedstructs.h:311
four 8-bit differences (byte)
Definition: seedstructs.h:419
#define SWAPIT(A)
Definition: seedstructs.cc:53
short int hw[2]
2 2-byte differences (halfword)
Definition: seedstructs.h:395
exception class declaration for libdatrwxx (prototypes)
FrameData Mdata
frame data (swapped)
Definition: seedstructs.h:528
unsigned short int next
Next blockette&#39;s byte number.
Definition: seedstructs.h:337
A copy of bytesex.h from libtfxx (prototypes)
Root namespace of library.
Definition: aalibdatrwxx.cc:16
four 8-bit differences (byte)
Definition: seedstructs.h:470
DataRecordBlocketteHeader blocketteheader
Definition: seedstructs.h:354
virtual void setn()
set Mn for current word (compression type specific)
Definition: seedstructs.cc:240
unsigned short int doy
Definition: seedstructs.h:220
DataRecordBlocketteHeader blocketteheader
Definition: seedstructs.h:379
#define DATRW_abort(M)
Abort and give a message.
Definition: error.h:101
one 32-bit difference (fullword)
Definition: seedstructs.h:472
contains non-data information, like headers
Definition: seedstructs.h:469
virtual void setn()=0
set Mn for current word (compression type specific)
int Mn
number of differences in this word
Definition: seedstructs.h:530
int Miword
current word in frame
Definition: seedstructs.h:533
int extract(const int &b, const int &p) const
Definition: seedstructs.cc:375
unsigned short int type
Blockette type.
Definition: seedstructs.h:336
contains non-data information, like headers
Definition: seedstructs.h:418
void next()
step to next difference value
Definition: seedstructs.cc:172
virtual int diff() const
return current difference value
Definition: seedstructs.cc:248
bool Mvalid
we are still inside the current frame
Definition: seedstructs.h:537
bool valid() const
we are still inside the frame
Definition: seedstructs.h:506
int Midiff
current difference value in word
Definition: seedstructs.h:535
static const int nwords
numer of words to process
Definition: seedstructs.h:463
int word() const
return current data word
Definition: seedstructs.h:496
char byte[4]
4 1-byte differences
Definition: seedstructs.h:394
int value(const int &i) const
Definition: seedstructs.cc:317
two 16-bit differences (halfword)
Definition: seedstructs.h:471