sffxx.h 18.8 KB
Newer Older
thomas.forbriger's avatar
thomas.forbriger committed
1
2
3
4
5
/*! \file sffxx.h
 * \brief SFF library (prototypes)
 * 
 * ----------------------------------------------------------------------------
 * 
thomas.forbriger's avatar
thomas.forbriger committed
6
 * $Id: sffxx.h,v 1.34 2007-06-26 17:02:29 tforb Exp $
thomas.forbriger's avatar
thomas.forbriger committed
7
8
9
10
 * \author Thomas Forbriger
 * \date 21/12/2003
 * 
 * SFF library (prototypes)
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
34
 *  - 23/12/2003   V1.1
 *                         - first version writing SFF successfully
 *                         - starting with reading code
35
36
37
 *  - 11/01/2004   V1.2  
 *                         - FileHeader modification functions
 *                         - TraceHeader modification functions
thomas.forbriger's avatar
thomas.forbriger committed
38
 *  - 23/12/2004   V1.3    added full block append to FREE
thomas.forbriger's avatar
thomas.forbriger committed
39
 *  - 27/03/2006   V1.4    introduced sff::STAT::decode_libversion
40
 *  - 27/06/2006   V1.5   added INFO comparison
thomas.forbriger's avatar
thomas.forbriger committed
41
 *  - 02/03/2007   V1.6   added offset calculation
thomas.forbriger's avatar
thomas.forbriger committed
42
 *  - 26/06/2007   V1.7   added verbose output
thomas.forbriger's avatar
thomas.forbriger committed
43
44
45
46
47
48
49
50
 * 
 * ============================================================================
 */

// include guard
#ifndef TF_SFFXX_H_VERSION

#define TF_SFFXX_H_VERSION \
thomas.forbriger's avatar
thomas.forbriger committed
51
  "TF_SFFXX_H   V1.7"
thomas.forbriger's avatar
thomas.forbriger committed
52
#define TF_SFFXX_H_CVSID \
thomas.forbriger's avatar
thomas.forbriger committed
53
  "$Id: sffxx.h,v 1.34 2007-06-26 17:02:29 tforb Exp $"
thomas.forbriger's avatar
thomas.forbriger committed
54
55

#include<string>
thomas.forbriger's avatar
thomas.forbriger committed
56
#include<cmath>
thomas.forbriger's avatar
thomas.forbriger committed
57
58
59
#include<list>
#include<iostream>
#include<libtime++.h>
thomas.forbriger's avatar
thomas.forbriger committed
60
#include<aff/iterator.h>
61
#include<tfxx/commandline.h>
thomas.forbriger's avatar
thomas.forbriger committed
62
#include<gsexx.h>
thomas.forbriger's avatar
thomas.forbriger committed
63
64
65
66
67

/*! \brief all SFF modules
 */
namespace sff {

68
69
70
71
72
73
74
75
76
77
/*======================================================================*/
// basic error handling
// --------------------

  class Terror: public GSE2::Terror 
  {
    public:
      Terror(char* message): GSE2::Terror(message) { }
  }; // class Terror

thomas.forbriger's avatar
thomas.forbriger committed
78
79
80
81
/*======================================================================*/
// enum
// ----
  
thomas.forbriger's avatar
thomas.forbriger committed
82
83
84
85
86
87
  //! valid coordinate systems
  enum Ecoosys {
    CS_cartesian,
    CS_spherical
  }; // enum Ecoosys

thomas.forbriger's avatar
thomas.forbriger committed
88
89
90
91
92
93
  char coosysID(const Ecoosys& csid);
  Ecoosys coosysID(const char& csid);

/*----------------------------------------------------------------------*/

