DATRW++ library: seismic data I/O with multiple formats
pdasread.cc
Go to the documentation of this file.
1 /*! \file pdasread.cc
2  * \brief read pdas file (implementation)
3  *
4  * ----------------------------------------------------------------------------
5  *
6  * \author Thomas Forbriger
7  * \date 30/03/2004
8  *
9  * read pdas file (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  * - 30/03/2004 V1.0 Thomas Forbriger
31  * - 10/09/2004 V1.1 support long format
32  * - 19/10/2004 V1.2
33  * - long reading works now
34  * - supports gainranged format
35  * - 28/04/2006 V1.3 - long int appears to be of
36  * implementation dependent size
37  * - use long long int (8 byte) for delim
38  *
39  * ============================================================================
40  */
41 #define DATRW_PDASREAD_CC_VERSION \
42  "DATRW_PDASREAD_CC V1.3"
43 
44 #include<iostream>
45 #include <datrwxx/pdasread.h>
46 #include <datrwxx/error.h>
47 
48 namespace datrw {
49 
50  namespace pdas {
51 
52  struct FoundEOF { }; // struct FoundEOF
53 
54  //! function to read the file header line
55  HeaderLine readline(std::istream& is, const bool& verbose)
56  {
57  HeaderLine retval;
58  DATRW_assert(is.good(), "ERROR: unexpected end of file!");
59  std::getline(is, retval.line);
60  // remove CR
61  unsigned long long int delim=retval.line.find_first_of(0x0D);
62  retval.line.erase(delim);
63  // strip value from token
64  delim=retval.line.find_first_of(' ');
65  if (delim!=std::string::npos)
66  {
67  retval.token=retval.line.substr(0,delim);
68  retval.value=retval.line.substr(delim+1);
69  }
70  if (verbose)
71  {
72  std::cout << "line: " << retval.line << std::endl;
73  std::cout << " token: \"" << retval.token << "\"" << std::endl;
74  std::cout << " value: \"" << retval.value << "\"" << std::endl;
75  }
76  return(retval);
77  }
78 
79  /*----------------------------------------------------------------------*/
80 
81  //! function to read the file header
82  Header readheader(std::istream& is, const bool& verbose)
83  {
84  Header retval;
85  HeaderLine hdline;
86  while (hdline.line!="DATA")
87  {
88  hdline=readline(is, verbose);
89  retval.lines.push_back(hdline.line);
90  if (hdline.token=="DATASET")
91  { retval.dataset=hdline.value; }
92  else if (hdline.token=="SIGNAL")
93  { retval.signal=hdline.value; }
94  else if (hdline.token=="VERSION")
95  { retval.version=hdline.value; }
96  else if (hdline.token=="DATE")
97  { retval.date=hdline.value; }
98  else if (hdline.token=="TIME")
99  { retval.time=hdline.value; }
100  else if (hdline.token=="INTERVAL")
101  { retval.interval=hdline.value; }
102  else if (hdline.token=="VERT_UNITS")
103  { retval.vertunits=hdline.value; }
104  else if (hdline.token=="HORZ_UNITS")
105  { retval.horzunits=hdline.value; }
106  else if (hdline.token=="COMMENT")
107  {
108  retval.comment=hdline.value;
109  if (retval.type == FtypeLONG)
110  {
111  if (hdline.value=="GAINRANGED")
112  { retval.type=FtypeGAINRANGED; }
113  }
114  }
115  else if (hdline.token=="FILE_TYPE")
116  {
117  if (hdline.value=="INT")
118  { retval.type=FtypeINT; }
119  else if (hdline.value=="LONG")
120  { retval.type=FtypeLONG; }
121  else
122  { DATRW_abort("ERROR: unsupported data type!"); }
123  }
124  }
125  if (verbose)
126  {
127  std::cout << "dataset: " << retval.dataset << std::endl;
128  std::cout << "signal: " << retval.signal << std::endl;
129  std::cout << "version: " << retval.version << std::endl;
130  std::cout << "date: " << retval.date << std::endl;
131  std::cout << "time: " << retval.time << std::endl;
132  std::cout << "interval: " << retval.interval << std::endl;
133  std::cout << "vert units: " << retval.vertunits << std::endl;
134  std::cout << "horz units: " << retval.horzunits << std::endl;
135  std::cout << "comment: " << retval.comment << std::endl;
136  std::cout << "data type: ";
137  if (retval.type==FtypeINT)
138  { std::cout << "INT integer" << std::endl; }
139  else
140  { std::cout << "unknown!" << std::endl; }
141  }
142  return(retval);
143  }
144 
145  /*----------------------------------------------------------------------*/
146 
147  /*! function to read the file data
148  * passes vector by reference to avoid deep copy
149  */
150  void readdata(std::istream& is, Tdata& data, const Etype& type)
151  {
152  data.clear();
153  bool hot=true;
154  while(is.good()&&hot)
155  {
156  Tvalue sample;
157  try { sample=readsample(is, type); }
158  catch (FoundEOF) { hot=false; }
159  if (hot) data.push_back(sample);
160  }
161  }
162 
163  /*----------------------------------------------------------------------*/
164 
165  //! function to skip the file data but count the samples
166  int countdata(std::istream& is, const Etype& type)
167  {
168  int retval=0;
169  bool hot=true;
170  while(is.good()&&hot)
171  {
172  try { readsample(is, type); }
173  catch (FoundEOF) { hot=false; --retval; }
174  ++retval;
175  }
176  return(retval);
177  }
178 
179  /*----------------------------------------------------------------------*/
180 
181  //! function to read one sample
182  Tvalue readsample(std::istream& is, const Etype& type)
183  {
184  int invalue;
185  Tvalue value;
186  union Byte {
187  char inchar;
188  unsigned char byte;
189  }; // union byte
190  if (type==FtypeINT)
191  {
192  Byte lbyte, hbyte;
193  if (is.eof()) throw FoundEOF();
194  is.get(lbyte.inchar);
195  if (is.eof()) throw FoundEOF();
196  is.get(hbyte.inchar);
197  invalue=int(lbyte.byte)+256*int(hbyte.byte);
198  if (int(hbyte.byte)>127)
199  { value=Tvalue(invalue-65536); } else { value=Tvalue(invalue); }
200  }
201  else if (type==FtypeLONG)
202  {
203  union Long {
204  // long int ival;
205  int ival;
206  char byte[4];
207  unsigned char ubyte[4];
208  }; // union Long
209  Long inval;
210  if (is.eof()) throw FoundEOF();
211  is.get(inval.byte[0]);
212  if (is.eof()) throw FoundEOF();
213  is.get(inval.byte[1]);
214  if (is.eof()) throw FoundEOF();
215  is.get(inval.byte[2]);
216  if (is.eof()) throw FoundEOF();
217  is.get(inval.byte[3]);
218  value=inval.ival;
219  }
220  else if (type==FtypeGAINRANGED)
221  {
222  // DATRW_abort("gainranged format ist not supported");
223  union Short {
224  short int ival;
225  char byte[2];
226  unsigned char ubyte[2];
227  }; // union Short
228  Short inval;
229  if (is.eof()) throw FoundEOF();
230  is.get(inval.byte[0]);
231  if (is.eof()) throw FoundEOF();
232  is.get(inval.byte[1]);
233  Short Smantissa=inval;
234  Smantissa.ubyte[0]=(inval.ubyte[0] & 0xFC);
235  int mantissa=Smantissa.ival/4;
236  unsigned short int exponent=(inval.ubyte[0] & 0x03);
237  int shifts=(5-exponent)*3;
238  int factor=(1<<shifts);
239  value=mantissa*factor;
240  /*
241  std::cerr
242  << inval.ival << " "
243  << Smantissa.ival << " "
244  << mantissa << " "
245  << exponent << " "
246  << shifts << " "
247  << factor << " "
248  << value << " " << std::endl;
249  */
250  }
251  else
252  {
253  DATRW_abort("ERROR: unsupported data type!");
254  }
255  return(value);
256  }
257 
258  /*----------------------------------------------------------------------*/
259 
260  using std::endl;
261 
262  void help(std::ostream& os)
263  {
264  os << std::endl;
265  os << "PDAS data reading functions" << std::endl;
266  os << "---------------------------" << std::endl;
267  os << endl;
268  os
269  << "The scaling of the data samples depends on the data format" << endl
270  << "used store original PDAS data files. The sacling is defined" << endl
271  << "in section 4.1.7.2 on pages 4-15 and 4-16 in the PDAS" << endl
272  << "user's guide. The definitions are:" << endl << endl
273  << " 16-bit data format" << endl
274  << " Data is stored in two byte integer two's complement format."
275  << endl
276  << " m: digitized value in counts" << endl
277  << " p: pre-amplifier gain" << endl
278  << " v: signal value in volts" << endl
279  << " v = m / (32768 * p) for high gain inputs" << endl
280  << " v = 20 * m / (32768 * p) for low gain inputs" << endl
281  << " where 32768 = 2**15 = 0x8000" << endl << endl
282  << " 32-bit data format" << endl
283  << " Data is stored in four byte integer two's complement format."
284  << endl
285  << " m: digitized value in counts" << endl
286  << " v: signal value in volts" << endl
287  << " v = m / (2147483648) for high gain inputs" << endl
288  << " v = 20 * m / (2147483648) for low gain inputs" << endl
289  << " where 2147483648 = 2**31 = 0x80000000" << endl << endl
290  << " 14/2 gain ranged format" << endl
291  << " The data is stored in two byte format. The gain code" << endl
292  << " is stored in the two least significant bits of the" << endl
293  << " 16 bits and the digitized value is in the upper 14" << endl
294  << " bits of the 16 bits." << endl
295  << " g: gain code from the lower two bits" << endl
296  << " p: pre-amplifier gain" << endl
297  << " m: two's complement value from the upper 14 bits" << endl
298  << " v: signal value in volts" << endl
299  << " v = m * (8**(5-g)) / ( 268435456 * p) "
300  << "for high gain inputs" << endl
301  << " v = 20 * m * (8**(5-g)) / ( 268435456 * p) "
302  << "for low gain inputs" << endl
303  << " where 268435456 = 2**28 = 0x10000000" << endl << endl;
304  os
305  << "Scaling applied by the reading functions:" << endl
306  << " The PDAS data files contain no information about the" << endl
307  << " pre-amplifier setting and about the input terminals" << endl
308  << " (high or low gain) used. The data can thus not be" << endl
309  << " scaled to volts. The conversion applied when reading is" << endl
310  << " m and g: as defined above" << endl
311  << " i: value returned by integer reading function (iseries)" << endl
312  << " f: value returned by float reading functions "
313  << "(fseries and dseries)" << endl
314  << " 16-bit data (indicated as INT in the FILE_TYPE field)" << endl
315  << " i = m" << endl
316  << " f = m / 32768 " << endl
317  << " 32-bit data (indicated as LONG in the FILE_TYPE field)" << endl
318  << " i = m" << endl
319  << " f = m / 2147483648 " << endl
320  << " 14/2 bit data (indicated as GAINRANGED in the COMMENT field)"
321  << endl
322  << " i = m * (8**(5-g))" << endl
323  << " f = m * (8**(5-g)) / 268435456 " << endl << endl
324  << " Thus if extracting floating point numbers from 16-bit" << endl
325  << " or 14/2-bit data files, you just have to apply" << endl
326  << " v = f / p for high gain inputs and" << endl
327  << " v = 20 * f / p for low gain inputs," << endl
328  << " where p is the pre-amplifier gain" << endl
329  << " to obtain the signal in volts." << endl << endl
330  << " For 32-bit data its even easier. You obtain the" << endl
331  << " signal's voltage by" << endl
332  << " v = f for high gain inputs and" << endl
333  << " v = 20 * f for low gain inputs." << endl;
334  os << endl;
335  }
336 
337  } // namespace pdas
338 
339 } // namespace datrw
340 
341 /* ----- END OF pdasread.cc ----- */
#define DATRW_assert(C, M)
Check an assertion and report by throwing an exception.
Definition: error.h:92
std::string vertunits
Definition: pdasread.h:70
std::string token
Definition: pdasread.h:64
std::string value
Definition: pdasread.h:64
std::string interval
Definition: pdasread.h:69
std::string version
Definition: pdasread.h:69
Etype
define pdas data types
Definition: pdasflags.h:47
exception class declaration for libdatrwxx (prototypes)
const char *const data
keywords for consistency checks
std::string signal
Definition: pdasread.h:69
Tvalue readsample(std::istream &is, const Etype &type)
function to read one sample
Definition: pdasread.cc:182
std::string time
Definition: pdasread.h:69
int Tvalue
Definition: pdasread.h:75
Root namespace of library.
Definition: aalibdatrwxx.cc:16
std::vector< std::string > lines
Definition: pdasread.h:72
void readdata(std::istream &is, Tdata &data, const Etype &type)
Definition: pdasread.cc:150
std::string dataset
Definition: pdasread.h:69
HeaderLine readline(std::istream &is, const bool &verbose)
function to read the file header line
Definition: pdasread.cc:55
struct to hold content of header line
Definition: pdasread.h:63
#define DATRW_abort(M)
Abort and give a message.
Definition: error.h:101
struct to hold complete header
Definition: pdasread.h:68
std::string line
Definition: pdasread.h:64
void help(std::ostream &os)
function to print online help
Definition: pdasread.cc:262
Header readheader(std::istream &is, const bool &verbose)
function to read the file header
Definition: pdasread.cc:82
std::string date
Definition: pdasread.h:69
std::string horzunits
Definition: pdasread.h:70
std::string comment
Definition: pdasread.h:70
int countdata(std::istream &is, const Etype &type)
function to skip the file data but count the samples
Definition: pdasread.cc:166
std::vector< Tvalue > Tdata
Definition: pdasread.h:76