sffxx.cc 17.8 KB
Newer Older
thomas.forbriger's avatar
thomas.forbriger committed
1
2
3
4
5
/*! \file sffxx.cc
 * \brief SFF library (implementation)
 * 
 * ----------------------------------------------------------------------------
 * 
6
 * $Id: sffxx.cc,v 1.21 2006-06-29 07:11:41 tforb Exp $
thomas.forbriger's avatar
thomas.forbriger committed
7
8
9
10
 * \author Thomas Forbriger
 * \date 21/12/2003
 * 
 * SFF library (implementation)
thomas.forbriger's avatar
thomas.forbriger committed
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 *
 * ----
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. 
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * ----
thomas.forbriger's avatar
thomas.forbriger committed
27
28
29
30
31
 * 
 * Copyright (c) 2003 by Thomas Forbriger (BFO Schiltach) 
 * 
 * REVISIONS and CHANGES 
 *  - 21/12/2003   V1.0   Thomas Forbriger
32
33
 *  - 23/02/2004   V1.1   changed DAST and STAT reading code
 *                        there are not necessarily any flag characters
34
35
36
 *  - 07/04/2004   V1.2  
 *                        - provide debug output
 *                        - correct reading of FREE block
thomas.forbriger's avatar
thomas.forbriger committed
37
 *  - 23/12/2004   V1.3   added full block append to FREE
38
 *  - 26/01/2004   V1.4   SRCE reading and INFO reading was not satisfactory
thomas.forbriger's avatar
thomas.forbriger committed
39
40
41
42
43
 *  - 15/03/2005   V1.5   
 *                        - made SRCE date and time reading more robust against
 *                          whitespace 
 *                        - added some debug output
 *                        - check SFF file type version to be at least 1.10
thomas.forbriger's avatar
thomas.forbriger committed
44
45
 *  - 27/03/2006   V1.6   allow reading of V1.09 files
 *                        introduced sff::STAT::decode_libversion
46
 *  - 27/06/2006   V1.7   added INFO comparison
thomas.forbriger's avatar
thomas.forbriger committed
47
48
49
50
 * 
 * ============================================================================
 */
#define TF_SFFXX_CC_VERSION \
51
  "TF_SFFXX_CC   V1.7"
thomas.forbriger's avatar
thomas.forbriger committed
52
#define TF_SFFXX_CC_CVSID \
53
  "$Id: sffxx.cc,v 1.21 2006-06-29 07:11:41 tforb Exp $"
thomas.forbriger's avatar
thomas.forbriger committed
54

55
#include<sstream>
thomas.forbriger's avatar
thomas.forbriger committed
56
#include <sffxx.h>
thomas.forbriger's avatar
thomas.forbriger committed
57
#include <gsexx.h>
thomas.forbriger's avatar
thomas.forbriger committed
58
59
60

namespace sff {

61
62
63
64
65
66
67
  namespace helper {
    //! Check GSE identifier at beginning of line.
    template<class C>
    bool IDmatch(const std::string& line)
    { return(line.substr(0,4)==std::string(C::LINEID)); }
  } // namespace helper

thomas.forbriger's avatar
thomas.forbriger committed
68
  //! Fortran library version (to ensure compatibility)
thomas.forbriger's avatar
thomas.forbriger committed
69
  //! library writes version 1.10
thomas.forbriger's avatar
thomas.forbriger committed
70
  const double STAT::libversion=1.10;
thomas.forbriger's avatar
thomas.forbriger committed
71
72
  //! library decodes version 1.09
  const double STAT::decode_libversion=1.09;
thomas.forbriger's avatar
thomas.forbriger committed
73
74
75
76
77
78
  const char* const STAT::LINEID="STAT";
  const char* const FREE::LINEID="FREE";
  const char* const SRCE::LINEID="SRCE";
  const char* const DAST::LINEID="DAST";
  const char* const INFO::LINEID="INFO";

thomas.forbriger's avatar
thomas.forbriger committed
79
80
  /*----------------------------------------------------------------------*/

thomas.forbriger's avatar
thomas.forbriger committed
81
82
83
84
85
86
  char coosysID(const Ecoosys& csid)
  {
    char retval;
    if (csid == CS_cartesian) retval='C';
    else if (csid == CS_spherical) retval='S';
    else throw
thomas.forbriger's avatar
thomas.forbriger committed
87
      GSE2::Terror("ERROR (sff::coosysID): library inconsistency!");
thomas.forbriger's avatar
thomas.forbriger committed
88
89
90
91
92
    return(retval);
  } // coosysID

