Waveform filter programs

◆ main()

int main ( int  iargc,
char *  argv[] 
)

Definition at line 80 of file resaseda.cc.

References cmdlinekeys, Options::debug, Options::delay, Options::delaytime, Options::dt, Options::dtset, Options::edge, Options::inputformat, Options::n, Options::nset, Options::outputformat, Options::overwrite, RESASEDA_VERSION, Options::sampleoffsetbegin, Options::sampleoffsetbeginset, Options::sampleoffsetend, Options::sampleoffsetendset, Options::shrink, Options::timefirst, Options::timefirstset, Options::timelast, Options::timelastset, Options::timespan, Options::timespanset, tracekey, and Options::verbose.

81 {
82 
83  // define usage information
84  char usage_text[]=
85  {
86  RESASEDA_VERSION "\n"
87  "usage: resaseda [-tf time] [-tl time] [-n n] [-dt dt] [-ts time]" "\n"
88  " [-v] [-o] [-sf time] [-sl time] [-edge s]" "\n"
89  " [-delay d] [-type type] [-Type type]\n"
90  " [-sof n] [-sol n] [-shrink]" "\n"
91  " outfile infile [t:T] [infile [t:T] ...]" "\n"
92  " or: resaseda --help|-h" "\n"
93  " or: resaseda --xhelp" "\n"
94  };
95 
96  // define full help text
97  char help_text[]=
98  {
99  "outfile output filename" "\n"
100  "infile input filename" "\n"
101  " t:T select traces T, where T may be any range" "\n"
102  " specification like \'3-4\' or \'5,6,7-12,20\'" "\n"
103  "\n"
104  "-v be verbose" "\n"
105  "-o overwrite output" "\n"
106  "-tf time time of first sample" "\n"
107  " (default: time of first input sample)" "\n"
108  "-tl time time of last sample" "\n"
109  "-sf time time of first sample" "\n"
110  " (default: time of first input sample)" "\n"
111  "-sl time time of last sample" "\n"
112  "-sf and -sl are alternatives to -tf and -tl" "\n"
113  "-n n number of samples" "\n"
114  "-ts time duration of output time series" "\n"
115  "-dt dt new sampling interval in seconds" "\n"
116  "-edge s reduce time window by \"s\" seconds at the edges" "\n"
117  "-type type input format is \'type\'" "\n"
118  "-Type type output format is \'type\'" "\n"
119  "-delay d apply delay of \"d\" seconds by shifting the time\n"
120  " of the first sample in the input series\n"
121  "-sof n define first sample index by offset n\n"
122  " positive sample index: define by offset from first sample\n"
123  " negative sample index: define by offset from last sample\n"
124  "-sol n define last sample index by offset n\n"
125  " positive sample index: define by offset from last sample\n"
126  " negative sample index: define by offset from first sample\n"
127  "-shrink if defined output time window is larger than time span\n"
128  " for which input data is available, reduce output time\n"
129  " window approrpiate for each input trace while maintaining\n"
130  " the defined Ń•ampling raster (useful for input data\n"
131  " containing gaps)\n"
132  };
133 
134  // define commandline options
135  using namespace tfxx::cmdline;
136  static Declare options[]=
137  {
138  // 0: print help
139  {"help",arg_no,"-"},
140  // 1: verbose mode
141  {"v",arg_no,"-"},
142  // 2: overwrite mode
143  {"o",arg_no,"-"},
144  // 3: time of first sample
145  {"tf",arg_yes,"1/1/1"},
146  // 4: time of last sample
147  {"tl",arg_yes,"1/1/1"},
148  // 5: time span
149  {"ts",arg_yes,"1/1/1"},
150  // 6: number of samples
151  {"n",arg_yes,"1"},
152  // 7: sampling interval
153  {"dt",arg_yes,"1."},
154  // 8: DEBUG mode
155  {"D",arg_no,"-"},
156  // 9: input format
157  {"type",arg_yes,"sff"},
158  // 10: time of first sample
159  {"sf",arg_yes,"1/1/1"},
160  // 11: time of last sample
161  {"sl",arg_yes,"1/1/1"},
162  // 12: reduce time window
163  {"edge",arg_yes,"0."},
164  // 13: apply delay
165  {"delay",arg_yes,"0."},
166  // 14: define first sample by offset
167  {"sof",arg_yes,"0"},
168  // 15: define last sample by offset
169  {"sol",arg_yes,"0"},
170  // 16: output format
171  {"Type",arg_yes,"sff"},
172  // 17: extended help
173  {"xhelp",arg_no,"-"},
174  // 18: use shrink option with resample function
175  {"shrink",arg_no,"-"},
176  {NULL}
177  };
178 
179  static const char tracekey[]="t";
180 
181  // define commandline argument modifier keys
182  static const char* cmdlinekeys[]={tracekey, 0};
183 
184  // no arguments? print usage...
185  if (iargc<2)
186  {
187  cerr << usage_text << endl;
188  cerr << tfxx::seitosh::repository_reference << endl;
189  exit(0);
190  }
191 
192  // collect options from commandline
193  Commandline cmdline(iargc, argv, options);
194 
195  // help requested? print full help text...
196  if (cmdline.optset(0))
197  {
198  cerr << usage_text << endl;
199  cerr << help_text << endl;
200  cerr << libtime::usage_time_format_string << endl;
201  cerr << tfxx::seitosh::repository_reference << endl;
202  exit(0);
203  }
204 
205  // help on file format details requested?
206  if (cmdline.optset(17))
207  {
208  cerr << usage_text << endl;
209  cerr << endl;
210  datrw::online_help(cerr);
211  cerr << endl << tfxx::seitosh::repository_reference << endl;
212  exit(0);
213  }
214 
215  Options opt;
216  opt.verbose=cmdline.optset(1);
217  opt.overwrite=cmdline.optset(2);
218  opt.timefirstset=cmdline.optset(3);
219  opt.timefirst=TAbsoluteTime(cmdline.string_arg(3));
220  opt.timelastset=cmdline.optset(4);
221  opt.timelast=TAbsoluteTime(cmdline.string_arg(4));
222  opt.timespanset=cmdline.optset(5);
223  opt.timespan=TRelativeTime(cmdline.string_arg(5));
224  opt.nset=cmdline.optset(6);
225  opt.n=cmdline.int_arg(6);
226  opt.dtset=cmdline.optset(7);
227  opt.dt=cmdline.double_arg(7);
228  opt.debug=cmdline.optset(8);
229  opt.inputformat=cmdline.string_arg(9);
230  if (cmdline.optset(10))
231  {
232  opt.timefirstset=true;
233  opt.timefirst=TAbsoluteTime(cmdline.string_arg(10));
234  }
235  if (cmdline.optset(11))
236  {
237  opt.timelastset=true;
238  opt.timelast=TAbsoluteTime(cmdline.string_arg(11));
239  }
240  opt.edge=libtime::double2time(cmdline.double_arg(12));
241  opt.delay=cmdline.optset(13);
242  opt.delaytime=cmdline.double_arg(13);
243  opt.sampleoffsetbeginset=cmdline.optset(14);
244  opt.sampleoffsetendset=cmdline.optset(15);
245  opt.sampleoffsetbegin=cmdline.int_arg(14);
246  opt.sampleoffsetend=cmdline.int_arg(15);
247  opt.outputformat=cmdline.string_arg(16);
248  opt.shrink=cmdline.optset(18);
249 
250  // check options consistency
251  {
252  int nopt=0;
253  if (opt.timelastset) ++nopt;
254  if (opt.timespanset) ++nopt;
255  if (opt.nset) ++nopt;
256  if (opt.sampleoffsetendset) ++nopt;
257  TFXX_assert(nopt<=1,
258  "only specify one of the options that "
259  "limit the end of the output time window");
260  }
261 
262  // check options consistency
263  {
264  int nopt=0;
265  if (opt.timefirstset) ++nopt;
266  if (opt.sampleoffsetbeginset) ++nopt;
267  TFXX_assert(nopt<=1,
268  "only specify one of the options that "
269  "limit the begin of the output time window");
270  }
271 
272  if (opt.verbose)
273  { cout << RESASEDA_VERSION << endl; }
274 
275  // extract commandline arguments
276  TFXX_assert(cmdline.extra(), "missing output file");
277  std::string outfile=cmdline.next();
278  TFXX_assert(cmdline.extra(), "missing input file");
279  tfxx::cmdline::Tparsed arguments=parse_cmdline(cmdline, cmdlinekeys);
280  if ((arguments.size()>1) && opt.verbose)
281  {
282  cout << "NOTICE: file specific information (SRCE line and file FREE)" <<
283  endl
284  << " will be taken from first file only!" << endl;
285  }
286 
287  /*======================================================================*/
288  // start processing
289 
290  // open output file
291  // ----------------
292  if (opt.verbose) { cout << "open output file " << outfile << endl; }
293  // check if output file exists and open
294  if (!opt.overwrite)
295  {
296  std::ifstream file(outfile.c_str(),std::ios_base::in);
297  TFXX_assert((!file.good()),"ERROR: output file exists!");
298  }
299 
300  std::ofstream ofs(outfile.c_str(),
301  datrw::oanystream::openmode(opt.outputformat));
302  datrw::oanystream os(ofs, opt.outputformat, opt.debug);
303 
304  // prepare file FREE block
305  sff::FREE filefree;
306  filefree.append(RESASEDA_VERSION);
307  // set flag to process header of first input file
308  bool firstfile=true;
309  // cycle through all input files
310  // -----------------------------
311  tfxx::cmdline::Tparsed::const_iterator infile=arguments.begin();
312  while (infile != arguments.end())
313  {
314  // open input file
315  if (opt.verbose) { cout << "open input file " << infile->name << endl; }
316  std::ifstream ifs(infile->name.c_str());
317  datrw::ianystream is(ifs, opt.inputformat);
318  // handle file header
319  if (firstfile)
320  {
321  if (is.hasfree())
322  {
323  sff::FREE infilefree;
324  is >> infilefree;
325  filefree.append("block read from first input file:");
326  filefree.append(infilefree);
327  }
328  os << filefree;
329  if (is.hassrce())
330  {
331  sff::SRCE insrceline;
332  is >> insrceline;
333  os << insrceline;
334  }
335  }
336 
337  // cycle through traces of input file
338  // ----------------------------------
339  // setup trace selection
340  typedef tfxx::RangeList<int> Trangelist;
341  bool doselect=infile->haskey(tracekey);
342  Trangelist traceranges=
343  tfxx::string::rangelist<Trangelist::Tvalue>(infile->value(tracekey));
344  int itrace=0;
345  while (is.good())
346  {
347  ++itrace;
348  if ((!doselect) || traceranges.contains(itrace))
349  {
350  TFXX_debug(opt.debug, "main", "process trace #" << itrace );
351  if (opt.verbose)
352  { std::cout << " process trace #" << itrace << std::endl; }
353  Tseries series;
354  is >> series;
355  sff::WID2 wid2;
356  is >> wid2;
357  TFXX_debug(opt.debug, "main",
358  " series and WID2 are read");
359 
360  // calculate trace specific resampling parameters
361  TAbsoluteTime firstsample=wid2.date+opt.edge;
362  if (opt.timefirstset)
363  { firstsample=opt.timefirst+opt.edge; }
364  else if (opt.sampleoffsetbeginset)
365  {
366  TAbsoluteTime timeofs=firstsample;
367  if (opt.sampleoffsetbegin<0)
368  {
369  timeofs = sff::wid2lastsample(wid2)-
370  (-opt.sampleoffsetbegin)*libtime::double2time(wid2.dt);
371  }
372  else
373  {
374  timeofs += opt.sampleoffsetbegin*libtime::double2time(wid2.dt);
375  }
376  if (timeofs>sff::wid2lastsample(wid2))
377  { timeofs=sff::wid2lastsample(wid2); }
378  if (timeofs<wid2.date)
379  { timeofs=wid2.date; }
380  firstsample=timeofs;
381  }
382 
383  // set time of last sample
384  TAbsoluteTime lastsample=sff::wid2lastsample(wid2)-opt.edge;
385  if (opt.sampleoffsetendset)
386  {
387  TAbsoluteTime timeols=lastsample;
388  if (opt.sampleoffsetend<0)
389  {
390  timeols = firstsample+
391  (-opt.sampleoffsetend)*libtime::double2time(wid2.dt);
392  }
393  else
394  {
395  timeols -= opt.sampleoffsetend*libtime::double2time(wid2.dt);
396  }
397  if (timeols>lastsample)
398  { timeols=lastsample; }
399  if (timeols<firstsample)
400  { timeols=firstsample; }
401  lastsample=timeols;
402  }
403 
404  // set dt
405  TRelativeTime newdt=libtime::double2time(wid2.dt);
406  if (opt.dtset)
407  { newdt=libtime::double2time(opt.dt); }
408  int nsamples=(sff::wid2lastsample(wid2)-opt.edge-firstsample)/newdt;
409 
410  // set number of samples
411  if (opt.nset)
412  { nsamples=opt.n; }
413  else if (opt.timelastset)
414  { nsamples=1+(opt.timelast-opt.edge-firstsample)/newdt; }
415  else if (opt.timespanset)
416  { nsamples=1+opt.timespan/newdt; }
417  else if (opt.sampleoffsetendset)
418  { nsamples=1+(lastsample-opt.edge-firstsample)/newdt; }
419 
420  TFXX_assert(nsamples>0,
421  "ERROR: unreasonable time window");
422 
423  if (opt.verbose)
424  {
425  cout << " resampling parameters are:" << endl
426  << " time of first sample: "
427  << firstsample.timestring() << endl
428  << " sampling interval: " << newdt.timestring() << endl
429  << " number of samples: " << nsamples << endl;
430  if (newdt > libtime::double2time(wid2.dt))
431  {
432  cout << " NOTICE: "
433  << "New sampling interval is larger than old one."
434  << endl
435  << " You are responsible to apply an appropriate"
436  << " anti-alias filter"
437  << endl
438  << " prior to resampling!"
439  << endl;
440  }
441  if (opt.shrink)
442  {
443  cout << " shrink output time window to available input" <<
444  endl
445  << " data while maintaining the defined sampling" <<
446  endl
447  << " raster" << endl;
448  }
449  }
450 
451  // go for interpolation
452  typedef ts::ipo::Interpolator Tinterpolator;
453  ::sff::WID2 inwid2=wid2;
454  if (opt.delay)
455  {
456  if (opt.delaytime<0)
457  {
458  inwid2.date-=libtime::double2time(-opt.delaytime);
459  if (opt.verbose)
460  {
461  cout << " advance series by "
462  << libtime::double2time(-opt.delaytime).timestring() << endl;
463  }
464  }
465  else
466  {
467  inwid2.date+=libtime::double2time(opt.delaytime);
468  cout << " delay series by "
469  << libtime::double2time(opt.delaytime).timestring() << endl;
470  }
471  }
472  Tinterpolator::Tconst_timeseries inseries(series, inwid2);
473  typedef tfxx::Handle<Tinterpolator> Thipo;
474  Thipo hipo(new ts::ipo::LinearInterpolator(inseries, opt.debug));
475  Ttimeseries outseries;
476  bool hot=true;
477  try
478  {
479  outseries=ts::ipo::resample(*hipo, firstsample, newdt, nsamples,
480  opt.shrink);
481  }
482  catch (ts::ipo::ExceptionTimeWindowOutside)
483  {
484  cout << "NOTICE: skipping this trace silently..." << endl;
485  hot=false;
486  }
487  catch (ts::ipo::ExceptionTimeWindowEmpty)
488  {
489  cout << "NOTICE: skipping this trace silently..." << endl;
490  hot=false;
491  }
492  if (hot)
493  {
494  if (opt.shrink && opt.verbose)
495  {
496  cout << " time window returned from interpolator:" << endl
497  << " begin: "
498  << outseries.header.date.timestring() << endl
499  << " end: "
500  << sff::wid2lastsample(outseries.header).timestring() << endl
501  << " number of samples: "
502  << outseries.header.nsamples << endl;
503  }
504  TFXX_debug(opt.debug, "main",
505  " series is resampled");
506  os << outseries.header;
507  TFXX_debug(opt.debug, "main",
508  " series and WID are written");
509  if (is.hasinfo()) { sff::INFO info; is >> info; os << info; }
510  if (is.hasfree() || true)
511  {
512  sff::FREE tracefree;
513  is >> tracefree;
514  tracefree.append(RESASEDA_VERSION);
515  tracefree.append("read from file " + infile->name);
516  os << tracefree;
517  }
518  os << Tseries(outseries);
519  TFXX_debug(opt.debug, "main",
520  "trace #" << itrace << " successfully processed");
521  }
522  }
523  else
524  {
525  TFXX_debug(opt.debug, "main", "skip trace #" << itrace );
526  if (opt.verbose)
527  { std::cout << " skip trace #" << itrace << std::endl; }
528  is.skipseries();
529  }
530  }
531 
532  // go to next file
533  firstfile=false;
534  ++infile;
535  }
536 
537 }
int n
Definition: resaseda.cc:71
ts::sff::SFFTimeSeries< Tseries > Ttimeseries
Definition: deconv.cc:62
bool timefirstset
Definition: resaseda.cc:67
TAbsoluteTime timelast
Definition: resaseda.cc:68
std::string inputformat
Definition: cross.cc:75
bool timespanset
Definition: resaseda.cc:67
static const char * cmdlinekeys[]
Definition: fidasexx.cc:131
TAbsoluteTime timefirst
Definition: resaseda.cc:68
bool shrink
Definition: resaseda.cc:66
bool sampleoffsetbeginset
Definition: resaseda.cc:73
bool overwrite
Definition: autocorr.cc:61
std::string outputformat
Definition: cross.cc:75
double dt
Definition: resaseda.cc:70
bool sampleoffsetendset
Definition: resaseda.cc:73
bool timelastset
Definition: resaseda.cc:67
Ttimeseries::Tseries Tseries
Definition: resaseda.cc:78
bool nset
Definition: resaseda.cc:67
bool debug
Definition: autocorr.cc:61
TRelativeTime edge
Definition: resaseda.cc:69
bool verbose
Definition: autocorr.cc:61
int sampleoffsetend
Definition: resaseda.cc:74
const char *const tracekey
key to select traces
Definition: deconv.cc:68
bool delay
Definition: resaseda.cc:66
double delaytime
Definition: resaseda.cc:70
#define RESASEDA_VERSION
Definition: resaseda.cc:41
TRelativeTime timespan
Definition: resaseda.cc:69
bool dtset
Definition: resaseda.cc:67
aff::Series< double > Tseries
Definition: cross.cc:69
int sampleoffsetbegin
Definition: resaseda.cc:74