Commit 0a944512 authored by thomas.forbriger's avatar thomas.forbriger Committed by thomas.forbriger
Browse files

reintegrating code from branch libdatrwxx.su after implementing format

This is a legacy commit from before 2015-03-01.
It may be incomplete as well as inconsistent.
See COPYING.legacy and README.history for details.
modifiers and scaling of ultrasonic data parameters in SeismicUnix I/O


SVN Path:     http://gpitrsvn.gpi.uni-karlsruhe.de/repos/TFSoftware/trunk
SVN Revision: 4466
SVN UUID:     67feda4a-a26e-11df-9d6e-31afc202ad0c
parent 9ff2934a
......@@ -30,14 +30,17 @@
*
* REVISIONS and CHANGES
* - 28/07/2011 V1.0 Thomas Forbriger
* - 21/01/2012 V1.1 provide online help output support class
*
* ============================================================================
*/
#define DATRW_FORMATMODIFIER_CC_VERSION \
"DATRW_FORMATMODIFIER_CC V1.0 "
"DATRW_FORMATMODIFIER_CC V1.1"
#define DATRW_FORMATMODIFIER_CC_CVSID \
"$Id$"
#include <iostream>
#include <iomanip>
#include <datrwxx/formatmodifier.h>
#include <datrwxx/util.h>
#include <algorithm>
......@@ -182,6 +185,42 @@ namespace datrw {
}
} // void Subformat::notchecked(std::ostream& os) const
/*======================================================================*/
namespace formatmodifiers {
std::ostream& ModifierHelp::operator() ()
{
Mos.width(Mwidth);
Mos << std::left << std::setfill(' ') << " " << " ";
return(Mos);
} // std::ostream& ModifierHelp::operator() ()
/*----------------------------------------------------------------------*/
std::ostream& ModifierHelp::operator() (const std::string& key)
{
Mos.width(Mwidth);
std::string keyval=key;
keyval += ": ";
Mos << std::left << std::setfill('.') << keyval << " ";
return(Mos);
} // std::ostream& ModifierHelp::operator() (key)
/*----------------------------------------------------------------------*/
std::ostream& ModifierHelp::operator() (const std::string& key,
const std::string& val)
{
Mos.width(Mwidth);
std::string keyval=key;
keyval += "=" + val + ": ";
Mos << std::left << std::setfill('.') << keyval << " ";
return(Mos);
} // std::ostream& ModifierHelp::operator() (key, val)
} // namespace formatmodifiers
} // namespace datrw
/* ----- END OF formatmodifier.cc ----- */
......@@ -30,6 +30,7 @@
*
* REVISIONS and CHANGES
* - 28/07/2011 V1.0 Thomas Forbriger
* - 21/01/2012 V1.1 provide online help output support class
*
* ============================================================================
*/
......@@ -38,7 +39,7 @@
#ifndef DATRW_FORMATMODIFIER_H_VERSION
#define DATRW_FORMATMODIFIER_H_VERSION \
"DATRW_FORMATMODIFIER_H V1.0 "
"DATRW_FORMATMODIFIER_H V1.1"
#define DATRW_FORMATMODIFIER_H_CVSID \
"$Id$"
......@@ -130,6 +131,27 @@ namespace datrw {
*/
void online_help(std::ostream& os);
/*----------------------------------------------------------------------*/
/*! \brief Help formatting modifier online help
* \ingroup formatmodifiers
* \sa datrw::su::osustream::help()
*/
class ModifierHelp
{
public:
ModifierHelp(std::ostream& os,
const unsigned int& width):
Mos(os), Mwidth(width) { }
std::ostream& operator()(const std::string& key,
const std::string& val);
std::ostream& operator()(const std::string& key);
std::ostream& operator()();
private:
std::ostream& Mos;
unsigned int Mwidth;
}; // class ModifierHelp
} // namespace formatmodifiers
/*----------------------------------------------------------------------*/
......
......@@ -47,11 +47,12 @@
* - 07/11/2011 V1.16 make ASCII input module visible
* - 19/11/2011 V1.17 provide binary input
* - 05/12/2011 V1.18 itsoftstream takes format modifiers
* - 21/01/2012 V1.19 prepared isustream to take modifiers
*
* ============================================================================
*/
#define DATRW_READANY_CC_VERSION \
"DATRW_READANY_CC V1.18"
"DATRW_READANY_CC V1.19"
#define DATRW_READANY_CC_CVSID \
"$Id$"
......@@ -210,8 +211,7 @@ namespace datrw {
}
else if (Mformat==Fsu)
{
DATRW_expect_no_modifier(Mformat,modifiers);
Mis=new isustream(is, debug);
Mis=new isustream(is, modifiers, debug);
}
else if (Mformat==Fseife)
{
......
......@@ -31,6 +31,18 @@
* - 19/11/2010 V1.0 Thomas Forbriger
* - 23/11/2010 V1.1 introduced static member data
* - 07/06/2011 V1.2 promise constness of series samples
* - 21/01/2012 V1.3
* - prepared isustream and osustream to take modifiers
* - use SUHeaderControl to store format modifier values
* - 24/01/2012 V1.4 there is a subtle bute relevant difference in the
* possible orders of member data fields of isustream:
* Mheadercontrol must be first, followed by
* Mnextheader. Otherwise Mnexheader is
* initialized with a non-initialized Mheadercontrol
* which contains the improper scalco value "0"; the
* wrong order results in warning messages each time
* the code is used and in an unavoidable abort if the
* strict format modifier is set
*
* ============================================================================
*/
......@@ -39,13 +51,14 @@
#ifndef DATRW_SU_H_VERSION
#define DATRW_SU_H_VERSION \
"DATRW_SU_H V1.2"
"DATRW_SU_H V1.3"
#define DATRW_SU_H_CVSID \
"$Id$"
#include<datrwxx/datread.h>
#include<datrwxx/datwrite.h>
#include<datrwxx/suheader.h>
#include <datrwxx/datread.h>
#include <datrwxx/datwrite.h>
#include <datrwxx/suheader.h>
#include <datrwxx/suformat.h>
namespace datrw {
......@@ -65,7 +78,9 @@ namespace datrw {
class isustream: public idatstream {
public:
typedef idatstream Tbase;
isustream(std::istream& is, const bool& debug=false);
isustream(std::istream& is,
const std::string& modifier="",
const bool& debug=false);
virtual ~isustream() { }
virtual Tdseries dseries();
virtual Tfseries fseries();
......@@ -75,6 +90,7 @@ namespace datrw {
private:
void readheader();
bool Mdebug;
datrw::su::options::SUHeaderControl Mheadercontrol;
datrw::su::SUheader Mnextheader;
}; // class isustream
......@@ -87,7 +103,9 @@ namespace datrw {
class osustream: public odatstream {
public:
typedef odatstream Tbase;
osustream(std::ostream& os, const bool& debug=false);
osustream(std::ostream& os,
const std::string& modifier="",
const bool& debug=false);
inline virtual ~osustream() { }
static void help(std::ostream& os=std::cout);
static const std::ios_base::openmode openmode;
......@@ -99,6 +117,7 @@ namespace datrw {
private:
bool Mdebug;
unsigned int Mitrace;
datrw::su::options::SUHeaderControl Mheadercontrol;
}; // class osustream
} // namespace datrw
......
......@@ -30,11 +30,17 @@
* REVISIONS and CHANGES
* - 19/11/2010 V1.0 Thomas Forbriger
* - 23.12.2010 V1.1 use stream buffer seekg() function to skip series
* - 21/01/2012 V1.2
* - prepared isustream to take modifiers
* - use SUHeaderControl to store format modifier values
* - pass control parameters to SUheader
* - bestrict is bundled with spatial sampling control
* parameters
*
* ============================================================================
*/
#define DATRW_SU_CC_VERSION \
"DATRW_SU_CC V1.1"
"DATRW_SU_CC V1.2"
#define DATRW_SU_CC_CVSID \
"$Id$"
......@@ -42,6 +48,8 @@
#include <datrwxx/util.h>
#include <datrwxx/error.h>
#include <datrwxx/debug.h>
#include <datrwxx/suformat.h>
#include <datrwxx/formatmodifier.h>
namespace datrw {
......@@ -50,12 +58,20 @@ namespace datrw {
/*----------------------------------------------------------------------*/
isustream::isustream(std::istream& is, const bool& debug):
Tbase(is, true, true, false), Mdebug(debug), Mnextheader(debug)
isustream::isustream(std::istream& is,
const std::string& modifier,
const bool& debug):
Tbase(is, true, true, false), Mdebug(debug),
Mnextheader(Mheadercontrol, debug)
{
DATRW_debug(Mdebug, "isustream::isustream","entering constructor");
// evaluate format modifiers
Mheadercontrol=su::inputmodifiers(modifier, Mdebug);
// read first (next) trace header
DATRW_assert(is.good(),
"ERROR (isustream::isustream): input stream is bad");
Mnextheader.set(Mheadercontrol);
Mnextheader.read(is);
this->setsrce(Mnextheader.srce());
DATRW_debug(Mdebug, "isustream::isustream", "finished constructor");
......@@ -141,42 +157,25 @@ namespace datrw {
{
os <<
std::endl <<
"SeismicUnix reading functions" << std::endl <<
"SeismicUn*x reading functions" << std::endl <<
"-----------------------------" << std::endl <<
DATRW_SU_CC_VERSION << std::endl <<
DATRW_SU_CC_CVSID << std::endl <<
DATRW_SU_H_CVSID << std::endl <<
std::endl <<
"This module provides reading of SeismicUnix binary data files."
<< std::endl <<
"Only a few header fields are extracted:"
"This module provides reading of SeismicUn*x binary data files."
<< std::endl;
os << std::endl;
datrw::su::SUheader::help(os);
os << std::endl;
os <<
"wid2.nsamples = header.ns\n"
"wid2.dt = header.dt*1.e-6\n"
"wid2.date = srce.date+header.delrt*1.e-3\n"
"wid2.channel = header.tracf\n"
" (tracf = Trace number within original field record)\n"
"wid2.station = header.tracf\n"
"wid2.auxid = header.fldr\n"
" (fldr = Original field record number)\n";
os <<
"info.cx = header.gx*scalcof\n"
"info.cy = header.gy*scalcof\n"
"info.cz = header.gelev*scalelf\n"
"info.nstacks = header.nvs\n";
os <<
"srce.cx = header.sx*scalcof\n"
"srce.cy = header.sy*scalcof\n"
"srce.cz = header.sdepth*scalelf\n"
"srce.date = date(year,day,hour,minute,sec)\n";
os <<
"header.scalco and header.scalel are as defined for the SEG-Y "
"format:\n"
"http://www.seg.org/SEGportalWEBproject/prod/SEG-Publications/Pub-Technical-Standards/Documents/seg_y_rev1.pdf\n"
"except when their modulus is smaller than 10 and larger than 0.\n"
"In this case the scaling factors scalcof and scalelf are taken to be\n"
"10 to the power of header.scalco or header.scalel, respectively\n";
"Valid format modifiers are:\n";
formatmodifiers::ModifierHelp mh(os, 14);
mh(su::subformat::key::strict) <<
"Abort if scalco violates the definition of SeismicUn*x.\n";
mh() << "The default is to tolerate spatial sampling\n";
mh() << "scaling factors being zero or being small\n";
mh() << "powers of ten.\n";
} // void isustream::help(std::ostream& os)
} // namespace datrw
......
......@@ -30,11 +30,15 @@
* REVISIONS and CHANGES
* - 03/12/2010 V1.0 Thomas Forbriger
* - 07/06/2011 V1.1 promise constness of series samples
* - 21/01/2012 V1.2
* - prepared osustream to take modifiers
* - use SUHeaderControl to store format modifier values
* - 24/01/2012 V1.3 output modifiers are evaluated in dedicated function
*
* ============================================================================
*/
#define DATRW_OSUSTREAM_CC_VERSION \
"DATRW_OSUSTREAM_CC V1.1"
"DATRW_OSUSTREAM_CC V1.3"
#define DATRW_OSUSTREAM_CC_CVSID \
"$Id$"
......@@ -42,6 +46,9 @@
#include <datrwxx/error.h>
#include <datrwxx/debug.h>
#include <datrwxx/util.h>
#include <datrwxx/suformat.h>
#include <datrwxx/sucomanager.h>
#include <datrwxx/formatmodifier.h>
namespace datrw {
......@@ -50,19 +57,60 @@ namespace datrw {
/*----------------------------------------------------------------------*/
osustream::osustream(std::ostream& os, const bool& debug):
osustream::osustream(std::ostream& os,
const std::string& modifier,
const bool& debug):
Tbase(os, Ffloat, false, false, true, true),
Mdebug(debug), Mitrace(0)
{
DATRW_debug(Mdebug, "osustream::osustream",
"new instance established");
// evaluate format modifiers
Mheadercontrol=su::outputmodifiers(modifier, Mdebug);
} // osustream::osustream(std::ostream& os, const bool& debug)
/*----------------------------------------------------------------------*/
void osustream::help(std::ostream& os)
{
os << "This module writes SeismicUn*x data." << std::endl;
os <<
std::endl <<
"SeismicUn*x writing functions" << std::endl <<
"-----------------------------" << std::endl <<
DATRW_OSUSTREAM_CC_VERSION << std::endl <<
DATRW_OSUSTREAM_CC_CVSID << std::endl <<
DATRW_SU_H_CVSID << std::endl <<
std::endl <<
"This module provides writing of SeismicUn*x binary data files."
<< std::endl;
os << std::endl;
datrw::su::SUheader::help(os);
os << std::endl;
os <<
"Valid format modifiers are:\n";
formatmodifiers::ModifierHelp mh(os, 14);
mh(su::subformat::key::forceultrasonic) <<
"Force writing of ultrasonic data header\n";
mh() << "The default is to write standard SeismicUn*x\n";
mh() << "headers for seismic sampling intervals.\n";
mh(su::subformat::key::forceseismic) <<
"Force writing of seismic data header even\n";
mh() << "is sampling interval is too small.\n";
mh() << "Choosing both modifiers at once is an\n";
mh() << "inconsistency and causes abort().\n";
mh(su::subformat::key::scalco, "s") <<
"\"s\" is used as the preferred scalco and scalel value.\n";
mh() << "It is used only if it does not cause round-off truncation.\n";
mh() << "The default is "
<< su::subformat::key::scalco << "="
<< datrw::su::subformat::def::scalco << "\n";
mh(su::subformat::key::coodigits, "n") <<
"Limits the maximum number of significant digits in\n";
mh() << "spatial coordinates to \"n\". Coordinate values with\n";
mh() << "more digits will be truncated.\n";
mh() << "The default is "
<< su::subformat::key::coodigits << "="
<< datrw::su::subformat::def::coodigits << "\n";
} // void osustream::help(std::ostream& os=std::cout)
/*----------------------------------------------------------------------*/
......@@ -102,7 +150,7 @@ namespace datrw {
DATRW_debug(Mdebug, "osustream::writetrace(const Tfseries& series)",
"actually write trace");
++Mitrace;
::datrw::su::SUheader header(Mdebug);
::datrw::su::SUheader header(Mheadercontrol, Mdebug);
::sff::WID2 wid2=this->wid2();
wid2.nsamples=series.size();
header.set(wid2);
......
......@@ -45,15 +45,28 @@
* exceed 0.1%
* - 29/03/2011 V1.2 - search for the smallest possible power larger or
* equal a desired value
* - 22/01/2012 V1.3
* - handle control parameters
* - pass control parameters to Coordinates and ScalCoo
* - add conversion functions
* - 24/01/2012 V1.4
* - static cast of value to type float in function
* ScalCoo::set(const double&) caused terrible
* roundoff resulting in awfully many trailing
* digits. I see no reason for this cast and remove
* it.
* - reworked ScalCoo::smallestpower(const short&)
*
* ============================================================================
*/
#define DATRW_SUCOMANAGER_CC_VERSION \
"DATRW_SUCOMANAGER_CC V1.2"
"DATRW_SUCOMANAGER_CC V1.4"
#define DATRW_SUCOMANAGER_CC_CVSID \
"$Id$"
#include <cmath>
#include <climits>
#include <datrwxx/suformat.h>
#include <datrwxx/sucomanager.h>
#include <datrwxx/error.h>
#include <datrwxx/debug.h>
......@@ -66,10 +79,12 @@ namespace datrw {
/*======================================================================*/
/*! some local helpers
* \ingroup su
*/
namespace helper {
/*! \brief output format modifier for debug output
* \ingroup su
*/
class MyOutputFormat {
public:
......@@ -96,8 +111,7 @@ namespace datrw {
/*======================================================================*/
// constants to support coordinate scaling
double ScalCoo::effectivezero=1.e-12;
int ScalCoo::maxnsigdigits=4;
double ScalCoo::effectivezero=datrw::su::subformat::def::thresholdzero;
/*----------------------------------------------------------------------*/
......@@ -107,43 +121,10 @@ namespace datrw {
*/
void ScalCoo::set(const short& sin, const int& c)
{
/*
* a scale value of 0 is not defined for the trace header in the SEGY
* standard; since Geode data acquisitions produce SEGY data with scalel
* set to 0, we have to deal with this value
*/
DATRW_report_assert(sin != 0,
"WARNING (ScalCoo::set): incorrect scale",
"value: " << sin << "; will be set to 1");
// make a copy to allow modification
short s=sin;
if (s==0) { s=1; }
int sabs=s > 0 ? s : -s;
if ((sabs < 10) && (s != 1))
{
/*
* some code out there produces SU data with scale values understood
* as exponents of ten; SEGY defines the scale value to be taken as
* numerator or denominator of the scaling factor with values -10000,
* -1000, -100, -10, 1, 10, 100, 1000, 10000 only; here we allow for
* the non-standard setting indicated by the absolute value of scale
* being larger than 1 and smaller than 10
*/
DATRW_report_assert(((sabs < 10) && (s != 1)),
"WARNING (ScalCoo::set): non-standard scale",
"value: " << s);
/*
* 10 to a power larger than 4 cannot be represented by a short int
*/
DATRW_assert((sabs<5),
"ERROR (ScalCoo::set): "
"scale value does not fit in short int field");
this->scale= s > 0 ? std::pow(10,sabs) : -std::pow(10,sabs);
}
else
{
this->scale = s;
}
fixscalevalue(s, Mcontrol.bestrict);
this->scale=s;
this->coo=c;
} // void ScalCoo::set(const short& s, const int& c)
......@@ -158,12 +139,12 @@ namespace datrw {
void ScalCoo::set(const double& value)
{
const bool debug=false;
this->scale=1;
this->scale=Mcontrol.scalco;
this->coo=static_cast<int>(nearbyint(value));
double v=static_cast<float>(value>=0 ? value : -value);
double v=(value>=0 ? value : -value);
if (v<ScalCoo::effectivezero)
{
this->scale=1;
this->scale=Mcontrol.scalco;
this->coo=0;
}
else
......@@ -177,15 +158,16 @@ namespace datrw {
int nsig=::datrw::util::nsignificantdigits(v, debug);
int nzero=ntrail-nsig;
DATRW_debug(debug, "ScalCoo::set(const double& v)",
"nlead: " << nlead << "\n"
"ntrail: " << ntrail << "\n"
"nsig: " << nsig);
nsig = nsig>maxnsigdigits ? maxnsigdigits : nsig;
"nlead: " << nlead <<
" ntrail: " << ntrail <<
" nsig: " << nsig);
nsig = nsig>static_cast<int>(Mcontrol.coodigits)
? Mcontrol.coodigits : nsig;
ntrail=nsig+nzero;
DATRW_debug(debug, "ScalCoo::set(const double& v)",
"nlead: " << nlead << "\n"
"ntrail: " << ntrail << "\n"
"nsig: " << nsig);
"nlead: " << nlead <<
" ntrail: " << ntrail <<
" nsig: " << nsig);
if (ntrail>0)
{
DATRW_debug(debug, "ScalCoo::set(const double& value)",
......@@ -243,10 +225,7 @@ namespace datrw {
*/
int ScalCoo::power() const
{
int sabs=this->scale > 0 ? this->scale : -this->scale;
int retval=std::log10(sabs);
if (this->scale < 0) { retval *= -1; }
return(retval);
return(datrw::su::scaletopower(this->scale));
} // int ScalCoo::power() const
/*----------------------------------------------------------------------*/
......@@ -275,9 +254,7 @@ namespace datrw {
<< helper::MyOutputFormat() << this->coo <<
" value will be " << vcmp);
this->coo = vnew;
int pp = p < 0 ? -p : p;
short s=static_cast<short>(std::pow(10,pp));
this->scale= p<0 ? -s: s;
this->scale=powertoscale(p);
DATRW_assert(this-scale != 0,
"ERROR (ScalCoo::scaletopower): illegal scale value!");
} // void ScalCoo::scaletopower(const int& p)
......@@ -305,26 +282,29 @@ namespace datrw {
this->coo /= 10;
}
} while ((v1==v2) && (p<4));
int pp = p < 0 ? -p : p;
short s=static_cast<short>(std::pow(10,pp));
this->scale= p<0 ? -s: s;
this->scale=powertoscale(p);
DATRW_assert(this-scale != 0,
"ERROR (ScalCoo::scaletopower): illegal scale value!");
} // void ScalCoo::adjustscaling()
} // void ScalCoo::adjustscale()
/*----------------------------------------------------------------------*/
/*! \brief return smallest power possible without truncation
*/
int ScalCoo::smallestpower(const int& desired) const
int ScalCoo::smallestpower(const short& desiredscale) const
{
// limiting power values
int desired=datrw::su::scaletopower(desiredscale);
int lp=desired >= -4 ? desired : -4;
lp = lp <= 4 ? lp : 4;
// initial power
int p=this->power();
/*
* code modification; 24.1.2012
* tests were previously done detecting overflow
*
// value and compare value
ScalCoo v1, v2;
ScalCoo v1(Mcontrol), v2(Mcontrol);
v1.coo=this->coo;
v2.coo=std::floor(v1.coo*10)/10;
do {
......@@ -335,6 +315,27 @@ namespace datrw {
v2.coo=std::floor(v1.coo*10)/10;
}
} while ((v1.coo==v2.coo) && (p>lp));
*
* I prefer to use numerical comparison
* increasing the scale power will decrease the coo value and vice versa;
* start with the optimal power as being found in this->scale
* decrease the power until
* either a further decrease would result in coo not fitting into a
* variable of type short
* or the desired scale (scale power) value is obtained
*/
int c1=this->coo;