#include <DataFormats/FEDRawData/interface/DaqData.h>
Public Member Functions | |
char * | Buffer () const |
DaqData (const DaqData &a) | |
DaqData (const unsigned char *ptr, int sizeinbytes) | |
DaqData (std::vector< unsigned int > &v) | |
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_ |
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 56 of file DaqData.h.
Definition at line 60 of file DaqData.h.
References DaqData< Format >::buffer_, DaqData< Format >::compressObject(), GenMuonPlsPt100GeV_cfg::cout, DaqData< Format >::data_, lat::endl(), i, int, name, DaqData< Format >::nobjects_, p, s, and DaqData< Format >::size_.
00060 : size_(0), buffer_(0), nobjects_(0) { 00061 00062 try { 00063 00064 if (v.size() == 0) throw string("DaqData: empty input data vector provided: "); 00065 00066 int Nfields = Format::getNumberOfFields(); 00067 if (v.size()%Nfields != 0) throw string("DaqData: ERROR. You must provide a number of input values compatibles with the requested format: "); 00068 00069 00070 int ObjSize = Format::getFieldLastBit(Nfields-1)+1; 00071 nobjects_ = v.size()/Nfields; 00072 // cout<<"Going to create "<<nobjects_<< " objects of type "<<typeid(Format).name()<<endl; 00073 00074 00075 size_ = (int) ceil(((double)(ObjSize*nobjects_))/8); 00076 buffer_= new char[size_]; 00077 // cout<<"The buffer will be "<<size_ <<" bytes long"<<endl; 00078 00079 std::vector<unsigned int>::iterator vit = v.begin(); 00080 char * p = buffer_; 00081 int bitsalreadyfilled = 0; 00082 00083 int Totbytes=1; 00084 00085 for(int i=0; i<nobjects_; i++) { 00086 00087 //additional bytes necessary to accomodate the current object 00088 int Nbytes = (int) ceil((double)(Format::getFieldLastBit(Nfields-1)+1-8+bitsalreadyfilled)/8); 00089 00090 if ((Totbytes+=Nbytes) > size_) throw string("Exceeded allocated buffer size"); 00091 00092 compressObject(p, vit, bitsalreadyfilled); 00093 00094 // cout<<"Successfully compressed object "<< i <<endl; 00095 00096 data_.insert(std::pair< int, std::vector<unsigned int> >(i,std::vector<unsigned int>(vit-Nfields,vit) )); 00097 00098 //the second term is necessary in the case the last byte has been fully used 00099 p+=(Nbytes+(8-bitsalreadyfilled)/8) ; 00100 Totbytes+=(8-bitsalreadyfilled)/8 ; 00101 } 00102 if(bitsalreadyfilled==0) Totbytes--; 00103 00104 /* 00105 cout << "Compression successful. "<< Totbytes<<" bytes compressed in total"<< endl; 00106 cout<< "Buffer pointer: "<<hex<< buffer_<< dec << "Size of buffer= "<< size_<<endl; 00107 for(int i=0; i<nobjects_; i++) { 00108 cout << "Object # "<< i << " fields: " <<endl; 00109 for(int j=0; j<Format::getNumberOfFields(); j++) cout << getValue(j,i) <<endl; 00110 } 00111 */ 00112 00113 } 00114 00115 catch (std::string s){ 00116 00117 cout<<"DaqData - Exception caught: " << s <<endl; 00118 cout<<"Object compression failed! No data has been constructed for format: "<< string(typeid(Format).name())<<endl; 00119 00120 } 00121 00122 }
DaqData< Format >::DaqData | ( | const unsigned char * | ptr, | |
int | sizeinbytes | |||
) | [inline] |
Definition at line 125 of file DaqData.h.
References GenMuonPlsPt100GeV_cfg::cout, DaqData< Format >::data_, lat::endl(), i, int, name, DaqData< Format >::nobjects_, p, s, and DaqData< Format >::uncompressObject().
00126 : size_(0), buffer_(0), nobjects_(0) { 00127 00128 00129 try { 00130 00131 if (sizeinbytes==0) throw std::string("Buffer size is zero"); 00132 00133 int Nfields = Format::getNumberOfFields(); 00134 int ObjSize = Format::getFieldLastBit(Nfields-1)+1; 00135 nobjects_ = (sizeinbytes*8)/ObjSize; 00136 00137 // cout<<"Going to create "<<nobjects_<< " objects of type "<<typeid(Format).name()<<endl; 00138 // cout<<"The buffer will be "<<size_ <<" bytes long"<<endl; 00139 00140 if ((sizeinbytes*8)%ObjSize != 0) { 00141 cout<<"DaqData: there will be " << (sizeinbytes*8)%ObjSize <<" meaningless bits at the end of the buffer"<<endl; 00142 } 00143 00144 // buffer_ = new char[sizeinbytes]; 00145 // memmove(buffer_,ptr,sizeinbytes); 00146 00147 // char * p = buffer_; 00148 00149 const unsigned char * p = ptr; 00150 int bitsalreadyfilled = 0; 00151 00152 int Totbytes=1; 00153 00154 for(int i=0; i<nobjects_; i++) { 00155 00156 std::vector<unsigned int> objdata; 00157 objdata.reserve(Nfields); 00158 00159 //additional bytes necessary to accomodate the current object 00160 int Nbytes = (int) ceil((double)(Format::getFieldLastBit(Nfields-1)+1-8+bitsalreadyfilled)/8); 00161 00162 00163 if ((Totbytes+=Nbytes) > sizeinbytes) throw std::string("Exceeded allocated buffer size"); 00164 00165 00166 uncompressObject(p, objdata, bitsalreadyfilled); 00167 00168 // cout<<"Successfully uncompressed object "<< i <<endl; 00169 data_.insert(std::pair< int, std::vector<unsigned int> >(i,objdata) ); 00170 00171 //the second term is necessary in the case the last byte has been fully used 00172 p+= (Nbytes + (8-bitsalreadyfilled)/8); 00173 Totbytes+= (8-bitsalreadyfilled)/8; 00174 00175 } 00176 00177 if(bitsalreadyfilled==0) Totbytes--; 00178 00179 /* 00180 cout << "Uncompression succeeded. "<< Totbytes<<" bytes uncompressed in total"<< endl; 00181 cout<< "Buffer pointer: "<<hex<< buffer_<< dec<< "Size of buffer= "<< size_<<endl; 00182 00183 for(int i=0; i<nobjects_; i++) { 00184 cout << "Object # "<< i << " fields: " <<endl; 00185 for(int j=0; j<Format::getNumberOfFields(); j++) cout << getValue(j,i) <<endl; 00186 } 00187 */ 00188 00189 } 00190 catch (std::string s){ 00191 00192 std::cout<<"DaqData - Exception caught: " << s <<std::endl; 00193 std::cout<<"Object uncompression failed! No data has been constructed for format: "<<std::string(typeid(Format).name())<<endl; 00194 00195 } 00196 00197 }
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_.
00200 { 00201 00202 size_ = a.Size(); 00203 buffer_ = new char[size_]; 00204 memmove(buffer_,a.Buffer(),size_); 00205 nobjects_ = a.Nobjects(); 00206 00207 for(int i=0; i<nobjects_; i++) { 00208 std::vector<unsigned int> vec; 00209 for(int j=0; j<Format::getNumberOfFields(); j++) vec.push_back(a.getValue(j,i)); 00210 data_.insert(std::pair< int, std::vector<unsigned int> >(i, vec)); 00211 } 00212 00213 }
Definition at line 216 of file DaqData.h.
References DaqData< Format >::buffer_.
00216 { 00217 00218 // cout<<"Deleting DaqData of type "<<typeid(Format).name()<<endl; 00219 if (buffer_!=0) delete [] buffer_; 00220 00221 };
char* DaqData< Format >::Buffer | ( | ) | const [inline] |
Definition at line 224 of file DaqData.h.
References DaqData< Format >::buffer_.
Referenced by DaqData< Format >::DaqData().
00224 {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 int, and funct::pow().
Referenced by DaqData< Format >::DaqData().
00375 { 00376 00377 int Nfields = Format::getNumberOfFields(); 00378 00379 int bitstoaccomodate=Format::getFieldLastBit(0)+1; // of current field 00380 00381 if (*vit > pow(2.,bitstoaccomodate)-1) throw string("The value is too large to fit in the field "); 00382 00383 int ifield = 0; 00384 00385 //Lower all bits but those already filled 00386 *ptr &= 0xff + 1 - (unsigned int)pow(2.,8-bitsalreadyfilled); 00387 00388 while (ifield < Nfields) { 00389 00390 00391 if(bitstoaccomodate > 8 - bitsalreadyfilled ) { 00392 00393 // cout<<"Field cannot be compressed from what left in current byte"<<endl; 00394 // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; 00395 00396 *ptr += (((*vit) >> (bitstoaccomodate - (8 - bitsalreadyfilled))) & 0xff); 00397 // cout<< "value: "<< hex << *vit <<" - " << dec << *vit<< endl; 00398 // cout<< "byte: "<< hex << (unsigned int)(*ptr) <<" - "<< dec << (unsigned int)(*ptr) << endl; 00399 00400 00401 bitstoaccomodate -= (8-bitsalreadyfilled); 00402 bitsalreadyfilled = 0; 00403 ptr++; 00404 *ptr &= 0xff + 1 - (unsigned int)pow(2.,8-bitsalreadyfilled); 00405 00406 // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; 00407 00408 } 00409 00410 else if(bitstoaccomodate < (8 - bitsalreadyfilled) && bitstoaccomodate >0){ 00411 00412 // cout<<"Field can be compressed in the current byte, which will not be completely filled"<<endl; 00413 00414 *ptr += ( (((*vit) << 8-bitstoaccomodate) & 0xff) >> (bitsalreadyfilled) ); 00415 00416 // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; 00417 // cout<< "value: "<< hex << *vit <<" - " << dec << *vit<< endl; 00418 // cout<< "byte: "<< hex << (unsigned int)(*ptr) <<" - "<< dec << (unsigned int)(*ptr) << endl; 00419 00420 vit++; 00421 bitsalreadyfilled+=bitstoaccomodate; 00422 00423 // cout<<"Field completed"<<endl; 00424 00425 if(ifield==Nfields-1) return; 00426 00427 // cout<<"Compressing new Field"<<endl; 00428 00429 ifield++; 00430 bitstoaccomodate=Format::getFieldLastBit(ifield)-Format::getFieldLastBit(ifield-1); 00431 if (*vit > pow(2.,bitstoaccomodate)-1) throw string("The value is too large to fit in the field "); 00432 00433 // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; 00434 00435 } 00436 00437 else if(bitstoaccomodate == (8 - bitsalreadyfilled) && bitstoaccomodate >0){ 00438 00439 // cout<<"Field can be compressed in the current byte, which will be completely filled"<<endl; 00440 00441 00442 *ptr += ( (((*vit) << 8-bitstoaccomodate) & 0xff) >> (bitsalreadyfilled) ); 00443 00444 // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; 00445 // cout<< "value: "<< hex << *vit <<" - " << dec << *vit<< endl; 00446 // cout<< "byte: "<< hex << (unsigned int)(*ptr) <<" - "<< dec << (unsigned int)(*ptr) << endl; 00447 00448 vit++; 00449 bitsalreadyfilled=0; 00450 00451 // cout<<"Field completed"<<endl; 00452 00453 if(ifield==Nfields-1) return; 00454 00455 // cout<<"Compressing new Field"<<endl; 00456 00457 ptr++; 00458 *ptr &= 0xff + 1 - (unsigned int)pow(2.,8-bitsalreadyfilled); 00459 00460 ifield++; 00461 bitstoaccomodate=Format::getFieldLastBit(ifield)-Format::getFieldLastBit(ifield-1); 00462 00463 if (*vit > pow(2.,bitstoaccomodate)-1) throw string("The value is too large to fit in the field "); 00464 00465 // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; 00466 00467 } 00468 else throw string(" unexpected situation during compression"); 00469 00470 } //end of cycle over fields 00471 00472 }
unsigned int DaqData< Format >::getValue | ( | int | indfield, | |
int | indobj = 0 | |||
) | const [inline] |
Definition at line 236 of file DaqData.h.
References GenMuonPlsPt100GeV_cfg::cout, DaqData< Format >::data_, lat::endl(), it, and DaqData< Format >::nobjects_.
Referenced by DaqData< Format >::DaqData().
00236 { 00237 00238 if (indobj<nobjects_ && indfield < Format::getNumberOfFields()) { 00239 std::map < int, std::vector<unsigned int> >::const_iterator it = data_.find(indobj); 00240 if (it != data_.end()) return ((*it).second)[indfield]; 00241 else { 00242 cout<<"DaqData - Strange: object should exist but was not found "<<endl; 00243 return 0; 00244 } 00245 } 00246 else cout<<"DaqData - Non existent field or object"<<endl; 00247 return 0; 00248 00249 }
Definition at line 228 of file DaqData.h.
References DaqData< Format >::nobjects_.
Referenced by DaqData< Format >::DaqData().
00228 { 00229 return nobjects_; 00230 /* cout<<"Nobjects()"<<endl; 00231 int Nfields = Format::getNumberOfFields(); 00232 return size_/(Format::getFieldLastBit(Nfields-1)+1); 00233 */ 00234 }
Definition at line 226 of file DaqData.h.
References DaqData< Format >::size_.
Referenced by DaqData< Format >::DaqData().
00226 {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 value.
Referenced by DaqData< Format >::DaqData().
00255 { 00256 00257 int Nfields = Format::getNumberOfFields(); 00258 00259 int bitstoaccomodate=Format::getFieldLastBit(0)+1; // of current field 00260 00261 int ifield = 0; 00262 unsigned int value = 0; 00263 00264 while (ifield < Nfields) { 00265 00266 if(bitstoaccomodate > 8 - bitsalreadyfilled ) { 00267 00268 // cout<<"can't complete value from current byte"<<endl; 00269 // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; 00270 00271 //1)The syntax below could be faster. 00272 // To be checked as soon as time available(check started with prog test4.C) . 00273 //2)check if all cast to unsigned int are really necessary(done, they are not). 00274 //3)Instead of using pow(2,1;2;3;4;5..), a faster enum could be used 00275 //Lower all bits but those not yet read 00276 //value += ( (*ptr & ((unsigned int)pow(2.,8-bitsalreadyfilled)-1)) << bitstoaccomodate + bitsalreadyfilled - 8 ) ; 00277 // if(bitstoaccomodate > 8) value += ( ((((unsigned int)(*ptr)) << bitsalreadyfilled) & 0xff) << (bitstoaccomodate - 8) ); 00278 // else value += ( ((((unsigned int)(*ptr)) << bitsalreadyfilled) & 0xff) >> (8 - bitstoaccomodate) ); 00279 00280 00281 if(bitstoaccomodate > 8) value += ( ( (*ptr << bitsalreadyfilled) & 0xff ) << (bitstoaccomodate - 8) ); 00282 else value += ( ( (*ptr << bitsalreadyfilled) & 0xff) >> (8 - bitstoaccomodate) ); 00283 00284 00285 // cout<< "value: "<< hex << value << " - " << dec << value<< endl; 00286 // cout<< "byte: "<< hex << (unsigned int)(*ptr) << " - " << dec << (unsigned int)(*ptr) << endl; 00287 00288 00289 ptr++; 00290 bitstoaccomodate -= (8-bitsalreadyfilled); 00291 bitsalreadyfilled = 0; 00292 00293 // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; 00294 00295 } 00296 00297 else if(bitstoaccomodate < (8 - bitsalreadyfilled) && bitstoaccomodate >0){ 00298 // cout<<"value can be completed from current byte, which still contain info"<<endl; 00299 00300 // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; 00301 00302 //1)The syntax below could be faster. 00303 // To be checked as soon as time available. 00304 //2)check if all cast to unsigned int are really necessary. 00305 //3)Instead of using pow(2,1;2;3;4;5..), a faster enum could be used 00306 //Lower all bits but those not yet read 00307 //value += (*ptr & ((unsigned int)pow(2.,8-bitsalreadyfilled)-1)) >> (8 - bitstoaccomodate - bitsalreadyfilled); 00308 00309 value += ( ( (*ptr << bitsalreadyfilled) & 0xff ) >> (8 - bitstoaccomodate) ) ; 00310 00311 // cout<< "value: "<< hex << value << " - " << dec << value<< endl; 00312 // cout<< "byte: "<< hex << (unsigned int)(*ptr) << " - " << dec << (unsigned int)(*ptr) << endl; 00313 00314 00315 objdata.push_back(value); 00316 value = 0; 00317 bitsalreadyfilled+=bitstoaccomodate; 00318 00319 // cout<<"Field completed"<<endl; 00320 00321 if(ifield==Nfields-1) return; 00322 00323 // cout<<"Uncompressing new Field"<<endl; 00324 00325 ifield++; 00326 bitstoaccomodate=Format::getFieldLastBit(ifield)-Format::getFieldLastBit(ifield-1); 00327 00328 // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; 00329 00330 } 00331 00332 else if(bitstoaccomodate == (8 - bitsalreadyfilled) && bitstoaccomodate >0){ 00333 // cout<<"value can be completed from what left in current byte"<<endl; 00334 // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; 00335 00336 //1)The syntax below could be faster. 00337 // To be checked as soon as time available. 00338 //2)check if all cast to unsigned int are really necessary. 00339 //3)Instead of using pow(2,1;2;3;4;5..), a faster enum could be used 00340 //Lower all bits but those not yet read 00341 // value += *ptr & ((unsigned int)pow(2.,8-bitsalreadyfilled)-1); 00342 00343 value += ( ( (*ptr << bitsalreadyfilled) & 0xff ) >> (8 - bitstoaccomodate) ) ; 00344 00345 // cout<< "value: "<< hex << value << " - " << dec << value<< endl; 00346 // cout<< "byte: "<< hex << (unsigned int)(*ptr) << " - " << dec << (unsigned int)(*ptr) << endl; 00347 00348 00349 objdata.push_back(value); 00350 value = 0; 00351 bitsalreadyfilled=0; 00352 00353 // cout<<"Field completed"<<endl; 00354 00355 if(ifield==Nfields-1) return; 00356 00357 // cout<<"Uncompressing new Field"<<endl; 00358 00359 ptr++; 00360 ifield++; 00361 bitstoaccomodate=Format::getFieldLastBit(ifield)-Format::getFieldLastBit(ifield-1); 00362 00363 // cout <<"bitstoaccomodate= "<<bitstoaccomodate<<" bitsalreadyfilled= "<<bitsalreadyfilled<<" ifield="<< ifield<<" Nfields="<<Nfields<<endl; 00364 00365 } 00366 else throw std::string(" unexpected situation during uncompression"); 00367 00368 } //end of cycle over fields 00369 00370 }
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().