  Ecoosys coosysID(const char& csid)
  {
thomas.forbriger's avatar
thomas.forbriger committed
93
94
95
    Ecoosys retval;
    if (csid=='C') { retval=CS_cartesian; }
    else if (csid=='S') { retval=CS_spherical; }
thomas.forbriger's avatar
thomas.forbriger committed
96
    else throw
thomas.forbriger's avatar
thomas.forbriger committed
97
98
      GSE2::Terror("ERROR (sff::coosysID): unknown coordinate system key!");
    return(retval);
thomas.forbriger's avatar
thomas.forbriger committed
99
100
  } // coosysID

thomas.forbriger's avatar
thomas.forbriger committed
101
102
103
104
105
106
107
/*======================================================================*/
// SFF structs
// -----------
//
// STAT
// ----

108
109
110
111
112
113
  /*! \struct STAT
   *
   * The STAT line is the first line in the file header.
   * It contains the version of the library that wrote the file,
   * a timestamp and flags indicating the presence of optional elements lika a
   * FREE block or an SRCE line.
thomas.forbriger's avatar
thomas.forbriger committed
114
115
   *
   * 27/3/2006: Allow reading of version 1.09 files.
116
   */
thomas.forbriger's avatar
thomas.forbriger committed
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
  STAT::STAT(): hasfree(false), hassrce(false) 
  { setstamp(libtime::now()); }

  void STAT::setstamp(const libtime::TAbsoluteTime& date) const
  {
    char stamp[14];
    int yeardigits, century;
    century=int(date.year()/100);
    yeardigits=date.year()-100*century;
    sprintf(stamp, "%2.2i%2.2li%2.2li.%2.2li%2.2li%2.2li",
            yeardigits, date.month(), date.day(),
            date.hour(), date.minute(), date.second());
    timestamp=std::string(stamp);
  }

