291 "usage: cross [-v] [-o] [-D] [-convolve] [--itype t] [--otype f]\n" 293 " file [f:F] [t:T] [file [f:F] [t:T] [...]] outfile\n" 294 " or: cross --help|-h" "\n" 295 " or: cross --xhelp" "\n" 303 "-o overwrite existing output file" "\n" 304 "-convolve apply convolution rather than correlation\n" 305 "-fourier operate in the Fourier domain\n" 306 "-itype t file format for input files\n" 307 "-otype t file format for output files\n" 309 "file ... input file(s)" "\n" 310 " t:T select traces T, where T may be any range\n" 311 " specification like '3-4' or '5,6,7-12,20'\n" 312 " f:F specifies an input file format differing from\n" 313 " the format selected by \"--itype\"\n" 314 "outfile output file" "\n" 316 "--xhelp print details on supported I/O formats\n" 318 "The first trace read will be taken as a reference. All other\n" 319 "traces will be cross-correlated with the reference or convolved\n" 320 "with the reference. Convolution and cross-correlation are understood\n" 321 "as an approximation to the corresponding integral form. Consequently\n" 322 "the sampling interval of time series must be identical and the\n" 323 "result of the discrete operation will be scaled with the sampling\n" 326 "Data time will be handled as follows:\n" 329 " The reference series is understood as the impulse response of a\n" 330 " filter which s to be applied to the other input series. If a\n" 331 " source date is given in the file of the reference trace, this will\n" 332 " be taken as the origin of time, allowing for acausal impulse\n" 333 " response. If it is missing, the first sample of the reference (filter\n" 334 " impulse response) is understood to be at lag=0s. The date of the\n" 335 " first sample of the output trace is set to account for possible\n" 336 " acausal parts of the filter response. Source definition is taken\n" 337 " only from the first of the input files and is passed unaltered to\n" 340 "Cross-correlation\n" 341 " Each input trace is cross-correlated with the reference trace.\n" 342 " When calculating the lag time, absolute time of the first sample\n" 343 " of each of the traces is taken into account. Absolute time of the\n" 344 " output is set with respect to the source time. The source time is\n" 345 " taken from the file header of the reference trace. If a source time\n" 346 " is missing there, it will be set to a default value.\n" 348 "If option -convolve is selected, all traces will be convolved with\n" 349 "the reference trace.\n" 354 using namespace tfxx::cmdline;
355 static Declare options[]=
366 {
"convolve",arg_no,
"-"},
368 {
"xhelp",arg_no,
"-"},
370 {
"itype",arg_yes,
"sff"},
372 {
"otype",arg_yes,
"sff"},
374 {
"fourier",arg_no,
"-"},
394 cerr << usage_text << endl;
399 Commandline cmdline(iargc, argv, options);
402 if (cmdline.optset(0) || cmdline.optset(5))
404 cerr << usage_text << endl;
405 cerr << help_text << endl;
407 datrw::supported_data_types(cerr);
409 if (cmdline.optset(5))
412 datrw::online_help(cerr);
422 opt.
debug=cmdline.optset(3);
430 TFXX_assert(cmdline.extra(),
"missing input file!");
431 tfxx::cmdline::Tparsed arguments=parse_cmdline(cmdline,
cmdlinekeys);
432 TFXX_assert(arguments.size()>1,
"missing output file!");
434 std::string outfile=arguments.back().name;
435 arguments.pop_back();
437 if ((arguments.size()>1) && opt.
verbose)
440 <<
"NOTICE: file specific information (SRCE line and file FREE)" << endl
441 <<
" will be taken from first file only!" << endl;
453 if (opt.
verbose) { cout <<
"open output file " << outfile << endl; }
455 if (!opt.
overwrite) { datrw::abort_if_exists(outfile); }
456 std::ios_base::openmode oopenmode
458 std::ofstream ofs(outfile.c_str(), oopenmode);
459 TFXX_debug(opt.
debug,
"main()",
"open os");
461 TFXX_debug(opt.
debug,
"main()",
"os is open");
467 bool referenceread=
false;
470 ts::sff::FileHeader referencefileheader;
473 tfxx::cmdline::Tparsed::const_iterator infile=arguments.begin();
474 while (infile!=arguments.end())
476 if (opt.
verbose) { cout <<
"open " << std::string(infile->name) << endl; }
482 std::ios_base::openmode iopenmode
483 =datrw::ianystream::openmode(inputformat);
484 std::ifstream ifs(infile->name.c_str(), iopenmode);
485 datrw::ianystream is(ifs, inputformat);
489 ts::sff::FileHeader fileheader;
495 typedef tfxx::RangeList<int> Trangelist;
496 bool doselect=infile->haskey(
tracekey);
497 Trangelist traceranges=
498 tfxx::string::rangelist<Trangelist::Tvalue>(infile->value(
tracekey));
504 if (doselect && (!traceranges.contains(iftrace)))
507 { std::cout <<
" skip trace #" << iftrace << std::endl; }
512 if (opt.
verbose) { std::cout <<
"process trace #" << iftrace <<
": "; }
519 sff::FREE freeblock(fileheader.free());
524 if (!fileheader.hassrce())
527 srce.date=libtime::TAbsoluteTime(2000);
528 fileheader.srce(srce);
529 freeblock.append(
"added SRCE definition to file header");
532 fileheader.free(freeblock);
534 referencefileheader=fileheader;
539 { std::cout <<
"read reference trace" << std::endl; }
542 if (opt.
verbose) { cout << reference.header.wid2().line() << endl; }
545 TFXX_debug(opt.
debug,
546 "main()",
"prepare FFTreference " 547 << TFXX_value(reference.header.wid2().dt));
549 TFXX_debug(opt.
debug,
550 "main()", TFXX_value(dtreference.header.dt));
551 FFTreference.setseries(dtreference);
556 if (opt.
verbose) { cout <<
"read trace" << endl; }
559 if (opt.
verbose) { cout << data.header.wid2().line() << endl; }
560 TFXX_assert((data.header.wid2().dt == reference.header.wid2().dt),
561 "sampling intervals do not match!");
563 sff::WID2 wid2line(data.header.wid2());
566 TFXX_debug(opt.
debug,
567 "main()",
"prepare FFTdata");
569 FFTdata.setseries(dtdata);
575 TFXX_debug(opt.
debug,
576 "main()",
"start convolution in the Fourier domain");
577 unsigned int n=data.size()+reference.size();
578 TFXX_debug(opt.
debug,
579 "main()",
"padded size: " << TFXX_value(n));
580 FourierProcessor::Tspectrum::Tcoc sdata=FFTdata(n);
581 FourierProcessor::Tspectrum::Tcoc sreference=FFTreference(n);
582 TFXX_debug(opt.
debug,
583 "main()",
"call specconv " 584 << TFXX_value(sreference.size()) <<
", " 585 << TFXX_value(sdata.size()));
587 sresult=
specconv(sreference, sdata);
588 TFXX_debug(opt.
debug,
589 "main()",
"returned: " << TFXX_value(sresult.size()));
590 result=FFT(sresult, reference.header.wid2().dt);
594 result=ts::convolve(reference,data);
595 result *= wid2line.dt;
597 wid2line.auxid=
"conv";
600 if (referencefileheader.hasfree())
603 libtime::TRelativeTime t0(reference.header.wid2().date
604 -referencefileheader.srce().date);
605 if (reference.header.wid2().date
606 <referencefileheader.srce().date)
618 unsigned int n=data.size()+reference.size();
619 FourierProcessor::Tspectrum::Tcoc sdata=FFTdata(n);
620 FourierProcessor::Tspectrum::Tcoc sreference=FFTreference(n);
622 sresult=
speccorr(sreference, sdata);
623 result=FFT(sresult, reference.header.wid2().dt);
627 result=ts::correlate(reference,data);
628 result *= wid2line.dt;
630 wid2line.auxid=
"corr";
646 libtime::TRelativeTime
647 Tr(libtime::double2time(reference.header.wid2().dt
648 *(reference.header.wid2().nsamples-1)));
649 libtime::TRelativeTime
650 Ts(libtime::double2time(data.header.wid2().dt
651 *(data.header.wid2().nsamples-1)));
652 libtime::TRelativeTime tor(data.header.wid2().date
653 -reference.header.wid2().date);
654 libtime::TAbsoluteTime
655 torigin=referencefileheader.srce().date-((Tr+Ts)/2);
656 if (data.header.wid2().date
657 >=reference.header.wid2().date)
665 wid2line.date=torigin;
667 result.header.wid2(wid2line);
674 if (opt.
verbose) { cout << result.header.wid2().line() << endl; }
Tfft::Tspectrum Tspectrum
type of Fourier coefficient data
fourier::fft::DRFFTWAFF Tfft
type of FFT processor
static const char * cmdlinekeys[]
FourierProcessor::Tspectrum specconv(const FourierProcessor::Tspectrum::Tcoc &sref, const FourierProcessor::Tspectrum::Tcoc &ssig)
Tts::Tdttimeseries Tdttimeseries
static const char formatkey[]
const char *const tracekey
key to select traces
FourierProcessor::Tspectrum speccorr(const FourierProcessor::Tspectrum::Tcoc &sref, const FourierProcessor::Tspectrum::Tcoc &ssig)