CMS 3D CMS Logo

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