149 "usage: sigfit [-v] [-DEBUG] [-Tdate v] [-truncate]" "\n" 150 " [-Sramp[=v]] [-Sconst[=v]] [-Sexp[=v]]" "\n" 151 " [-residual f]" "\n" 152 " [-searchrange[=r]] [-equalsearch] [-skip n]" "\n" 153 " [-itype F] [-otype F]" "\n" 154 " signal [t:T f:F] trial [t:T f:F] [trial [t:T f:F]...]" "\n" 155 " or: sigfit --help|-h" "\n" 162 "-Sramp[=v] add a ramp to the set of trial signals with amplitude v" "\n" 163 "-Sconst[=v] add a constant (of value v) to the set of trial signals" "\n" 164 "-Sexp[=v] add a exponential decay (with time constant v relative" "\n" 165 " to the length of the time series) to the set of trial" "\n" 167 "-Tdate v tolerance for comparison of date of first sample" "\n" 168 " v give the tolerance in units of the sampling interval" "\n" 169 "-truncate truncate all series to the same number of samples" "\n" 170 "-residual f write waveforms containing residual to file \"f\"" "\n" 171 "-searchrange[=r] set search range to stabilize the fit in cases" "\n" 172 " where a trial series does not (or almost not)" "\n" 173 " contribute to the signal" "\n" 174 " the search range r is given in units of" "\n" 175 " rms(signal)/rms(trial signals)" "\n" 176 "-equalsearch use same search range for each trial signal" "\n" 177 "-skip n skip n seconds at beginning of each trace" "\n" 178 "-itype F set input file formats to F (default: sff)" "\n" 179 "-otype F set output (residual) file format to F (default: sff)" "\n" 181 "signal signal to by explained by a linear combination" "\n" 182 " of trial signals" "\n" 183 "trial any set of trial signals" "\n" 185 "File specific options:" "\n" 186 "t:T select specific traces from input file" "\n" 187 " T can be a list of traces like '1,4,5' or" "\n" 188 " a range like '6-19' or mixed like '5,8,12-17,20'" "\n" 189 "f:F specific file format (overrides -itype setting)" "\n" 191 "The last line of the output is a summary of all results." "\n" 192 "This line contains the following information separated by blanks:" "\n" 193 " channel station instrument julian_day date time" "\n" 194 " explained_rms signal_rms residual_rms" "\n" 195 " for each trial signal: regression_coefficient" "\n" 196 " rms_of_all_coefficients" "\n" 197 " for each trial signal: normalized_regression_coefficient" "\n" 198 " for each trial signal: regression_coefficient*trial_signal_rms" "\n" 199 " for each trial signal:" "\n" 200 " normalized_scalar_product_between_trial_signal_and_signal" "\n" 202 "The output file (residual argument on the command line) will contain\n" 203 "several traces (N test signals including DC offset and linear trend):\n" 204 " trace #1 signal, channel name as in input file\n" 205 " trace #2 \"syn\", synthetic trace, superposition of all\n" 207 " trace #3 \"dif\", residual dif=signal-syn\n" 208 " traces #4 - #4+N-1 raw test signals\n" 209 " traces #4+N - #4+2N-1 scaled test signals in units of the final\n" 210 " displaying their contribution to \"syn\"\n" 211 " trace #4+2N \"csi\": csi=signal-cor\n" 212 " trace #4+2N+1 \"cys\": csy=syn-cor\n" 213 " trace #4+2N+2 \"cor\" internal corretion, i.e. the\n" 214 " contributions of the DC offset and the linear\n" 215 " trend to \"syn\"\n" 219 using namespace tfxx::cmdline;
220 static Declare options[]=
227 {
"Tdate",arg_yes,
"0."},
229 {
"truncate",arg_no,
"-"},
231 {
"residual",arg_yes,
"-"},
233 {
"searchrange",arg_opt,
"100."},
235 {
"equalsearch",arg_no,
"-"},
237 {
"Sramp",arg_opt,
"1."},
239 {
"Sconst",arg_opt,
"1."},
241 {
"skip",arg_yes,
"0"},
243 {
"Sexp",arg_opt,
"1."},
245 {
"itype",arg_yes,
"sff"},
247 {
"otype",arg_yes,
"sff"},
249 {
"DEBUG",arg_no,
"-"},
258 static const char*
keys[]={
269 cerr << usage_text << endl;
270 cerr << tfxx::seitosh::repository_reference << endl;
275 Commandline cmdline(iargc, argv, options);
278 if (cmdline.optset(0))
280 cout << usage_text << endl;
281 cout << help_text << endl;
282 cerr << tfxx::seitosh::repository_reference << endl;
289 opt.
Tdate=cmdline.double_arg(2);
300 opt.
skip=cmdline.double_arg(9);
301 opt.
doskip=cmdline.optset(9);
302 opt.
fitexp=cmdline.optset(10);
303 opt.
tcexp=cmdline.double_arg(10);
304 opt.
itype=cmdline.string_arg(11);
305 opt.
otype=cmdline.string_arg(12);
306 opt.
debug=cmdline.optset(13);
311 TFXX_assert(cmdline.extra(),
"ERROR: missing signal file name!");
313 tfxx::cmdline::Tparsed infiles(tfxx::cmdline::parse_cmdline(cmdline,
keys));
320 tfxx::cmdline::Tparsed::const_iterator infile(infiles.begin());
322 "ERROR (sigfit): missing trial signal file name");
323 std::string tracelist(
"1");
325 tfxx::RangeListStepper<int> rls(tfxx::string::rangelist<int>(tracelist));
326 TFXX_assert(rls.valid(),
"Illegal tracelist");
327 std::string signalname(infile->name);
328 int signaltrace = rls.current();
329 std::string signalformat(opt.
itype);
333 sff::FREE signalfilefree, signaltracefree;
334 bool hasSignalFileFree;
338 cout <<
"sigfit: open signal file " << signalname <<
" of format " 339 << signalformat << endl;
341 std::ifstream ifs(signalname.c_str(),
342 datrw::ianystream::openmode(signalformat));
343 datrw::ianystream is(ifs, signalformat);
346 is >> signalfilefree;
347 hasSignalFileFree =
true;
350 while (itrace!=signaltrace) { is.skipseries(); ++itrace; }
351 TFXX_assert(is.good(),
"Illegal trace for signal input");
352 if (opt.
verbose) { cout <<
"read trace" << endl; }
355 if (is.hasfree()) { is >> signaltracefree; }
361 while (infile != infiles.end())
363 std::string itype(opt.
itype);
367 cout <<
"sigfit: Open trial signal file " << infile->name
368 <<
" of format " << itype << endl;
371 std::ifstream ifs(infile->name.c_str(),
372 datrw::ianystream::openmode(itype));
373 datrw::ianystream is(ifs, itype);
375 bool selectedTraces=infile->haskey(
tracekey);
376 tfxx::RangeList<int> rangeList;
379 rangeList = tfxx::string::rangelist<int>(infile->value(
tracekey));
385 bool readthistrace=
true;
386 if (selectedTraces) { readthistrace=rangeList.contains(traceNum); }
391 cout <<
"sigfit: Reading trace #" << traceNum <<
" ..." << endl;
395 bundlevec.push_back(bundle);
398 cout <<
" " << bundle.header.line().substr(0,69) << endl;
410 unsigned int ntracesread=bundlevec.size();
415 if (opt.
verbose) { cout <<
"add offset to trial signals" << endl; }
417 synsignal.header=signal.header;
418 synsignal=
Tseries(signal.shape());
420 synsignal.header.station=
"NSP";
421 synsignal.header.channel=
"off";
422 synsignal.header.auxid=
"NSP";
423 synsignal.header.instype=
"NSP";
424 bundlevec.push_back(synsignal);
429 if (opt.
verbose) { cout <<
"add trend to trial signals" << endl; }
431 synsignal.header=signal.header;
432 synsignal=
Tseries(signal.shape());
433 for (
int i=synsignal.first(); i<=synsignal.last(); ++i)
436 (i-(0.5*(synsignal.first()+synsignal.last())))/
439 synsignal.header.station=
"NSP";
440 synsignal.header.channel=
"ramp";
441 synsignal.header.auxid=
"NSP";
442 synsignal.header.instype=
"NSP";
443 bundlevec.push_back(synsignal);
450 cout <<
"add exponential decay to trial signals" << endl;
453 synsignal.header=signal.header;
454 synsignal=
Tseries(signal.shape());
455 for (
int i=synsignal.first(); i<=synsignal.last(); ++i)
457 double argval=-1.*double(i-synsignal.first())/
458 (
double(synsignal.size())*opt.
tcexp);
459 synsignal(i)=std::exp(argval);
461 synsignal.header.station=
"NSP";
462 synsignal.header.channel=
"exp";
463 synsignal.header.auxid=
"NSP";
464 synsignal.header.instype=
"NSP";
465 bundlevec.push_back(synsignal);
473 if (opt.
verbose) { cout <<
"truncate signals if necessary..." << endl; }
474 long int n=signal.last();
475 for (Tbundlevec::const_iterator i=bundlevec.begin();
476 i!=bundlevec.end(); i++)
477 { n=n<i->last() ? n : i->last(); }
480 signal.setlastindex(n);
481 signal.header.nsamples=signal.size();
482 if (opt.
verbose) { cout <<
"truncate signal to " 483 << signal.header.nsamples <<
" samples" << endl; }
485 for (Tbundlevec::iterator i=bundlevec.begin();
486 i!=bundlevec.end(); i++)
491 i->header.nsamples=signal.size();
492 if (opt.
verbose) { cout <<
"truncate trial signal" << endl
493 << i->header.line() << endl; }
501 sff::WID2compare compare(sff::Fnsamples | sff::Fdt | sff::Fdate);
502 compare.setdatetolerance(opt.
Tdate);
503 if (opt.
verbose) { cout <<
"checking consistency..." << endl; }
504 for (Tbundlevec::const_iterator i=bundlevec.begin(); i!=bundlevec.end(); i++)
506 if (!compare (i->header,signal.header))
508 cerr <<
"ERROR: header signature mismatch:" << endl;
509 cerr <<
"signal:" << endl;
510 cerr << signal.header.line();
511 cerr <<
"trial signal:" << endl;
512 cerr << i->header.line();
513 TFXX_abort(
"baling out...");
524 cout <<
"skip " << opt.
skip <<
" seconds" << endl;
526 int nskip=int(floor(opt.
skip/signal.header.dt));
529 libtime::TRelativeTime add=nskip*libtime::double2time(signal.header.dt);
530 signal.setfirstindex(signal.first()+nskip);
531 signal.header.date+=add;
532 for (Tbundlevec::iterator i=bundlevec.begin();
533 i!=bundlevec.end(); i++)
535 i->setfirstindex(i->first() + nskip);
536 i->header.date += add;
540 cout <<
"skipped " << nskip <<
" samples (" 541 << add.timestring() <<
")" << endl;
548 cout <<
"NOTICE: nothing to skip..." << endl;
549 cout <<
" seems like " 550 << opt.
skip <<
" seconds to skip < " 551 << signal.header.dt <<
" seconds sampling interval" << endl;
557 double signalrms=ts::rms(signal);
560 if (opt.
verbose) { cout <<
"set up system of linear equations..." << endl; }
561 int N=bundlevec.size();
562 if (opt.
verbose) { cout <<
"system is of size " << N <<
"x" << N << endl; }
563 Tmatrix Matrix(N,N), rhs(N), coeff(N), normproduct(N), trialrms(N);
564 double fulltrialrms=0.;
565 for (
int i=1; i<=N; ++i)
567 for (
int k=i; k<=N; ++k)
569 Matrix(i,k)=ts::innerproduct(bundlevec[i-1], bundlevec[k-1]);
570 Matrix(k,i)=Matrix(i,k);
572 rhs(i)=ts::innerproduct(bundlevec[i-1], signal);
573 trialrms(i)=ts::rms(bundlevec[i-1]);
574 fulltrialrms+=(trialrms(i)*trialrms(i));
575 normproduct(i)=rhs(i)/(signalrms*trialrms(i)*signal.size());
577 fulltrialrms=sqrt(fulltrialrms/
double(N));
584 cout <<
"stabilize fit:" << endl;
585 cout <<
" relative search range: " << opt.
searchrange << endl;
587 double searchfac=signal.size()*signalrms;
588 for (
int i=1; i<=N; ++i)
597 cout <<
" search range for trial series " << i
598 <<
" is " << range << endl;
600 Matrix(i,i)+=pow((searchfac/range),2);
605 coeff=linear::lapack::dposv(Matrix,rhs);
609 synthetics=
Tseries(signal.shape());
611 for (
int i=1; i<=N; ++i)
612 { synthetics += coeff(i) * bundlevec[i-1]; }
613 synthetics.header=signal.header;
614 synthetics.header.channel=
"synt";
618 correction=
Tseries(signal.shape());
620 if (ntracesread<bundlevec.size())
622 for (
int i=ntracesread; i<N; ++i)
623 { correction += coeff(i+1) * bundlevec[i]; }
625 correction.header=signal.header;
626 correction.header.channel=
"corr";
628 corrsignal.header=signal.header;
629 corrsignal.header.channel=
"csig";
630 corrsignal=signal-correction;
632 corrsynthetics.header=signal.header;
633 corrsynthetics.header.channel=
"csyn";
634 corrsynthetics=synthetics-correction;
638 residual=
Tseries(signal.shape());
639 residual=signal-synthetics;
640 residual.header=signal.header;
641 residual.header.channel=
"diff";
648 cout <<
"write residual waveform to " << opt.
residualname 649 <<
" in format " << opt.
otype << endl;
652 datrw::oanystream::openmode(opt.
otype));
653 datrw::oanystream os(ofs, opt.
otype, opt.
debug);
654 if (os.handlesfilefree())
656 sff::FREE residualFileFree;
658 if (hasSignalFileFree)
660 residualFileFree.append(
"Signal file free block:");
661 residualFileFree.append(signalfilefree);
663 os << residualFileFree;
665 TFXX_debug(opt.
debug,
"main()",
"write trace signal\n " <<
666 TFXX_value(signal.header.channel) <<
"\n " <<
667 TFXX_value(signal.header.date.timestring()));
669 TFXX_debug(opt.
debug,
"main()",
"write trace synthetics\n " <<
670 TFXX_value(synthetics.header.channel) <<
"\n " <<
671 TFXX_value(synthetics.header.date.timestring()));
673 TFXX_debug(opt.
debug,
"main()",
"write trace residual\n " <<
674 TFXX_value(residual.header.channel) <<
"\n " <<
675 TFXX_value(residual.header.date.timestring()));
677 for (Tbundlevec::const_iterator i=bundlevec.begin();
678 i!=bundlevec.end(); i++)
679 { os << i->header; os << *i; }
680 for (
int i=1; i<=N; ++i)
686 std::sprintf(chan,
"s%1.1d", i);
687 psyn.header.channel=std::string(chan);
692 os << corrsynthetics;
697 double residualrms=ts::rms(residual);
698 double explained=1.-(residualrms/signalrms);
703 for (
int i=1; i<=N; ++i)
704 { length += coeff(i)*coeff(i); }
706 for (
int i=1; i<=N; ++i)
707 { normcoeff(i) = coeff(i)/length; }
709 std::string timestring(signal.header.date.timestring());
710 cout <<
" time: " << timestring.substr(4,21) << endl;
711 cout <<
" channel: " << signal.header.channel << endl;
712 cout <<
" station: " << signal.header.station << endl;
713 cout <<
" instrument: " << signal.header.instype << endl;
714 cout <<
" signalrms: " << signalrms << endl;
715 cout <<
" residualrms: " << residualrms << endl;
716 cout <<
"explained rms: " << explained << endl;
717 cout <<
" coefficients: ";
718 for (
int i=1; i<=N; ++i)
719 { cout << coeff(i) <<
" "; }
721 cout <<
" rms coeffic.: " << length << endl;
722 cout <<
" normalized coefficients: ";
723 for (
int i=1; i<=N; ++i)
724 { cout << normcoeff(i) <<
" "; }
726 cout <<
" coefficients x rms: ";
727 for (
int i=1; i<=N; ++i)
729 cout << coeff(i)*trialrms(i) <<
" ";
732 cout <<
" normalized scalar product: ";
733 for (
int i=1; i<=N; ++i)
735 cout << normproduct(i) <<
" ";
740 cout << signal.header.station <<
" " 741 << signal.header.channel <<
" " 742 << signal.header.instype <<
" " 743 << timestring <<
" ";
747 for (
int i=1; i<=N; ++i)
752 for (
int i=1; i<=N; ++i)
756 for (
int i=1; i<=N; ++i)
760 for (
int i=1; i<=N; ++i)
std::vector< Tbundle > Tbundlevec
aff::Array< Tbundle::Tseries::Tvalue > Tmatrix
static const char formatkey[]
const char * keys[]
list of keys for filename specific parameters
std::string formatfloat(const double &v)
const char *const tracekey
key to select traces
ts::TDsfftimeseries Tbundle