LISOUSI: Line Source Simulation

◆ main()

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

Definition at line 82 of file lisousi.cc.

References Options::debug, description_text, IntegParam::edge, experimental_text, Options::fdfilter, Options::fdtype, Ffdexplosion, Ffdfarfield, Ffdlamb, Ffdwizforce, Ffdzforce, Options::fredomain, help_text, Options::inputformat, Options::integshift, Options::ipa, Options::limitlength, LISOUSI_VERSION, Options::nointeg, Options::npad, IntegParam::nsteps, Parameters::offset, Options::outputformat, Options::overwrite, padseries(), Options::pquality, Model::Qp, Model::Qs, Options::radial, singlevelocitytransformation(), Options::spatialdistance, Options::sqrttaper, Options::squality, Options::tapdel, IntegParam::taper, Options::taperfirst, Options::tapslo, Options::tapsloset, Options::tdfilter, tdtapertransformation(), Options::tfac, Options::tlim, Options::transition, Options::transition1, Options::transition2, transitionmixer(), Options::tshift, usage_text, Options::velocity, Options::verbose, Model::Vp, Options::vpvsratio, and Model::Vs.

83 {
84 
85  // define usage information
86  char usage_text_version[]=
87  {
88  LISOUSI_VERSION "\n"
89  };
90 
91  // define commandline options
92  using namespace tfxx::cmdline;
93  static Declare options[]=
94  {
95  // 0: print help
96  {"help",arg_no,"-"},
97  // 1: output file format
98  {"xhelp",arg_opt,"all"},
99  // 2: generate debug output
100  {"DEBUG",arg_no,"-"},
101  // 3: verbose mode
102  {"v",arg_no,"-"},
103  // 4: overwrite mode
104  {"o",arg_no,"-"},
105  // 5: input file format
106  {"type",arg_yes,"sff"},
107  // 6: output file format
108  {"Type",arg_yes,"sff"},
109  // 7: apply taper first, than do convolution
110  {"taperlast",arg_no,"-"},
111  // 8: use Picas taper
112  {"sqrttaper",arg_no,"-"},
113  // 9: limit the number of samples
114  {"limitlength",arg_no,"-"},
115  // 10: processing shall take place in the Fourier domain
116  {"fredomain",arg_no,"-"},
117  // 11: scaling velocity in the Fourier domain
118  {"velocity",arg_yes,"1."},
119  // 12: apply filter in the time domain
120  {"tdfilter",arg_no,"-"},
121  // 13: apply filter by analytic Fourier coefficients
122  {"fdfilter",arg_no,"-"},
123  // 14: pad with zeroes
124  {"pad",arg_yes,"1"},
125  // 15: shift time axis
126  {"tshift",arg_yes,"1."},
127  // 16: lower limit of time values
128  {"tlim",arg_yes,"0."},
129  // 17: fixed value of time for small values
130  {"tfac",arg_yes,"0.1"},
131  // 18: choose convolution weights by integration
132  {"integshift",arg_yes,"0.5"},
133  // 19: delay taper function
134  {"tapdel",arg_yes,"0."},
135  // 20: do not use integration for construction of 1/sqrt(t)
136  {"nointeg",arg_no,"-"},
137  // 21: upper limit slowness
138  {"tapslo",arg_yes,"0."},
139  // 22: transition from fredomain to standard approach
140  {"transition",arg_yes,"0.,1."},
141  // 23: exact single velocity transformation (instead of far-field
142  // approximation)
143  {"fdexplosion",arg_no,"-"},
144  // 24: single force in full space
145  {"fdzforce",arg_no,"-"},
146  // 25: single vertical force on homogeneous halfspace (Lamb's problem)
147  {"fdlamb",arg_no,"-"},
148  // 26: vp/vs ratio
149  {"vpvsratio",arg_yes,"1.732"},
150  // 27: quality factor or P-wave and S-wave modulus
151  {"quality",arg_yes,"30.,30."},
152  // 28: trapezoid rule parameters for wavenumber integration
153  {"ktrapezoid",arg_yes,"1000,2.,0.1"},
154  // 29: use specific radial component transformation, where applicable
155  {"radial",arg_no,"-"},
156  // 30: single force in full space by wavenumber integration
157  {"fdwizforce",arg_no,"-"},
158  // 31: use spatial distance to source rather than offset along surface
159  {"spatialdistance",arg_no,"-"},
160  // 32: report undocumented and experimental options
161  {"listexperimental",arg_no,"-"},
162  {NULL}
163  };
164 
165  /*----------------------------------------------------------------------*/
166  /* we keep the framework for file specific parameters
167  * but we do not use them
168  */
169 
170  static const char formatkey[]="f";
171  static const char tracekey[]="t";
172  /*
173  static const char applykey[]="a";
174  static const char prefiltertaperkey[]="prft";
175  static const char postfiltertaperkey[]="poft";
176  */
177 
178  // define commandline argument modifier keys
179  static const char* cmdlinekeys[]
180  ={formatkey, tracekey, 0};
181  /*
182  ={tracekey, formatkey, applykey, prefiltertaperkey, postfiltertaperkey, 0};
183  */
184 
185  /*----------------------------------------------------------------------*/
186 
187  // no arguments? print usage...
188  if (iargc<2)
189  {
190  cerr << usage_text_version << endl;
191  cerr << usage_text << endl;
192  cerr << tfxx::seitosh::repository_reference << endl;
193  exit(0);
194  }
195 
196  // collect options from commandline
197  Commandline cmdline(iargc, argv, options);
198 
199  // help requested? print full help text...
200  if (cmdline.optset(0))
201  {
202  cerr << usage_text_version << endl;
203  cerr << usage_text << endl;
204  cerr << help_text << endl;
205  cerr << endl;
206  cerr << description_text << endl;
207  datrw::supported_data_types(cerr);
208  cerr << endl << tfxx::seitosh::repository_reference << endl;
209  exit(0);
210  }
211 
212  // help on file format details requested?
213  if (cmdline.optset(1))
214  {
215  cerr << usage_text_version << endl;
216  cerr << usage_text << endl;
217  cerr << endl;
218  if (cmdline.string_arg(1) == "all")
219  {
220  datrw::online_help(cerr);
221  }
222  else
223  {
224  datrw::online_help(cmdline.string_arg(1), cerr);
225  }
226  exit(0);
227  }
228 
229  // list experimental options
230  if (cmdline.optset(32))
231  {
232  cerr << usage_text_version << endl;
233  cerr << usage_text << endl;
234  cerr << endl;
235  cerr << experimental_text << endl;
236  exit(0);
237  }
238 
239  // extract commandline options
240  Options opt;
241  // 1 is --xhelp
242  {
243  std::istringstream iss;
244  std::string args;
245  opt.debug=cmdline.optset(2);
246  opt.verbose=cmdline.optset(3);
247  opt.overwrite=cmdline.optset(4);
248  opt.inputformat=cmdline.string_arg(5);
249  opt.outputformat=cmdline.string_arg(6);
250  opt.taperfirst=!cmdline.optset(7);
251  opt.sqrttaper=cmdline.optset(8);
252  opt.limitlength=cmdline.optset(9);
253  opt.fredomain=cmdline.optset(10);
254  opt.velocity=cmdline.double_arg(11);
255  opt.tdfilter=cmdline.optset(12);
256  opt.fdfilter=cmdline.optset(13);
257  opt.npad=cmdline.int_arg(14);
258  opt.tshift=cmdline.double_arg(15);
259  opt.tlim=cmdline.double_arg(16);
260  opt.tfac=cmdline.double_arg(17);
261  opt.integshift=cmdline.double_arg(18);
262  opt.tapdel=cmdline.double_arg(19);
263  opt.nointeg=cmdline.optset(20);
264  opt.tapslo=cmdline.double_arg(21);
265  opt.tapsloset=cmdline.optset(21);
266  opt.transition=cmdline.optset(22);
267  opt.fdtype=Ffdfarfield;
268  if (cmdline.optset(23)) { opt.fdtype=Ffdexplosion; };
269  if (cmdline.optset(24)) { opt.fdtype=Ffdzforce; };
270  if (cmdline.optset(25)) { opt.fdtype=Ffdlamb; };
271  opt.vpvsratio=cmdline.double_arg(26);
272  args=cmdline.string_arg(27);
273  args.replace(args.find(","),1," ");
274  iss.str(args);
275  iss >> opt.pquality >> opt.squality;
276  args=cmdline.string_arg(28);
277  args.replace(args.find(","),1," ");
278  iss.str(args);
279  iss >> opt.ipa.nsteps >> opt.ipa.edge >> opt.ipa.taper;
280  opt.radial=cmdline.optset(29);
281  if (cmdline.optset(30)) { opt.fdtype=Ffdwizforce; };
282  opt.spatialdistance=cmdline.optset(31);
283  }
284 
285  /* ---------------------------------------------------------------------- */
286  /* check options for plausibility, etc */
287 
288  // notify user if experimental option is selected
289  if ((opt.fdtype==Ffdexplosion) ||
290  (opt.fdtype==Ffdzforce) ||
291  (opt.fdtype==Ffdlamb) ||
292  (opt.fdtype==Ffdwizforce) || (opt.radial)) {
293  cerr << "WARNING:" << endl;
294  cerr << "You selected an experimental option!" << endl;
295  cerr << "This function is not yet properly implemented." << endl;
296  cerr << "It is not well tested and is likely to provide" << endl;
297  cerr << "false results.\n" << endl;
298  }
299 
300  // check offset range for hybrid transformation
301  if (opt.transition)
302  {
303  std::istringstream transopt(tfxx::string::patsubst(cmdline.string_arg(22),
304  ",", " "));
305  transopt >> opt.transition1 >> opt.transition2;
306  TFXX_assert((opt.transition1>=0.) && (opt.transition2>=0.),
307  "transition offsets must be positive");
308  TFXX_assert(opt.transition2>opt.transition1,
309  "second transition offset must be larger than first");
310  }
311 
312  // plausibility checks for command line parameters
313  TFXX_assert(opt.tshift>=0.,
314  "just positive shifting is allowed");
315  TFXX_assert(opt.tlim>=0.,
316  "just positive times are allowed");
317  TFXX_assert(opt.tfac>=0.,
318  "just positive time values are allowed");
319  TFXX_assert((opt.integshift>=0.)&&(opt.integshift<1.),
320  "just values in [0.,1.) are allowed for -integ parameter");
321  TFXX_assert(opt.tapslo>=0.,
322  "just positive slowness values are allowed");
323 
324  /* ---------------------------------------------------------------------- */
325 
326  if (opt.verbose)
327  { cout << LISOUSI_VERSION << endl; }
328 
329  // extract commandline arguments
330  TFXX_assert(cmdline.extra(), "missing output file");
331  std::string outfile=cmdline.next();
332  TFXX_assert(cmdline.extra(), "missing input file");
333  tfxx::cmdline::Tparsed arguments=parse_cmdline(cmdline, cmdlinekeys);
334  if ((arguments.size()>1) && opt.verbose)
335  {
336  cout << "NOTICE: file specific information (SRCE line and file FREE)" <<
337  endl
338  << " will be taken from first file only!" << endl;
339  }
340 
341  /*======================================================================*/
342  /*
343  * all prerequisites exist
344  * options and parameters are extracted from the command line
345  * file names are extracted from the command line
346  *
347  */
348 
349  /*----------------------------------------------------------------------*/
350  /*
351  * report: what are we going to apply to the data
352  *
353  * prepare a character string FREE block
354  * this can be written to file as well as output to terminal
355  */
356  sff::FREE processingreport;
357 
358  /*----------------------------------------------------------------------*/
359  // prepare file FREE block
360  sff::FREE filefree;
361  {
362  filefree.append(LISOUSI_VERSION);
363  std::string line;
364  filefree.append("output file name:");
365  filefree.append(" " + outfile);
366  filefree.append("input file selection:");
367  tfxx::cmdline::Tparsed::const_iterator file=arguments.begin();
368  while (file != arguments.end())
369  {
370  filefree.append(" " + file->name);
371  line=" ";
372  tfxx::cmdline::Toptionmap::const_iterator option=file->options.begin();
373  while (option != file->options.end())
374  {
375  line += " " + option->first + ":" + option->second;
376  ++option;
377  }
378  if (line.size()>2) { filefree.append(line); }
379  ++file;
380  }
381  if (arguments.size()>1)
382  {
383  filefree.append("In cases where more than one input file is read,");
384  filefree.append("the SRCE line is taken from the first file only (if");
385  filefree.append("present there).");
386  }
387  filefree.append(processingreport);
388  }
389 
390  if (opt.verbose) { cout << filefree << endl; }
391 
392  /*======================================================================*/
393  // start actual processing
394  // =======================
395  //
396 
397  // prepare expansion coefficients for wavenumber integration methods
398  Exco expansioncoefficients;
399 
400  if (opt.fredomain)
401  {
402  Model mod;
403  mod.Vs=1.e3*opt.velocity;
404  mod.Vp=1.e3*opt.velocity*opt.vpvsratio;
405  mod.Qs=opt.squality;
406  mod.Qp=opt.pquality;
407  if (opt.fdtype==Ffdwizforce)
408  {
409  FSECZ ec(mod);
410  expansioncoefficients=Exco(ec, opt.ipa);
411  }
412  else if (opt.fdtype==Ffdlamb)
413  {
414  if (opt.radial)
415  {
416  HSECR ec(mod);
417  expansioncoefficients=Exco(ec, opt.ipa);
418  }
419  else
420  {
421  HSECZ ec(mod);
422  expansioncoefficients=Exco(ec, opt.ipa);
423  }
424  }
425  }
426 
427  /*----------------------------------------------------------------------*/
428 
429  // open output file
430  // ----------------
431  if (opt.verbose) { cout << "open output file " << outfile << endl; }
432  // check if output file exists and open
433  if (!opt.overwrite)
434  {
435  std::ifstream file(outfile.c_str(),std::ios_base::in);
436  TFXX_assert((!file.good()),"ERROR: output file exists!");
437  }
438  std::ios_base::openmode oopenmode
439  =datrw::oanystream::openmode(opt.outputformat);
440  std::ofstream ofs(outfile.c_str(), oopenmode);
441  datrw::oanystream os(ofs, opt.outputformat, opt.debug);
442 
443  // set flag to process header of first input file
444  bool firstfile=true;
445  // cycle through all input files
446  // -----------------------------
447  tfxx::cmdline::Tparsed::const_iterator infile=arguments.begin();
448  while (infile != arguments.end())
449  {
450  // open input file
451  if (opt.verbose) { cout << "open input file " << infile->name << endl; }
452  std::string inputformat=opt.inputformat;
453  if (infile->haskey(formatkey))
454  {
455  inputformat=infile->value(formatkey);
456  }
457  std::ios_base::openmode iopenmode
458  =datrw::ianystream::openmode(inputformat);
459  std::ifstream ifs(infile->name.c_str(), iopenmode);
460  datrw::ianystream is(ifs, inputformat);
461 
462  // handle file header
463  // ------------------
464  sff::SRCE insrceline;
465  bool srceavailable=false;
466  if (firstfile)
467  {
468  if (is.hasfree())
469  {
470  sff::FREE infilefree;
471  is >> infilefree;
472  filefree.append("block read from first input file:");
473  filefree.append(infilefree);
474  }
475  if (os.handlesfilefree()) { os << filefree; }
476  if (is.hassrce())
477  {
478  is >> insrceline;
479  srceavailable=true;
480  if (os.handlessrce()) { os << insrceline; }
481  }
482  }
483 
484  // cycle through traces of input file
485  // ----------------------------------
486  // setup trace selection
487  typedef tfxx::RangeList<int> Trangelist;
488  bool doselect=infile->haskey(tracekey);
489  Trangelist traceranges=
490  tfxx::string::rangelist<Trangelist::Tvalue>(infile->value(tracekey));
491 
492  int itrace=0;
493  while (is.good())
494  {
495  ++itrace;
496  if ((!doselect) || traceranges.contains(itrace))
497  {
498  TFXX_debug(opt.debug, "main", "process trace #" << itrace );
499  if (opt.verbose)
500  { std::cout << "process trace #" << itrace << ":"; }
501  Tseries series;
502  is >> series;
503  sff::WID2 wid2;
504  is >> wid2;
505  TFXX_debug(opt.debug, "main", " series and WID2 are read:\n" << wid2);
506  sff::INFO info;
507  if (is.hasinfo()) { is >> info; }
508 
509  // apply filter only if requested
510  // ------------------------------
511  if ((!doselect) || traceranges.contains(itrace))
512  {
513  /*======================================================================*/
514  /* actual processing takes place here */
515 
516  // pad in the case of frequency domain processing
517  if (!opt.tdfilter)
518  {
519  series=padseries(series, opt);
520  }
521 
522  // extract trace parameters
523  TFXX_assert(is.hasinfo() && srceavailable,
524  "Source and receiver coordinates are required");
525 
526  Parameters par;
527  if (opt.spatialdistance)
528  {
529  par.offset=::sff::sourcedistance(insrceline, info);
530  }
531  else
532  {
533  par.offset=::sff::offset(insrceline, info);
534  }
535  par.t0=libtime::time2double(insrceline.date-wid2.date);
536  par.T=wid2.dt*series.size();
537  par.dt=wid2.dt;
538  par.nsamples=wid2.nsamples;
539 
540  if (opt.verbose)
541  {
542  cout << " offset=" << par.offset << "m"
543  << "; "
544  << " t0=" << par.t0 << "s"
545  << "; "
546  << " T=" << par.T << "s"
547  << "; "
548  << " dt=" << par.dt << "s"
549  << endl;
550  }
551 
552  TFXX_assert(fabs(par.t0) < 1.e-6,
553  "Cannot handle shift of time origin in data");
554 
555  // store space for results
556  Tseries singlevelocityseries, directwaveseries;
557 
558  /* processing is prepared
559  * select different approaches
560  * ---------------------------
561  */
562  if (opt.fredomain || (opt.transition &&
563  (par.offset <= opt.transition2)))
564  {
565  singlevelocityseries
567  par,
568  expansioncoefficients,
569  opt);
570  }
571 
572  if ((!opt.fredomain) || (opt.transition &&
573  (par.offset >= opt.transition1)))
574  {
575  directwaveseries=tdtapertransformation(series,
576  par,
577  opt);
578  }
579 
580  /* transformation results are available
581  * construct final output
582  */
583  // mixing stage
584  if (opt.transition)
585  {
586  series=transitionmixer(singlevelocityseries,
587  directwaveseries,
588  par, opt);
589  }
590  else if (opt.fredomain)
591  {
592  series=singlevelocityseries;
593  }
594  else
595  {
596  series=directwaveseries;
597  }
598 
599  if (opt.limitlength)
600  {
601  series.setlastindex(wid2.nsamples+series.f()-1);
602  }
603 
604  TFXX_debug(opt.debug, "main", " series is filtered");
605  /*
606  * processing has finished
607  */
608  /*======================================================================*/
609 
610  if (opt.verbose) { std::cout << " filtered" << std::endl; }
611  // ------------------------------
612  }
613  else
614  {
615  if (opt.verbose) { std::cout << " passed unchanged" << std::endl; }
616  }
617 
618  os << wid2;
619  if (is.hasinfo()) { if (os.handlesinfo()) { os << info; } }
620  if (is.hasfree() || true)
621  {
622  sff::FREE tracefree;
623  is >> tracefree;
624  tracefree.append(LISOUSI_VERSION);
625  tracefree.append("read from file " + infile->name);
626  if ((!doselect) || traceranges.contains(itrace))
627  {
628  tracefree.append(processingreport);
629  }
630  else
631  {
632  tracefree.append("passed unchanged");
633  }
634  if (os.handlestracefree()) { os << tracefree; }
635  }
636  TFXX_debug(opt.debug, "main",
637  "trace #" << itrace << " successfully processed");
638  os << series;
639  TFXX_debug(opt.debug, "main", " series and WID are written");
640  }
641  else
642  {
643  TFXX_debug(opt.debug, "main", "skip trace #" << itrace );
644  if (opt.verbose)
645  { std::cout << " skip trace #" << itrace << std::endl; }
646  is.skipseries();
647  }
648  }
649 
650  // go to next file
651  firstfile=false;
652  ++infile;
653  }
654 
655 }
Ttimeseries::Tseries Tseries
Definition: lisousi.h:71
double edge
edge factor at upper limit of wavenumber range
Definition: lisousi.h:107
double squality
Definition: lisousi.h:128
bool tapsloset
Definition: lisousi.h:119
bool fredomain
Definition: lisousi.h:119
double velocity
Definition: lisousi.h:128
std::string inputformat
Definition: lisousi.h:124
double vpvsratio
Definition: lisousi.h:128
char usage_text[]
Definition: usage_text.cc:3
int nsteps
number of steps
Definition: lisousi.h:105
char description_text[]
double tapdel
Definition: lisousi.h:121
time series parameters.
Definition: lisousi.h:138
double integshift
Definition: lisousi.h:121
double tlim
Definition: lisousi.h:121
bool nointeg
Definition: lisousi.h:119
double transition2
Definition: lisousi.h:122
bool overwrite
Definition: lisousi.h:118
std::string outputformat
Definition: lisousi.h:124
bool spatialdistance
Definition: lisousi.h:120
double Vs
S-wave propagation velocity.
Definition: wnintegration.h:49
double Qp
P-wave quality.
Definition: wnintegration.h:51
bool debug
Definition: lisousi.h:117
TFourier::Tseries singlevelocitytransformation(const TFourier::Tseries &series, const Parameters &par, const Exco &ec, const Options &opt)
double Vp
P-wave propagation velocity.
Definition: wnintegration.h:47
double tshift
Definition: lisousi.h:121
TFourier::Tseries transitionmixer(TFourier::Tseries singlevelocityseries, TFourier::Tseries directwaveseries, const Parameters &par, const Options &opt)
bool limitlength
Definition: lisousi.h:118
bool tdfilter
Definition: lisousi.h:119
bool taperfirst
Definition: lisousi.h:118
double Qs
S-wave quality.
Definition: wnintegration.h:53
int npad
Definition: lisousi.h:123
TFourier::Tseries tdtapertransformation(TFourier::Tseries series, Parameters &par, const Options &opt)
double pquality
Definition: lisousi.h:128
bool verbose
Definition: lisousi.h:117
bool radial
Definition: lisousi.h:118
IntegParam ipa
Definition: lisousi.h:130
double tfac
Definition: lisousi.h:121
TFourier::Tseries padseries(const TFourier::Tseries &series, const Options &opt)
Definition: padseries.cc:41
Efdtype fdtype
Definition: lisousi.h:126
bool transition
Definition: lisousi.h:119
double offset
either epicentral distance or hypocentral distance.
Definition: lisousi.h:150
double tapslo
Definition: lisousi.h:122
bool fdfilter
Definition: lisousi.h:119
bool sqrttaper
Definition: lisousi.h:118
char experimental_text[]
double transition1
Definition: lisousi.h:122
double taper
taper fraction at upper limit of wavenumber range
Definition: lisousi.h:109
char help_text[]
Definition: help_text.cc:3
#define LISOUSI_VERSION
Definition: lisousi.cc:67
Here is the call graph for this function: