81 "usage: fregra [-v] [-o] [-type type] [-Type type] [-D] [-boxcar]" "\n" 82 " [-fmin f] [-fmax f] [-n n] [-olap f]\n" 83 " [-width f] [-log]\n" 84 " outpattern infile [t:T] [infile [t:T] ...]" "\n" 85 " or: fregra --help|-h" "\n" 86 " or: fregra --xhelp" "\n" 88 "NOTICE: fregra is not yet fully implemented!" 94 "outpattern name pattern for output file (may contain %N, which\n" 95 " will be replaced by sequential number).\n" 96 "infile input file (traces can be selected by the a list\n" 97 " definition like 3,5,8-12)\n" 100 "-o overwrite existing output file\n" 101 "-type type select input file type\n" 102 "-Type type select output file type\n" 103 "-DEBUG produce debug output\n" 104 "-boxcar use boxcar window (default: Hanning)\n" 105 "-fmin f smallest frequency to be used\n" 106 "-fmax f largest frequency to be used\n" 107 "-n n number of frequencies to be used\n" 108 "-olap f overlap of time windows\n" 109 "-width f width of frequency resolution\n" 110 "-log use logarithmic frequency scale\n" 114 using namespace tfxx::cmdline;
115 static Declare options[]=
124 {
"DEBUG",arg_no,
"-"},
126 {
"boxcar",arg_no,
"-"},
128 {
"fmin",arg_yes,
"0.1"},
130 {
"fmax",arg_yes,
"1."},
134 {
"olap",arg_yes,
"0.5"},
136 {
"width",arg_yes,
"2."},
140 {
"type",arg_yes,
"sff"},
142 {
"Type",arg_yes,
"sff"},
144 {
"xhelp",arg_no,
"-"},
156 cerr << usage_text << endl;
161 Commandline cmdline(iargc, argv, options);
164 if (cmdline.optset(0) || cmdline.optset(13))
166 cerr << usage_text << endl;
167 cerr << help_text << endl;
168 datrw::supported_input_data_types(cerr);
169 datrw::supported_output_data_types(cerr);
170 if (cmdline.optset(13)) { datrw::online_help(cerr); }
177 opt.
debug=cmdline.optset(3);
178 opt.
boxcar=cmdline.optset(4);
179 opt.
fmin=cmdline.double_arg(5);
180 opt.
fmax=cmdline.double_arg(6);
181 opt.
nfreq=cmdline.int_arg(7);
182 opt.
olap=cmdline.double_arg(8);
183 opt.
width=cmdline.double_arg(9);
184 opt.
log=cmdline.optset(10);
189 TFXX_assert((opt.
fmin > 0),
"illegal frequency value");
190 TFXX_assert((opt.
fmax > 0),
"illegal frequency value");
191 TFXX_assert((opt.
olap > 0) && (opt.
olap<1.),
"illegal overlap value");
192 TFXX_assert((opt.
width > 0),
"illegal width value");
193 TFXX_assert((opt.
nfreq > 0),
"illegal number of frequencies");
199 TFXX_assert(cmdline.extra(),
"missing output file pattern");
200 std::string outpattern=cmdline.next();
201 TFXX_assert(cmdline.extra(),
"missing input file");
203 tfxx::cmdline::Tparsed arguments=parse_cmdline(cmdline,
cmdlinekeys);
204 if ((arguments.size()>1) && opt.
verbose)
206 cout <<
"NOTICE: only the first trace will be processed!" <<
212 sff::FREE processfree;
214 ts::tapers::Hanning hanningtaper;
220 double lfmin=std::log10(opt.
fmin);
221 double lfmax=std::log10(opt.
fmax);
222 double ldf=(lfmax-lfmin)/(static_cast<double>(opt.
nfreq)-1);
223 for (
int i=0; i<opt.
nfreq; ++i)
225 frequencies(i)=std::pow(10.,lfmin+i*ldf);
230 double df=(opt.
fmax-opt.
fmin)/(static_cast<double>(opt.
nfreq)-1);
231 for (
int i=0; i<opt.
nfreq; ++i)
233 frequencies(i)=opt.
fmin+i*df;
240 unsigned int otrace=0;
241 tfxx::cmdline::Tparsed::const_iterator infile=arguments.begin();
242 while (infile != arguments.end())
246 if (opt.
verbose) { cout <<
"open input file " << infile->name << endl; }
247 std::ifstream ifs(infile->name.c_str(),
252 sff::FREE infilefree;
253 if (is.hasfree()) { is >> infilefree; }
254 sff::SRCE insrceline;
255 if (is.hassrce()) { is >> insrceline; }
260 unsigned int itrace=0;
261 typedef tfxx::RangeList<int> Trangelist;
262 bool doselect=infile->haskey(
tracekey);
263 Trangelist traceranges=
264 tfxx::string::rangelist<Trangelist::Tvalue>(infile->value(
tracekey));
268 if ((!doselect) || traceranges.contains(itrace))
272 TFXX_debug(opt.
debug,
"main",
"process trace #" << itrace );
275 { std::cout <<
" process trace #" << itrace << std::endl; }
286 ::sff::FREE inputtracefree;
287 is >> inputtracefree;
290 std::ostringstream oss;
294 std::string outfile=outpattern;
298 outfile=tfxx::string::patsubst(outfile,
"%N",
299 tfxx::string::trimws(oss.str()));
301 if (opt.
verbose) { cout <<
"open output file " << outfile << endl; }
305 std::ifstream file(outfile.c_str(),std::ios_base::in);
306 TFXX_assert((!file.good()),
"ERROR: output file exists!");
308 std::ofstream ofs(outfile.c_str(),
313 ::sff::FREE outfilefree;
315 oss <<
"trace #" << itrace <<
" from file " << infile->name;
316 outfilefree.append(oss.str());
317 outfilefree.append(processfree);
319 ::sff::SRCE outsrce=insrce;
327 for (
int ifreq=0; ifreq<opt.
nfreq; ++ifreq)
332 const double pi=3.141592653589793115998;
333 const double pi2=2.*
pi;
336 if (ifreq<opt.
nfreq-1)
338 df=frequencies(ifreq+1)-frequencies(ifreq);
342 double fwidth=df*opt.
width;
343 double twin=1./(pi2*fwidth);
344 int nwin=
static_cast<int>(twin/(dt));
345 TFXX_assert(nwin>0,
"ERROR: invalid value!");
346 int nstep=
static_cast<int>(twin/(dt*opt.
olap));
347 if (nstep<1) { nstep=1; }
350 ::sff::FREE tracefree;
352 oss <<
"processing frequency #" << ifreq
353 <<
" " << frequencies(ifreq) <<
" Hz";
354 tracefree.append(oss.str());
356 oss <<
"frequency resolution: " << fwidth <<
" Hz";
357 tracefree.append(oss.str());
359 oss <<
"Fourier transform window size: " 360 << nwin <<
" samples, " 361 << nwin*dt <<
" seconds";
362 tracefree.append(oss.str());
364 oss <<
"Fourier transform window shifting: " 365 << nstep <<
" samples";
366 tracefree.append(oss.str());
367 tracefree.append(inputtracefree);
371 outinfo.cs=sff::CS_cartesian;
372 outinfo.cx=frequencies(ifreq);
374 Tseries fregram(inputseries.shape());
377 typedef std::complex<double> Tcplx;
378 typedef aff::Series<Tcplx> Tcoeff;
379 unsigned int isize=
static_cast<unsigned int>(2*nwin+1);
382 Tcplx ftexpfac=ime*pi2*frequencies(ifreq)*dt;
383 for (
int i=ftfac.f(); i<=ftfac.l(); ++i)
384 { ftfac(i)=std::exp(ftexpfac*static_cast<double>(i)); }
388 double tapscaling=1.;
398 hanningtaper.apply(ftfac);
403 double scalingfactor=2.*tapscaling/(isize*dt);
404 ftfac *= scalingfactor;
408 for (
int i=0; i<2*nstep; ++i)
410 depfac(i)=-0.5*(std::cos(pi2*i/(2*nstep-1))-1.);
414 int isample=inputseries.first();
415 while (isample <=inputseries.last())
418 std::complex<double> C(0.,0.);
419 int imin=isample-nwin;
420 int imax=isample+nwin;
421 for (
int i=imin; i<=imax; ++i)
423 if ((i>=inputseries.first()) && (i<=inputseries.last()))
426 C += ftfac(i-imin-ftfac.f())*inputseries(i);
429 double PSD=C.real()*C.real()+C.imag()*C.imag();
432 int ibase=isample-nstep;
433 for (
int i=0; i<2*nstep; ++i)
436 if ((j>=fregram.f())&&(j<=fregram.l()))
438 fregram(j)+=depfac(i)*PSD;
457 { std::cout <<
" skipping trace #" << itrace << std::endl; }
static const char * cmdlinekeys[]
const char *const tracekey
key to select traces
aff::Series< double > Tseries