Commit 8bb19743 authored by thomas.forbriger's avatar thomas.forbriger

cooset [WP]: start implementation of full libdatrwxx support in cooset

parent 4fb95a1e
......@@ -4,11 +4,11 @@
* ----------------------------------------------------------------------------
*
* \author Thomas Forbriger
* \date 08/09/2004
* \date 14/11/2016
*
* set coordinates
*
* Copyright (c) 2004 by Thomas Forbriger (BFO Schiltach)
* Copyright (c) 2004, 2016 by Thomas Forbriger (BFO Schiltach)
*
* ----
* This program is free software; you can redistribute it and/or modify
......@@ -28,18 +28,19 @@
*
* REVISIONS and CHANGES
* - 08/09/2004 V1.0 Thomas Forbriger
* - 14/11/2016 V1.1 support all libdatrwxx I/O formats
*
* ============================================================================
*/
#define COOSET_VERSION \
"COOSET V1.0 set coordinates"
"COOSET V1.1 set coordinates"
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <sffxx.h>
#include <sffostream.h>
#include <datrwxx/readany.h>
#include <datrwxx/writeany.h>
#include <aff/series.h>
#include <aff/subarray.h>
#include <libtime++.h>
......@@ -52,9 +53,10 @@ using std::cerr;
using std::endl;
struct Options {
bool verbose, overwrite, dostations, debug;
bool verbose, overwrite, dostations, debug, single, integer;
std::string stationsystem, stationfile, sourcetime, sourcecoo;
bool sesot, sesoc;
std::string itype, otype;
}; // struct Options
// structure to hold station coordinates
......@@ -67,7 +69,24 @@ struct Station {
typedef std::vector<Station> Tvecofstations;
// container to handle samples
typedef aff::Series<double> Tseries;
typedef aff::Series<double> Tdseries;
typedef aff::Series<int> Tiseries;
typedef aff::Series<float> Tfseries;
/* ---------------------------------------------------------------------- */
std::ostream& operator<<(std::ostream& os, const sff::FREE& free)
{
os << "contents of SFF FREE block:" << std::endl;
sff::FREE::Tlines::const_iterator I=free.lines.begin();
while (I != free.lines.end())
{
os << " " << *I << std::endl;;
++I;
}
} // std::ostream& operator<<(std::ostream& os, const sff::FREE& free)
/* ====================================================================== */
int main(int iargc, char* argv[])
{
......@@ -77,8 +96,10 @@ int main(int iargc, char* argv[])
{
COOSET_VERSION "\n"
"usage: cooset [-stc s] [-stf file] [-soc \"C x y z\"] [-sot date]" "\n"
" [-itype f] [-otype f] [-integer] [-float]\n"
" [-v] [-o] infile outfile" "\n"
" or: cooset --help|-h" "\n"
" or: cooset --xhelp" "\n"
};
// define full help text
......@@ -86,12 +107,18 @@ int main(int iargc, char* argv[])
{
"set source and station coordinates" "\n"
"\n"
"-xhelp print I/O format details\n"
"\n"
"-stc s station coordinates system" "\n"
"-stf file station coordinates file" "\n"
"-soc C,x,y,z source coordinates" "\n"
"-sot date source time" "\n"
"-v be verbose" "\n"
"-o overwrite" "\n"
"-itype f input file data format type\'f\'\n"
"-otype f output file data format type\'f\'\n"
"-integer use integer sample values rather than double\n"
"-float use single precision sample values rather than double\n"
"\n"
"station coordinate file:\n"
" Each line provides coordinates for one station. The coordinate\n"
......@@ -102,6 +129,8 @@ int main(int iargc, char* argv[])
" 2nd column: value for x-coordinate or latitude field\n"
" 3rd column: value for y-coordinate or longitude field\n"
" 4th column: value for z-coordinate or height field\n"
"\n"
"Use program sehefixx to modify other header fields.\n"
};
// define commandline options
......@@ -124,6 +153,16 @@ int main(int iargc, char* argv[])
{"sot",arg_yes,"-"},
// 7: debug mode
{"D",arg_no,"-"},
// 8: input file type
{"itype",arg_yes,"sff"},
// 9: output file type
{"otype",arg_yes,"sff"},
// 10: extra help
{"xhelp",arg_no,"-"},
// 11: integer values
{"integer",arg_no,"-"},
// 12: single precision values
{"float",arg_no,"-"},
{NULL}
};
......@@ -142,6 +181,16 @@ int main(int iargc, char* argv[])
{
cerr << usage_text << endl;
cerr << help_text << endl;
cerr << endl;
datrw::supported_data_types(cerr);
cerr << endl;
cerr << libtime::usage_time_format_string;
cerr << endl;
if (cmdline.optset(10))
{
cerr << endl;
datrw::online_help(cerr);
}
exit(0);
}
......@@ -159,6 +208,10 @@ int main(int iargc, char* argv[])
opt.sourcetime=cmdline.string_arg(6);
opt.sesot=cmdline.optset(6);
opt.debug=cmdline.optset(7);
opt.itype=cmdline.string_arg(8);
opt.otype=cmdline.string_arg(9);
opt.integer=cmdline.optset(11);
opt.single=cmdline.optset(12);
TFXX_assert(cmdline.extra(),"ERROR: missing input file name!");
std::string infile=cmdline.next();
......@@ -193,114 +246,273 @@ int main(int iargc, char* argv[])
/*----------------------------------------------------------------------*/
// open files
if (opt.verbose) { cout << "open input file" << endl; }
std::ifstream is(infile.c_str());
TFXX_assert(is.good(),"ERROR: opening input file");
if (opt.verbose)
{
cout << "open input file " << infile
<< " of format " << opt.itype << endl;
}
std::ifstream ifs(infile.c_str());
TFXX_assert(ifs.good(),"ERROR: opening input file");
datrw::ianystream is(ifs, opt.itype, opt.debug);
if (!opt.overwrite)
if (!opt.overwrite) { datrw::abort_if_exists(outfile); }
if (opt.verbose)
{
std::ifstream check(outfile.c_str());
TFXX_assert(!check,"ERROR: output file exists");
cout << "open output file " << outfile
<< " with format " << opt.otype << endl;
}
std::ofstream ofs(outfile.c_str());
TFXX_assert(ofs.good(),"ERROR: opening output file");
sff::SFFostream<Tseries> os(ofs, opt.debug);
datrw::oanystream os(ofs, opt.otype, opt.debug);
/*----------------------------------------------------------------------*/
// modify file header
sff::FileHeader fileheader(is);
// pass file header data
sff::FREE filefree;
// read file FREE block
if (is.hasfree())
{
is >> filefree;
if (!os.handlesfilefree())
{
if (opt.verbose)
{
cout << " Output format cannot handle FREE block." << endl;
cout << " File FREE block will be discarded." << endl;
}
}
} // if (is.hasfree())
// leave a note
fileheader.appendfree(COOSET_VERSION);
sff::SRCE filesrce=fileheader.srce();
if (fileheader.hassrce())
{ fileheader.appendfree("input file has SRCE line"); }
if (opt.sesot)
// read and modify SRCE line
sff::SRCE srceline;
if (is.hassrce())
{
fileheader.appendfree("set source time");
libtime::TAbsoluteTime newsot(opt.sourcetime);
filesrce.date=newsot;
fileheader.setsrce(filesrce);
}
if (opt.sesoc)
is >> srceline;
// modify file header
filefree.appendfree("input file has SRCE line");
if (opt.sesot)
{
filefree.appendfree("set source time");
libtime::TAbsoluteTime newsot(opt.sourcetime);
srceline.date=newsot;
}
if (opt.sesoc)
{
filefree.appendfree("set source coordinates");
std::istringstream socospec(opt.sourcecoo);
char syst;
double x,y,z;
socospec >> syst >> x >> y >> z;
std::ostringstream message;
message << "new coordinates: " << syst << ","
<< x << "," << y << "," << z;
srceline.cs=sff::coosysID(syst);
srceline.cx=x;
srceline.cy=y;
srceline.cz=z;
filefree.appendfree(message.str());
}
} // if (is.hassrce())
// write file FREE block
if (os.handlesfilefree())
{
fileheader.appendfree("set source coordinates");
std::istringstream socospec(opt.sourcecoo);
char syst;
double x,y,z;
socospec >> syst >> x >> y >> z;
std::ostringstream message;
message << "new coordinates: " << syst << ","
<< x << "," << y << "," << z;
filesrce.cs=sff::coosysID(syst);
filesrce.cx=x;
filesrce.cy=y;
filesrce.cz=z;
fileheader.appendfree(message.str());
fileheader.setsrce(filesrce);
os << filefree;
}
// write SRCE line
if (is.hassrce())
{
if (os.handlessrce())
{
os << srceline;
}
else
{
if (opt.verbose)
{
cout << " Output format cannot handle SRCE line." << endl;
cout << " SRCE line is discarded." << endl;
}
}
} // if (is.hassrce())
// report
if (opt.verbose)
{
cout << endl << "output file FREE block:" << endl;
cout << fileheader.free();
cout << filefree.free();
}
os << fileheader;
/*----------------------------------------------------------------------*/
// handle traces
bool last=false;
while (!last)
int itrace=0;
while (is.good())
{
if (opt.verbose) { cout << endl << "read next trace:" << endl; }
sff::InputWaveform<Tseries> inputwaveform(is,opt.debug);
sff::TraceHeader traceheader(inputwaveform.header());
last=traceheader.last();
sff::INFO newinfo(traceheader.info());
const sff::WID2& wid2(traceheader.wid2());
if (opt.verbose) { cout << "station: " << wid2.station << endl; }
bool infoset=false;
if (opt.dostations)
++itrace;
if (opt.verbose) { std::cout << " edit trace #" << itrace << std::endl; }
// check output data format
switch (os.seriestype()) {
case datrw::Fint:
if (!opt.integer)
{
cout << " WARNING: converting floating point data to integer!"
<< endl;
}
break;
case datrw::Ffloat:
if (!(opt.single || opt.integer))
{
cout << " WARNING: "
"converting double precision to single precision data!"
<< endl;
}
break;
case datrw::Fdouble:
// that's just fine
break;
case datrw::Fall:
// that's just fine
break;
default:
TFXX_abort("output stream uses unknown variable type!");
} // switch (os.seriestype())
datrw::Tiseries iseries;
datrw::Tfseries fseries;
datrw::Tdseries dseries;
// read time series
if (opt.integer)
{
TFXX_assert(is.providesi(),
"ERROR: input data is not provided as integer values");
is >> iseries;
}
else if (opt.single)
{
TFXX_assert(is.providesf(),
"ERROR: input data is not provided as "
"single precision floats");
is >> fseries;
}
else
{
TFXX_assert(is.providesd(),
"ERROR: input data is not provided as "
"double precision floats");
is >> dseries;
}
// pass WID2
sff::WID2 wid2;
is >> wid2;
os << wid2;
// read trace FRRE
sff::FREE freeblock;
if (is.hasfree())
{
is >> freeblock;
freeblock.append("Edited with: ");
freeblock.append(COOSET_VERSION);
} // if (is.hasfree())
// modify INFO
if (is.hasinfo())
{
Station thestation;
for (unsigned int i=0; i<station.size(); ++i)
if (os.handlesinfo())
{
thestation=station[i];
if (opt.debug) { cout << "'" << thestation.id << "' '"
<< wid2.station << "'" << endl; }
if (tfxx::string::trimws_end(thestation.id)
== tfxx::string::trimws_end(wid2.station))
{
infoset=true;
char syst=opt.stationsystem[0];
std::ostringstream message;
message << "new coordinates: " << syst << ","
<< thestation.x << "," << thestation.y << "," << thestation.z;
newinfo.cs=sff::coosysID(syst);
newinfo.cx=thestation.x;
newinfo.cy=thestation.y;
newinfo.cz=thestation.z;
traceheader.appendfree(message.str());
i=station.size();
}
sff::INFO infoline;
is >> infoline;
bool infoset=false;
if (opt.dostations)
{
if (opt.verbose) { cout << "station: " << wid2.station << endl; }
Station thestation;
for (unsigned int i=0; i<station.size(); ++i)
{
thestation=station[i];
if (opt.debug) { cout << "'" << thestation.id << "' '"
<< wid2.station << "'" << endl; }
if (tfxx::string::trimws_end(thestation.id)
== tfxx::string::trimws_end(wid2.station))
{
infoset=true;
char syst=opt.stationsystem[0];
std::ostringstream message;
message << "new coordinates: " << syst << ","
<< thestation.x << "," << thestation.y << "," << thestation.z;
infoline.cs=sff::coosysID(syst);
infoline.cx=thestation.x;
infoline.cy=thestation.y;
infoline.cz=thestation.z;
freeblock.appendfree(message.str());
i=station.size();
}
}
if (infoset)
{
if (opt.verbose)
{
cout << freeblock.free() << endl;
}
}
else
{
cerr << "could not find station " << wid2.station << endl;
freeblock.appendfree("could not find station!");
}
} // if (opt.dostations)
os << infoline;
}
if (infoset)
else
{
if (opt.verbose)
{
cout << traceheader.free() << endl;
cout << " INFO line is discarded." << endl;
}
}
}
///////////////////
// write trace FREE block
if (is.hasfree())
{
if (os.handlestracefree())
{
os << freeblock;
}
else
{
cerr << "could not find station " << wid2.station << endl;
traceheader.appendfree("could not find station!");
{
if (opt.verbose)
{
cout << " Output format cannot handle trace FREE block." << endl;
cout << " Trace FREE block is discarded." << endl;
}
}
} // if (is.hasfree())
// write time series
if (opt.integer)
{
os << iseries;
}
else if (opt.single)
{
os << fseries;
}
else
{
os << dseries;
}
// NOTICE: samples must be written first!
os << inputwaveform.series();
os << traceheader;
if (infoset) { os << newinfo; }
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment