Fourier library: Operations in the Fourier domain
cxxfftwartest.cc
Go to the documentation of this file.
1 
37 #define CXXFFTWARTEST_VERSION \
38  "CXXFFTWARTEST V1.2 test fftw3 array engine"
39 
40 // use the input/output facilities from the standard library
41 #include <iostream>
42 #include <fstream>
43 
44 // use output string streams to create strings
45 #include <sstream>
46 
47 // use the vector container from the STL (standard template library) to store
48 // collections of traces and files
49 #include <vector>
50 
51 // use command line argument reader from libtfxx
52 #include <tfxx/commandline.h>
53 #include <tfxx/xcmdline.h>
54 
55 // use the error handling and debugging facilities from libtfxx
56 #include <tfxx/error.h>
57 #include <tfxx/misc.h>
58 
59 // use the facility in libtfxx to handle lists of trace number ranges
60 #include <tfxx/rangestring.h>
61 #include <tfxx/rangelist.h>
62 
63 // use series container from libaff
64 #include <aff/series.h>
65 
66 // use data file reading and writing facility from libdatrwxx
67 #include <datrwxx/readany.h>
68 #include <datrwxx/writeany.h>
69 
70 // use operators defined for series
71 #include <aff/seriesoperators.h>
72 // use operators defined for array
73 #include <aff/arrayoperators.h>
74 
75 // use fft modules
76 #include <fourier/fftwaff.h>
77 #include <fourier/fftwaffar.h>
78 
79 /*----------------------------------------------------------------------*/
80 
81 using std::cout;
82 using std::cerr;
83 using std::endl;
84 
85 /*----------------------------------------------------------------------*/
86 
87 // a struct to store values of command line arguments
88 struct Options {
89  // be verbose
91  // file format to be used
92  std::string fileformat;
93  // overwrite output files in case they already exist
94  bool overwrite;
95 }; // struct Options
96 
97 /*----------------------------------------------------------------------*/
98 
99 // type of actual time series samples
100 typedef double Tvalue;
101 
102 // type of time series
103 typedef aff::Series<Tvalue> Tseries;
104 
105 /*----------------------------------------------------------------------*/
106 
107 // a struct to store the contents of one data trace
108 struct Trace {
109  // the time series
111  // number of trace in file
113  // the waveform header (sampling rate, etc)
114  sff::WID2 wid2;
115  // coordinates of receiver
116  sff::INFO info;
117 }; // struct Trace
118 
119 // several traces (e.g. the traces of one file) are collected in a vector
120 // of the STL (standard template library)
121 typedef std::vector<Trace> Tvecoftraces;
122 
123 /*======================================================================*/
124 
125 int main(int iargc, char* argv[])
126 {
127 
128  // define usage information
129  char usage_text[]=
130  {
132  "usage: cxxfftwartest input output [-s] [-v] [-o] [-x] [-type f]" "\n"
133  " or: cxxfftwartest --help|-h" "\n"
134  " or: cxxfftwartest --xhelp" "\n"
135  };
136 
137  // define full help text
138  char help_text[]=
139  {
140  "\n"
141  "input input file name\n"
142  "output output file name\n"
143  "\n"
144  "-v verbose mode\n"
145  "-s report container sizes\n"
146  "-o overwrite output file\n"
147  "-x reverse order of DRFFTWAFF and DRFFTWAFFArrayEngine\n"
148  " (see below)\n"
149  "-type f file format\n"
150  "\n"
151  "Fourier coefficients for input time series are obtained from\n"
152  "DRFFTWAFFArrayEngine. Then time series are constructed from these\n"
153  "coefficients by application of DRFFTWAFF. If the -x option is\n"
154  "selected, both transformation tools are exchanged in the\n"
155  "application order.\n"
156  };
157 
158  // define commandline options
159  using namespace tfxx::cmdline;
160  static Declare options[]=
161  {
162  // 0: print help
163  {"help",arg_no,"-"},
164  // 1: print detailed online help
165  {"xhelp",arg_no,"-"},
166  // 2: verbose mode
167  {"v",arg_no,"-"},
168  // 3: overwrite mode
169  {"o",arg_no,"-"},
170  // 4: file type
171  {"type",arg_no,"sff"},
172  // 5: report container sizes
173  {"s",arg_no,"-"},
174  // 6: exchange engines
175  {"x",arg_no,"-"},
176  {NULL}
177  };
178 
179  // no arguments? print usage...
180  if (iargc<2)
181  {
182  cerr << usage_text << endl;
183  exit(0);
184  }
185 
186  // collect options from commandline
187  Commandline cmdline(iargc, argv, options);
188 
189  // help requested? print full help text...
190  if (cmdline.optset(0))
191  {
192  cerr << usage_text << endl;
193  cerr << help_text << endl;
194  datrw::supported_data_types(cerr);
195  exit(0);
196  }
197 
198  // help on file format details requested?
199  if (cmdline.optset(1))
200  {
201  cerr << usage_text << endl;
202  cerr << endl;
203  datrw::online_help(cerr);
204  exit(0);
205  }
206 
207  Options opt;
208 
209  opt.verbose=cmdline.optset(2);
210  opt.overwrite=cmdline.optset(3);
211  opt.fileformat=cmdline.string_arg(4);
212  opt.verbsize=cmdline.optset(5);
213  opt.exchangeengines=cmdline.optset(6);
214 
215  // report program version if in verbose mode
216  if (opt.verbose)
217  { cout << CXXFFTWARTEST_VERSION << endl; }
218 
219  // extract commandline arguments
220  // here the rest of the command line is parsed; i.e. the names of input
221  // files together with file specific options
222  TFXX_assert(cmdline.extra(), "missing input file");
223  std::string infilename=cmdline.next();
224  TFXX_assert(cmdline.extra(), "missing output file");
225  std::string outfilename=cmdline.next();
226 
227  /*----------------------------------------------------------------------*/
228 
229  // here we read the input file
230  // ---------------------------
231 
232  // open input file
233  // ---------------
234  if (opt.verbose) { cout << "open input file " << infilename << endl; }
235  // open the input file with appropriate input mode
236  std::ios_base::openmode iopenmode
237  =datrw::ianystream::openmode(opt.fileformat);
238  // open file stream
239  std::ifstream ifs(infilename.c_str(), iopenmode);
240  // open seismic time series stream
241  datrw::ianystream is(ifs, opt.fileformat);
242 
243  // read file specific header information
244  sff::SRCE srce;
245  is >> srce;
246 
247  /*----------------------------------------------------------------------*/
248 
249  // read all traces from this file
250  // ------------------------------
251 
252  Tvecoftraces vecoftraces;
253  // count traces
254  unsigned int itrace=0;
255 
256  unsigned int nsamples=0;
257 
258  // read next trace, while input stream is good
259  while (is.good())
260  {
261  // count traces
262  ++itrace;
263 
264  // create a place to store trace data
265  Trace trace;
266 
267  // remember number of trace
268  trace.tracenumber=itrace;
269 
270  // read trace data
271  is >> trace.series;
272  is >> trace.wid2;
273  is >> trace.info;
274 
275  nsamples=nsamples > trace.series.size() ? nsamples : trace.series.size();
276 
277  // trace data is read; add to collection
278  vecoftraces.push_back(trace);
279 
280  } // while (is.good())
281 
282  /*----------------------------------------------------------------------*/
283 
284  unsigned int ntraces=vecoftraces.size();
285 
286  /*----------------------------------------------------------------------*/
287 
288  if (opt.verbose)
289  {
290  cout << "input files are read..." << endl;
291  }
292 
293  if (opt.verbose)
294  {
295  cout << "number of traces: " << ntraces << endl;
296  cout << "number of samples in largest trace: " << nsamples << endl;
297  }
298 
299  /*----------------------------------------------------------------------*/
300 
301  if (opt.exchangeengines)
302  {
303  // prepare array engine
304  if (opt.verbose) { cout << "create FFT array engine" << endl; }
306  primaryengine=fourier::fft::DRFFTWAFFArrayEngine(ntraces, nsamples);
307  fourier::fft::DRFFTWAFFArrayEngine engine(primaryengine);
308 
309  if (opt.verbose)
310  {
311  cout << "fill FFT array engine with Fourier coefficients" << endl;
312  }
313  engine.spectrum()=0;
314 
316  fft.size(nsamples);
317 
318  for (int i=0; i<engine.nseries(); ++i)
319  {
321  spectrum=fft(vecoftraces[i].series,vecoftraces[i].wid2.dt);
322  engine.spectrum(i).copyin(spectrum);
323  }
324 
325  if (opt.verbose) { cout << "execute FFT array engine" << endl; }
326  engine.c2r();
327 
328  if (opt.verbose)
329  {
330  cout << "read time series samples from FFT array engine" << endl;
331  }
332  for (int i=0; i<engine.nseries(); ++i)
333  {
334  Trace& trace=vecoftraces[i];
335  Tseries& series=trace.series;
336  series.copyin(engine.series(i)*engine.scale_series(trace.wid2.dt));
337  }
338  }
339  else // if (opt.exchangeengines)
340  {
341  // prepare array engine
342  if (opt.verbose) { cout << "create FFT array engine" << endl; }
343  fourier::fft::DRFFTWAFFArrayEngine engine(ntraces, nsamples);
344 
345  if (opt.verbose) { cout << "fill FFT array engine" << endl; }
346  engine.series()=0;
347  // fill sample array
348  for (int i=0; i<engine.nseries(); ++i)
349  {
350  engine.series(i).copyin(vecoftraces[i].series);
351  if (opt.verbsize)
352  {
353  cout << "engine series #" << i << " has " << engine.series(i).size()
354  << " samples" << endl;
355  }
356  }
357 
358  if (opt.verbose) { cout << "execute FFT array engine" << endl; }
359  engine.r2c();
360 
361  if (opt.verbose)
362  {
363  cout << "read coefficients and transform to time domain" << endl;
364  }
366  fft.size(nsamples);
367  for (int i=0; i<engine.nseries(); ++i)
368  {
369  Trace& trace=vecoftraces[i];
370  Tseries& series=trace.series;
372  =engine.spectrum(i)*engine.scale_spectrum(trace.wid2.dt);
373  fourier::fft::DRFFTWAFF::Tspectrum spectrum(coeff.size());
374  spectrum.copyin(coeff);
375  series=fft(spectrum,trace.wid2.dt);
376  if (opt.verbsize)
377  {
378  cout << "after return from engine for trace #" << i << endl;
379  cout << " size of engine spectrum: " << engine.spectrum(i).size()
380  << endl;
381  cout << " size of copy of spectrum: " << spectrum.size()
382  << endl;
383  cout << " returned series size: " << series.size() << endl;
384  }
385  }
386  } // if (opt.exchangeengines)
387 
388  /*----------------------------------------------------------------------*/
389 
390  // write back transformed traces
391  // -----------------------------
392 
393  if (opt.verbose) { cout << "write transformed traces" << endl; }
394  if (opt.verbose)
395  {
396  cout << "write file " << outfilename << endl;
397  }
398 
399  // check if output file exists and open
400  if (!opt.overwrite)
401  {
402  std::ifstream file(outfilename.c_str(),std::ios_base::in);
403  TFXX_assert((!file.good()),"ERROR: output file exists!");
404  }
405 
406  // create output stream of desired file format
407  std::ios_base::openmode oopenmode
408  =datrw::oanystream::openmode(opt.fileformat);
409  std::ofstream ofs(outfilename.c_str(), oopenmode);
410  datrw::oanystream os(ofs, opt.fileformat);
411 
412  // write srce data and file free block if supported
413  if (os.handlessrce()) { os << srce; }
414 
415  // write trace data
416  for (unsigned int j=0; j<vecoftraces.size(); ++j)
417  {
418  if (opt.verbose)
419  {
420  cout << " write trace #" << j+1 << endl;
421  }
422  Trace& currenttrace=vecoftraces[j];
423 
424  os << currenttrace.wid2;
425  if (os.handlesinfo()) { os << currenttrace.info; }
426  os << currenttrace.series;
427  } // for (unsigned int j=0; j<currentfile.traces.size(); ++j)
428 }
429 
430 /* ----- END OF cxxfftwartest.cc ----- */
std::string fileformat
Tsample scale_spectrum(const Tsample &dt) const
Return appropriate scaling factor for sampling interval dt.
Definition: fftwaffar.cc:280
Tseries series
sff::WID2 wid2
engine to transfrom several signals at once (prototypes)
aff::Array< Tcoeff > TAspectrum
Definition: fftwaffar.h:92
unsigned int size() const
Definition: fftwaff.h:163
std::vector< Trace > Tvecoftraces
aff::Series< Tcoeff > Tspectrum
Definition: fftwaff.h:134
TAseries series() const
return a reference to the time series arrays
Definition: fftwaffar.h:106
void r2c()
execute r2c plan
Definition: fftwaffar.cc:127
bool overwrite
int tracenumber
Tsample scale_series(const Tsample &dt) const
Return appropriate scaling factor for sampling interval dt.
Definition: fftwaffar.cc:263
double Tvalue
bool verbose
int main(int iargc, char *argv[])
sff::INFO info
unsigned int nseries() const
return the number of series in the arrays
Definition: fftwaffar.cc:301
aff::Series< Tvalue > Tseries
use fftw together with aff containers (prototypes)
TAspectrum spectrum() const
return a reference to the Fourier coefficient arrays
Definition: fftwaffar.h:108
bool verbsize
Engine to transform several signals at once. References to workspace are passed to the contstructor...
Definition: fftwaffar.h:87
void c2r()
execute c2r plan
Definition: fftwaffar.cc:115
#define CXXFFTWARTEST_VERSION
bool exchangeengines