  std::string STAT::line() const
  {
    this->setstamp(libtime::now());
    char charline[40];
    std::string code("");
    if (this->hasfree) { code.append("F"); }
    if (this->hassrce) { code.append("S"); }
thomas.forbriger's avatar
thomas.forbriger committed
139
    sprintf(charline, "%-4s  %6.2f %-13s %-10s\n",
thomas.forbriger's avatar
thomas.forbriger committed
140
141
142
143
144
145
146
147
            STAT::LINEID, 
            STAT::libversion,
            timestamp.c_str(),
            code.c_str());
    std::string retval(charline);
    return(retval);
  } // STAT::line()

thomas.forbriger's avatar
thomas.forbriger committed
148
  void STAT::read(std::istream& fis, const bool& debug)
149
  {
thomas.forbriger's avatar
thomas.forbriger committed
150
    if (debug) { std::cerr << "DEBUG (STAT::read):" << std::endl; }
151
152
153
    std::string theline;
    std::getline(fis, theline);
    std::istringstream is(theline);
thomas.forbriger's avatar
thomas.forbriger committed
154
    if (debug) { std::cerr << theline << std::endl; }
155
156
    std::string lineID;
    is >> lineID;
thomas.forbriger's avatar
thomas.forbriger committed
157
    if (debug) { std::cerr << lineID << std::endl; }
158
159
160
161
162
163
164
165
166
167
    if (!helper::IDmatch<STAT>(lineID)) throw
       GSE2::Terror("ERROR (STAT::read): missing STAT ID!");

    double inlibversion;
    is >> inlibversion;
    if (inlibversion>STAT::libversion) 
    { 
      throw 
        GSE2::Terror("ERROR (STAT::read): file library version too large!"); 
    }
thomas.forbriger's avatar
thomas.forbriger committed
168
    if (inlibversion<STAT::decode_libversion) 
thomas.forbriger's avatar
thomas.forbriger committed
169
170
171
172
    { 
      throw 
        GSE2::Terror("ERROR (STAT::read): incompatible SFF version!"); 
    }
173
174
175
176
177
178
179

    is >> timestamp;

    std::string code;
    is >> code;
    this->hasfree=(code.find('F')!=std::string::npos);
    this->hassrce=(code.find('S')!=std::string::npos);
thomas.forbriger's avatar
thomas.forbriger committed
180
181
182
183
184
185
186
187
    if (debug)
    {
      if (this->hasfree) 
      { std::cerr << "DEBUG (STAT::read): has FREE block" << std::endl; }
      if (this->hassrce) 
      { std::cerr << "DEBUG (STAT::read): has SRCE line" << std::endl; }
      std::cerr << "DEBUG (STAT::read): finished" << std::endl;
    }
188
189
  } // STAT::read

thomas.forbriger's avatar
thomas.forbriger committed
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/*----------------------------------------------------------------------*/
// SRCE
// ----

  SRCE::SRCE(): 
    type("NSP"), date(libtime::now()),
    cs(CS_cartesian), cx(0.), cy(0.), cz(0.) { }

  std::string SRCE::line() const
  {
    char charline[95];
    int yeardigits, century;
    century=int(date.year()/100);
    yeardigits=date.year()-100*century;
thomas.forbriger's avatar
thomas.forbriger committed
204
    sprintf(charline, "%-4s %-20s %1c %15.6f%15.6f%15.6f "
thomas.forbriger's avatar
thomas.forbriger committed
205
206
207
208
209
210
211
212
213
214
            "%2.2i%2.2li%2.2li %2.2li%2.2li%2.2li.%3.3li\n",
            SRCE::LINEID, 
            type.c_str(), 
            coosysID(cs), cx, cy, cz,
            yeardigits, date.month(), date.day(),
            date.hour(), date.minute(), date.second(), date.milsec());
    std::string retval(charline);
    return(retval);
  } // SRCE::line()

thomas.forbriger's avatar
thomas.forbriger committed
215
  void SRCE::read(std::istream& fis, const bool& debug)
216
  {
217
218
219
    std::string theline;
    std::getline(fis, theline);
    std::istringstream is(theline);
220
221
222
223
224
225
226
    std::string lineID;
    is >> lineID;
    if (!helper::IDmatch<SRCE>(lineID)) throw
       GSE2::Terror("ERROR (SRCE::read): missing SRCE ID!");

    char intype[21];
    is.get(intype, 21);
227
    type=&intype[1];
thomas.forbriger's avatar
thomas.forbriger committed
228
229
    if (debug)
    { std::cerr << "DEBUG (SRCE::read): type: " << type << std::endl; }
230
231
232
233
234
235
236

    char cschar;
    is >> cschar;
    cs=coosysID(cschar);
    is >> cx;
    is >> cy;
    is >> cz;
thomas.forbriger's avatar
thomas.forbriger committed
237
238
239
240
241
    if (debug)
    { 
      std::cerr << "DEBUG (SRCE::read): cs,cx,cy,cz: " 
        << cs << "," << cx << "," << cy << "," << cz << std::endl; 
    }
242
243

    std::string datestring,timestring;
thomas.forbriger's avatar
thomas.forbriger committed
244
245
246
247
248
249
250
251
252
253
254
255
256
    char indatestring[8];
    char intimestring[11];
    is.get(indatestring, 8);
    is.get(intimestring, 11);
    datestring=&indatestring[1];
    timestring=&intimestring[1];
    if (debug)
    { 
      std::cerr << "DEBUG (SRCE::read): datestring: " 
        << datestring << std::endl;
      std::cerr << "DEBUG (SRCE::read): timestring: " 
        << timestring << std::endl;
    }
257
    std::string fulldate("");
258
    fulldate+=datestring.substr(0,2);
259
    fulldate+="/";
260
    fulldate+=datestring.substr(2,2);
261
    fulldate+="/";
262
    fulldate+=datestring.substr(4,2);
263
    fulldate+=" ";
264
    fulldate+=timestring.substr(0,2);
265
    fulldate+=":";
266
    fulldate+=timestring.substr(2,2);
267
    fulldate+=":";
268
    fulldate+=timestring.substr(4,6);
thomas.forbriger's avatar
thomas.forbriger committed
269
270
271
    if (debug)
    { 
      std::cerr << "DEBUG (SRCE::read): convert string: " 
thomas.forbriger's avatar
thomas.forbriger committed
272
        << fulldate << std::endl; 
thomas.forbriger's avatar
thomas.forbriger committed
273
    }
274
    date=libtime::TAbsoluteTime(fulldate);
thomas.forbriger's avatar
thomas.forbriger committed
275
276
277
278
279
    if (debug)
    { 
      std::cerr << "DEBUG (SRCE::read): time: " 
        << date.timestring() << std::endl; 
    }
280
281
  } // SRCE::read

thomas.forbriger's avatar
thomas.forbriger committed
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
/*----------------------------------------------------------------------*/
// DAST
// ----

