* 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
class block
{
// associated key
// associated IMC key
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
// w.r.t. to entire raw file
unsigned long int begin_, end_;
@ -38,16 +41,16 @@ namespace imc
std::vector<imc::parameter> parameters_;
// particular imc object represented by this block
imc::rawobject imc_object_;
// imc::rawobject imc_object_;
public:
// constructor
block(key thekey, unsigned long int begin, unsigned long int end,
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;
end_ = end;
if ( end_ <= begin_ )
@ -68,7 +71,7 @@ namespace imc
try {
parse_parameters();
parse_object();
// parse_object();
} catch (const std::exception& e) {
throw std::runtime_error(
std::string("block: failed to parse parameters/objects: ") + e.what()
@ -85,7 +88,7 @@ namespace imc
// (consider only first four of any CS block)
int count = 0;
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_ )
{
@ -104,22 +107,23 @@ namespace imc
}
// pass buffer and parameters associated to block to generate corres. object
void parse_object()
{
try {
imc_object_.parse(thekey_,buffer_,parameters_);
} catch (const std::exception& e) {
throw std::runtime_error(
std::string("failed to parse imc::object for key ")
+ thekey_.name_ + std::string(": ") + e.what()
);
}
}
// void parse_object()
// {
// try {
// imc_object_.parse(thekey_,buffer_,parameters_);
// } catch (const std::exception& e) {
// throw std::runtime_error(
// std::string("failed to parse imc::object for key ")
// + thekey_.name_ + std::string(": ") + e.what()
// );
// }
// }
public:
// access members
imc::key get_key() { return thekey_; }
std::string get_uuid() { return uuid_; }
unsigned long int get_begin() { return begin_; }
unsigned long int get_end() { return end_; }
@ -172,6 +176,7 @@ namespace imc
ss<<std::setw(width)<<std::left<<"block:"<<thekey_.name_
<<" version "<<thekey_.version_
<<" ("<<thekey_.description_<<")"<<"\n"
<<std::setw(width)<<std::left<<"uuid:"<<uuid_<<"\n"
<<std::setw(width)<<std::left<<"begin:"<<begin_<<"\n"
<<std::setw(width)<<std::left<<"end:"<<end_<<"\n"
<<std::setw(width)<<std::left<<"rawfile:"<<raw_file_<<"\n"
@ -179,12 +184,12 @@ namespace imc
<<std::setw(width)<<std::left<<"parameters:"<<prsstr<<"\n";
// include meta data of specific object
if ( include_object )
{
ss<<std::setfill('-')<<std::left<<std::setw(60)<<""<<std::setfill(' ')<<"\n";
// if ( include_object )
// {
// ss<<std::setfill('-')<<std::left<<std::setw(60)<<""<<std::setfill(' ')<<"\n";
// ss<<thekey_.description_<<"\n";
ss<<imc_object_.get_info()<<"\n";
}
// ss<<imc_object_.get_info()<<"\n";
// }
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
key(bool critical, std::string name,
std::string description = std::string(""), int version = 1)
std::string description = std::string(""), int version = -1)
{
critical_ = critical;
if ( name.size() != 2 ) throw std::logic_error("invalid key name");
@ -62,36 +62,98 @@ namespace imc
};
// 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
{"CF", key(true,"CF","format version and processor",1)},
{"CK", key(true,"CK","start of group of keys",1)},
{"CB", key(true,"CB","group of channels",1)},
{"CT", key(true,"CT","text definition",1)},
{"CG", key(true,"CG","group of components",1)},
{"CD", key(true,"CD","abscissa description",1)},
// {"CD2", key(true,"CD","abscissa description",2)},
{"CZ", key(true,"CZ","scaling of z-axis",1)},
{"CC", key(true,"CC","start of component",1)},
{"CP", key(true,"CP","buffer, datatype and samples of component",1)},
{"Cb", key(true,"Cb","buffer description",1)},
{"CR", key(true,"CR","permissible range of values in component",1)},
{"CN", key(true,"CN","name and comment of channel",1)},
{"CS", key(true,"CS","raw binary data",1)},
{"CI", key(true,"CI","single numerical value",1)},
{"Ca", key(true,"Ca","add reference key",1)},
key(true,"CF","format version and processor",2),
key(true,"CK","start of group of keys",1),
key(true,"CB","group of channels",1),
key(true,"CT","text definition",1),
key(true,"CG","group of components",1),
key(true,"CD","abscissa description",1),
key(true,"CD","abscissa description",2),
key(true,"CZ","scaling of z-axis",1),
key(true,"CC","start of component",1),
key(true,"CP","buffer, datatype and samples of component",1),
key(true,"Cb","buffer description",1),
key(true,"CR","permissible range of values in component",1),
key(true,"CN","name and comment of channel",1),
key(true,"CS","raw binary data",1),
key(true,"CI","single numerical value",1),
key(true,"Ca","add reference key",1),
// noncritical keys
{"NO", key(false,"NO","origin of data",1)},
{"NT", key(false,"NT","timestamp of trigger",1)},
{"ND", key(false,"ND","(color) display properties",1)},
{"NU", key(false,"NU","user defined key",1)},
{"Np", key(false,"Np","property of channel",1)},
{"NE", key(false,"NE","extraction rule for BUS channels",1)}
key(false,"NO","origin of data",1),
key(false,"NT","timestamp of trigger",1),
key(false,"ND","(color) display properties",1),
key(false,"NU","user defined key",1),
key(false,"Np","property of channel",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_object.hpp"
#include "imc_result.hpp"
#include "imc_channel.hpp"
//---------------------------------------------------------------------------//
@ -25,14 +26,15 @@ namespace imc
// buffer of raw-file
std::vector<unsigned char> buffer_;
// list of imc-blocks
// list and map of imc-blocks
std::vector<imc::block> rawblocks_;
std::map<std::string,imc::block> mapblocks_;
// check computational complexity for parsing blocks
unsigned long int cplxcnt_;
// collect meta-information, channel definition, etc.
std::vector<imc::keygroup> keygroups_;
// list groups and channels with their affiliate blocks
std::map<std::string,imc::channel_env> channel_envs_;
public:
@ -46,6 +48,8 @@ namespace imc
raw_file_ = raw_file;
this->fill_buffer();
this->parse_blocks();
this->generate_block_map();
this->generate_channel_env();
}
private:
@ -86,12 +90,10 @@ namespace imc
// check for (non)critical key
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) };
imc::key itkey(*(it+1) == imc::key_crit_,newkey);
// check for known keys
if ( keys.count(newkey) == 1 )
{
// expecting ch_sep_ after key
if ( *(it+3) == ch_sep_ )
{
@ -105,6 +107,13 @@ namespace imc
}
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
std::string leng("");
pos++;
@ -116,9 +125,9 @@ namespace imc
unsigned long length = std::stoul(leng);
// declare and initialize corresponding key and block
imc::key bkey( *(it+1)==imc::key_crit_ , newkey,
imc::keys.at(newkey).description_, version );
imc::block blk(bkey,it-buffer_.begin(),
// imc::key bkey( *(it+1)==imc::key_crit_ , newkey,
// imc::keys.at(newkey).description_, version );
imc::block blk(itkey,it-buffer_.begin(),
it-buffer_.begin()+pos+1+length,
raw_file_, &buffer_);
@ -132,16 +141,27 @@ namespace imc
}
}
else
{
// all critical must be known !! while a noncritical may be ignored
if ( *(it+1) == imc::key_crit_ )
{
throw std::runtime_error(
std::string("invalid block or corrupt buffer at byte: ")
+ std::to_string(it+3-buffer_.begin())
std::string("unknown critical key: ") + newkey + std::to_string(version)
);
}
else
{
std::cout<<"WARNING: unknown noncritical key '"
<<newkey<<version<<"' will be ignored\n";
}
}
}
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
template<typename datatype>
void convert_data_to_type(std::vector<unsigned char>& subbuffer,
@ -230,7 +296,7 @@ namespace imc
// list all groups (associated to blocks "CB")
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
@ -239,7 +305,7 @@ namespace imc
std::vector<std::string> channels;
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];
channels.push_back(blk.get_parameter(prm));
@ -251,74 +317,74 @@ namespace imc
// get specific channel data
// TODO generalize and simplify channel extraction!!
imc::channel_tab get_channel(std::string channel)
{
// declare single channel table
imc::channel_tab chtab;
// ordinate parameters
std::string yunit = std::string("");
unsigned long int num_samples = -1;
// imc::datatype dtype;
int numbits = -1;
double yoffset = -1.0, yfactor = -1.0;
// abscissa parameters
double dx = -1.0;
double xoffset = -1.0;
std::string xunit = std::string("");
// search block for required parameters
for ( imc::block blk: this->rawblocks_ )
{
if ( blk.get_key() == imc::keys.at("CR") )
{
yunit = blk.get_parameter(blk.get_parameters()[7]);
}
if ( blk.get_key() == imc::keys.at("Cb") )
{
num_samples = std::stoul(blk.get_parameter(blk.get_parameters()[7]));
xoffset = std::stod(blk.get_parameter(blk.get_parameters()[11]));
}
if ( blk.get_key() == imc::keys.at("CP") )
{
numbits = std::stoi(blk.get_parameter(blk.get_parameters()[5]));
}
if ( blk.get_key() == imc::keys.at("CR") )
{
yfactor = std::stod(blk.get_parameter(blk.get_parameters()[3]));
yoffset = std::stod(blk.get_parameter(blk.get_parameters()[4]));
yunit = blk.get_parameter(blk.get_parameters()[7]);
}
if ( blk.get_key() == imc::keys.at("CD") )
{
std::cout<<"got CD\n";
dx = std::stod(blk.get_parameter(blk.get_parameters()[2]));
xunit = blk.get_parameter(blk.get_parameters()[7]);
}
}
std::cout<<"yunit:"<<yunit<<"\n"
<<"yoffset:"<<yoffset<<"\n"
<<"yfactor:"<<yfactor<<"\n"
<<"numbits:"<<numbits<<"\n"
<<"num_samples:"<<num_samples<<"\n"
<<"dx:"<<dx<<"\n"
<<"xoffset:"<<xoffset<<"\n"
<<"xunit:"<<xunit<<"\n";
// generate abscissa data
// generate ordinate data
return chtab;
}
// imc::channel_tab get_channel(std::string channel)
// {
// // declare single channel table
// imc::channel_tab chtab;
//
// // ordinate parameters
// std::string yunit = std::string("");
// unsigned long int num_samples = -1;
// // imc::datatype dtype;
// int numbits = -1;
// double yoffset = -1.0, yfactor = -1.0;
//
// // abscissa parameters
// double dx = -1.0;
// double xoffset = -1.0;
// std::string xunit = std::string("");
//
// // search block for required parameters
// for ( imc::block blk: this->rawblocks_ )
// {
// if ( blk.get_key() == imc::keys.at("CR") )
// {
// yunit = blk.get_parameter(blk.get_parameters()[7]);
// }
//
// if ( blk.get_key() == imc::keys.at("Cb") )
// {
// num_samples = std::stoul(blk.get_parameter(blk.get_parameters()[7]));
// xoffset = std::stod(blk.get_parameter(blk.get_parameters()[11]));
// }
//
// if ( blk.get_key() == imc::keys.at("CP") )
// {
// numbits = std::stoi(blk.get_parameter(blk.get_parameters()[5]));
// }
//
// if ( blk.get_key() == imc::keys.at("CR") )
// {
// yfactor = std::stod(blk.get_parameter(blk.get_parameters()[3]));
// yoffset = std::stod(blk.get_parameter(blk.get_parameters()[4]));
// yunit = blk.get_parameter(blk.get_parameters()[7]);
// }
//
// if ( blk.get_key() == imc::keys.at("CD") )
// {
// std::cout<<"got CD\n";
// dx = std::stod(blk.get_parameter(blk.get_parameters()[2]));
// xunit = blk.get_parameter(blk.get_parameters()[7]);
// }
// }
//
// std::cout<<"yunit:"<<yunit<<"\n"
// <<"yoffset:"<<yoffset<<"\n"
// <<"yfactor:"<<yfactor<<"\n"
// <<"numbits:"<<numbits<<"\n"
// <<"num_samples:"<<num_samples<<"\n"
// <<"dx:"<<dx<<"\n"
// <<"xoffset:"<<xoffset<<"\n"
// <<"xunit:"<<xunit<<"\n";
//
// // generate abscissa data
//
//
// // generate ordinate data
//
//
// return chtab;
// }
};