conv/many suite: convert (m)any seismic data format(s)
any2any.cc
Go to the documentation of this file.
1 
36 #define ANY2ANY_VERSION \
37  "ANY2ANY V1.0 conversion between libdatrwxx data file formats"
38 
39 #include <iostream>
40 #include <fstream>
41 #include <tfxx/commandline.h>
42 #include <tfxx/xcmdline.h>
43 #include <tfxx/error.h>
44 #include <tfxx/misc.h>
45 #include <tfxx/rangestring.h>
46 #include <tfxx/rangelist.h>
47 #include <tfxx/seitosh.h>
48 #include <datrwxx/readany.h>
49 #include <datrwxx/writeany.h>
50 #include <datrwxx/datatypes.h>
51 
52 using std::cout;
53 using std::cerr;
54 using std::endl;
55 
56 struct Options {
59  std::string inputformat, outputformat;
60 }; // struct Options
61 
62 /*======================================================================*/
63 
64 int main(int iargc, char* argv[])
65 {
66 
67  // define usage information
68  char usage_text[]=
69  {
70  ANY2ANY_VERSION "\n"
71  "usage: any2any [--verbose] [--overwrite] [--integer] [--single]" "\n"
72  " [--itype t] [--otype t] [--vconversion]" "\n"
73  " outfile infile [t:T] [f:F] [infile [t:T] [f:F] ... ]" "\n"
74  " or: any2any --help|-h" "\n"
75  " or: any2any --xhelp" "\n"
76  };
77 
78  // define full help text
79  char help_text[]=
80  {
81  "Options may be abbreviated to a short string as long as they" "\n"
82  "remain unique. \"-v\" is identical to \"--verbose\"." "\n"
83  "\n"
84  "--verbose be verbose" "\n"
85  "--vconversion be verbose on type conversion" "\n"
86  "--overwrite overwrite output if file already exists" "\n"
87  "--integer use integer values for copying" "\n"
88  "--single use single precision floats for copying" "\n"
89  " default data type for copying is double presicion floats\n"
90  "--itype t standard format of input file(s) (see below)" "\n"
91  "--otype t data format of output file (see below)" "\n"
92  "\n"
93  "outfile output data file name" "\n"
94  "infile input data file name" "\n"
95  "\n"
96  "File specific options:" "\n"
97  "t:T select specfic traces from input file" "\n"
98  " T can be a list of traces like \"1,4,5\" or" "\n"
99  " a range like \"6-19\" or mixed like \"5,8,12-17,20\"" "\n"
100  "f:F specify file format (overrides --itype setting)" "\n"
101  "\n"
102  "The output format might not be able to store all header information" "\n"
103  "from the input data." "\n"
104  };
105 
106  // define commandline options
107  using namespace tfxx::cmdline;
108  static Declare options[]=
109  {
110  // 0: print help
111  {"help",arg_no,"-"},
112  // 1: print help
113  {"xhelp",arg_no,"-"},
114  // 2: verbose mode
115  {"verbose",arg_no,"-"},
116  // 3: overwrite output
117  {"overwrite",arg_no,"-"},
118  // 4: overwrite output
119  {"itype",arg_yes,"sff"},
120  // 5: overwrite output
121  {"otype",arg_yes,"sff"},
122  // 6: overwrite output
123  {"DEBUG",arg_no,"-"},
124  // 7: read integer data
125  {"integer",arg_no,"-"},
126  // 8: read single precision data
127  {"single",arg_no,"-"},
128  // 9: read single precision data
129  {"vconversion",arg_no,"-"},
130  {NULL}
131  };
132 
133  static const char tracekey[]="t";
134  static const char formatkey[]="f";
135 
136  // define commandline argument modifier keys
137  static const char* cmdlinekeys[]={tracekey, formatkey, 0};
138 
139  /*----------------------------------------------------------------------*/
140  // action!
141 
142  // no arguments? print usage...
143  if (iargc<2)
144  {
145  cerr << usage_text << endl;
146  cerr << tfxx::seitosh::repository_reference << endl;
147  exit(0);
148  }
149 
150  // collect options from commandline
151  Commandline cmdline(iargc, argv, options);
152 
153  // help requested? print full help text...
154  if (cmdline.optset(0) || cmdline.optset(1))
155  {
156  cerr << usage_text << endl;
157  cerr << help_text << endl;
158  datrw::supported_data_types(cerr);
159  if (cmdline.optset(1))
160  {
161  cerr << endl;
162  datrw::online_help(cerr);
163  }
164  cerr << endl << tfxx::seitosh::repository_reference << endl;
165  exit(0);
166  }
167 
168  // extract command line options
169  Options opt;
170  opt.verbose=cmdline.optset(2);
171  opt.overwrite=cmdline.optset(3);
172  opt.inputformat=cmdline.string_arg(4);
173  opt.outputformat=cmdline.string_arg(5);
174  opt.debug=cmdline.optset(6);
175  opt.integer=cmdline.optset(7);
176  opt.single=cmdline.optset(8);
177  opt.verboseconversion=cmdline.optset(9);
178 
179  if (opt.verbose) { cout << ANY2ANY_VERSION "\n"; }
180 
181  if (opt.verboseconversion)
182  {
183  ::datrw::report_type_conversion();
184  }
185 
186  // extract commandline arguments
187  TFXX_assert(cmdline.extra(), "missing output file");
188  std::string outfile=cmdline.next();
189  TFXX_assert(cmdline.extra(), "missing input file");
190  tfxx::cmdline::Tparsed arguments=parse_cmdline(cmdline, cmdlinekeys);
191  if ((arguments.size()>1) && opt.verbose)
192  {
193  cout << "NOTICE: file specific information (SRCE line and file FREE)\n"
194  << " of the second and subsequent files might get lost!\n";
195  }
196 
197  /*----------------------------------------------------------------------*/
198  // full action!
199 
200  // check whether output file exists
201  if (opt.verbose)
202  {
203  cout << "open output file " << outfile
204  << " with format " << opt.outputformat << endl;
205  }
206  if (!opt.overwrite) { datrw::abort_if_exists(outfile); }
207  std::ofstream ofs(outfile.c_str(),
208  datrw::oanystream::openmode(opt.outputformat));
209  datrw::oanystream os(ofs, opt.outputformat, opt.debug);
210 
211  if (opt.verbose) {
212  cout << "file data is stored in ";
213  // report output data format
214  switch (os.seriestype()) {
215  case datrw::Fint:
216  cout << "integer";
217  break;
218  case datrw::Ffloat:
219  cout << "single precision floating point";
220  break;
221  case datrw::Fdouble:
222  cout << "double precision floating point";
223  break;
224  case datrw::Fall:
225  cout << "any desired";
226  break;
227  default:
228  TFXX_abort("output stream uses unknown variable type!");
229  } // switch (os.seriestype())
230  cout << " variable type" << endl;
231  }
232 
233  // cycle through all input files
234  // -----------------------------
235  bool firstfile=true;
236  tfxx::cmdline::Tparsed::const_iterator infile=arguments.begin();
237  while (infile != arguments.end())
238  {
239  // open input file
240  std::string inputformat=opt.inputformat;
241  if (infile->haskey(formatkey))
242  { inputformat=infile->value(formatkey); }
243  if (opt.verbose)
244  {
245  cout << "open input file " << infile->name
246  << " of format " << inputformat << endl;
247  }
248  std::ifstream ifs(infile->name.c_str(),
249  datrw::ianystream::openmode(inputformat));
250  datrw::ianystream is(ifs, inputformat, opt.debug);
251 
252 
253  /*----------------------------------------------------------------------*/
254  // pass file header data
255 
256  // handle file header
257  if (firstfile)
258  {
259  if (is.hasfree())
260  {
261  if (os.handlesfilefree())
262  {
263  sff::FREE filefree;
264  is >> filefree;
265  os << filefree;
266  }
267  else
268  {
269  if (opt.verbose)
270  {
271  cout << " file FREE block is discarded." << endl;
272  }
273  }
274  } // if (is.hasfree())
275  } // if (firstfile)
276 
277  if (is.hassrce())
278  {
279  if (os.handlessrce())
280  {
281  sff::SRCE srceline;
282  is >> srceline;
283  os << srceline;
284  }
285  else
286  {
287  if (opt.verbose)
288  {
289  cout << " SRCE line is discarded." << endl;
290  }
291  }
292  }
293 
294  /*----------------------------------------------------------------------*/
295 
296  // cycle through traces of input file
297  // ----------------------------------
298  // setup trace selection
299  typedef tfxx::RangeList<int> Trangelist;
300  bool doselect=infile->haskey(tracekey);
301  Trangelist traceranges=
302  tfxx::string::rangelist<Trangelist::Tvalue>(infile->value(tracekey));
303  int itrace=0;
304  while (is.good())
305  {
306  ++itrace;
307  if ((!doselect) || traceranges.contains(itrace))
308  {
309  if (opt.verbose)
310  { std::cout << " copy trace #" << itrace << std::endl; }
311 
312  datrw::Tfseries fseries;
313  datrw::Tdseries dseries;
314  datrw::Tiseries iseries;
315 
316  // read time series
317  if (opt.integer)
318  {
319  TFXX_assert(is.providesi(),
320  "ERROR: input data is not provided as integer values");
321  is >> iseries;
322  }
323  else if (opt.single)
324  {
325  TFXX_assert(is.providesf(),
326  "ERROR: input data is not provided as "
327  "single precision floats");
328  is >> fseries;
329  }
330  else
331  {
332  TFXX_assert(is.providesd(),
333  "ERROR: input data is not provided as "
334  "double precision floats");
335  is >> dseries;
336  }
337 
338  // pass WID2
339  sff::WID2 wid2;
340  is >> wid2;
341  os << wid2;
342 
343  TFXX_debug(opt.debug, "any2any: trace header data availability",
344  " is.hasinfo(): " << is.hasinfo() <<
345  " is.hasfree(): " << is.hasfree());
346 
347  // pass INFO
348  if (is.hasinfo())
349  {
350  if (os.handlesinfo())
351  {
352  sff::INFO infoline;
353  is >> infoline;
354  os << infoline;
355  TFXX_debug(opt.debug, "any2any: INFO data",
356  infoline.line());
357  }
358  else
359  {
360  if (opt.verbose)
361  {
362  cout << " INFO line is discarded." << endl;
363  }
364  }
365  }
366 
367  // pass trace FREE
368  if (is.hasfree())
369  {
370  if (os.handlestracefree())
371  {
372  sff::FREE freeblock;
373  is >> freeblock;
374  os << freeblock;
375  }
376  else
377  {
378  if (opt.verbose)
379  {
380  cout << " trace FREE block is discarded." << endl;
381  }
382  }
383  }
384 
385  // check output data format
386  switch (os.seriestype()) {
387  case datrw::Fint:
388  if (!opt.integer)
389  {
390  cout << " WARNING: converting floating point data to integer!"
391  << endl;
392  }
393  break;
394  case datrw::Ffloat:
395  if (!(opt.single || opt.integer))
396  {
397  cout << " WARNING: "
398  "converting double precision to single precision data!"
399  << endl;
400  }
401  break;
402  case datrw::Fdouble:
403  // that's just fine
404  break;
405  case datrw::Fall:
406  // that's just fine
407  break;
408  default:
409  TFXX_abort("output stream uses unknown variable type!");
410  } // switch (os.seriestype())
411 
412  // write output
413  if (opt.integer)
414  {
415  os << iseries;
416  }
417  else if (opt.single)
418  {
419  os << fseries;
420  }
421  else
422  {
423  os << dseries;
424  }
425  } // if ((!doselect) || traceranges.contains(itrace))
426  else
427  {
428  if (opt.verbose)
429  { std::cout << " skip trace #" << itrace << std::endl; }
430  is.skipseries();
431  } // if ((!doselect) || traceranges.contains(itrace))
432 
433  // end of this trace
434  } // while (is.good())
435 
436  // end of this file
437  ++infile;
438  } // while (infile != arguments.end())
439 
440 }
441 
442 /* ----- END OF any2any.cc ----- */
#define ANY2ANY_VERSION
Definition: any2any.cc:36
int main(int iargc, char *argv[])
Definition: any2any.cc:64
std::string inputformat
Definition: any2any.cc:59
bool single
Definition: any2any.cc:57
datrw::Tfseries Tfseries
Definition: anyextract.cc:159
bool verboseconversion
Definition: any2any.cc:58
bool overwrite
Definition: any2any.cc:57
std::string outputformat
Definition: any2any.cc:59
bool integer
Definition: any2any.cc:57
bool debug
Definition: any2any.cc:57
bool verbose
Definition: any2any.cc:57
datrw::Tiseries Tiseries
Definition: anyextract.cc:160