  enum Enormmode {
thomas.forbriger's avatar
thomas.forbriger committed
94
95
    NM_one,       //!< do not scale
    NM_maxdyn,    //!< scale for maximum dynamic range
96
    NM_ifneeded   //!< scale if largest amplitude larger than limit
thomas.forbriger's avatar
thomas.forbriger committed
97
98
99
100
101
102
  }; // enum Enormmode

/*======================================================================*/
// SFF structs
// -----------

thomas.forbriger's avatar
thomas.forbriger committed
103
104
  struct STAT {
    static const double libversion;
thomas.forbriger's avatar
thomas.forbriger committed
105
    static const double decode_libversion;
thomas.forbriger's avatar
thomas.forbriger committed
106
    static const char* const LINEID;
thomas.forbriger's avatar
thomas.forbriger committed
107
    STAT();
thomas.forbriger's avatar
thomas.forbriger committed
108
    STAT(std::istream& is, const bool& debug=false) { read(is, debug); }
thomas.forbriger's avatar
thomas.forbriger committed
109
    std::string line() const;
thomas.forbriger's avatar
thomas.forbriger committed
110
    void read(std::istream& is, const bool& debug=false);
thomas.forbriger's avatar
thomas.forbriger committed
111
112
113
114
115
    void setstamp(const libtime::TAbsoluteTime& date) const;
    public:
      mutable std::string timestamp;
      bool hasfree;
      bool hassrce;
thomas.forbriger's avatar
thomas.forbriger committed
116
117
118
  }; // struct STAT

  struct FREE {
thomas.forbriger's avatar
thomas.forbriger committed
119
    typedef std::list<std::string> Tlines;
thomas.forbriger's avatar
thomas.forbriger committed
120
    static const char* const LINEID;
thomas.forbriger's avatar
thomas.forbriger committed
121
    FREE();
122
    FREE(std::istream& is) { read(is); }
thomas.forbriger's avatar
thomas.forbriger committed
123
    void write(std::ostream& os) const;
124
    void read(std::istream& is, const bool& debug=false);
125
    void append(const std::string& line) { lines.push_back(line); }
thomas.forbriger's avatar
thomas.forbriger committed
126
    void append(const Tlines& newlines);
thomas.forbriger's avatar
thomas.forbriger committed
127
    void append(const FREE& free) { this->append(free.lines); }
thomas.forbriger's avatar
thomas.forbriger committed
128
    Tlines lines;
thomas.forbriger's avatar
thomas.forbriger committed
129
130
131
132
  }; // struct FREE

  struct SRCE {
    static const char* const LINEID;
thomas.forbriger's avatar
thomas.forbriger committed
133
    SRCE();
134
    SRCE(std::istream& is) { read(is); }
thomas.forbriger's avatar
thomas.forbriger committed
135
    std::string line() const;
thomas.forbriger's avatar
thomas.forbriger committed
136
    void read(std::istream& is, const bool& debug=false);
thomas.forbriger's avatar
thomas.forbriger committed
137
138
139
140
141
    public:
      std::string type;
      libtime::TAbsoluteTime date;        //!< time of source
      Ecoosys cs;
      double cx, cy, cz;
thomas.forbriger's avatar
thomas.forbriger committed
142
143
144
145
  }; // struct SRCE

  struct DAST {
    static const char* const LINEID;
thomas.forbriger's avatar
thomas.forbriger committed
146
    DAST();
147
    DAST(std::istream& is) { read(is); }
thomas.forbriger's avatar
thomas.forbriger committed
148
    std::string line() const;
149
    void read(std::istream& is, const bool& debug=false);
thomas.forbriger's avatar
thomas.forbriger committed
150
151
152
153
154
155
    public:
      int nchar;
      double ampfac;
      bool hasfree;
      bool hasinfo;
      bool last;
thomas.forbriger's avatar
thomas.forbriger committed
156
157
158
159
  }; // struct DAST

  struct INFO {
    static const char* const LINEID;
thomas.forbriger's avatar
thomas.forbriger committed
160
    INFO();
161
    INFO(std::istream& is) { read(is); }
thomas.forbriger's avatar
thomas.forbriger committed
162
    std::string line() const;
163
    void read(std::istream& is);
164
    bool operator==(const INFO& info) const;
thomas.forbriger's avatar
thomas.forbriger committed
165
166
167
168
    public:
      Ecoosys cs;
      double cx, cy, cz;
      int nstacks;
thomas.forbriger's avatar
thomas.forbriger committed
169
170
  }; // struct INFO

thomas.forbriger's avatar
thomas.forbriger committed
171
172
173
174
175
  /*! \brief Waveform Header
   * 
   */
  struct WID2 {
    WID2();
176
    WID2(std::istream& is) { read(is); }
thomas.forbriger's avatar
thomas.forbriger committed
177
    std::string line() const;
178
    void read(std::istream& is);
thomas.forbriger's avatar
thomas.forbriger committed
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
    public:
      libtime::TAbsoluteTime date;       //!< time of first sample
      std::string           station;     //!< Station code
      std::string           channel;     //!< FDSN channel code
      std::string           auxid;       //!< Auxiliary identification code
      int                   nsamples;    //!< number of samples
      double                dt;          //!< sampling interval (sec)
      double                calib;       //!< calibration factor
      double                calper;      //!< calibration reference period
      std::string           instype;     //!< instrument type
      double                hang;        //!< horizontal orientation
      double                vang;        //!< veritcal orientation
  }; // struct WID2

/*======================================================================*/
// file I/O classes
// ----------------

  class FileHeader {
    public:
thomas.forbriger's avatar
thomas.forbriger committed
199
200
201
202
203
204
205
206
      FileHeader()
      { Mstat.hasfree=false; Mstat.hassrce=false; }
      FileHeader(const FREE& free): 
        Mfree(free) 
      { Mstat.hasfree=true; Mstat.hassrce=false; }
      FileHeader(const SRCE& srce): 
        Msrce(srce)
      { Mstat.hasfree=false; Mstat.hassrce=true; }
thomas.forbriger's avatar
thomas.forbriger committed
207
      FileHeader(const SRCE& srce, const FREE& free):
thomas.forbriger's avatar
thomas.forbriger committed
208
209
        Mfree(free), Msrce(srce)
      { Mstat.hasfree=true; Mstat.hassrce=true; }
thomas.forbriger's avatar
thomas.forbriger committed
210
211
      FileHeader(std::istream& is, const bool& debug=false) 
      { read(is, debug); }
thomas.forbriger's avatar
thomas.forbriger committed
212
      void write(std::ostream&) const;
thomas.forbriger's avatar
thomas.forbriger committed
213
      void read(std::istream&, const bool& debug=false);
214
215
216
217
218
      const STAT& stat() const { return(Mstat); }
      const FREE& free() const { return(Mfree); }
      const SRCE& srce() const { return(Msrce); }
      const bool& hassrce() const { return(Mstat.hassrce); }
      const bool& hasfree() const { return(Mstat.hasfree); }
219
220
      void appendfree(const std::string& line)
      { Mstat.hasfree=true; Mfree.lines.push_back(line); }
221
222
      void setfree(const FREE& free)
      { Mstat.hasfree=true; Mfree=free; }
223
224
      void setsrce(const SRCE& srce)
      { Mstat.hassrce=true; Msrce=srce; }
thomas.forbriger's avatar
thomas.forbriger committed
225
226
227
228
229
230
    private:
      STAT Mstat;
      FREE Mfree;
      SRCE Msrce;
  }; // class FileHeader

thomas.forbriger's avatar
thomas.forbriger committed
231
232
233
  /*! \brief class to normalize waveforms
   */
  class WaveformNormalizer {
thomas.forbriger's avatar
thomas.forbriger committed
234
    public:
thomas.forbriger's avatar
thomas.forbriger committed
235
236
237
238
239
240
241
242
243
244
245
246
247
      static const int limit;
      WaveformNormalizer(const Enormmode& nm, const double& maxval); 
      const double& maxval() const { return(Mmaxval); }
      const double& ampfac() const { return(Mampfac); }
      const bool& scale() const { return(Mscale); }
    private:
      double Mampfac;
      double Mmaxval;
      bool Mscale;
      Enormmode Mnorm;
  }; // class WaveformNormalizer