  DAST::DAST(): 
    nchar(-1), ampfac(1.), hasfree(false), 
    hasinfo(false), last(false) { }

  std::string DAST::line() const
  {
    char charline[50];
    std::string code("");
    if (this->hasfree) { code.append("F"); }
    if (this->hasinfo) { code.append("I"); }
    if (!this->last) { code.append("D"); }
297
    // write -1 to nchar field in any case
thomas.forbriger's avatar
thomas.forbriger committed
298
    sprintf(charline, "%-4s  %10i %16.6E %-10s\n",
thomas.forbriger's avatar
thomas.forbriger committed
299
            DAST::LINEID, 
300
            -1, ampfac, code.c_str());
thomas.forbriger's avatar
thomas.forbriger committed
301
302
303
304
    std::string retval(charline);
    return(retval);
  } // DAST::line()

305
  void DAST::read(std::istream& fis, const bool& debug)
306
  {
307
308
309
310
311
312
313
314
    if (debug)
    {
      std::cerr << "DEBUG (DAST::read):" << std::endl;
    }
    std::string theline;
    std::getline(fis, theline);
    std::istringstream is(theline);
    if (debug) { std::cerr << theline << std::endl; }
315
316
    std::string lineID;
    is >> lineID;
317
    if (debug) { std::cerr << lineID << std::endl; }
318
319
320
321
322
323
    if (!helper::IDmatch<DAST>(lineID)) throw
       GSE2::Terror("ERROR (DAST::read): missing DAST ID!");
    is >> nchar;
    is >> ampfac;
    std::string code;
    is >> code;
324
325
326
327
328
    if (debug)
    {
      std::cerr << "DEBUG (DAST): read nchar=" << nchar
        << " ampfac=" << ampfac << " code=" << code << std::endl;
    }
329
330
331
332
333
    this->hasinfo=(code.find('I')!=std::string::npos);
    this->hasfree=(code.find('F')!=std::string::npos);
    this->last=(code.find('D')==std::string::npos);
  } // DAST::read

thomas.forbriger's avatar
thomas.forbriger committed
334
335
336
337
338
339
340
341
/*----------------------------------------------------------------------*/
// FREE
// ----

    FREE::FREE() { lines.clear(); }

