#include <DaqData.h>
Public Member Functions | |
char * | Buffer () const |
DaqData (std::vector< unsigned int > &v) | |
DaqData (const unsigned char *ptr, int sizeinbytes) | |
DaqData (const DaqData &a) | |
unsigned int | getValue (int indfield, int indobj=0) const |
int | Nobjects () const |
int | Size () const |
~DaqData () | |
Private Member Functions | |
void | compressObject (const unsigned char *ptr, std::vector< unsigned int >::iterator &vit, int &bitsalreadyfilled) |
void | uncompressObject (const unsigned char *ptr, std::vector< unsigned int > &objdata, int &bitsalreadyfilled) |
Private Attributes | |
unsigned char * | buffer_ |
std::map< int, std::vector < unsigned int > > | data_ |
int | nobjects_ |
int | size_ |
This is the basic class accomplishing raw data formatting/unformatting.
1) Creation of a buffer of bytes representing the raw data
the user must create a DaqData object providing as input the data in the form of a vector of unsigned integers. The input data are all the values necessary to specify one (or more) object of the given format, which is the templated type. In case more than one object of the same given format should be put in the buffer, then the values of the second object must follow in the vector those of the first object and so on. DaqData will then compress these values in a bitstream according to the desired format. The bitstream is always aligned to the byte. The user, after successful compression, can request the pointer to the beginning of the buffer of bytes that represent the raw data (method Buffer() ) and the length of this buffer (method Size() ).
2) Interpretation of a buffer of bytes representing the raw data
the user must create a DaqData object providing as input a pointer to a buffer of bytes and the length in bytes of this buffer. DaqData will then extract the values (unsigned integers) present in the buffer according to a proper format, which is again the templated type. After successful uncompression of the buffer, the user can request the number of objects of the given format that were present in the buffer ( method Nobjects() ) and retrieve the individual values characterizing these objects ( method getValue() ).
WARNING: at the moment the interpretation of a buffer of bytes proceeds through the constructor of DaqData. This operation implies more than one copy of the data, which is not the most efficient way of accomplishing the task. In a future version of DaqData, more efficient methods will be made available.
Definition at line 60 of file DaqData.h.
References DaqData< Format >::buffer_, DaqData< Format >::compressObject(), gather_cfg::cout, DaqData< Format >::data_, i, mergeVDriftHistosByStation::name, DaqData< Format >::nobjects_, AlCaHLTBitMon_ParallelJobs::p, alignCSCRings::s, and DaqData< Format >::size_.
: size_(0), buffer_(0), nobjects_(0) { try { if (v.size() == 0) throw string("DaqData: empty input data vector provided: "); int Nfields = Format::getNumberOfFields(); if (v.size()%Nfields != 0) throw string("DaqData: ERROR. You must provide a number of input values compatibles with the requested format: "); int ObjSize = Format::getFieldLastBit(Nfields-1)+1; nobjects_ = v.size()/Nfields; // cout<<"Going to create "<<nobjects_<< " objects of type "<<typeid(Format).name()<<endl; size_ = (int) ceil(((double)(ObjSize*nobjects_))/8); buffer_= new char[size_]; // cout<<"The buffer will be "<<size_ <<" bytes long"<<endl; std::vector<unsigned int>::iterator vit = v.begin(); char * p = buffer_; int bitsalreadyfilled = 0; int Totbytes=1; for(int i=0; i<nobjects_; i++) { //additional bytes necessary to accomodate the current object int Nbytes = (int) ceil((double)(Format::getFieldLastBit(Nfields-1)+1-8+bitsalreadyfilled)/8); if ((Totbytes+=Nbytes) > size_) throw string("Exceeded allocated buffer size"); compressObject(p, vit, bitsalreadyfilled); // cout<<"Successfully compressed object "<< i <<endl; data_.insert(std::pair< int, std::vector<unsigned int> >(i,std::vector<unsigned int>(vit-Nfields,vit) )); //the second term is necessary in the case the last byte has been fully used p+=(Nbytes+(8-bitsalreadyfilled)/8) ; Totbytes+=(8-bitsalreadyfilled)/8 ; } if(bitsalreadyfilled==0) Totbytes--; /* cout << "Compression successful. "<< Totbytes<<" bytes compressed in total"<< endl; cout<< "Buffer pointer: "<<hex<< buffer_<< dec << "Size of buffer= "<< size_<<endl; for(int i=0; i<nobjects_; i++) { cout << "Object # "<< i << " fields: " <<endl; for(int j=0; j<Format::getNumberOfFields(); j++) cout << getValue(j,i) <<endl; } */ } catch (std::string s){ cout<<"DaqData - Exception caught: " << s <<endl; cout<<"Object compression failed! No data has been constructed for format: "<< string(typeid(Format).name())<<endl; } }
DaqData< Format >::DaqData | ( | const unsigned char * | ptr, |
int | sizeinbytes | ||
) | [inline] |
Definition at line 125 of file DaqData.h.
References gather_cfg::cout, DaqData< Format >::data_, i, mergeVDriftHistosByStation::name, DaqData< Format >::nobjects_, AlCaHLTBitMon_ParallelJobs::p, alignCSCRings::s, and DaqData< Format >::uncompressObject().
: size_(0), buffer_(0), nobjects_(0) { try { if (sizeinbytes==0) throw std::string("Buffer size is zero"); int Nfields = Format::getNumberOfFields(); int ObjSize = Format::getFieldLastBit(Nfields-1)+1; nobjects_ = (sizeinbytes*8)/ObjSize; // cout<<"Going to create "<<nobjects_<< " objects of type "<<typeid(Format).name()<<endl; // cout<<"The buffer will be "<<size_ <<" bytes long"<<endl; if ((sizeinbytes*8)%ObjSize != 0) { cout<<"DaqData: there will be " << (sizeinbytes*8)%ObjSize <<" meaningless bits at the end of the buffer"<<endl; } // buffer_ = new char[sizeinbytes]; // memmove(buffer_,ptr,sizeinbytes); // char * p = buffer_; const unsigned char * p = ptr; int bitsalreadyfilled = 0; int Totbytes=1; for(int i=0; i<nobjects_; i++) { std::vector<unsigned int> objdata; objdata.reserve(Nfields); //additional bytes necessary to accomodate the current object int Nbytes = (int) ceil((double)(Format::getFieldLastBit(Nfields-1)+1-8+bitsalreadyfilled)/8); if ((Totbytes+=Nbytes) > sizeinbytes) throw std::string("Exceeded allocated buffer size"); uncompressObject(p, objdata, bitsalreadyfilled); // cout<<"Successfully uncompressed object "<< i <<endl; data_.insert(std::pair< int, std::vector<unsigned int> >(i,objdata) ); //the second term is necessary in the case the last byte has been fully used p+= (Nbytes + (8-bitsalreadyfilled)/8); Totbytes+= (8-bitsalreadyfilled)/8; } if(bitsalreadyfilled==0) Totbytes--; /* cout << "Uncompression succeeded. "<< Totbytes<<" bytes uncompressed in total"<< endl; cout<< "Buffer pointer: "<<hex<< buffer_<< dec<< "Size of buffer= "<< size_<<endl; for(int i=0; i<nobjects_; i++) { cout << "Object # "<< i << " fields: " <<endl; for(int j=0; j<Format::getNumberOfFields(); j++) cout << getValue(j,i) <<endl; } */ } catch (std::string s){ std::cout<<"DaqData - Exception caught: " << s <<std::endl; std::cout<<"Object uncompression failed! No data has been constructed for format: "<<std::string(typeid(Format).name())<<endl; } }
Definition at line 200 of file DaqData.h.
References DaqData< Format >::Buffer(), DaqData< Format >::buffer_, DaqData< Format >::data_, DaqData< Format >::getValue(), i, j, DaqData< Format >::Nobjects(), DaqData< Format >::nobjects_, DaqData< Format >::Size(), and DaqData< Format >::size_.
{ size_ = a.Size(); buffer_ = new char[size_]; memmove(buffer_,a.Buffer(),size_); nobjects_ = a.Nobjects(); for(int i=0; i<nobjects_; i++) { std::vector<unsigned int> vec; for(int j=0; j<Format::getNumberOfFields(); j++) vec.push_back(a.getValue(j,i)); data_.insert(std::pair< int, std::vector<unsigned int> >(i, vec)); } }
Definition at line 216 of file DaqData.h.
References DaqData< Format >::buffer_.
char* DaqData< Format >::Buffer | ( | ) | const [inline] |
Definition at line 224 of file DaqData.h.
References DaqData< Format >::buffer_.
Referenced by DaqData< Format >::DaqData().
{return buffer_;}
void DaqData< Format >::compressObject | ( | const unsigned char * | ptr, |
std::vector< unsigned int >::iterator & | vit, | ||
int & | bitsalreadyfilled | ||
) | [inline, private] |
Definition at line 375 of file DaqData.h.
References funct::pow().
Referenced by DaqData< Format >::DaqData().
{ int Nfields = Format::getNumberOfFields(); int bitstoaccomodate=Format::getFieldLastBit(0)+1; // of current field if (*vit > pow(2.,bitstoaccomodate)-1) throw string("The value is too large to fit in the field "); int ifield = 0; //Lower all bits but those already filled *ptr &= 0xff + 1 - (unsigned int)pow(2.,8-bitsalreadyfilled); while (ifield < Nfields) { if(bitstoaccomodate > 8 - bitsalreadyfilled ) { // cout<<"Field cannot be compressed from what left in current byte"<<endl; // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; *ptr += (((*vit) >> (bitstoaccomodate - (8 - bitsalreadyfilled))) & 0xff); // cout<< "value: "<< hex << *vit <<" - " << dec << *vit<< endl; // cout<< "byte: "<< hex << (unsigned int)(*ptr) <<" - "<< dec << (unsigned int)(*ptr) << endl; bitstoaccomodate -= (8-bitsalreadyfilled); bitsalreadyfilled = 0; ptr++; *ptr &= 0xff + 1 - (unsigned int)pow(2.,8-bitsalreadyfilled); // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; } else if(bitstoaccomodate < (8 - bitsalreadyfilled) && bitstoaccomodate >0){ // cout<<"Field can be compressed in the current byte, which will not be completely filled"<<endl; *ptr += ( (((*vit) << 8-bitstoaccomodate) & 0xff) >> (bitsalreadyfilled) ); // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; // cout<< "value: "<< hex << *vit <<" - " << dec << *vit<< endl; // cout<< "byte: "<< hex << (unsigned int)(*ptr) <<" - "<< dec << (unsigned int)(*ptr) << endl; vit++; bitsalreadyfilled+=bitstoaccomodate; // cout<<"Field completed"<<endl; if(ifield==Nfields-1) return; // cout<<"Compressing new Field"<<endl; ifield++; bitstoaccomodate=Format::getFieldLastBit(ifield)-Format::getFieldLastBit(ifield-1); if (*vit > pow(2.,bitstoaccomodate)-1) throw string("The value is too large to fit in the field "); // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; } else if(bitstoaccomodate == (8 - bitsalreadyfilled) && bitstoaccomodate >0){ // cout<<"Field can be compressed in the current byte, which will be completely filled"<<endl; *ptr += ( (((*vit) << 8-bitstoaccomodate) & 0xff) >> (bitsalreadyfilled) ); // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; // cout<< "value: "<< hex << *vit <<" - " << dec << *vit<< endl; // cout<< "byte: "<< hex << (unsigned int)(*ptr) <<" - "<< dec << (unsigned int)(*ptr) << endl; vit++; bitsalreadyfilled=0; // cout<<"Field completed"<<endl; if(ifield==Nfields-1) return; // cout<<"Compressing new Field"<<endl; ptr++; *ptr &= 0xff + 1 - (unsigned int)pow(2.,8-bitsalreadyfilled); ifield++; bitstoaccomodate=Format::getFieldLastBit(ifield)-Format::getFieldLastBit(ifield-1); if (*vit > pow(2.,bitstoaccomodate)-1) throw string("The value is too large to fit in the field "); // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; } else throw string(" unexpected situation during compression"); } //end of cycle over fields }
unsigned int DaqData< Format >::getValue | ( | int | indfield, |
int | indobj = 0 |
||
) | const [inline] |
Definition at line 236 of file DaqData.h.
References gather_cfg::cout, DaqData< Format >::data_, and DaqData< Format >::nobjects_.
Referenced by DaqData< Format >::DaqData().
{ if (indobj<nobjects_ && indfield < Format::getNumberOfFields()) { std::map < int, std::vector<unsigned int> >::const_iterator it = data_.find(indobj); if (it != data_.end()) return ((*it).second)[indfield]; else { cout<<"DaqData - Strange: object should exist but was not found "<<endl; return 0; } } else cout<<"DaqData - Non existent field or object"<<endl; return 0; }
int DaqData< Format >::Nobjects | ( | ) | const [inline] |
Definition at line 228 of file DaqData.h.
References DaqData< Format >::nobjects_.
Referenced by DaqData< Format >::DaqData().
{ return nobjects_; /* cout<<"Nobjects()"<<endl; int Nfields = Format::getNumberOfFields(); return size_/(Format::getFieldLastBit(Nfields-1)+1); */ }
int DaqData< Format >::Size | ( | ) | const [inline] |
Definition at line 226 of file DaqData.h.
References DaqData< Format >::size_.
Referenced by DaqData< Format >::DaqData().
{return size_;}
void DaqData< Format >::uncompressObject | ( | const unsigned char * | ptr, |
std::vector< unsigned int > & | objdata, | ||
int & | bitsalreadyfilled | ||
) | [inline, private] |
Definition at line 253 of file DaqData.h.
References relativeConstraints::value.
Referenced by DaqData< Format >::DaqData().
{ int Nfields = Format::getNumberOfFields(); int bitstoaccomodate=Format::getFieldLastBit(0)+1; // of current field int ifield = 0; unsigned int value = 0; while (ifield < Nfields) { if(bitstoaccomodate > 8 - bitsalreadyfilled ) { // cout<<"can't complete value from current byte"<<endl; // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; //1)The syntax below could be faster. // To be checked as soon as time available(check started with prog test4.C) . //2)check if all cast to unsigned int are really necessary(done, they are not). //3)Instead of using pow(2,1;2;3;4;5..), a faster enum could be used //Lower all bits but those not yet read //value += ( (*ptr & ((unsigned int)pow(2.,8-bitsalreadyfilled)-1)) << bitstoaccomodate + bitsalreadyfilled - 8 ) ; // if(bitstoaccomodate > 8) value += ( ((((unsigned int)(*ptr)) << bitsalreadyfilled) & 0xff) << (bitstoaccomodate - 8) ); // else value += ( ((((unsigned int)(*ptr)) << bitsalreadyfilled) & 0xff) >> (8 - bitstoaccomodate) ); if(bitstoaccomodate > 8) value += ( ( (*ptr << bitsalreadyfilled) & 0xff ) << (bitstoaccomodate - 8) ); else value += ( ( (*ptr << bitsalreadyfilled) & 0xff) >> (8 - bitstoaccomodate) ); // cout<< "value: "<< hex << value << " - " << dec << value<< endl; // cout<< "byte: "<< hex << (unsigned int)(*ptr) << " - " << dec << (unsigned int)(*ptr) << endl; ptr++; bitstoaccomodate -= (8-bitsalreadyfilled); bitsalreadyfilled = 0; // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; } else if(bitstoaccomodate < (8 - bitsalreadyfilled) && bitstoaccomodate >0){ // cout<<"value can be completed from current byte, which still contain info"<<endl; // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; //1)The syntax below could be faster. // To be checked as soon as time available. //2)check if all cast to unsigned int are really necessary. //3)Instead of using pow(2,1;2;3;4;5..), a faster enum could be used //Lower all bits but those not yet read //value += (*ptr & ((unsigned int)pow(2.,8-bitsalreadyfilled)-1)) >> (8 - bitstoaccomodate - bitsalreadyfilled); value += ( ( (*ptr << bitsalreadyfilled) & 0xff ) >> (8 - bitstoaccomodate) ) ; // cout<< "value: "<< hex << value << " - " << dec << value<< endl; // cout<< "byte: "<< hex << (unsigned int)(*ptr) << " - " << dec << (unsigned int)(*ptr) << endl; objdata.push_back(value); value = 0; bitsalreadyfilled+=bitstoaccomodate; // cout<<"Field completed"<<endl; if(ifield==Nfields-1) return; // cout<<"Uncompressing new Field"<<endl; ifield++; bitstoaccomodate=Format::getFieldLastBit(ifield)-Format::getFieldLastBit(ifield-1); // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; } else if(bitstoaccomodate == (8 - bitsalreadyfilled) && bitstoaccomodate >0){ // cout<<"value can be completed from what left in current byte"<<endl; // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; //1)The syntax below could be faster. // To be checked as soon as time available. //2)check if all cast to unsigned int are really necessary. //3)Instead of using pow(2,1;2;3;4;5..), a faster enum could be used //Lower all bits but those not yet read // value += *ptr & ((unsigned int)pow(2.,8-bitsalreadyfilled)-1); value += ( ( (*ptr << bitsalreadyfilled) & 0xff ) >> (8 - bitstoaccomodate) ) ; // cout<< "value: "<< hex << value << " - " << dec << value<< endl; // cout<< "byte: "<< hex << (unsigned int)(*ptr) << " - " << dec << (unsigned int)(*ptr) << endl; objdata.push_back(value); value = 0; bitsalreadyfilled=0; // cout<<"Field completed"<<endl; if(ifield==Nfields-1) return; // cout<<"Uncompressing new Field"<<endl; ptr++; ifield++; bitstoaccomodate=Format::getFieldLastBit(ifield)-Format::getFieldLastBit(ifield-1); // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; } else throw std::string(" unexpected situation during uncompression"); } //end of cycle over fields }
Definition at line 480 of file DaqData.h.
Referenced by DaqData< Format >::Buffer(), DaqData< Format >::DaqData(), and DaqData< Format >::~DaqData().
std::map< int, std::vector<unsigned int> > DaqData< Format >::data_ [private] |
Definition at line 477 of file DaqData.h.
Referenced by DaqData< Format >::DaqData(), and DaqData< Format >::getValue().
Definition at line 481 of file DaqData.h.
Referenced by DaqData< Format >::DaqData(), DaqData< Format >::getValue(), and DaqData< Format >::Nobjects().
Definition at line 479 of file DaqData.h.
Referenced by DaqData< Format >::DaqData(), and DaqData< Format >::Size().