  class TraceHeader {
thomas.forbriger's avatar
thomas.forbriger committed
248
    public:
249
250
251
      TraceHeader(): Mdebug(false) { }
      TraceHeader(const WID2& wid2, const bool& last=false): 
        Mwid2(wid2), Mdebug(false)
thomas.forbriger's avatar
thomas.forbriger committed
252
253
      { Mdast.hasfree=false; Mdast.hasinfo=false; Mdast.last=last; }
      TraceHeader(const WID2& wid2, const FREE& free, const bool& last=false): 
254
        Mwid2(wid2), Mfree(free), Mdebug(false)
thomas.forbriger's avatar
thomas.forbriger committed
255
256
      { Mdast.hasfree=true; Mdast.hasinfo=false; Mdast.last=last; }
      TraceHeader(const WID2& wid2, const INFO& info, const bool& last=false): 
257
        Mwid2(wid2), Minfo(info), Mdebug(false)
thomas.forbriger's avatar
thomas.forbriger committed
258
259
260
      { Mdast.hasfree=false; Mdast.hasinfo=true; Mdast.last=last; }
      TraceHeader(const WID2& wid2, const INFO& info, 
                  const FREE& free, const bool& last=false):
261
        Mwid2(wid2), Mfree(free), Minfo(info), Mdebug(false)
thomas.forbriger's avatar
thomas.forbriger committed
262
      { Mdast.hasfree=true; Mdast.hasinfo=true; Mdast.last=last; }
thomas.forbriger's avatar
thomas.forbriger committed
263
264
      void writeheader(std::ostream&) const;
      void writetrailer(std::ostream&) const;
265
266
      void readheader(std::istream&);
      void readtrailer(std::istream&);
thomas.forbriger's avatar
thomas.forbriger committed
267
268
269
270
271
272
273
274
      bool last() const { return(Mdast.last); }
      template<class C> void scanseries(const C&, 
                                        const Enormmode& nm=NM_maxdyn);
      const WID2& wid2() const { return(Mwid2); }
      const DAST& dast() const { return(Mdast); }
      const FREE& free() const { return(Mfree); }
      const INFO& info() const { return(Minfo); }
      const bool& scale() const { return(Mscale); }
275
276
      const bool& hasinfo() const { return(Mdast.hasinfo); }
      const bool& hasfree() const { return(Mdast.hasfree); }
277
      void setlast(const bool& flag) { Mdast.last=flag; }
278
      void setdebug(const bool& flag) { Mdebug=flag; }
279
      void setwid2(const WID2& wid2line) { Mwid2=wid2line; }
thomas.forbriger's avatar
thomas.forbriger committed
280
      void setnsamples(const long int& n) { Mwid2.nsamples=n; }
281
282
      void setinfo(const INFO& infoline) 
      { Mdast.hasinfo=true; Minfo=infoline; }
283
284
      void setfree(const FREE& free)
      { Mdast.hasfree=true; Mfree=free; }
285
286
      void appendfree(const std::string& line)
      { Mdast.hasfree=true; Mfree.lines.push_back(line); }
thomas.forbriger's avatar
thomas.forbriger committed
287
    private:
thomas.forbriger's avatar
thomas.forbriger committed
288
      WID2 Mwid2;
thomas.forbriger's avatar
thomas.forbriger committed
289
290
291
      DAST Mdast;
      FREE Mfree;
      INFO Minfo;
thomas.forbriger's avatar
thomas.forbriger committed
292
      bool Mscale;
293
      bool Mdebug;
thomas.forbriger's avatar
thomas.forbriger committed
294
295
  }; // class TraceHeader

thomas.forbriger's avatar
thomas.forbriger committed
296
297
298
299
300
301
  template<class C>
    class OutputWaveform {
      public:
        typedef typename C::Tcoc Tcoc;
        OutputWaveform(const Tcoc& c, const TraceHeader& th,
                       const Enormmode& nm=NM_maxdyn):
thomas.forbriger's avatar
thomas.forbriger committed
302
303
          Mseries(c), Mheader(th) 
          { Mheader.scanseries(Mseries,nm); }
thomas.forbriger's avatar
thomas.forbriger committed
304
305
306
        void write(std::ostream& os) const;
      private:
        Tcoc Mseries;
thomas.forbriger's avatar
thomas.forbriger committed
307
        mutable TraceHeader Mheader;
thomas.forbriger's avatar
thomas.forbriger committed
308
    }; // class Waveform
thomas.forbriger's avatar
thomas.forbriger committed
309

310
311
312
313
  template<class C>
    class InputWaveform {
      public:
        typedef C Tcontainer;
314
315
        InputWaveform(const bool& debug=false): 
          Mvalid(false), Mdebug(debug) { }
316
317
        InputWaveform(std::istream& is, const bool& debug=false):
          Mdebug(debug) { this->read(is); }
318
319
320
321
322
323
324
325
326
        void read(std::istream& is);
        const bool& valid() const { return(Mvalid); }
        Tcontainer series() const { return(Mseries); }
        TraceHeader header() const { return(Mheader); }
        const bool& last() const { return(Mheader.dast().last); }
      private:
        bool Mvalid;
        Tcontainer Mseries;
        TraceHeader Mheader;
327
        bool Mdebug;
328
    }; // class InputWaveform
thomas.forbriger's avatar
thomas.forbriger committed
329

thomas.forbriger's avatar
thomas.forbriger committed
330
  class SkipWaveform {
331
332
333
334
335
336
337
338
339
340
    public:
      SkipWaveform(): Mvalid(false) { }
      SkipWaveform(std::istream& is) { this->read(is); }
      void read(std::istream& is);
      const bool& valid() const { return(Mvalid); }
      TraceHeader header() const { return(Mheader); }
      const bool& last() const { return(Mheader.dast().last); }
    private:
      bool Mvalid;
      TraceHeader Mheader;
thomas.forbriger's avatar
thomas.forbriger committed
341
342
343
344
345
346
  }; // class SkipWaveform

/*======================================================================*/
// I/O operators
// -------------

thomas.forbriger's avatar
thomas.forbriger committed
347
  inline std::istream& operator >> (std::istream& is, FileHeader& fh)
348
  { fh.read(is); return(is); }
349
350
351
  template<class C>
  inline std::istream& operator >> (std::istream& is, InputWaveform<C>& wf)
  { wf.read(is); return(is); }
thomas.forbriger's avatar
thomas.forbriger committed
352
  inline std::istream& operator >> (std::istream& is, SkipWaveform& swf)
353
  { swf.read(is); return(is); }
thomas.forbriger's avatar
thomas.forbriger committed
354
355
356
  inline std::ostream& operator << (std::ostream& os, const FileHeader& fh)
  { fh.write(os); return(os); }
  inline std::ostream& operator << (std::ostream& os, const TraceHeader& th)
thomas.forbriger's avatar
thomas.forbriger committed
357
358
359
360
361
362
  { 
    th.writeheader(os);
    os << "DATA!" << std::endl;
    th.writetrailer(os);
    return(os);
  }
thomas.forbriger's avatar
thomas.forbriger committed
363
364
365
366
367
368
369
370
371
372
  template<class C> 
    inline std::ostream& operator << (std::ostream& os, const
                                      OutputWaveform<C>& wf)
  { wf.write(os); return(os); }

/*======================================================================*/
// WaveformNormalizer template functions
// -------------------------------------