    void FREE::write(std::ostream& os) const
    {
thomas.forbriger's avatar
thomas.forbriger committed
342
      os << FREE::LINEID << " " << std::endl;
thomas.forbriger's avatar
thomas.forbriger committed
343
344
345
      for(Tlines::const_iterator I=lines.begin();
          I != lines.end(); I++)
      { os << *I << std::endl; }
thomas.forbriger's avatar
thomas.forbriger committed
346
      os << FREE::LINEID << " " << std::endl;
thomas.forbriger's avatar
thomas.forbriger committed
347
348
    } // FREE::write

349
  void FREE::read(std::istream& is, const bool& debug)
350
351
  {
    std::string lineID;
352
    // getline(is,lineID);
353
    is >> lineID;
354
355
356
    if (debug) 
    { std::cerr << "DEBUG (FREE): lineID=" << lineID << std::endl; }
    if (!helper::IDmatch<FREE>(lineID.substr(0,4))) throw
357
       GSE2::Terror("ERROR (FREE::read): missing FREE ID!");
358
    lines.clear();
359
360
361
    is.ignore(10,'\n');
    getline(is,lineID);
    while (!helper::IDmatch<FREE>(lineID.substr(0,4)))
362
    {
363
364
      lines.push_back(lineID);
      getline(is,lineID);
365
366
367
    }
  } // FREE::read

thomas.forbriger's avatar
thomas.forbriger committed
368
  void FREE::append(const Tlines& newlines)
thomas.forbriger's avatar
thomas.forbriger committed
369
  {
thomas.forbriger's avatar
thomas.forbriger committed
370
371
    Tlines::const_iterator I(newlines.begin());
    while (I != newlines.end())
thomas.forbriger's avatar
thomas.forbriger committed
372
373
374
375
376
377
    {
      this->append(*I);
      ++I;
    }
  } // void FREE::append(const Tlines& lines)

thomas.forbriger's avatar
thomas.forbriger committed
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
/*----------------------------------------------------------------------*/
// WID2
// ----

  WID2::WID2():
    date(libtime::now()), station("NSP"), channel("NSP"), auxid("NSP"),
    nsamples(-1), dt(-1.), calib(-1.), calper(-1.), instype("NSP"),
    hang(-1.),vang(-1.) { }

  std::string WID2::line() const
  {
    GSE2::waveform::TWID2 wid2line;
    wid2line.Fyear=date.year();
    wid2line.Fmonth=date.month();
    wid2line.Fday=date.day();
    wid2line.Fhour=date.hour();
    wid2line.Fminute=date.minute();
    wid2line.Fseconds=double(date.second())+
      1.e-3*double(date.milsec()+1.e-3*double(date.micsec()));
    wid2line.Fstation=station;
    wid2line.Fchannel=channel;
    wid2line.Fauxid=auxid;
    wid2line.Fsamps=nsamples;
    wid2line.Fsamprate=1./dt;
    wid2line.Fcalib=calib;
    wid2line.Fcalper=calper;
    wid2line.Finstype=instype;
    wid2line.Fhang=hang;
    wid2line.Fvang=vang;
    return(wid2line.line());
  } // WID2::line()

410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
  void WID2::read(std::istream& is)
  {
    GSE2::waveform::TWID2 wid2line;
    wid2line.read(is);
    int second=int(wid2line.Fseconds);
    int milsec=int(1000*(wid2line.Fseconds-double(second)));
    date=libtime::TAbsoluteTime(wid2line.Fyear,
                                wid2line.Fmonth,
                                wid2line.Fday,
                                wid2line.Fhour,
                                wid2line.Fminute,
                                second, milsec);
    this->station=wid2line.Fstation;
    this->channel=wid2line.Fchannel;
    this->auxid=wid2line.Fauxid;
    this->nsamples=wid2line.Fsamps;
    this->dt=1./wid2line.Fsamprate;
    this->calib=wid2line.Fcalib;
    this->calper=wid2line.Fcalper;
    this->instype=wid2line.Finstype;
    this->hang=wid2line.Fhang;
    this->vang=wid2line.Fvang;
  } // WID2::read

thomas.forbriger's avatar
thomas.forbriger committed
434
435
436
437
438
439
440
441
442
443
/*----------------------------------------------------------------------*/
// INFO
// ----

