CMS 3D CMS Logo

DCCDataParser.cc
Go to the documentation of this file.
1 #include "DCCDataParser.h"
2 
3 
4 
5 /*----------------------------------------------*/
6 /* DCCTBDataParser::DCCTBDataParser */
7 /* class constructor */
8 /*----------------------------------------------*/
9 DCCTBDataParser::DCCTBDataParser(const std::vector<uint32_t>& parserParameters, bool parseInternalData,bool debug):
10  buffer_(nullptr),parseInternalData_(parseInternalData),debug_(debug), parameters(parserParameters){
11 
12  mapper_ = new DCCTBDataMapper(this); //build a new data mapper
13  resetErrorCounters(); //restart error counters
14  computeBlockSizes(); //calculate block sizes
15 
16 }
17 
18 
19 /*----------------------------------------------*/
20 /* DCCTBDataParser::resetErrorCounters */
21 /* resets error counters */
22 /*----------------------------------------------*/
24  //set error counters to 0
25  errors_["DCC::BOE"] = 0; //begin of event (header B[60-63])
26  errors_["DCC::EOE"] = 0; //end of event (trailer B[60-63])
27  errors_["DCC::EVENT LENGTH"] = 0; //event length (trailer B[32-55])
28 }
29 
30 
31 /*----------------------------------------------*/
32 /* DCCTBDataParser::computeBlockSizes */
33 /* calculate the size of TCC and SR blocks */
34 /*----------------------------------------------*/
36  uint32_t nTT = numbTTs(); //gets the number of the trigger towers (default:68)
37  uint32_t tSamples = numbTriggerSamples(); //gets the number of trigger time samples (default: 1)
38  uint32_t nSr = numbSRF(); //gests the number of SR flags (default:68)
39 
40  uint32_t tf(0), srf(0);
41 
42  if( (nTT*tSamples)<4 || (nTT*tSamples)%4 ) tf=1; //test is there is no TTC primitives or if it's a multiple of 4?
43  else tf=0;
44 
45 
46  if( srf<16 || srf%16 ) srf=1; //??? by default srf=0 why do we make this test ?????
47  else srf=0;
48 
49  //TTC block size: header (8 bytes) + 17 words with 4 trigger primitives (17*8bytes)
50  tccBlockSize_ = 8 + ((nTT*tSamples)/4)*8 + tf*8 ;
51 
52  //SR block size: header (8 bytes) + 4 words with 16 SR flags + 1 word with 4 SR flags (5*8bytes)
53  srpBlockSize_ = 8 + (nSr/16)*8 + srf*8;
54 }
55 
56 
57 /*------------------------------------------------*/
58 /* DCCTBDataParser::parseFile */
59 /* reada data from file and parse it */
60 /*------------------------------------------------*/
62 
63  std::ifstream inputFile; //open file as input
64  inputFile.open(fileName.c_str());
65 
66  resetErrorCounters(); //reset error counters
67 
68  //for debug purposes
69  //std::cout << "Now in DCCTBDataParser::parseFile " << std::endl;
70 
71 
72  //if file opened correctly read data to a buffer and parse it
73  //else throw an exception
74  if( !inputFile.fail() ){
75 
76  std::string myWord; //word read from line
77  std::vector<std::string> dataVector; //data vector
78 
79  //until the end of file read each line as a string and add it to the data vector
80  while( inputFile >> myWord ){
81  dataVector.push_back( myWord );
82  }
83 
84  bufferSize_ = (dataVector.size() ) * 4 ; //buffer size in bytes (note:each char is an hex number)
85 
86  uint32_t *myData = new uint32_t[dataVector.size()]; //allocate memory for a new data buffer
87  uint32_t * const myDataBeginning = myData; //pointer that stays at the beginning of the allocated memory
88 
89  //fill buffer data with data from file lines
90  for(uint32_t i = 1; i <= dataVector.size() ; i++, myData++ ){
91  sscanf((dataVector[i-1]).c_str(),"%x",myData);
92 
93  //for debug purposes
94  //std::cout << std::endl << "Data position: " << dec << i << " val = " << getHexString(*myData);
95  }
96 
97  inputFile.close(); //close file
98 
99  parseBuffer( myData,bufferSize_,singleEvent); //parse data from the newly filled myData
100  delete [] myDataBeginning;
101  }
102  else{
103  std::string errorMessage = std::string(" Error::Unable to open file :") + fileName;
104  throw ECALTBParserException(errorMessage);
105  }
106 }
107 
108 
109 /*----------------------------------------------------------*/
110 /* DCCTBDataParser::parseBuffer */
111 /* parse data from a buffer */
112 /*----------------------------------------------------------*/
113 void DCCTBDataParser::parseBuffer(const uint32_t * buffer, uint32_t bufferSize, bool singleEvent){
114 
115  resetErrorCounters(); //reset error counters
116 
117  buffer_ = buffer; //set class buffer
118 
119  //clear stored data
120  processedEvent_ = 0;
121  events_.clear();
122  std::vector<DCCTBEventBlock *>::iterator it;
123  for( it = dccEvents_.begin(); it!=dccEvents_.end(); it++ ) { delete *it; }
124  dccEvents_.clear();
125  eventErrors_ = "";
126 
127  //for debug purposes
128  //std::cout << std::endl << "Now in DCCTBDataParser::parseBuffer" << std::endl;
129  //std::cout << std::endl << "Buffer Size:" << dec << bufferSize << std::endl;
130 
131  //check if we have a coherent buffer size
132  if( bufferSize%8 ){
133  std::string fatalError ;
134  fatalError += "\n ======================================================================";
135  fatalError += "\n Fatal error at event = " + getDecString(events_.size()+1);
136  fatalError += "\n Buffer Size of = "+ getDecString(bufferSize) + "[bytes] is not divisible by 8 ... ";
137  fatalError += "\n ======================================================================";
138  throw ECALTBParserException(fatalError);
139  }
140  if ( bufferSize < EMPTYEVENTSIZE ){
141  std::string fatalError ;
142  fatalError += "\n ======================================================================";
143  fatalError += "\n Fatal error at event = " + getDecString(events_.size()+1);
144  fatalError += "\n Buffer Size of = "+ getDecString(bufferSize) + "[bytes] is less than an empty event ... ";
145  fatalError += "\n ======================================================================";
146  throw ECALTBParserException(fatalError);
147  }
148 
149  const uint32_t *myPointer = buffer_;
150 
151  // uint32_t processedBytes(0), wordIndex(0), lastEvIndex(0),eventSize(0), eventLength(0), errorMask(0);
152  uint32_t processedBytes(0), wordIndex(0), eventLength(0), errorMask(0);
153 
154  //parse until there are no more events
155  while( processedBytes + EMPTYEVENTSIZE <= bufferSize ){
156 
157  //for debug purposes
158  //std::cout << "-> processedBytes. = " << dec << processedBytes << std::endl;
159  //std::cout << " -> Processed Event index = " << dec << processedEvent_ << std::endl;
160  //std::cout << "-> First ev.word = 0x" << hex << (*myPointer) << std::endl;
161  //std::cout << "-> word index = " << dec << wordIndex << std::endl;
162 
163  //check if Event Length is coherent /////////////////////////////////////////
164  uint32_t bytesToEnd = bufferSize - processedBytes;
165  std::pair<uint32_t,uint32_t> eventD = checkEventLength(myPointer,bytesToEnd,singleEvent);
166  eventLength = eventD.second;
167  errorMask = eventD.first;
169 
170  //for debug purposes
171  //std::cout <<" -> EventSizeBytes = " << dec << eventLength*8 << std::endl;
172 
173 
174 
175  //for debug purposes debug
176  //std::cout<<std::endl;
177  //std::cout<<" out... Bytes To End.... = "<<dec<<bytesToEnd<<std::endl;
178  //std::cout<<" out... Processed Event = "<<dec<<processedEvent_<<std::endl;
179  //std::cout<<" out... Event Length = "<<dec<<eventLength<<std::endl;
180  //std::cout<<" out... LastWord = 0x"<<hex<<*(myPointer+eventLength*2-1)<<std::endl;
181 
182  if (parseInternalData_){
183  //build a new event block from buffer
184  DCCTBEventBlock *myBlock = new DCCTBEventBlock(this,myPointer,eventLength*8, eventLength*2 -1 ,wordIndex,0);
185 
186  //add event to dccEvents vector
187  dccEvents_.push_back(myBlock);
188  }
189 
190  //build the event pointer with error mask and add it to the events vector
191  std::pair<const uint32_t *, uint32_t> eventPointer(myPointer,eventLength);
192  std::pair<uint32_t, std::pair<const uint32_t*, uint32_t> > eventPointerWithErrorMask(errorMask,eventPointer);
193  events_.push_back(eventPointerWithErrorMask);
194 
195  //update processed buffer size
196  processedEvent_++;
197  processedBytes += eventLength*8;
198  //std::cout << std::endl << "Processed Bytes = " << dec << processedBytes << std::endl;
199 
200  //go to next event
201  myPointer += eventLength*2;
202  wordIndex += eventLength*2;
203  }
204 }
205 
206 
207 /*---------------------------------------------*/
208 /* DCCTBDataParser::checkEventLength */
209 /* check if event length is consistent with */
210 /* the words written in buffer */
211 /* returns a 3 bit error mask codified as: */
212 /* bit 1 - BOE error */
213 /* bit 2 - EVENT LENGTH error */
214 /* bit 3 - EOE Error */
215 /* and the event length */
216 /*---------------------------------------------*/
217 std::pair<uint32_t,uint32_t> DCCTBDataParser::checkEventLength(const uint32_t *pointerToEvent, uint32_t bytesToEnd, bool singleEvent){
218 
219  std::pair<uint32_t,uint32_t> result; //returns error mask and event length
220  uint32_t errorMask(0); //error mask to return
221 
222  //check begin of event (BOE bits field)
223  //(Note: we have to add one to read the 2nd 32 bit word where BOE is written)
224  const uint32_t *boePointer = pointerToEvent + 1;
225  if( ( ((*boePointer)>>BOEBEGIN)& BOEMASK ) != BOE ) {
226  (errors_["DCC::BOE"])++; errorMask = 1;
227  }
228 
229 
230  //get Event Length from buffer (Note: we have to add two to read the 3rd 32 bit word where EVENT LENGTH is written)
231  const uint32_t * myPointer = pointerToEvent + 2;
232  uint32_t eventLength = (*myPointer)&EVENTLENGTHMASK;
233 
234  // std::cout << " Event Length(from decoding) = " << dec << eventLength << "... bytes to end... " << bytesToEnd << ", event numb : " << processedEvent_ << std::endl;
235 
236  bool eoeError = false;
237 
238  //check if event is empty but but EVENT LENGTH is not corresponding to it
239  if( singleEvent && eventLength != bytesToEnd/8 ){
240  eventLength = bytesToEnd/8;
241  (errors_["DCC::EVENT LENGTH"])++;
242  errorMask = errorMask | (1<<1);
243  }
244  //check if event length mismatches the number of words written as data
245  else if( eventLength == 0 || eventLength > (bytesToEnd / 8) || eventLength < (EMPTYEVENTSIZE/8) ){
246  // How to handle bad event length in multiple event buffers
247  // First approach : Send an exception
248  // Second aproach : Try to find the EOE (To be done? If yes check dataDecoder tBeam implementation)
249  std::string fatalError;
250 
251  fatalError +="\n ======================================================================";
252  fatalError +="\n Fatal error at event = " + getDecString(events_.size()+1);
253  fatalError +="\n Decoded event length = " + getDecString(eventLength);
254  fatalError +="\n bytes to buffer end = " + getDecString(bytesToEnd);
255  fatalError +="\n Unable to procead the data decoding ...";
256 
257  if(eventLength > (bytesToEnd / 8)){ fatalError +=" (eventLength > (bytesToEnd / 8)";}
258  else{ fatalError += "\n event length not big enough heaven to build an empty event ( 4x8 bytes)";}
259 
260  fatalError +="\n ======================================================================";
261 
262  throw ECALTBParserException(fatalError);
263  }
264 
265  //check end of event (EOE bits field)
266  //(Note: event length is multiplied by 2 because its written as 32 bit words and not 64 bit words)
267  const uint32_t *endOfEventPointer = pointerToEvent + eventLength*2 -1;
268  if ( ( ((*endOfEventPointer) >> EOEBEGIN & EOEMASK ) != EOEMASK) && !eoeError ){
269  (errors_["DCC::EOE"])++;
270  errorMask = errorMask | (1<<2);
271  }
272 
273  //build result to return
274  result.first = errorMask;
275  result.second = eventLength;
276 
277  return result;
278 }
279 
280 
281 
282 /*----------------------------------------------*/
283 /* DCCTBDataParser::index */
284 /* build an index string */
285 /*----------------------------------------------*/
287 
288  char indexBuffer[20];
289  long unsigned int pos = position;
290  snprintf(indexBuffer, sizeof(indexBuffer), "W[%08lu]",pos); //build an index string for display purposes, p.e. W[15]
291 
292  return std::string(indexBuffer);
293 }
294 
295 
296 /*-----------------------------------------------*/
297 /* DCCTBDataParser::getDecString */
298 /* print decimal data to a string */
299 /*-----------------------------------------------*/
301 
302  char buffer[15];
303  long unsigned int data = dat;
304  snprintf(buffer, sizeof(buffer), "%lu",data);
305 
306  return std::string(buffer);
307 }
308 
309 
310 /*-------------------------------------------------*/
311 /* DCCTBDataParser::getHexString */
312 /* print data in hexadecimal base to a string */
313 /*-------------------------------------------------*/
315 
316  char buffer[15];
317  snprintf(buffer, sizeof(buffer), "0x%08x",(uint16_t)(data));
318 
319  return std::string(buffer);
320 }
321 
322 
323 /*------------------------------------------------*/
324 /* DCCTBDataParser::getIndexedData */
325 /* build a string with index and data */
326 /*------------------------------------------------*/
328  std::string ret;
329 
330  //char indexBuffer[20];
331  //char dataBuffer[20];
332  //sprintf(indexBuffer,"W[%08u] = ",position);
333  //sprintf(dataBuffer,"0x%08x",*pointer);
334  //ret = std::string(indexBuffer)+std::string(dataBuffer);
335 
336  ret = index(position) + getHexString(*pointer);
337 
338  return ret;
339 }
340 
341 
342 /*-------------------------------------------------*/
343 /* DCCTBDataParser::~DCCTBDataParser */
344 /* destructor */
345 /*-------------------------------------------------*/
347 
348  // delete DCCTBEvents if any...
349  std::vector<DCCTBEventBlock *>::iterator it;
350  for(it=dccEvents_.begin();it!=dccEvents_.end();it++){delete *it;}
351  dccEvents_.clear();
352 
353  delete mapper_;
354 }
std::vector< DCCTBEventBlock * > dccEvents_
void resetErrorCounters()
std::map< std::string, uint32_t > errors_
#define nullptr
void computeBlockSizes()
std::string getDecString(uint32_t data)
std::string getIndexedData(uint32_t indexed, uint32_t *pointer)
uint32_t tccBlockSize_
uint32_t numbTriggerSamples()
#define nTT
Definition: TMEGeom.h:6
uint32_t srpBlockSize_
void parseFile(std::string fileName, bool singleEvent=false)
const uint32_t * buffer_
uint32_t processedEvent_
uint32_t numbTTs()
std::pair< uint32_t, uint32_t > checkEventLength(const uint32_t *pointerToEvent, uint32_t bytesToEnd, bool singleEvent=false)
#define debug
Definition: HDRShower.cc:19
uint32_t numbSRF()
std::string getHexString(uint32_t data)
std::vector< std::pair< uint32_t, std::pair< const uint32_t *, uint32_t > > > events_
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
static int position[264][3]
Definition: ReadPGInfo.cc:509
std::string eventErrors_
DCCTBDataMapper * mapper_
DCCTBDataParser(const std::vector< uint32_t > &parserParameters, bool parseInternalData=true, bool debug=true)
Definition: DCCDataParser.cc:9
uint32_t bufferSize_
void parseBuffer(const uint32_t *buffer, uint32_t bufferSize, bool singleEvent=false)
std::string index(uint32_t position)