  template<class C>
thomas.forbriger's avatar
thomas.forbriger committed
373
    inline
thomas.forbriger's avatar
thomas.forbriger committed
374
    void TraceHeader::scanseries(const C& c,
thomas.forbriger's avatar
thomas.forbriger committed
375
                                 const Enormmode& nm)
thomas.forbriger's avatar
thomas.forbriger committed
376
377
    {
      Mwid2.nsamples=0;
thomas.forbriger's avatar
thomas.forbriger committed
378
379
380
      double maxval=0.;
      double absval, value;
      double null(0);
thomas.forbriger's avatar
thomas.forbriger committed
381
      for(aff::Browser<C> i(c); i.valid(); ++i)
thomas.forbriger's avatar
thomas.forbriger committed
382
383
384
385
386
387
388
389
390
391
      { 
        Mwid2.nsamples++;
        value= *i;
        absval= (value < null) ? -value : value;
        maxval= (maxval < absval) ? absval : maxval;
      }
      double dmaxval=double((maxval==0) ? WaveformNormalizer::limit : maxval);
      WaveformNormalizer normalizer(nm, dmaxval);
      Mdast.ampfac=normalizer.ampfac();
      Mscale=normalizer.scale();
392
    } // TraceHeader::scanseries
thomas.forbriger's avatar
thomas.forbriger committed
393
394
395
396

/*----------------------------------------------------------------------*/
// template OutputWaveform functions
// ---------------------------------
thomas.forbriger's avatar
thomas.forbriger committed
397

thomas.forbriger's avatar
thomas.forbriger committed
398
  template<class C>
thomas.forbriger's avatar
thomas.forbriger committed
399
400
    inline
    void OutputWaveform<C>::write(std::ostream& os) const
thomas.forbriger's avatar
thomas.forbriger committed
401
    {
thomas.forbriger's avatar
thomas.forbriger committed
402
      Mheader.setnsamples(Mseries.size());
thomas.forbriger's avatar
thomas.forbriger committed
403
      Mheader.writeheader(os);;
thomas.forbriger's avatar
thomas.forbriger committed
404
      GSE2::waveform::TDAT2writeCM6 fwriter(Mheader.wid2().nsamples);
thomas.forbriger's avatar
thomas.forbriger committed
405
      int idata;
thomas.forbriger's avatar
thomas.forbriger committed
406
      typename C::Tvalue data;
407
      for(aff::Browser<Tcoc> i(Mseries); i.valid(); ++i)
thomas.forbriger's avatar
thomas.forbriger committed
408
409
410
      { 
        data= *i;
        if (Mheader.scale())
thomas.forbriger's avatar
thomas.forbriger committed
411
        { idata=int(round(data/Mheader.dast().ampfac)); }
thomas.forbriger's avatar
thomas.forbriger committed
412
        else
thomas.forbriger's avatar
thomas.forbriger committed
413
        { idata=int(round(data)); }
thomas.forbriger's avatar
thomas.forbriger committed
414
415
        os << fwriter(idata);
      }
416
417
418
419
420
421
422
423
424
425
426
427
      Mheader.writetrailer(os);
    } // OutputWaveform::write

/*----------------------------------------------------------------------*/
// template InputWaveform functions
// --------------------------------