  INFO::INFO():
    cs(CS_cartesian), cx(0.), cy(0.), cz(0.), nstacks(0) { }

  std::string INFO::line() const
  {
    char charline[60];
thomas.forbriger's avatar
thomas.forbriger committed
444
    sprintf(charline, "%-4s %1c %15.6f%15.6f%15.6f %4i\n",
thomas.forbriger's avatar
thomas.forbriger committed
445
446
447
448
449
450
            INFO::LINEID, 
            coosysID(cs), cx, cy, cz, nstacks);
    std::string retval(charline);
    return(retval);
  } // INFO::line()

451
  void INFO::read(std::istream& fis)
452
  {
453
454
455
    std::string theline;
    std::getline(fis, theline);
    std::istringstream is(theline);
456
457
    std::string lineID;
    is >> lineID;
458
459
    if (!helper::IDmatch<INFO>(lineID)) throw
       GSE2::Terror("ERROR (INFO::read): missing INFO ID!");
460
461
462
463
464
465
466
467
468
    char cschar;
    is >> cschar;
    cs=coosysID(cschar);
    is >> cx;
    is >> cy;
    is >> cz;
    is >> nstacks;
  } // INFO::read

469
470
471
472
473
474
475
476
477
  bool INFO::operator==(const INFO& info) const
  {
    return ((info.cs==this->cs) |
            (info.cx==this->cx) |
            (info.cy==this->cy) |
            (info.cz==this->cz) |
            (info.nstacks==this->nstacks));
  }

thomas.forbriger's avatar
thomas.forbriger committed
478
479
480
481
482
483
484
485
486
487
488
/*----------------------------------------------------------------------*/
// FileHeader
// ----------

  void FileHeader::write(std::ostream& os) const
  {
    os << Mstat.line();
    if (Mstat.hasfree) { Mfree.write(os); }
    if (Mstat.hassrce) { os << Msrce.line(); }
  }

thomas.forbriger's avatar
thomas.forbriger committed
489
  void FileHeader::read(std::istream& is, const bool& debug)
490
  {
thomas.forbriger's avatar
thomas.forbriger committed
491
    Mstat.read(is, debug);
thomas.forbriger's avatar
thomas.forbriger committed
492
493
494
495
496
497
498
499
500
501
502
503
504
505
    if (Mstat.hasfree) 
    { 
      Mfree.read(is); 
      if (debug)
      { std::cerr << "DEBUG (FileHeader::read): file FREE read" << std::endl; }
    }
    if (Mstat.hassrce) 
    { 
      Msrce.read(is, debug); 
      if (debug)
      { std::cerr << "DEBUG (FileHeader::read): SRCE line read" << std::endl; }
    }
    if (debug)
    { std::cerr << "DEBUG (FileHeader::read): finished" << std::endl; }
506
507
  }

thomas.forbriger's avatar
thomas.forbriger committed
508
509
510
511
/*----------------------------------------------------------------------*/
// TraceHeader
// -----------

thomas.forbriger's avatar
thomas.forbriger committed
512
  void TraceHeader::writeheader(std::ostream& os) const
thomas.forbriger's avatar
thomas.forbriger committed
513
  {
514
    if (Mdebug) { std::cerr << "DEBUG: write DAST line" << std::endl; } 
thomas.forbriger's avatar
thomas.forbriger committed
515
    os << Mdast.line();
516
    if (Mdebug) { std::cerr << "DEBUG: write WID2 line" << std::endl; } 
thomas.forbriger's avatar
thomas.forbriger committed
517
    os << Mwid2.line();
thomas.forbriger's avatar
thomas.forbriger committed
518
519
520
521
  }

