Waveform filter programs
sigval.cc
Go to the documentation of this file.
1 
44 #define SIGVAL_VERSION \
45  "SIGVAL V1.8 extract values from input signals"
46 
47 #include <iostream>
48 #include <tfxx/commandline.h>
49 #include <aff/series.h>
50 #include <aff/iterator.h>
51 #include <aff/dump.h>
52 #include <aff/seriesoperators.h>
53 #include <aff/functions/avg.h>
54 #include <aff/functions/rms.h>
55 #include <aff/functions/min.h>
56 #include <aff/functions/max.h>
57 #include <aff/functions/sqrsum.h>
58 #include <aff/subarray.h>
59 #include <tsxx/tsxx.h>
60 #include <tsxx/tapers.h>
61 #include <tsxx/filter.h>
62 #include <tsxx/wid2timeseries.h>
63 #include <tsioxx/tsioxx.h>
64 #include <fstream>
65 #include <tfxx/error.h>
66 #include <tfxx/rangestring.h>
67 #include <tfxx/xcmdline.h>
68 #include <tfxx/misc.h>
69 #include <tfxx/handle.h>
70 #include <tfxx/seitosh.h>
71 #include <datrwxx/readany.h>
72 #include <sstream>
73 
74 using std::cout;
75 using std::cerr;
76 using std::endl;
77 
78 struct Options {
79  std::string inputformat;
80  std::string outputformat;
82 }; // struct Options
83 
84 // values type to be used for samples
85 typedef double Tvalue;
86 
87 // time series
88 typedef aff::Series<Tvalue> Tseries;
89 
90 // full featured time series file
91 typedef ts::sff::File<Tseries> Tfile;
92 
93 typedef ts::TDsfftimeseries Ttimeseries;
95 
96 int main(int iargc, char* argv[])
97 {
98 
99  // define usage information
100  char usage_text[]=
101  {
102  SIGVAL_VERSION "\n"
103  "usage: sigval [-format s] [-type f] file [t:l] [file [t:l] ...]" "\n"
104  " [-rms]\n"
105  " or: sigval --help|-h" "\n"
106  " or: sigval --xhelp" "\n"
107  };
108 
109  // define full help text
110  char help_text[]=
111  {
112  "-format s define a format string for output lines" "\n"
113  "-type f define file format of input files" "\n"
114  "-rms Calculate total rms value over all traces assuming that\n"
115  " all traces have the same physical sample units.\n"
116  "\n"
117  "Patterns that may be used in format descriptions are:" "\n"
118  "%F file name" "\n"
119  "%NT number of trace in file" "\n"
120  "%COO trace coordinates" "\n"
121  "%SCO source coordinates" "\n"
122  "%OFF trace offset" "\n"
123  "%D date of first sample" "\n"
124  "%T time of first sample" "\n"
125  "%UT time of first sample including microsecond" "\n"
126  "%HT hierarchical time string (can be used as control parameter\n"
127  " for programs selecting a time window - like resaseda)\n"
128  "%L time duration of signal" "\n"
129  "%SI sampling interval in seconds" "\n"
130  "%NS number of samples" "\n"
131  "%S station identifier" "\n"
132  "%C channel identifier" "\n"
133  "%A auxiliary identifier" "\n"
134  "%I instrument identifier" "\n"
135  "%MEAN signal average" "\n"
136  "%MIN minimum value in signal" "\n"
137  "%MAX maximum value in signal" "\n"
138  "%PPA peak-to-peak amplitude" "\n"
139  "%RMS rms of signal" "\n"
140  "%XT tab character" "\n"
141  "%% will be replaced by a literal \'%\'" "\n"
142  };
143 
144  // define commandline options
145  using namespace tfxx::cmdline;
146  static Declare options[]=
147  {
148  // 0: print help
149  {"help",arg_no,"-"},
150  // 1: output format
151  {"format",arg_yes,"%F(t#%NT) %S %C"},
152  // 2: input file format
153  {"type",arg_yes,"sff"},
154  // 3: extended help for formats
155  {"xhelp",arg_no,"-"},
156  // 4: extended help for formats
157  {"rms",arg_no,"-"},
158  {NULL}
159  };
160 
161  static const char tracekey[]="t";
162 
163  // define commandline argument modifier keys
164  static const char* cmdlinekeys[]={tracekey, 0};
165 
166  // no arguments? print usage...
167  if (iargc<2)
168  {
169  cerr << usage_text << endl;
170  cerr << tfxx::seitosh::repository_reference << endl;
171  exit(0);
172  }
173 
174  // collect options from commandline
175  Commandline cmdline(iargc, argv, options);
176 
177  // help requested? print full help text...
178  if (cmdline.optset(0))
179  {
180  cerr << usage_text << endl;
181  cerr << help_text << endl;
182  datrw::supported_data_types(cerr);
183  cerr << endl << tfxx::seitosh::repository_reference << endl;
184  exit(0);
185  }
186 
187  if (cmdline.optset(3))
188  {
189  cerr << usage_text << endl;
190  datrw::online_help(cerr);
191  cerr << endl << tfxx::seitosh::repository_reference << endl;
192  exit(0);
193  }
194 
195  Options opt;
196  opt.outputformat=cmdline.string_arg(1);
197  opt.inputformat=cmdline.string_arg(2);
198  opt.reporttotalrms=cmdline.optset(4);
199 
200  // extract commandline arguments
201  TFXX_assert(cmdline.extra(), "missing input file");
202  tfxx::cmdline::Tparsed arguments=parse_cmdline(cmdline, cmdlinekeys);
203 
204  /*======================================================================*/
205  // start processing
206 
207  // two variables needed to calculate the overall rms value
208  double overallrms=0., totaltime=0.;
209 
210  // cycle through all input files
211  // -----------------------------
212  tfxx::cmdline::Tparsed::const_iterator infile=arguments.begin();
213  while (infile != arguments.end())
214  {
215  // open input file
216  std::ifstream ifs(infile->name.c_str());
217  datrw::ianystream is(ifs, opt.inputformat);
218  sff::SRCE srce;
219  is >> srce;
220 
221  // cycle through traces of input file
222  // ----------------------------------
223  // setup trace selection
224  typedef tfxx::RangeList<int> Trangelist;
225  bool doselect=infile->haskey(tracekey);
226  Trangelist traceranges=
227  tfxx::string::rangelist<Trangelist::Tvalue>(infile->value(tracekey));
228  int itrace=0;
229  while (is.good())
230  {
231  ++itrace;
232  if ((!doselect) || traceranges.contains(itrace))
233  {
234  Tseries series;
235  is >> series;
236  sff::WID2 wid2;
237  is >> wid2;
238  sff::INFO info;
239  is >> info;
240 
241  std::string retval=opt.outputformat;
242 
243  std::ostringstream oss;
244 
245  // pattern to be replaced by file name
246  retval=tfxx::string::patsubst(retval, "%F",
247  infile->name);
248 
249  // pattern to be replaced by trace coordinate
250  oss.str("");
251  if (info.cs == sff::CS_cartesian)
252  {
253  oss << "cartesian coordinates:";
254  }
255  else if (info.cs == sff::CS_spherical)
256  {
257  oss << "spherical coordinates:";
258  }
259  else
260  {
261  oss << "unknown coordinate system:";
262  }
263  oss << " c1=" << info.cx;
264  oss << " c2=" << info.cy;
265  oss << " c3=" << info.cz;
266  retval=tfxx::string::patsubst(retval, "%COO",
267  tfxx::string::trimws(oss.str()));
268 
269  // pattern to be replaced by source coordinate
270  oss.str("");
271  if (srce.cs == sff::CS_cartesian)
272  {
273  oss << "cartesian source coordinates:";
274  }
275  else if (srce.cs == sff::CS_spherical)
276  {
277  oss << "spherical source coordinates:";
278  }
279  else
280  {
281  oss << "unknown source coordinate system:";
282  }
283  oss << " s1=" << srce.cx;
284  oss << " s2=" << srce.cy;
285  oss << " s3=" << srce.cz;
286  retval=tfxx::string::patsubst(retval, "%SCO",
287  tfxx::string::trimws(oss.str()));
288 
289  // pattern to be replaced by trace offset
290  if (is.hassrce() && is.hasinfo())
291  {
292  oss.str("");
293  oss << " r=" << sff::offset(srce, info) << "m";
294  retval=tfxx::string::patsubst(retval, "%OFF",
295  tfxx::string::trimws(oss.str()));
296  }
297  else
298  {
299  TFXX_assert(retval.find("%OFF") == std::string::npos,
300  "offset cannot be calculated, because either SRCE or INFO\n"
301  "is missing in input file");
302  } // else, if (is.hassrce() && is.hasinfo())
303 
304  // pattern to be replaced by trace number
305  oss.str("");
306  oss << itrace;
307  retval=tfxx::string::patsubst(retval, "%NT",
308  tfxx::string::trimws(oss.str()));
309 
310  std::string timestring=wid2.date.timestring();
311  // pattern to be replaced by date of first samples
312  retval=tfxx::string::patsubst(retval, "%D",
313  timestring.substr(4,10));
314  // pattern to be replaced by time of first samples
315  retval=tfxx::string::patsubst(retval, "%T",
316  timestring.substr(15,8));
317  // pattern to be replaced by time of first samples
318  retval=tfxx::string::patsubst(retval, "%UT",
319  timestring.substr(15,15));
320  // pattern to be replaced by time of first samples
321  // using an hierarchical time string
322  retval=tfxx::string::patsubst(retval, "%HT",
323  wid2.date.hierarchicalstring());
324  // pattern to be replaced by time duration of signal
325  libtime::TRelativeTime duration=
326  libtime::double2time(wid2.dt)*(series.size()-1);
327  retval=tfxx::string::patsubst(retval, "%L",
328  duration.timestring());
329  // pattern to be replaced by sampling interval in seconds
330  oss.str("");
331  oss << wid2.dt;
332  retval=tfxx::string::patsubst(retval, "%SI",
333  tfxx::string::trimws(oss.str()));
334  // pattern to be replaced by number of samples
335  oss.str("");
336  oss << series.size();
337  retval=tfxx::string::patsubst(retval, "%NS",
338  tfxx::string::trimws(oss.str()));
339  // pattern to be replaced by station identifier
340  retval=tfxx::string::patsubst(retval, "%S",
341  tfxx::string::trimws(wid2.station));
342  // pattern to be replaced by channel identifier
343  retval=tfxx::string::patsubst(retval, "%C",
344  tfxx::string::trimws(wid2.channel));
345  // pattern to be replaced by auxiliary identifier
346  retval=tfxx::string::patsubst(retval, "%A",
347  tfxx::string::trimws(wid2.auxid));
348  // pattern to be replaced by instrument identifier
349  retval=tfxx::string::patsubst(retval, "%I",
350  tfxx::string::trimws(wid2.instype));
351 
352  // pattern to be replaced by instrument identifier
353  retval=tfxx::string::patsubst(retval, "%XT", "\t");
354 
355  // average
356  double avg=aff::func::avg(series);
357  oss.str("");
358  oss << avg;
359  retval=tfxx::string::patsubst(retval, "%MEAN",
360  tfxx::string::trimws(oss.str()));
361  // maximum
362  double max=aff::func::max(series);
363  oss.str("");
364  oss << max;
365  retval=tfxx::string::patsubst(retval, "%MAX",
366  tfxx::string::trimws(oss.str()));
367  // minimum
368  double min=aff::func::min(series);
369  oss.str("");
370  oss << min;
371  retval=tfxx::string::patsubst(retval, "%MIN",
372  tfxx::string::trimws(oss.str()));
373  // peak-to-peak
374  double ppamp=(max-min);
375  if (ppamp < 0) { ppamp *= -1; }
376  oss.str("");
377  oss << ppamp;
378  retval=tfxx::string::patsubst(retval, "%PPA",
379  tfxx::string::trimws(oss.str()));
380  // rms
381  double rms=aff::func::rms(series);
382  oss.str("");
383  oss << rms;
384  retval=tfxx::string::patsubst(retval, "%RMS",
385  tfxx::string::trimws(oss.str()));
386 
387  // double-per-cent to be replaced by per-cent
388  retval=tfxx::string::patsubst(retval, "%%", "%");
389 
390  cout << retval << endl;
391 
392  // cumulative sum of signal power
393  overallrms+=aff::func::sqrsum(series);
394  // cumulative sum of seismogram time
395  totaltime += (wid2.dt*series.size());
396 
397  /*----------------------------------------------------------------------*/
398  }
399  else
400  {
401  is.skipseries();
402  }
403  }
404 
405  // go to next file
406  ++infile;
407  }
408 
409  if (opt.reporttotalrms)
410  {
411  // calculate overall rms from total signal power
412  overallrms=std::sqrt(overallrms/totaltime);
413  cout << "\n"
414  << "The overall rms value is: " << overallrms << "\n"
415  << " This value is calculated by integration of the total signal\n"
416  << " power of all traces over time. This integral is divided by\n"
417  << " the total time of integration and the square root of this\n"
418  << " is presented as the overall rms values. Notice that this\n"
419  << " implies that all trace have the same physical units for\n"
420  << " their sample values. If not, the outcome is meaningless."
421  << endl;
422  }
423 
424 } // main
425 
426 /* ----- END OF sigval.cc ----- */
int main(int iargc, char *argv[])
Definition: sigval.cc:96
std::string inputformat
Definition: cross.cc:75
static const char * cmdlinekeys[]
Definition: fidasexx.cc:131
bool reporttotalrms
Definition: sigval.cc:81
ts::sff::File< Tseries > Tfile
Definition: sigval.cc:91
#define SIGVAL_VERSION
Definition: sigval.cc:44
std::string outputformat
Definition: cross.cc:75
ts::TDsfftimeseries Ttimeseries
Definition: sigval.cc:93
aff::Series< Tvalue > Tseries
Definition: sigval.cc:88
const char *const tracekey
key to select traces
Definition: deconv.cc:68
aff::Series< double > Tseries
Definition: cross.cc:69
double Tvalue
Definition: sigval.cc:85