  template<class C>
    inline
    void InputWaveform<C>::read(std::istream& is) 
    {
      typedef typename C::Tvalue Tvalue;
428
429
430
431
432
433
      if (Mdebug)
      {
        std::cerr << "DEBUG (InputWaveform<C>::read): " << std::endl
          << "  calling function readheader() of member Mheader." 
          << std::endl;
      }
434
435
      Mheader.setdebug(Mdebug);
      Mheader.readheader(is);
436
437
      int nsamples=Mheader.wid2().nsamples;
      GSE2::waveform::TDAT2readCM6 freader(nsamples);
thomas.forbriger's avatar
thomas.forbriger committed
438
439
440
441
442
443
444
445
      try {
        Mseries=C(nsamples);
      }
      catch(...) {
        std::cerr << "ERROR (InputWaveform::read): "
          << "allocating series for " << nsamples << " samples!" << std::endl;
        throw;
      }
446
447
448
449
450
451
      for(aff::Iterator<C> i(Mseries); i.valid(); ++i)
      { (*i) = Tvalue(freader(is)*Mheader.dast().ampfac); }
      Mheader.readtrailer(is);
      Mvalid=true;
    } // InputWaveform::read

thomas.forbriger's avatar
thomas.forbriger committed
452
453
454
455
456
457
458
459
/*======================================================================*/
// some utilities
// --------------