  void TraceHeader::writetrailer(std::ostream& os) const
  {
522
523
524
525
526
527
528
529
530
531
    if (Mdast.hasfree) 
    {
      if (Mdebug) { std::cerr << "DEBUG: write FREE block" << std::endl; } 
      Mfree.write(os);
    }
    if (Mdast.hasinfo) 
    {
      if (Mdebug) { std::cerr << "DEBUG: write INFO line" << std::endl; } 
      os << Minfo.line();
    }
thomas.forbriger's avatar
thomas.forbriger committed
532
533
  }

534
535
  void TraceHeader::readheader(std::istream& is) 
  {
536
537
538
    if (Mdebug) { std::cerr << "DEBUG: read DAST line" << std::endl; } 
    Mdast.read(is,Mdebug);
    if (Mdebug) { std::cerr << "DEBUG: read WID2 line" << std::endl; } 
539
540
541
542
543
    Mwid2.read(is);
  }

  void TraceHeader::readtrailer(std::istream& is) 
  {
544
545
546
547
548
549
550
551
552
553
554
555
    if (Mdebug) { std::cerr << "DEBUG: read trace trailer" << std::endl; } 
    if (Mdast.hasfree) 
    {
      if (Mdebug) { std::cerr << "DEBUG: read FREE block" << std::endl; } 
      Mfree.read(is, Mdebug); 
      if (Mdebug) { Mfree.write(std::cerr); }
    }
    if (Mdast.hasinfo) 
    {
      if (Mdebug) { std::cerr << "DEBUG: read INFO line" << std::endl; } 
      Minfo.read(is);
    }
556
557
  }

thomas.forbriger's avatar
thomas.forbriger committed
558
559
560
561
562
563
564
565
/*----------------------------------------------------------------------*/
// WaveformNormalizer
// ------------------

  const int WaveformNormalizer::limit=0x800000;

  WaveformNormalizer::WaveformNormalizer(const Enormmode& nm, 
                                         const double& maxval):
thomas.forbriger's avatar
thomas.forbriger committed
566
    Mmaxval(maxval), Mnorm(nm)
thomas.forbriger's avatar
thomas.forbriger committed
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
  {
    if (Mnorm == NM_one) 
    { 
      Mampfac=1.; 
      Mscale=false;
      if (Mmaxval > double(WaveformNormalizer::limit)) throw
        GSE2::Terror("ERROR (sff::WaveformNormalizer::scan): "
                     "dynamic range to large for non-normalizing mode");
    }
    else if (Mnorm == NM_ifneeded)
    { 
      Mampfac=1.;
      Mscale=false;
      if (Mmaxval > double(WaveformNormalizer::limit))
      {
        Mampfac=Mmaxval/double(WaveformNormalizer::limit); 
        Mscale=true;
      }
    }
    else if (Mnorm == NM_maxdyn)
    { 
      Mampfac=Mmaxval/double(WaveformNormalizer::limit); 
      Mscale=true;
    }
    else throw
      GSE2::Terror("ERROR (sff::WaveformNormalizer::scan): "
                   "library inconsistency!");
  }

596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
/*----------------------------------------------------------------------*/
// SkipWaveform
// ------------

    void SkipWaveform::read(std::istream& is) 
    {
      Mheader.readheader(is);;
      int nsamples=Mheader.wid2().nsamples;
      GSE2::waveform::TDAT2readCM6 freader(nsamples);
      int idata;
      for (int i=0; i<nsamples; i++)
      { idata=freader(is); }
      Mheader.readtrailer(is);
      Mvalid=true;
    } // SkipWaveform::read

thomas.forbriger's avatar
thomas.forbriger committed
612
613
614
} // namespace sff

/* ----- END OF sffxx.cc ----- */