Waveform filter programs
soutifu.cc
Go to the documentation of this file.
1 
40 #define SOUTIFU_VERSION \
41  "SOUTIFU V1.4 inversion for source wavelet correction filter"
42 
43 #include <iostream>
44 #include <fstream>
45 #include <tfxx/error.h>
46 #include <tfxx/commandline.h>
47 #include <tfxx/seitosh.h>
48 #include <tsioxx/tsioxx.h>
49 #include <datrwxx/readany.h>
50 #include <datrwxx/writeany.h>
51 #include <stfinv/stfinvany.h>
52 
53 /*----------------------------------------------------------------------*/
54 
55 using std::cout;
56 using std::cerr;
57 using std::endl;
58 
59 /*----------------------------------------------------------------------*/
60 // debug helper
61 #define PAROUT( par ) cout << #par << "=" << par << " ";
62 
63 /*----------------------------------------------------------------------*/
64 // function to compare double
65 // is true if relative residual between a and b is smaller than eps
66 bool sameineps(const double &a, const double& b, const double& eps=1.e-8)
67 {
68  double reldif=std::abs(a-b);
69  return(reldif<=(std::abs(b*eps)));
70 }
71 
72 /*----------------------------------------------------------------------*/
73 
74 struct Options {
75  bool verbose, debug, overwrite;
81 }; // struct Options
82 
83 /*----------------------------------------------------------------------*/
84 
85 int main(int iargc, char* argv[])
86 {
87 
88  // define usage information
89  char usage_text[]=
90  {
91  SOUTIFU_VERSION "\n"
92  "usage: soutifu [-v] [-o] [-wc f] [-ws f] [--type f] [--Type f]\n"
93  " [-add f] [-wa f]\n"
94  " [-DEBUG=level]\n"
95  " parameters data synthetics" "\n"
96  " or: soutifu --help|-h" "\n"
97  " or: soutifu --xhelp | --iohelp | --phelp p" "\n"
98  };
99 
100  // define full help text
101  char help_text[]=
102  {
103  "Calculate optimized source wavelet correction filter to\n"
104  "minimize misfit between recorded data and synthetic waveforms.\n"
105  "\n"
106  "data name of file containing recorded data\n"
107  "synthetics name of file containing synthetic data\n"
108  "parameters parameterstring to select STF engine\n"
109  " The string consists of an ID selecting one of the\n"
110  " available engines and a set of options an parameters\n"
111  " to be passed to this engine.\n"
112  "\n"
113  "--xhelp print summary of usage instructions for available procedures\n"
114  "--iohelp print detailed usage instructions for file input/output\n"
115  "--phelp p print detailed usage instructions for procedure \"p\"\n"
116  "\n"
117  "-v be verbose\n"
118  "-DEBUG=level produce debug output at level \"level\"\n"
119  "-o overwrite existing output files\n"
120  "--type f use file format type \"f\" for file input\n"
121  "--Type f use file format type \"f\" for file output\n"
122  " if --Type is not used input and output format will\n"
123  " be the same\n"
124  "-wc f write convolved synthetics to file \"f\"\n"
125  "-ws f write source wavelet correction filter \n"
126  " impulse response to file \"f\"\n"
127  "-add f read additional time series to be convolved from file \"f\"\n"
128  "-wa f write additional time series after convolved to file \"f\"\n"
129  "\n"
130  "Upon input the consistency of recorded and synthetic data are\n"
131  "checked. For coordinates only receiver positions relative to\n"
132  "source coordinates are checked, not absolute locations.\n"
133  };
134 
135  // define commandline options
136  using namespace tfxx::cmdline;
137  static Declare options[]=
138  {
139  // 0: print help
140  {"help",arg_no,"-"},
141  // 1: verbose mode
142  {"v",arg_no,"-"},
143  // 2: overwrite mode
144  {"o",arg_no,"-"},
145  // 3: file format
146  {"type",arg_yes,"sff"},
147  // 4: name of convolved synthetics
148  {"wc",arg_yes,"-"},
149  // 5: name of source correction filter wavelet file
150  {"ws",arg_yes,"-"},
151  // 6: present full details regarding engines
152  {"xhelp",arg_no,"-"},
153  // 7: present full details
154  {"DEBUG",arg_yes,"0"},
155  // 8: file format
156  {"Type",arg_yes,"-"},
157  // 9: additional time series to be convolved
158  {"add",arg_yes,"-"},
159  // 10: output file for additional convolved time series
160  {"wa",arg_yes,"-"},
161  // 11: provide full details regarding file i/o
162  {"iohelp",arg_no,"-"},
163  // 12: provide full details regarding file i/o
164  {"phelp",arg_yes,"-"},
165  {NULL}
166  };
167 
168  // no arguments? print usage...
169  if (iargc<2)
170  {
171  cerr << usage_text << endl;
172  cerr << tfxx::seitosh::repository_reference << endl;
173  exit(0);
174  }
175 
176  // collect options from commandline
177  Commandline cmdline(iargc, argv, options);
178 
179  // help requested? print full help text...
180  if (cmdline.optset(0) || cmdline.optset(6) || cmdline.optset(11)
181  || cmdline.optset(12))
182  {
183  cerr << usage_text << endl;
184  cerr << endl;
185  cerr << help_text << endl;
186  datrw::supported_data_types(cerr);
187  if (cmdline.optset(11))
188  {
189  cerr << endl;
190  datrw::online_help(cerr);
191  }
192  if (cmdline.optset(6))
193  {
194  cerr << endl;
195  stfinv::help(cerr);
196  }
197  else
198  {
199  cerr << help_text << endl;
200  stfinv::engines(cerr);
201  }
202  if (cmdline.optset(12))
203  {
204  cerr << endl;
205  stfinv::usage(cmdline.string_arg(12), cerr);
206  }
207  cerr << endl << tfxx::seitosh::repository_reference << endl;
208  exit(0);
209  }
210 
211  /*----------------------------------------------------------------------*/
212  // read options and parameters
213  Options opt;
214  opt.verbose=cmdline.optset(1);
215  opt.overwrite=cmdline.optset(2);
216  opt.datafileformat=cmdline.string_arg(3);
217  opt.writeconvolved=cmdline.optset(4);
218  opt.convolvedfilename=cmdline.string_arg(4);
219  opt.writestf=cmdline.optset(5);
220  opt.stffilename=cmdline.string_arg(5);
221  opt.debug=cmdline.optset(7);
222  opt.debuglevel=cmdline.string_arg(7);
224  if (cmdline.optset(8)) { opt.outputfileformat=cmdline.string_arg(8); }
225  opt.additionalpairs=cmdline.optset(9);
226  opt.additionalseries=cmdline.string_arg(9);
227  if (cmdline.optset(10))
228  {
229  TFXX_assert(opt.additionalpairs,
230  "ERROR: provide input for additional series");
231  opt.additionaloutput=cmdline.string_arg(10);
232  }
233 
234  TFXX_assert(cmdline.extra(), "missing parameter string");
235  std::string parameters=cmdline.next();
236  TFXX_assert(cmdline.extra(), "missing recorded data file name");
237  std::string datafilename=cmdline.next();
238  TFXX_assert(cmdline.extra(), "missing synthetics data file name");
239  std::string syntheticsfilename=cmdline.next();
240 
241  /*----------------------------------------------------------------------*/
242  // go
243  // --
244 
245  // read input data
246  // ---------------
247  typedef aff::Series<float> Tseries;
248  typedef ts::sff::File<Tseries> Tfile;
249  Tfile recordeddata;
250  Tfile syntheticdata;
251  // input for additional series
252  Tfile seriesdata;
253 
254  std::ios_base::openmode iopenmode
255  =datrw::ianystream::openmode(opt.datafileformat);
256  if (opt.verbose) { cout << "open input file " << datafilename << endl; }
257  {
258  std::ifstream ifs(datafilename.c_str(), iopenmode);
259  datrw::ianystream is(ifs, opt.datafileformat);
260  recordeddata.read(is.idatstream(), opt.verbose);
261  }
262 
263  if (opt.verbose) { cout << "open input file " << syntheticsfilename << endl; }
264  {
265  std::ifstream ifs(syntheticsfilename.c_str(), iopenmode);
266  datrw::ianystream is(ifs, opt.datafileformat);
267  syntheticdata.read(is.idatstream(), opt.verbose);
268  }
269 
270  if (opt.additionalpairs)
271  {
272  if (opt.verbose)
273  { cout << "open input file " << opt.additionalseries << endl; }
274  {
275  std::ifstream ifs(opt.additionalseries.c_str(), iopenmode);
276  datrw::ianystream is(ifs, opt.datafileformat);
277  seriesdata.read(is.idatstream(), opt.verbose);
278  }
279  }
280 
281  // check input data consistency and prepare output files
282  // -----------------------------------------------------
283  if (opt.verbose)
284  {
285  cout << "check input data consistency,\n"
286  << "prepare output data containers, and\n"
287  << "prepare waveform data workspace" << endl;
288  }
289 
290  // number of traces per file
291  TFXX_assert(recordeddata.size() == syntheticdata.size(),
292  "ERROR: inconsitent number of traces");
293  const unsigned int ntraces=recordeddata.size();
294 
295  // output data
296  Tfile convolvedsynthetics;
297  Tfile stffile;
298 
299  // waveform data workspace
300  stfinv::Tvectoroftriples vectoroftriples;
301  stfinv::Waveform stfwaveform;
302 
303  convolvedsynthetics.fileheader=syntheticdata.fileheader;
304 
305  // cycle through all traces
306  for (unsigned int itrace=0; itrace<ntraces; ++itrace)
307  {
308  if (opt.verbose)
309  {
310  cout << " check trace #" << itrace+1 << endl;
311  }
312  // create a reference to the time series with trace header for thsi
313  // specific trace as read from file
314  const Tfile::Ttracevector::Ttimeseries& rdtseries=recordeddata[itrace];
315  const Tfile::Ttracevector::Ttimeseries& sdtseries=syntheticdata[itrace];
316 
317  // create a time series to be used in the output of convolved synthetics
318  // based on the input synthetics; copy trace header
320  cstseries(Tfile::Ttracevector::Ttimeseries::Tseries(sdtseries.shape()),
321  sdtseries.header, sdtseries.traceindex());
322 
323  // place reference in a waveform triple
324  stfinv::WaveformTriple tracetriple;
325  tracetriple.data=rdtseries;
326  tracetriple.synthetics=sdtseries;
327  tracetriple.convolvedsynthetics=cstseries;
328  tracetriple.header.sampling.dt=rdtseries.header.wid2().dt;
329  tracetriple.header.sampling.n=rdtseries.header.wid2().nsamples;
330 
331  TFXX_assert((rdtseries.header.wid2().nsamples
332  == sdtseries.header.wid2().nsamples),
333  "ERROR: inconsistent trace size");
334  TFXX_assert(sameineps(rdtseries.header.wid2().dt,
335  sdtseries.header.wid2().dt),
336  "ERROR: inconsistent sampling interval");
337 
338  // read out source coordinates
339  tracetriple.header.sx=recordeddata.fileheader.srce().cx;
340  tracetriple.header.sy=recordeddata.fileheader.srce().cy;
341  tracetriple.header.sz=recordeddata.fileheader.srce().cz;
342 
343  // read out receiver coordinates
344  tracetriple.header.rx=rdtseries.header.info().cx;
345  tracetriple.header.ry=rdtseries.header.info().cy;
346  tracetriple.header.rz=rdtseries.header.info().cz;
347 
348  // check coordinate consistency
349  double ddx=rdtseries.header.info().cx-recordeddata.fileheader.srce().cx;
350  double ddy=rdtseries.header.info().cy-recordeddata.fileheader.srce().cy;
351  double ddz=rdtseries.header.info().cz-recordeddata.fileheader.srce().cz;
352  double sdx=sdtseries.header.info().cx-syntheticdata.fileheader.srce().cx;
353  double sdy=sdtseries.header.info().cy-syntheticdata.fileheader.srce().cy;
354  double sdz=sdtseries.header.info().cz-syntheticdata.fileheader.srce().cz;
355  if (opt.debug)
356  if (!(sameineps(ddx,sdx) && sameineps(ddy,sdy) &&
357  sameineps(ddz,sdz)))
358  {
359  cout << "NOTICE: ";
360  PAROUT(ddx);
361  PAROUT(sdx);
362  PAROUT(ddy);
363  PAROUT(sdy);
364  PAROUT(ddz);
365  PAROUT(sdz);
366  PAROUT(sameineps(ddx,sdx));
367  PAROUT(sameineps(ddy,sdy));
368  PAROUT(sameineps(ddz,sdz));
369  cout << endl;
370  }
371  TFXX_assert((sameineps(ddx,sdx) && sameineps(ddy,sdy) &&
372  sameineps(ddz,sdz)),
373  "ERROR: inconsistent receiver positions");
374 
375  // check time consistency
376  TFXX_assert((rdtseries.header.wid2().date
377  == recordeddata.fileheader.srce().date),
378  "ERROR: trigger delay not supported");
379  TFXX_assert((sdtseries.header.wid2().date
380  == syntheticdata.fileheader.srce().date),
381  "ERROR: trigger delay not supported");
382 
383  // add this triple to collection
384  vectoroftriples.push_back(tracetriple);
385 
386  // add this trace to convolved synthetics
387  convolvedsynthetics.push_back(cstseries);
388 
389  // catch values for stf waveform
390  if (itrace==0)
391  {
393  stftseries
394  =Tfile::Ttracevector::Ttimeseries::Tseries(tracetriple.data.shape());
395 
396  stfwaveform.sampling.dt=tracetriple.header.sampling.dt;
397  stfwaveform.sampling.n=tracetriple.header.sampling.n;
398  stfwaveform.series=stftseries;
399 
400  ::sff::WID2 wid2=stftseries.header.wid2();
401  wid2.nsamples=stfwaveform.sampling.n;
402  wid2.dt=stfwaveform.sampling.dt;
403  wid2.date=libtime::now();
404  stftseries.header.wid2(wid2);
405  ::sff::SRCE srce=stffile.fileheader.srce();
406  srce.date=stftseries.header.wid2().date;
407  stffile.fileheader.srce(srce);
408 
409  stffile.push_back(stftseries);
410  } // if (itrace==0)
411 
412  } // for (unsigned int itrace=0; itrace<ntraces; ++itrace)
413 
414  /*----------------------------------------------------------------------*/
415 
416  // prepare additional pairs
417  Tfile convolvedseries;
418 
419  // waveform data workspace
420  stfinv::Tvectorofpairs vectorofpairs;
421  vectorofpairs.clear();
422 
423  if (opt.additionalpairs)
424  {
425 
426  convolvedseries.fileheader=seriesdata.fileheader;
427  if (opt.verbose)
428  {
429  cout << "prepare additional series to be convolved" << endl;
430  }
431 
432  // cycle through all traces
433  for (unsigned int itrace=0; itrace<seriesdata.size(); ++itrace)
434  {
435  if (opt.verbose)
436  {
437  cout << " check trace #" << itrace+1 << endl;
438  }
439  // create a reference to the time series with trace header for thsi
440  // specific trace as read from file
441  const Tfile::Ttracevector::Ttimeseries& sdtseries=seriesdata[itrace];
442 
443  // create a time series to be used in the output of convolved synthetics
444  // based on the input synthetics; copy trace header
446  cstseries(Tfile::Ttracevector::Ttimeseries::Tseries(sdtseries.shape()),
447  sdtseries.header, sdtseries.traceindex());
448 
449  // place reference in a waveform triple
450  stfinv::WaveformPair tracepair;
451  tracepair.synthetics=sdtseries;
452  tracepair.convolvedsynthetics=cstseries;
453  tracepair.sampling.dt=sdtseries.header.wid2().dt;
454  tracepair.sampling.n=sdtseries.header.wid2().nsamples;
455 
456  // add this triple to collection
457  vectorofpairs.push_back(tracepair);
458 
459  // add this trace to convolved synthetics
460  convolvedseries.push_back(cstseries);
461 
462  } // for (unsigned int itrace=0; itrace<seriesdata.size(); ++itrace)
463 
464  } // if (opt.additionalpairs)
465 
466  /*----------------------------------------------------------------------*/
467 
468  // create STF engine
469  // -----------------
470  if (opt.verbose)
471  {
472  parameters += ":verbose";
473  cout << "create STF engine" << endl;
474  }
475  if (opt.debug) { parameters += ":DEBUG="+opt.debuglevel; }
476  stfinv::STFEngine engine(vectoroftriples, stfwaveform,
477  vectorofpairs, parameters);
478 
479  // run STF engine
480  // --------------
481  if (opt.verbose) { cout << "run engine" << endl; }
482  engine.run();
483 
484  // write results
485  // -------------
486 
487  if (opt.writestf)
488  {
489  if (opt.verbose)
490  {
491  cout << "write STF to file " << opt.stffilename << endl;
492  }
493  if (!opt.overwrite)
494  {
495  std::ifstream file(opt.stffilename.c_str(),std::ios_base::in);
496  TFXX_assert((!file.good()),"ERROR: output file exists!");
497  }
498  std::ios_base::openmode oopenmode
499  =datrw::oanystream::openmode(opt.outputfileformat);
500  std::ofstream ofs(opt.stffilename.c_str(), oopenmode);
501  datrw::oanystream os(ofs, opt.outputfileformat, opt.debug);
502 
503  os << stffile.fileheader.srce();
504  for (unsigned int itrace=0; itrace<stffile.size(); ++itrace)
505  {
506  os << stffile[itrace];
507  }
508  } // if (opt.writestf)
509 
510  if (opt.writeconvolved)
511  {
512  if (opt.verbose)
513  {
514  cout << "write convolved synthetics to file "
515  << opt.convolvedfilename << endl;
516  }
517  if (!opt.overwrite)
518  {
519  std::ifstream file(opt.convolvedfilename.c_str(),std::ios_base::in);
520  TFXX_assert((!file.good()),"ERROR: output file exists!");
521  }
522  std::ios_base::openmode oopenmode
523  =datrw::oanystream::openmode(opt.outputfileformat);
524  std::ofstream ofs(opt.convolvedfilename.c_str(), oopenmode);
525  datrw::oanystream os(ofs, opt.outputfileformat, opt.debug);
526 
527  os << convolvedsynthetics.fileheader.srce();
528  for (unsigned int itrace=0; itrace<convolvedsynthetics.size(); ++itrace)
529  {
530  os << convolvedsynthetics[itrace];
531  }
532  } // if (opt.writeconvolved)
533 
534  if (opt.additionalpairs)
535  {
536  if (opt.verbose)
537  {
538  cout << "write additional convolved series to file "
539  << opt.additionaloutput << endl;
540  }
541  if (!opt.overwrite)
542  {
543  std::ifstream file(opt.additionaloutput.c_str(),std::ios_base::in);
544  TFXX_assert((!file.good()),"ERROR: output file exists!");
545  }
546  std::ios_base::openmode oopenmode
547  =datrw::oanystream::openmode(opt.outputfileformat);
548  std::ofstream ofs(opt.additionaloutput.c_str(), oopenmode);
549  datrw::oanystream os(ofs, opt.outputfileformat, opt.debug);
550 
551  os << convolvedseries.fileheader.srce();
552  for (unsigned int itrace=0; itrace<convolvedseries.size(); ++itrace)
553  {
554  os << convolvedseries[itrace];
555  }
556  } // if (opt.additionalpairs)
557 
558 } // main
559 
560 /* ----- END OF soutifu.cc ----- */
ts::sff::SFFTimeSeries< Tseries > Ttimeseries
Definition: deconv.cc:62
bool additionalpairs
Definition: soutifu.cc:77
#define SOUTIFU_VERSION
Definition: soutifu.cc:40
std::string datafileformat
Definition: soutifu.cc:79
std::string debuglevel
Definition: soutifu.cc:78
bool writeconvolved
Definition: soutifu.cc:76
int main(int iargc, char *argv[])
Definition: soutifu.cc:85
std::string additionalseries
Definition: soutifu.cc:80
bool overwrite
Definition: autocorr.cc:61
std::string stffilename
Definition: soutifu.cc:78
bool debug
Definition: autocorr.cc:61
std::string convolvedfilename
Definition: soutifu.cc:78
bool verbose
Definition: autocorr.cc:61
#define PAROUT(par)
Definition: soutifu.cc:61
std::string additionaloutput
Definition: soutifu.cc:80
bool sameineps(const double &a, const double &b, const double &eps=1.e-8)
Definition: soutifu.cc:66
std::string outputfileformat
Definition: soutifu.cc:79
bool writestf
Definition: soutifu.cc:76
aff::Series< double > Tseries
Definition: cross.cc:69
ts::sff::File< Tseries > Tfile
Definition: foutra.cc:131