  /*----------------------------------------------------------------------*/
  // compare WID2 headers
  // --------------------
thomas.forbriger's avatar
thomas.forbriger committed
460
461
462
  /*! \brief bit values to select WID2 fields to be compared
   * \sa sff::WID2compare
   */
thomas.forbriger's avatar
thomas.forbriger committed
463
  enum Ewid2field {
thomas.forbriger's avatar
thomas.forbriger committed
464
    //! compare dates of first sample
thomas.forbriger's avatar
thomas.forbriger committed
465
    Fdate    =1<<0,
thomas.forbriger's avatar
thomas.forbriger committed
466
    //! compare station IDs
thomas.forbriger's avatar
thomas.forbriger committed
467
    Fstation =1<<1,
thomas.forbriger's avatar
thomas.forbriger committed
468
    //! compare channel IDs
thomas.forbriger's avatar
thomas.forbriger committed
469
    Fchannel =1<<2,
thomas.forbriger's avatar
thomas.forbriger committed
470
    //! compare auxilliary IDs
thomas.forbriger's avatar
thomas.forbriger committed
471
    Fauxid   =1<<3,
thomas.forbriger's avatar
thomas.forbriger committed
472
    //! compare numbers of samples
thomas.forbriger's avatar
thomas.forbriger committed
473
    Fnsamples=1<<4,
thomas.forbriger's avatar
thomas.forbriger committed
474
    //! compare sampling intervals
thomas.forbriger's avatar
thomas.forbriger committed
475
    Fdt      =1<<5,
thomas.forbriger's avatar
thomas.forbriger committed
476
    //! compare calib fields
thomas.forbriger's avatar
thomas.forbriger committed
477
    Fcalib   =1<<6,
thomas.forbriger's avatar
thomas.forbriger committed
478
    //! compare calper fields
thomas.forbriger's avatar
thomas.forbriger committed
479
    Fcalper  =1<<7,
thomas.forbriger's avatar
thomas.forbriger committed
480
    //! compare instrument type strings
thomas.forbriger's avatar
thomas.forbriger committed
481
    Finstype =1<<8,
thomas.forbriger's avatar
thomas.forbriger committed
482
    //! compare hang fields
thomas.forbriger's avatar
thomas.forbriger committed
483
    Fhang    =1<<9,
thomas.forbriger's avatar
thomas.forbriger committed
484
    //! compare vang fields
thomas.forbriger's avatar
thomas.forbriger committed
485
    Fvang    =1<<10
thomas.forbriger's avatar
thomas.forbriger committed
486
487
  }; // enum Ewid2field

thomas.forbriger's avatar
thomas.forbriger committed
488
489
490
  /*! \brief compares selected fields from two WID2 objects
   * \sa sff::Ewid2field
   */
thomas.forbriger's avatar
thomas.forbriger committed
491
492
  class WID2compare {
    public:
thomas.forbriger's avatar
thomas.forbriger committed
493
494
495
496
      /*! \brief create compare object for comparison of selected fields
       *
       * \sa sff::Ewid2field
       */
thomas.forbriger's avatar
thomas.forbriger committed
497
      WID2compare(const int& flags=(Fstation | Fchannel | Fdt)):
thomas.forbriger's avatar
thomas.forbriger committed
498
        Mflags(flags), Mdttolerance(0.), Mdatetolerance(0.) { }
thomas.forbriger's avatar
thomas.forbriger committed
499
500
      void set(const int& flags) { Mflags=Mflags | flags; }
      void clear(const int& flags) { Mflags=Mflags & (0xffffffff ^ flags); }
thomas.forbriger's avatar
thomas.forbriger committed
501
      //! tolerance when comparing dt (as a fraction of the sampling interval)
thomas.forbriger's avatar
thomas.forbriger committed
502
      void setdttolerance(const double& tol) { Mdttolerance=tol; }
thomas.forbriger's avatar
thomas.forbriger committed
503
      //! tolerance when comparing date (as a fraction of the sampling interval)
thomas.forbriger's avatar
thomas.forbriger committed
504
      void setdatetolerance(const double& tol) { Mdatetolerance=tol; }
thomas.forbriger's avatar
thomas.forbriger committed
505
506
507
      bool operator()(const WID2& hd1, const WID2& hd2) const;
      int flags() const { return(Mflags); }
      double dttolerance() const { return(Mdttolerance); }
thomas.forbriger's avatar
thomas.forbriger committed
508
      double datetolerance() const { return(Mdatetolerance); }
thomas.forbriger's avatar
thomas.forbriger committed
509
510
511
    private:
      int Mflags;
      double Mdttolerance;
thomas.forbriger's avatar
thomas.forbriger committed
512
      double Mdatetolerance; //!< relative to mean sampling interval
thomas.forbriger's avatar
thomas.forbriger committed
513
514
  }; // class WID2compare

515
516
517
518
  /*======================================================================*/
  // functions
  // ---------
  
thomas.forbriger's avatar
thomas.forbriger committed
519
  //! return time of last sample in waveform
520
  libtime::TAbsoluteTime wid2lastsample(const WID2& wid2);
thomas.forbriger's avatar
thomas.forbriger committed
521
  //! return time of next first sample for contiguous data
522
  libtime::TAbsoluteTime wid2nextdate(const WID2& wid2);
thomas.forbriger's avatar
thomas.forbriger committed
523
  //! return index for sample at given date
524
525
  long int wid2isample(const WID2& wid2, 
                       const libtime::TAbsoluteTime& idate);
thomas.forbriger's avatar
thomas.forbriger committed
526
  //! return time for sample at given index
527
528
  libtime::TAbsoluteTime wid2isample(const WID2& wid2, 
                                     const long int& i);
thomas.forbriger's avatar
thomas.forbriger committed
529
  //! return time interval between idate and sample sample next to idate
530
531
532
  libtime::TRelativeTime wid2isamplerest(const WID2& wid2, 
                                         const libtime::TAbsoluteTime& idate);

thomas.forbriger's avatar
thomas.forbriger committed
533
534
535
536
537
  //! return ID string for synthtic time reference
  std::string srce_reference_ID();
  //! return synthetic time reference from nothing
  sff::SRCE srce_reference();

thomas.forbriger's avatar
thomas.forbriger committed
538
  //! return offset in meters
thomas.forbriger's avatar
thomas.forbriger committed
539
  double offset(const SRCE& srce, const INFO& info,
thomas.forbriger's avatar
thomas.forbriger committed
540
541
542
543
                const double& radius=6371.);
  //! return offset in degrees
  double offsetdeg(const SRCE& srce, const INFO& info, 
                   const double& radius=6371.);
thomas.forbriger's avatar
thomas.forbriger committed
544
545
546
547
548
549
550
551
552
553
554
555
  /*======================================================================*/
  // verbose output
  // --------------

  void verbose(std::ostream& os, const WID2& wid2);
  void verbose(std::ostream& os, const SRCE& srce);
  void verbose(std::ostream& os, const DAST& dast);
  void verbose(std::ostream& os, const INFO& info);
  void verbose(std::ostream& os, const FREE& free);
  void verbose(std::ostream& os, const STAT& stat);
  void verbose(std::ostream& os, const FileHeader& fh);
  void verbose(std::ostream& os, const TraceHeader& th);
thomas.forbriger's avatar
thomas.forbriger committed
556

thomas.forbriger's avatar
thomas.forbriger committed
557
558
559
560
561
} // namespace sff

#endif // TF_SFFXX_H_VERSION (includeguard)

/* ----- END OF sffxx.h ----- */