* remove usage of imc::object

* introduce imc_channel with collection of affiliate blocks
* imc::keys as list instead of map with custom check/get methods
* imc_raw: start generation of affiliate blocks
This commit is contained in:
Mario Fink 2021-02-11 12:48:49 +01:00
parent fb16935829
commit bed43d6785
4 changed files with 349 additions and 144 deletions

View File

@ -22,9 +22,12 @@ namespace imc
// define properties of a raw file block // define properties of a raw file block
class block class block
{ {
// associated key // associated IMC key
key thekey_; key thekey_;
// unique identifier for using block in hash maps (e.g. byte-position of block = begin_)
std::string uuid_;
// offset (in byte) of first (=ch_bgn_) and last byte (=ch_end_) of block // offset (in byte) of first (=ch_bgn_) and last byte (=ch_end_) of block
// w.r.t. to entire raw file // w.r.t. to entire raw file
unsigned long int begin_, end_; unsigned long int begin_, end_;
@ -38,16 +41,16 @@ namespace imc
std::vector<imc::parameter> parameters_; std::vector<imc::parameter> parameters_;
// particular imc object represented by this block // particular imc object represented by this block
imc::rawobject imc_object_; // imc::rawobject imc_object_;
public: public:
// constructor // constructor
block(key thekey, unsigned long int begin, unsigned long int end, block(key thekey, unsigned long int begin, unsigned long int end,
std::string raw_file, const std::vector<unsigned char>* buffer): std::string raw_file, const std::vector<unsigned char>* buffer):
thekey_(thekey) thekey_(thekey), uuid_(std::to_string(begin))
{ {
if ( keys.count(thekey.name_) != 1 ) throw std::logic_error("unknown key"); if ( !imc::check_key(thekey) ) throw std::logic_error("unknown key");
begin_ = begin; begin_ = begin;
end_ = end; end_ = end;
if ( end_ <= begin_ ) if ( end_ <= begin_ )
@ -68,7 +71,7 @@ namespace imc
try { try {
parse_parameters(); parse_parameters();
parse_object(); // parse_object();
} catch (const std::exception& e) { } catch (const std::exception& e) {
throw std::runtime_error( throw std::runtime_error(
std::string("block: failed to parse parameters/objects: ") + e.what() std::string("block: failed to parse parameters/objects: ") + e.what()
@ -85,7 +88,7 @@ namespace imc
// (consider only first four of any CS block) // (consider only first four of any CS block)
int count = 0; int count = 0;
for ( unsigned long int b = begin_; for ( unsigned long int b = begin_;
b < end_ && (!(thekey_==imc::keys.at("CS")) || count < 4 ); b++ ) b < end_ && (!(thekey_.name_==imc::get_key(true,"CS").name_) || count < 4 ); b++ )
{ {
if ( buffer_->at(b) == imc::ch_sep_ ) if ( buffer_->at(b) == imc::ch_sep_ )
{ {
@ -104,22 +107,23 @@ namespace imc
} }
// pass buffer and parameters associated to block to generate corres. object // pass buffer and parameters associated to block to generate corres. object
void parse_object() // void parse_object()
{ // {
try { // try {
imc_object_.parse(thekey_,buffer_,parameters_); // imc_object_.parse(thekey_,buffer_,parameters_);
} catch (const std::exception& e) { // } catch (const std::exception& e) {
throw std::runtime_error( // throw std::runtime_error(
std::string("failed to parse imc::object for key ") // std::string("failed to parse imc::object for key ")
+ thekey_.name_ + std::string(": ") + e.what() // + thekey_.name_ + std::string(": ") + e.what()
); // );
} // }
} // }
public: public:
// access members // access members
imc::key get_key() { return thekey_; } imc::key get_key() { return thekey_; }
std::string get_uuid() { return uuid_; }
unsigned long int get_begin() { return begin_; } unsigned long int get_begin() { return begin_; }
unsigned long int get_end() { return end_; } unsigned long int get_end() { return end_; }
@ -172,6 +176,7 @@ namespace imc
ss<<std::setw(width)<<std::left<<"block:"<<thekey_.name_ ss<<std::setw(width)<<std::left<<"block:"<<thekey_.name_
<<" version "<<thekey_.version_ <<" version "<<thekey_.version_
<<" ("<<thekey_.description_<<")"<<"\n" <<" ("<<thekey_.description_<<")"<<"\n"
<<std::setw(width)<<std::left<<"uuid:"<<uuid_<<"\n"
<<std::setw(width)<<std::left<<"begin:"<<begin_<<"\n" <<std::setw(width)<<std::left<<"begin:"<<begin_<<"\n"
<<std::setw(width)<<std::left<<"end:"<<end_<<"\n" <<std::setw(width)<<std::left<<"end:"<<end_<<"\n"
<<std::setw(width)<<std::left<<"rawfile:"<<raw_file_<<"\n" <<std::setw(width)<<std::left<<"rawfile:"<<raw_file_<<"\n"
@ -179,12 +184,12 @@ namespace imc
<<std::setw(width)<<std::left<<"parameters:"<<prsstr<<"\n"; <<std::setw(width)<<std::left<<"parameters:"<<prsstr<<"\n";
// include meta data of specific object // include meta data of specific object
if ( include_object ) // if ( include_object )
{ // {
ss<<std::setfill('-')<<std::left<<std::setw(60)<<""<<std::setfill(' ')<<"\n"; // ss<<std::setfill('-')<<std::left<<std::setw(60)<<""<<std::setfill(' ')<<"\n";
// ss<<thekey_.description_<<"\n"; // ss<<thekey_.description_<<"\n";
ss<<imc_object_.get_info()<<"\n"; // ss<<imc_object_.get_info()<<"\n";
} // }
return ss.str(); return ss.str();
} }

72
lib/imc_channel.hpp Normal file
View File

@ -0,0 +1,72 @@
//---------------------------------------------------------------------------//
#ifndef IMCCHANNEL
#define IMCCHANNEL
#include <sstream>
//---------------------------------------------------------------------------//
namespace imc
{
// collect uuid's of blocks required for full channel reconstruction
struct channel_env
{
// define unique identifer for channel_env
std::string uuid_;
// collect affiliate blocks for a single channel
std::string CBuuid_, CGuuid_, CCuuid_, CNuuid_;
std::string CDuuid_, CTuuid_, Cbuuid_, CPuuid_, CRuuid_, CSuuid_;
std::string NTuuid_, NOuuid_;
// get info
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"uuid:"<<uuid_<<"\n"
<<std::setw(width)<<std::left<<"CBuuid:"<<CBuuid_<<"\n"
<<std::setw(width)<<std::left<<"CGuuid:"<<CGuuid_<<"\n"
<<std::setw(width)<<std::left<<"CCuuid:"<<CCuuid_<<"\n"
<<std::setw(width)<<std::left<<"CNuuid:"<<CNuuid_<<"\n"
//
<<std::setw(width)<<std::left<<"CDuuid:"<<CDuuid_<<"\n"
<<std::setw(width)<<std::left<<"CTuuid:"<<CTuuid_<<"\n"
<<std::setw(width)<<std::left<<"Cbuuid:"<<Cbuuid_<<"\n"
<<std::setw(width)<<std::left<<"CPuuid:"<<CPuuid_<<"\n"
<<std::setw(width)<<std::left<<"CRuuid:"<<CRuuid_<<"\n"
<<std::setw(width)<<std::left<<"CSuuid:"<<CSuuid_<<"\n"
//
<<std::setw(width)<<std::left<<"NTuuid:"<<NTuuid_<<"\n"
<<std::setw(width)<<std::left<<"NOuuid:"<<NOuuid_<<"\n";
return ss.str();
}
};
// actual result and (meta)data of channel
struct channel_data
{
// collect meta-data of channels according to env,
// just everything valueable in here
std::string uuid_;
std::string name_;
std::string yunit_;
std::string xunit_;
std::vector<imc::datatype> ydata_;
std::vector<imc::datatype> xdata_;
// provide JSON sttring of metadata
std::string get_json()
{
std::stringstream ss;
ss<<""<<"\n";
return ss.str();
}
};
}
#endif
//---------------------------------------------------------------------------//

View File

@ -30,7 +30,7 @@ namespace imc
// constructor // constructor
key(bool critical, std::string name, key(bool critical, std::string name,
std::string description = std::string(""), int version = 1) std::string description = std::string(""), int version = -1)
{ {
critical_ = critical; critical_ = critical;
if ( name.size() != 2 ) throw std::logic_error("invalid key name"); if ( name.size() != 2 ) throw std::logic_error("invalid key name");
@ -62,36 +62,98 @@ namespace imc
}; };
// define (non)critical markers/keys // define (non)critical markers/keys
std::map<std::string,key> keys = { // std::map<std::string,key> keys = {
//
// // critical keys
// {"CF2", key(true,"CF","format version and processor",1)},
// {"CK1", key(true,"CK","start of group of keys",1)},
// {"CB1", key(true,"CB","group of channels",1)},
// {"CT1", key(true,"CT","text definition",1)},
// {"CG1", key(true,"CG","group of components",1)},
// {"CD1", key(true,"CD","abscissa description",1)},
// {"CD2", key(true,"CD","abscissa description",2)},
// {"CZ1", key(true,"CZ","scaling of z-axis",1)},
// {"CC1", key(true,"CC","start of component",1)},
// {"CP1", key(true,"CP","buffer, datatype and samples of component",1)},
// {"Cb1", key(true,"Cb","buffer description",1)},
// {"CR1", key(true,"CR","permissible range of values in component",1)},
// {"CN1", key(true,"CN","name and comment of channel",1)},
// {"CS1", key(true,"CS","raw binary data",1)},
// {"CI1", key(true,"CI","single numerical value",1)},
// {"Ca1", key(true,"Ca","add reference key",1)},
//
// // noncritical keys
// {"NO1", key(false,"NO","origin of data",1)},
// {"NT1", key(false,"NT","timestamp of trigger",1)},
// {"ND1", key(false,"ND","(color) display properties",1)},
// {"NU1", key(false,"NU","user defined key",1)},
// {"Np1", key(false,"Np","property of channel",1)},
// {"NE1", key(false,"NE","extraction rule for BUS channels",1)}
//
// };
const std::vector<key> keys = {
// critical keys // critical keys
{"CF", key(true,"CF","format version and processor",1)}, key(true,"CF","format version and processor",2),
{"CK", key(true,"CK","start of group of keys",1)}, key(true,"CK","start of group of keys",1),
{"CB", key(true,"CB","group of channels",1)}, key(true,"CB","group of channels",1),
{"CT", key(true,"CT","text definition",1)}, key(true,"CT","text definition",1),
{"CG", key(true,"CG","group of components",1)}, key(true,"CG","group of components",1),
{"CD", key(true,"CD","abscissa description",1)}, key(true,"CD","abscissa description",1),
// {"CD2", key(true,"CD","abscissa description",2)}, key(true,"CD","abscissa description",2),
{"CZ", key(true,"CZ","scaling of z-axis",1)}, key(true,"CZ","scaling of z-axis",1),
{"CC", key(true,"CC","start of component",1)}, key(true,"CC","start of component",1),
{"CP", key(true,"CP","buffer, datatype and samples of component",1)}, key(true,"CP","buffer, datatype and samples of component",1),
{"Cb", key(true,"Cb","buffer description",1)}, key(true,"Cb","buffer description",1),
{"CR", key(true,"CR","permissible range of values in component",1)}, key(true,"CR","permissible range of values in component",1),
{"CN", key(true,"CN","name and comment of channel",1)}, key(true,"CN","name and comment of channel",1),
{"CS", key(true,"CS","raw binary data",1)}, key(true,"CS","raw binary data",1),
{"CI", key(true,"CI","single numerical value",1)}, key(true,"CI","single numerical value",1),
{"Ca", key(true,"Ca","add reference key",1)}, key(true,"Ca","add reference key",1),
// noncritical keys // noncritical keys
{"NO", key(false,"NO","origin of data",1)}, key(false,"NO","origin of data",1),
{"NT", key(false,"NT","timestamp of trigger",1)}, key(false,"NT","timestamp of trigger",1),
{"ND", key(false,"ND","(color) display properties",1)}, key(false,"ND","(color) display properties",1),
{"NU", key(false,"NU","user defined key",1)}, key(false,"NU","user defined key",1),
{"Np", key(false,"Np","property of channel",1)}, key(false,"Np","property of channel",1),
{"NE", key(false,"NE","extraction rule for BUS channels",1)} key(false,"NE","extraction rule for BUS channels",1)
}; };
// check for existence of specific key
bool check_key(key& mykey)
{
for ( key ky: keys ) if ( mykey == ky ) return true;
return false;
}
// get key (with respect to name and evtl. version)
key get_key(bool critical, std::string name, int version = -1)
{
// check validity of required key name
if ( name.size() > 2 || name.size() < 1 )
{
throw std::runtime_error(std::string("invalid key name: ") + name);
}
// declare new key with available data
key mykey(critical,name,std::string(""),version);
// try to find matching key in list of predefined keys
for ( key ky: keys )
{
if ( critical == ky.critical_ && name == ky.name_
&& ( version == ky.version_ || version == -1 ) )
{
mykey = ky;
}
}
return mykey;
}
} }

View File

@ -12,6 +12,7 @@
#include "imc_datatype.hpp" #include "imc_datatype.hpp"
#include "imc_object.hpp" #include "imc_object.hpp"
#include "imc_result.hpp" #include "imc_result.hpp"
#include "imc_channel.hpp"
//---------------------------------------------------------------------------// //---------------------------------------------------------------------------//
@ -25,14 +26,15 @@ namespace imc
// buffer of raw-file // buffer of raw-file
std::vector<unsigned char> buffer_; std::vector<unsigned char> buffer_;
// list of imc-blocks // list and map of imc-blocks
std::vector<imc::block> rawblocks_; std::vector<imc::block> rawblocks_;
std::map<std::string,imc::block> mapblocks_;
// check computational complexity for parsing blocks // check computational complexity for parsing blocks
unsigned long int cplxcnt_; unsigned long int cplxcnt_;
// collect meta-information, channel definition, etc. // list groups and channels with their affiliate blocks
std::vector<imc::keygroup> keygroups_; std::map<std::string,imc::channel_env> channel_envs_;
public: public:
@ -46,6 +48,8 @@ namespace imc
raw_file_ = raw_file; raw_file_ = raw_file;
this->fill_buffer(); this->fill_buffer();
this->parse_blocks(); this->parse_blocks();
this->generate_block_map();
this->generate_channel_env();
} }
private: private:
@ -86,25 +90,30 @@ namespace imc
// check for (non)critical key // check for (non)critical key
if ( *(it+1) == imc::key_crit_ || *(it+1) == imc::key_non_crit_ ) if ( *(it+1) == imc::key_crit_ || *(it+1) == imc::key_non_crit_ )
{ {
// compose entire key // compose (entire) key
std::string newkey = { (char)*(it+1), (char)*(it+2) }; std::string newkey = { (char)*(it+1), (char)*(it+2) };
imc::key itkey(*(it+1) == imc::key_crit_,newkey);
// check for known keys // expecting ch_sep_ after key
if ( keys.count(newkey) == 1 ) if ( *(it+3) == ch_sep_ )
{ {
// expecting ch_sep_ after key // extract key version
if ( *(it+3) == ch_sep_ ) std::string vers("");
unsigned long int pos = 4;
while ( *(it+pos) != ch_sep_ )
{ {
// extract key version vers.push_back((char)*(it+pos));
std::string vers(""); pos++;
unsigned long int pos = 4; }
while ( *(it+pos) != ch_sep_ ) int version = std::stoi(vers);
{
vers.push_back((char)*(it+pos));
pos++;
}
int version = std::stoi(vers);
// try to retrieve full key
itkey.version_ = version;
itkey = imc::get_key(itkey.critical_,itkey.name_,itkey.version_);
// check for known keys (including version)
if ( imc::check_key(itkey) )
{
// get block length // get block length
std::string leng(""); std::string leng("");
pos++; pos++;
@ -116,11 +125,11 @@ namespace imc
unsigned long length = std::stoul(leng); unsigned long length = std::stoul(leng);
// declare and initialize corresponding key and block // declare and initialize corresponding key and block
imc::key bkey( *(it+1)==imc::key_crit_ , newkey, // imc::key bkey( *(it+1)==imc::key_crit_ , newkey,
imc::keys.at(newkey).description_, version ); // imc::keys.at(newkey).description_, version );
imc::block blk(bkey,it-buffer_.begin(), imc::block blk(itkey,it-buffer_.begin(),
it-buffer_.begin()+pos+1+length, it-buffer_.begin()+pos+1+length,
raw_file_, &buffer_); raw_file_, &buffer_);
// add block to list // add block to list
rawblocks_.push_back(blk); rawblocks_.push_back(blk);
@ -133,15 +142,26 @@ namespace imc
} }
else else
{ {
throw std::runtime_error( // all critical must be known !! while a noncritical may be ignored
std::string("invalid block or corrupt buffer at byte: ") if ( *(it+1) == imc::key_crit_ )
+ std::to_string(it+3-buffer_.begin()) {
); throw std::runtime_error(
std::string("unknown critical key: ") + newkey + std::to_string(version)
);
}
else
{
std::cout<<"WARNING: unknown noncritical key '"
<<newkey<<version<<"' will be ignored\n";
}
} }
} }
else else
{ {
throw std::runtime_error(std::string("unknown IMC key: ") + newkey); throw std::runtime_error(
std::string("invalid block or corrupt buffer at byte: ")
+ std::to_string(it+3-buffer_.begin())
);
} }
} }
} }
@ -166,6 +186,52 @@ namespace imc
} }
} }
// generate map of blocks using their uuid
void generate_block_map()
{
for ( imc::block blk: rawblocks_ )
{
mapblocks_.insert( std::pair<std::string,imc::block>(blk.get_uuid(),blk) );
}
}
// generate channel "environments"
void generate_channel_env()
{
// collect affiliate blocks for every channel WITH CHANNEL and AFFILIATE
// BLOCK CORRESPONDENCE GOVERNED BY BLOCK ORDER IN BUFFER!!
for ( imc::block blk: rawblocks_ )
{
// declare first channel environment
imc::channel_env chnenv;
// if ( blk.get_key() == imc::keys.at("CB") ) chnenv.CBuuid_ = blk.get_uuid();
// if ( blk.get_key() == imc::keys.at("CG") ) chnenv.CGuuid_ = blk.get_uuid();
// if ( blk.get_key() == imc::keys.at("CC") ) chnenv.CCuuid_ = blk.get_uuid();
// if ( blk.get_key() == imc::keys.at("CN") ) chnenv.CNuuid_ = blk.get_uuid();
// //
// if ( blk.get_key() == imc::keys.at("CD") ) chnenv.CDuuid_ = blk.get_uuid();
// if ( blk.get_key() == imc::keys.at("CT") ) chnenv.CTuuid_ = blk.get_uuid();
// if ( blk.get_key() == imc::keys.at("Cb") ) chnenv.Cbuuid_ = blk.get_uuid();
// if ( blk.get_key() == imc::keys.at("CP") ) chnenv.CPuuid_ = blk.get_uuid();
// if ( blk.get_key() == imc::keys.at("CR") ) chnenv.CRuuid_ = blk.get_uuid();
// if ( blk.get_key() == imc::keys.at("CS") ) chnenv.CSuuid_ = blk.get_uuid();
// //
// if ( blk.get_key() == imc::keys.at("NT") ) chnenv.NTuuid_ = blk.get_uuid();
// if ( blk.get_key() == imc::keys.at("NO") ) chnenv.NOuuid_ = blk.get_uuid();
//
// // a component is closed by any of {CS, CC, CG, CB}
// if ( blk.get_key() == imc::keys.at("CS") || blk.get_key() == imc::keys.at("CC")
// || blk.get_key() == imc::keys.at("CG") || blk.get_key() == imc::keys.at("CB") )
// {
// chnenv.uuid_ = chnenv.CNuuid_;
// channel_envs_.insert(
// std::pair<std::string,imc::channel_env>(chnenv.CNuuid_,chnenv)
// );
// }
}
}
// parse channel's raw data // parse channel's raw data
template<typename datatype> template<typename datatype>
void convert_data_to_type(std::vector<unsigned char>& subbuffer, void convert_data_to_type(std::vector<unsigned char>& subbuffer,
@ -230,7 +296,7 @@ namespace imc
// list all groups (associated to blocks "CB") // list all groups (associated to blocks "CB")
std::vector<imc::block> list_groups() std::vector<imc::block> list_groups()
{ {
return this->list_blocks(imc::keys.at("CB")); return this->list_blocks(imc::get_key(true,"CB"));
} }
// list all channels // list all channels
@ -239,7 +305,7 @@ namespace imc
std::vector<std::string> channels; std::vector<std::string> channels;
for ( imc::block blk: this->rawblocks_ ) for ( imc::block blk: this->rawblocks_ )
{ {
if ( blk.get_key() == imc::keys.at("CN") ) if ( blk.get_key() == imc::get_key(true,"CN") )
{ {
imc::parameter prm = blk.get_parameters()[6]; imc::parameter prm = blk.get_parameters()[6];
channels.push_back(blk.get_parameter(prm)); channels.push_back(blk.get_parameter(prm));
@ -251,74 +317,74 @@ namespace imc
// get specific channel data // get specific channel data
// TODO generalize and simplify channel extraction!! // TODO generalize and simplify channel extraction!!
imc::channel_tab get_channel(std::string channel) // imc::channel_tab get_channel(std::string channel)
{ // {
// declare single channel table // // declare single channel table
imc::channel_tab chtab; // imc::channel_tab chtab;
//
// ordinate parameters // // ordinate parameters
std::string yunit = std::string(""); // std::string yunit = std::string("");
unsigned long int num_samples = -1; // unsigned long int num_samples = -1;
// imc::datatype dtype; // // imc::datatype dtype;
int numbits = -1; // int numbits = -1;
double yoffset = -1.0, yfactor = -1.0; // double yoffset = -1.0, yfactor = -1.0;
//
// abscissa parameters // // abscissa parameters
double dx = -1.0; // double dx = -1.0;
double xoffset = -1.0; // double xoffset = -1.0;
std::string xunit = std::string(""); // std::string xunit = std::string("");
//
// search block for required parameters // // search block for required parameters
for ( imc::block blk: this->rawblocks_ ) // for ( imc::block blk: this->rawblocks_ )
{ // {
if ( blk.get_key() == imc::keys.at("CR") ) // if ( blk.get_key() == imc::keys.at("CR") )
{ // {
yunit = blk.get_parameter(blk.get_parameters()[7]); // yunit = blk.get_parameter(blk.get_parameters()[7]);
} // }
//
if ( blk.get_key() == imc::keys.at("Cb") ) // if ( blk.get_key() == imc::keys.at("Cb") )
{ // {
num_samples = std::stoul(blk.get_parameter(blk.get_parameters()[7])); // num_samples = std::stoul(blk.get_parameter(blk.get_parameters()[7]));
xoffset = std::stod(blk.get_parameter(blk.get_parameters()[11])); // xoffset = std::stod(blk.get_parameter(blk.get_parameters()[11]));
} // }
//
if ( blk.get_key() == imc::keys.at("CP") ) // if ( blk.get_key() == imc::keys.at("CP") )
{ // {
numbits = std::stoi(blk.get_parameter(blk.get_parameters()[5])); // numbits = std::stoi(blk.get_parameter(blk.get_parameters()[5]));
} // }
//
if ( blk.get_key() == imc::keys.at("CR") ) // if ( blk.get_key() == imc::keys.at("CR") )
{ // {
yfactor = std::stod(blk.get_parameter(blk.get_parameters()[3])); // yfactor = std::stod(blk.get_parameter(blk.get_parameters()[3]));
yoffset = std::stod(blk.get_parameter(blk.get_parameters()[4])); // yoffset = std::stod(blk.get_parameter(blk.get_parameters()[4]));
yunit = blk.get_parameter(blk.get_parameters()[7]); // yunit = blk.get_parameter(blk.get_parameters()[7]);
} // }
//
if ( blk.get_key() == imc::keys.at("CD") ) // if ( blk.get_key() == imc::keys.at("CD") )
{ // {
std::cout<<"got CD\n"; // std::cout<<"got CD\n";
dx = std::stod(blk.get_parameter(blk.get_parameters()[2])); // dx = std::stod(blk.get_parameter(blk.get_parameters()[2]));
xunit = blk.get_parameter(blk.get_parameters()[7]); // xunit = blk.get_parameter(blk.get_parameters()[7]);
} // }
} // }
//
std::cout<<"yunit:"<<yunit<<"\n" // std::cout<<"yunit:"<<yunit<<"\n"
<<"yoffset:"<<yoffset<<"\n" // <<"yoffset:"<<yoffset<<"\n"
<<"yfactor:"<<yfactor<<"\n" // <<"yfactor:"<<yfactor<<"\n"
<<"numbits:"<<numbits<<"\n" // <<"numbits:"<<numbits<<"\n"
<<"num_samples:"<<num_samples<<"\n" // <<"num_samples:"<<num_samples<<"\n"
<<"dx:"<<dx<<"\n" // <<"dx:"<<dx<<"\n"
<<"xoffset:"<<xoffset<<"\n" // <<"xoffset:"<<xoffset<<"\n"
<<"xunit:"<<xunit<<"\n"; // <<"xunit:"<<xunit<<"\n";
//
// generate abscissa data // // generate abscissa data
//
//
// generate ordinate data // // generate ordinate data
//
//
return chtab; // return chtab;
} // }
}; };