Waveform filter programs

◆ main()

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

Definition at line 70 of file teseco.cc.

References Options::add, cmdlinekeys, Options::datetolerance, Options::debug, Options::inputformat, Options::outputformat, Options::overwrite, TESECO_VERSION, tracekey, Options::trimseries, and Options::verbose.

71 {
72 
73  // define usage information
74  char usage_text[]=
75  {
76  TESECO_VERSION "\n"
77  "usage: teseco [-v] [-o] [-a] [-type type] [-Type type]" "\n"
78  " [-datetolerance t] [-trim]" "\n"
79  " outfile signal [t:T] [f:F]\n"
80  " infile [t:T] [f:F] [infile [t:T] [f:F] ... ]" "\n"
81  " or: teseco --help|-h" "\n"
82  " or: teseco --xhelp" "\n"
83  };
84 
85  // define full help text
86  char help_text[]=
87  {
88  "The program reads time series traces and adds or subtracts other" "\n"
89  "time series scaled by individual factors. This way a barometric" "\n"
90  "pressure correction or magentic field correction may be applied" "\n"
91  "to seismic recordings." "\n"
92  "\n"
93  "All input traces (all traces in signal and correction files) are\n"
94  "expected to cover the same time window. This program is not able\n"
95  "to handle time series containing gaps properly.\n"
96  "\n"
97  "outfile output filename" "\n"
98  "signal signal filename (multiple traces may be selected;\n"
99  " each correction will be applied to each of them)\n"
100  "infile name of file containing correction; scaled traces" "\n"
101  " will be subtraced from (or added to) the signals" "\n"
102  " t:T select traces T, where T may be any range" "\n"
103  " specification like \'3-4\' or \'5,6,7-12,20\'" "\n"
104  " f:F each of the traces will be scaled by the factor \'F\'\n"
105  " (default: F=1.)" "\n"
106  "\n"
107  "-v verbose mode" "\n"
108  "-o overwrite existing output file" "\n"
109  "-a rather add than subtract correction signals" "\n"
110  "-type type input file type (default: sff)" "\n"
111  "-Type type output file type (default: sff)" "\n"
112  "-datetolerance f\n"
113  " set a tolerance level f for comparison of date of\n"
114  " input time series; dates will be considered as different\n"
115  " if they differ by more than a fraction f of the average\n"
116  " sampling interval\n"
117  "-trim trim all series to the shortest series provided\n"
118  " if not set, providing series of different number of samples\n"
119  " is considered to be an error\n"
120  };
121 
122  // define commandline options
123  using namespace tfxx::cmdline;
124  static Declare options[]=
125  {
126  // 0: print help
127  {"help",arg_no,"-"},
128  // 1: verbose mode
129  {"v",arg_no,"-"},
130  // 2: overwrite mode
131  {"o",arg_no,"-"},
132  // 3: add mode
133  {"a",arg_no,"-"},
134  // 4: input file type
135  {"type",arg_yes,"sff"},
136  // 5: debug mode
137  {"D",arg_no,"-"},
138  // 6: output file type
139  {"Type",arg_yes,"sff"},
140  // 7: report details regarding data types
141  {"xhelp",arg_no,"-"},
142  // 8: set date and time tolerance when checking consistency
143  {"datetolerance",arg_yes,"0."},
144  // 9: trim size of series to the least number of samples
145  {"trim",arg_no,"-"},
146  {NULL}
147  };
148 
149  static const char tracekey[]="t";
150  static const char factorkey[]="f";
151 
152  // define commandline argument modifier keys
153  static const char* cmdlinekeys[]={
154  tracekey,
155  factorkey,
156  0
157  }; // cmdlinekeys
158 
159  // no arguments? print usage...
160  if (iargc<2)
161  {
162  cerr << usage_text << endl;
163  cerr << tfxx::seitosh::repository_reference << endl;
164  exit(0);
165  }
166 
167  // collect options from commandline
168  Commandline cmdline(iargc, argv, options);
169 
170  // help requested? print full help text...
171  if (cmdline.optset(0))
172  {
173  cerr << usage_text << endl;
174  cerr << help_text << endl;
175  cerr << endl;
176  datrw::supported_data_types(cerr);
177  cerr << endl << tfxx::seitosh::repository_reference << endl;
178  exit(0);
179  }
180 
181  // help on file format details requested?
182  if (cmdline.optset(7))
183  {
184  cerr << usage_text << endl;
185  cerr << endl;
186  datrw::online_help(cerr);
187  cerr << endl << tfxx::seitosh::repository_reference << endl;
188  exit(0);
189  }
190 
191  Options opt;
192  opt.verbose=cmdline.optset(1);
193  opt.overwrite=cmdline.optset(2);
194  opt.add=cmdline.optset(3);
195  opt.inputformat=cmdline.string_arg(4);
196  opt.debug=cmdline.optset(5);
197  opt.outputformat=cmdline.string_arg(6);
198  opt.datetolerance=cmdline.double_arg(8);
199  opt.trimseries=cmdline.optset(9);
200 
201  if (opt.verbose)
202  { cout << TESECO_VERSION << endl; }
203 
204  // extract commandline arguments
205  TFXX_assert(cmdline.extra(), "missing output file");
206  std::string outfile=cmdline.next();
207  TFXX_assert(cmdline.extra(), "missing signal file");
208  tfxx::cmdline::Tparsed infiles=parse_cmdline(cmdline, cmdlinekeys);
209  TFXX_assert((infiles.size()>1), "missing correction file");
210  tfxx::cmdline::Filename sigfile=infiles.front();
211  infiles.pop_front();
212 
213  /*======================================================================*/
214  // start processing
215 
216  // open output file
217  // ----------------
218  if (opt.verbose) { cout << "open output file " << outfile << endl; }
219  // check if output file exists and open
220  if (!opt.overwrite)
221  {
222  std::ifstream file(outfile.c_str(),std::ios_base::in);
223  TFXX_assert((!file.good()),"ERROR: output file exists!");
224  }
225  std::ios_base::openmode oopenmode
226  =datrw::oanystream::openmode(opt.outputformat);
227  std::ofstream ofs(outfile.c_str(), oopenmode);
228  datrw::oanystream os(ofs, opt.outputformat);
229 
230  // prepare the largest number of samples found in one of the input series so
231  // far
232  unsigned int maxsamples=0;
233 
234  // prepare file FREE block
235  sff::FREE filefree;
236  filefree.append(TESECO_VERSION);
237 
238  // read signal file
239  typedef ts::sff::File<Tseries> Tfile;
240  typedef Tfile::Trangelist Trangelist;
241  Tfile signal;
242  {
243  bool doselect=sigfile.haskey(tracekey);
244  Trangelist traceranges=
245  tfxx::string::rangelist<Trangelist::Tvalue>(sigfile.value(tracekey));
246 
247  if (opt.verbose) { cout << "open signal file " << sigfile.name << endl; }
248 
249  std::ios_base::openmode iopenmode
250  =datrw::ianystream::openmode(opt.inputformat);
251  std::ifstream ifs(sigfile.name.c_str(), iopenmode);
252  datrw::ianystream is(ifs, opt.inputformat);
253 
254  // read selected traces
255  if (doselect)
256  { signal.read(is.idatstream(), traceranges, opt.verbose); }
257  else
258  { signal.read(is.idatstream(), opt.verbose); }
259 
260  TFXX_assert(signal.size()>0,
261  "set of input signals is empty");
262 
263  // apply factor to each of the traces, if selected
264  if (sigfile.haskey(factorkey))
265  {
266  double factor=1.;
267  std::istringstream sfactor(sigfile.value(factorkey));
268  sfactor >> factor;
269  for (Tfile::Ttracevector::iterator isig=signal.begin();
270  isig != signal.end(); ++isig)
271  {
272  *isig *= factor;
273  }
274  } // if (sigfile.haskey(factorkey))
275 
276  // set max samples if series are to be trimmed
277  if (opt.trimseries)
278  {
279  for (Tfile::Ttracevector::iterator isig=signal.begin();
280  isig != signal.end(); ++isig)
281  {
282  TFXX_assert(isig->size()>0, "missing samples in input signal");
283  if ((maxsamples == 0) || (maxsamples > isig->size()))
284  {
285  maxsamples = isig->size();
286  }
287  }
288  } // if (opt.trimseries)
289 
290  }
291  TFXX_assert((signal.size()>0), "missing signal");
292  signal.fileheader.append(filefree);
293 
294 
295  // SFF WID2 compare
296  sff::WID2compare compare(sff::Fdt | sff::Fdate);
297  compare.setdatetolerance(opt.datetolerance);
298 
299  // cycle through all input files
300  // -----------------------------
301  tfxx::cmdline::Tparsed::const_iterator infile=infiles.begin();
302  while (infile != infiles.end())
303  {
304  // open input file
305  if (opt.verbose) { cout << "open correction file "
306  << infile->name << endl; }
307 
308  std::ios_base::openmode iopenmode
309  =datrw::ianystream::openmode(opt.inputformat);
310  std::ifstream ifs(infile->name.c_str(), iopenmode);
311  datrw::ianystream is(ifs, opt.inputformat);
312 
313  // cycle through traces of input file
314  // ----------------------------------
315 
316  // setup trace selection
317  typedef tfxx::RangeList<int> Trangelist;
318  bool doselect=infile->haskey(tracekey);
319  Trangelist traceranges=
320  tfxx::string::rangelist<Trangelist::Tvalue>(infile->value(tracekey));
321 
322  // setup correction factor
323  double factor=1.;
324  if (infile->haskey(factorkey))
325  {
326  std::istringstream sfactor(infile->value(factorkey));
327  sfactor >> factor;
328  }
329  if (opt.add) { factor *= -1.; }
330 
331  int itrace=0;
332  while (is.good())
333  {
334  ++itrace;
335  if ((!doselect) || traceranges.contains(itrace))
336  {
337  { std::cout << " process trace #" << itrace << std::endl; }
338  Tseries series;
339  is >> series;
340  sff::WID2 wid2;
341  is >> wid2;
342 
343  series *= factor;
344  for (Tfile::Ttracevector::iterator isig=signal.begin();
345  isig != signal.end(); ++isig)
346  {
347  // check matching headers
348  if (!compare (isig->header.wid2(),wid2))
349  {
350  cerr << "ERROR: header signature mismatch:" << endl;
351  cerr << "signal:" << endl;
352  cerr << isig->header.wid2().line();
353  cerr << "correction signal:" << endl;
354  cerr << wid2.line();
355 
356  // check start date explicitly and provide a hint
357  sff::WID2compare cmpdate(sff::Fdate);
358  cmpdate.setdatetolerance(opt.datetolerance);
359  if (!cmpdate(isig->header.wid2(),wid2))
360  {
361  cerr << "*** date mismatch "
362  << "(consider to use option -datetolerance)" << endl;
363  cerr << "*** signal: ";
364  cerr << isig->header.wid2().date.timestring() << endl;
365  cerr << "*** correction signal: ";
366  cerr << wid2.date.timestring() << endl;
367  }
368  TFXX_abort("bailing out...");
369  } // if (!compare (isig->header.wid2(),wid2))
370 
371  // check matching size
372  if (isig->size() != series.size())
373  {
374  if (opt.trimseries)
375  {
376  if (maxsamples > isig->size()) { maxsamples = isig->size(); }
377  if (maxsamples > series.size()) { maxsamples = series.size(); }
378  isig->setlastindex(isig->first()-1+maxsamples);
379  series.setlastindex(series.first()-1+maxsamples);
380  }
381  else
382  {
383  cerr << "ERROR: inconsistent number of samples:" << endl;
384  cerr << isig->size() << " samples for signal" << endl;
385  cerr << isig->header.wid2().line();
386  cerr << series.size() << " samples for correction signal"
387  << endl;
388  cerr << wid2.line();
389  cerr << "consider to use option -trim" << endl;
390  TFXX_abort("bailing out...");
391  } // else, if (opt.trimseries)
392  } // (isig->size() != series.size())
393 
394  // apply correction
395  *isig -= series;
396  }
397 
398  }
399  else
400  {
401  TFXX_debug(opt.debug, "main", "skip trace #" << itrace );
402  if (opt.verbose)
403  { std::cout << " skip trace #" << itrace << std::endl; }
404  is.skipseries();
405  }
406  }
407 
408  // go to next file
409  ++infile;
410  }
411  os << signal;
412 }
#define TESECO_VERSION
Definition: teseco.cc:40
std::string inputformat
Definition: cross.cc:75
static const char * cmdlinekeys[]
Definition: fidasexx.cc:131
bool overwrite
Definition: autocorr.cc:61
std::string outputformat
Definition: cross.cc:75
bool trimseries
Definition: teseco.cc:65
bool debug
Definition: autocorr.cc:61
bool verbose
Definition: autocorr.cc:61
const char *const tracekey
key to select traces
Definition: deconv.cc:68
bool add
Definition: teseco.cc:65
aff::Series< double > Tseries
Definition: cross.cc:69
double datetolerance
Definition: deconv.cc:81
ts::sff::File< Tseries > Tfile
Definition: foutra.cc:131