CMS 3D CMS Logo

DTROS25Unpacker.cc
Go to the documentation of this file.
1 
8 
12 
15 
17 
18 // Mapping
20 
21 #include <iostream>
22 #include <cmath>
23 
24 using namespace std;
25 using namespace edm;
26 
28  localDAQ = ps.getUntrackedParameter<bool>("localDAQ", false);
29  readingDDU = ps.getUntrackedParameter<bool>("readingDDU", true);
30 
31  readDDUIDfromDDU = ps.getUntrackedParameter<bool>("readDDUIDfromDDU", true);
32  hardcodedDDUID = ps.getUntrackedParameter<int>("dduID", 770);
33 
34  writeSC = ps.getUntrackedParameter<bool>("writeSC", false);
35  performDataIntegrityMonitor = ps.getUntrackedParameter<bool>("performDataIntegrityMonitor", false);
36  debug = ps.getUntrackedParameter<bool>("debug", false);
37 }
38 
40 
41 void DTROS25Unpacker::interpretRawData(const unsigned int* index,
42  int datasize,
43  int dduIDfromDDU,
45  std::unique_ptr<DTDigiCollection>& detectorProduct,
46  std::unique_ptr<DTLocalTriggerCollection>& triggerProduct,
47  uint16_t rosList) {
48  int dduID;
49  if (readDDUIDfromDDU)
50  dduID = dduIDfromDDU;
51  else
52  dduID = hardcodedDDUID;
53 
54  const int wordLength = 4;
55  int numberOfWords = datasize / wordLength;
56 
57  int rosID = 0;
58  DTROS25Data controlData(rosID);
59  controlDataFromAllROS.clear();
60 
61  int wordCounter = 0;
62  uint32_t word = index[swap(wordCounter)];
63 
64  map<uint32_t, int> hitOrder;
65 
66  /******************************************************
67  / The the loop is performed with "do-while" statements
68  / because the ORDER of the words in the event data
69  / is assumed to be fixed. Eventual changes into the
70  / structure should be considered as data corruption
71  *******************************************************/
72 
73  // Loop on ROSs
74  while (wordCounter < numberOfWords) {
75  controlData.clean();
76 
77  rosID++; // to be mapped;
78 
79  if (readingDDU) {
80  // matching the ROS number with the enabled DDU channel
81  if (rosID <= 12 && !((rosList & int(pow(2., (rosID - 1)))) >> (rosID - 1)))
82  continue;
83  if (debug)
84  cout << "[DTROS25Unpacker]: ros list: " << rosList << " ROS ID " << rosID << endl;
85  }
86 
87  // FRC prepare info for DTLocalTrigger: wheel and sector corresponding to this ROS
88 
89  int SCwheel = -3;
90  int SCsector = 0;
91  int dum1, dum2, dum3, dum4;
92 
93  if (writeSC && !mapping->readOutToGeometry(dduID, rosID, 1, 1, 1, SCwheel, dum1, SCsector, dum2, dum3, dum4)) {
94  if (debug)
95  cout << " found SCwheel: " << SCwheel << " and SCsector: " << SCsector << endl;
96  } else {
97  if (writeSC && debug)
98  cout << " WARNING failed to find WHEEL and SECTOR for ROS " << rosID << " !" << endl;
99  }
100 
101  // ROS Header;
103  DTROSHeaderWord rosHeaderWord(word);
104 
105  if (debug)
106  cout << "[DTROS25Unpacker]: ROSHeader " << rosHeaderWord.TTCEventCounter() << endl;
107 
108  // container for words to be sent to DQM
109  controlData.setROSId(rosID);
110  controlData.addROSHeader(rosHeaderWord);
111 
112  // Loop on ROBs
113  do {
114  wordCounter++;
115  word = index[swap(wordCounter)];
116 
117  // Eventual ROS Error: occurs when some errors are found in a ROB
119  DTROSErrorWord dtROSErrorWord(word);
120  controlData.addROSError(dtROSErrorWord);
121  if (debug)
122  cout << "[DTROS25Unpacker]: ROSError, Error type " << dtROSErrorWord.errorType() << " robID "
123  << dtROSErrorWord.robID() << endl;
124  }
125 
126  // Eventual ROS Debugging;
128  DTROSDebugWord rosDebugWord(word);
129  controlData.addROSDebug(rosDebugWord);
130  if (debug)
131  cout << "[DTROS25Unpacker]: ROSDebug, type " << rosDebugWord.debugType() << " message "
132  << rosDebugWord.debugMessage() << endl;
133  }
134 
135  // Check ROB header
137  DTROBHeaderWord robHeaderWord(word);
138  int eventID = robHeaderWord.eventID(); // from the TDCs
139  int bunchID = robHeaderWord.bunchID(); // from the TDCs
140  int robID = robHeaderWord.robID(); // to be mapped
141 
142  DTROBHeader robHeader(robID, robHeaderWord); // IJ
143  controlData.addROBHeader(robHeader); // IJ
144 
145  if (debug)
146  cout << "[DTROS25Unpacker] ROB: ID " << robID << " Event ID " << eventID << " BXID " << bunchID << endl;
147 
148  // Loop on TDCs data (headers and trailers are not there)
149  do {
150  wordCounter++;
151  word = index[swap(wordCounter)];
152 
153  // Eventual TDC Error
155  DTTDCErrorWord dtTDCErrorWord(word);
156  DTTDCError tdcError(robID, dtTDCErrorWord);
157  controlData.addTDCError(tdcError);
158 
159  DTTDCErrorNotifier dtTDCError(dtTDCErrorWord);
160  if (debug)
161  dtTDCError.print();
162  }
163 
164  // Eventual TDC Debug
166  if (debug)
167  cout << "TDC Debugging" << endl;
168  }
169 
170  // The TDC information
172  DTTDCMeasurementWord tdcMeasurementWord(word);
173  DTTDCData tdcData(robID, tdcMeasurementWord);
174  controlData.addTDCData(tdcData);
175 
176  int tdcID = tdcMeasurementWord.tdcID();
177  int tdcChannel = tdcMeasurementWord.tdcChannel();
178 
179  if (debug)
180  cout << "[DTROS25Unpacker] TDC: ID " << tdcID << " Channel " << tdcChannel << " Time "
181  << tdcMeasurementWord.tdcTime() << endl;
182 
183  DTROChainCoding channelIndex(dduID, rosID, robID, tdcID, tdcChannel);
184 
185  hitOrder[channelIndex.getCode()]++;
186 
187  if (debug) {
188  cout << "[DTROS25Unpacker] ROAddress: DDU " << dduID << ", ROS " << rosID << ", ROB " << robID
189  << ", TDC " << tdcID << ", Channel " << tdcChannel << endl;
190  }
191 
192  // FRC if not already done for this ROS, find wheel and sector for SC data
193  if (writeSC && (SCsector < 1 || SCwheel < -2)) {
194  if (debug)
195  cout << " second try to find SCwheel and SCsector " << endl;
196  if (!mapping->readOutToGeometry(
197  dduID, rosID, robID, tdcID, tdcChannel, SCwheel, dum1, SCsector, dum2, dum3, dum4)) {
198  if (debug)
199  cout << " ROS " << rosID << " SC wheel " << SCwheel << " SC sector " << SCsector << endl;
200  } else {
201  if (debug)
202  cout << " WARNING !! ROS " << rosID << " failed again to map for SC!! " << endl;
203  }
204  }
205 
206  // Map the RO channel to the DetId and wire
207  DTWireId detId;
208  // if ( ! mapping->readOutToGeometry(dduID, rosID, robID, tdcID, tdcChannel, detId)) {
209  int wheelId, stationId, sectorId, slId, layerId, cellId;
210  if (!mapping->readOutToGeometry(
211  dduID, rosID, robID, tdcID, tdcChannel, wheelId, stationId, sectorId, slId, layerId, cellId)) {
212  // skip the digi if the detId is invalid
213  if (sectorId == 0 || stationId == 0)
214  continue;
215  else
216  detId = DTWireId(wheelId, stationId, sectorId, slId, layerId, cellId);
217 
218  if (debug)
219  cout << "[DTROS25Unpacker] " << detId << endl;
220  int wire = detId.wire();
221 
222  // Produce the digi
223  DTDigi digi(wire, tdcMeasurementWord.tdcTime(), hitOrder[channelIndex.getCode()] - 1);
224 
225  // Commit to the event
226  detectorProduct->insertDigi(detId.layerId(), digi);
227  } else {
228  LogWarning("DTRawToDigi|DTROS25Unpacker")
229  << "Unable to map the RO channel: DDU " << dduID << " ROS " << rosID << " ROB " << robID << " TDC "
230  << tdcID << " TDC ch. " << tdcChannel;
231  if (debug)
232  cout << "[DTROS25Unpacker] ***ERROR*** Missing wire: DDU " << dduID << " ROS " << rosID << " ROB "
233  << robID << " TDC " << tdcID << " TDC ch. " << tdcChannel << endl;
234  }
235 
236  } // TDC information
237 
239  DTROSWordType(word).type() != DTROSWordType::ROSError); // loop on TDC's?
240 
241  // Check ROB Trailer (condition already verified)
243  DTROBTrailerWord robTrailerWord(word);
244  controlData.addROBTrailer(robTrailerWord);
245  if (debug)
246  cout << "[DTROS25Unpacker]: ROBTrailer, robID " << robTrailerWord.robID() << " eventID "
247  << robTrailerWord.eventID() << " wordCount " << robTrailerWord.wordCount() << endl;
248  }
249  } // ROB header
250 
251  // Check the eventual Sector Collector Header
253  DTLocalTriggerHeaderWord scHeaderWord(word);
254  if (debug)
255  cout << "[DTROS25Unpacker]: SC header eventID " << scHeaderWord.eventID() << endl;
256 
257  // RT added : first word following SCHeader is a SC private header
258  wordCounter++;
259  word = index[swap(wordCounter)];
260 
262  DTLocalTriggerSectorCollectorHeaderWord scPrivateHeaderWord(word);
263 
265  controlData.addSCPrivHeader(scPrivateHeaderWord);
266  }
267 
268  int numofscword = scPrivateHeaderWord.NumberOf16bitWords();
269  int leftword = numofscword;
270 
271  if (debug)
272  cout << " SC PrivateHeader (number of words + subheader = "
273  << scPrivateHeaderWord.NumberOf16bitWords() << ")" << endl;
274 
275  // if no SC data -> no loop ;
276  // otherwise subtract 1 word (subheader) and countdown for bx assignment
277  if (numofscword > 0) {
278  int bx_received = (numofscword - 1) / 2;
279  if (debug)
280  cout << " SC number of bx read-out: " << bx_received << endl;
281 
282  wordCounter++;
283  word = index[swap(wordCounter)];
285  //second word following SCHeader is a SC private SUB-header
286  leftword--;
287 
288  DTLocalTriggerSectorCollectorSubHeaderWord scPrivateSubHeaderWord(word);
289  // read the event BX in the SC header (will be stored in SC digis)
290  int scEventBX = scPrivateSubHeaderWord.LocalBunchCounter();
291  if (debug)
292  cout << " SC trigger delay = " << scPrivateSubHeaderWord.TriggerDelay() << endl
293  << " SC bunch counter = " << scEventBX << endl;
294 
295  controlData.addSCPrivSubHeader(scPrivateSubHeaderWord);
296 
297  // actual loop on SC time slots
298  int stationGroup = 0;
299  do {
300  wordCounter++;
301  word = index[swap(wordCounter)];
302  int SCstation = 0;
303 
305  leftword--;
306  //RT: bx are sent from SC in reverse order starting from the one
307  //which stopped the spy buffer
308  int bx_counter = int(round((leftword + 1) / 2.));
309 
310  if (debug) {
311  if (bx_counter < 0 || leftword < 0)
312  cout << "[DTROS25Unpacker]: SC data more than expected; negative bx counter reached! " << endl;
313  }
314 
315  DTLocalTriggerDataWord scDataWord(word);
316 
317  // DTSectorCollectorData scData(scDataWord, int(round(bx_counter/2.))); M.Z.
318  DTSectorCollectorData scData(scDataWord, bx_counter);
319  controlData.addSCData(scData);
320 
321  if (debug) {
322  //cout<<"[DTROS25Unpacker]: SCData bits "<<scDataWord.SCData()<<endl;
323  //cout << " word in esadecimale: " << hex << word << dec << endl;
324  if (scDataWord.hasTrigger(0))
325  cout << " at BX " << bx_counter //round(bx_counter/2.)
326  << " lower part has trigger! with track quality " << scDataWord.trackQuality(0) << endl;
327  if (scDataWord.hasTrigger(1))
328  cout << " at BX " << bx_counter //round(bx_counter/2.)
329  << " upper part has trigger! with track quality " << scDataWord.trackQuality(1) << endl;
330  }
331 
332  if (writeSC && SCwheel >= -2 && SCsector >= 1) {
333  // FRC: start constructing persistent SC objects:
334  // first identify the station (data come in 2 triggers per word: MB1+MB2, MB3+MB4)
335  if (scDataWord.hasTrigger(0) || (scDataWord.getBits(0) & 0x30)) {
336  if (stationGroup % 2 == 0)
337  SCstation = 1;
338  else
339  SCstation = 3;
340 
341  // construct localtrigger for first station of this "group" ...
342  DTLocalTrigger localtrigger(scEventBX, bx_counter, (scDataWord.SCData()) & 0xFF);
343  // ... and commit it to the event
344  DTChamberId chamberId(SCwheel, SCstation, SCsector);
345  triggerProduct->insertDigi(chamberId, localtrigger);
346  if (debug) {
347  cout << "Add SC digi to the collection, for chamber: " << chamberId << endl;
348  localtrigger.print();
349  }
350  }
351  if (scDataWord.hasTrigger(1) || (scDataWord.getBits(1) & 0x30)) {
352  if (stationGroup % 2 == 0)
353  SCstation = 2;
354  else
355  SCstation = 4;
356 
357  // construct localtrigger for second station of this "group" ...
358  DTLocalTrigger localtrigger(scEventBX, bx_counter, (scDataWord.SCData()) >> 8);
359  // ... and commit it to the event
360  DTChamberId chamberId(SCwheel, SCstation, SCsector);
361  triggerProduct->insertDigi(chamberId, localtrigger);
362  if (debug) {
363  cout << "Add SC digi to the collection, for chamber: " << chamberId << endl;
364  localtrigger.print();
365  }
366  }
367 
368  stationGroup++;
369  } // if writeSC
370  } // if SC data
372 
373  } // end SC subheader
374  } // end if SC send more than only its own header!
375  } // end if first data following SCheader is not SCData
376 
378  DTLocalTriggerTrailerWord scTrailerWord(word);
379  // add infos for data integrity monitoring
380  controlData.addSCHeader(scHeaderWord);
381  controlData.addSCTrailer(scTrailerWord);
382 
383  if (debug)
384  cout << " SC Trailer, # of words: " << scTrailerWord.wordCount() << endl;
385  }
386  }
387 
388  } while (DTROSWordType(word).type() != DTROSWordType::ROSTrailer); // loop on ROBS
389 
390  // check ROS Trailer (condition already verified)
392  DTROSTrailerWord rosTrailerWord(word);
393  controlData.addROSTrailer(rosTrailerWord);
394  if (debug)
395  cout << "[DTROS25Unpacker]: ROSTrailer " << rosTrailerWord.EventWordCount() << endl;
396  }
397 
398  // Perform dqm if requested:
399  // DQM IS PERFORMED FOR EACH ROS SEPARATELY
401  // dataMonitor->processROS25(controlData, dduID, rosID);
402  // fill the vector with ROS's control data
403  controlDataFromAllROS.push_back(controlData);
404  }
405 
406  }
407 
408  else if (index[swap(wordCounter)] == 0) {
409  // in the case of odd number of words of a given ROS the header of
410  // the next one is postponed by 4 bytes word set to 0.
411  // rosID needs to be step back by 1 unit
412  if (debug)
413  cout << "[DTROS25Unpacker]: odd number of ROS words" << endl;
414  rosID--;
415  } // if ROS header
416 
417  else {
418  cout << "[DTROS25Unpacker]: ERROR! First word is not a ROS Header" << endl;
419  }
420 
421  // (needed if there are more than 1 ROS)
422  wordCounter++;
423  word = index[swap(wordCounter)];
424 
425  } // loop on ROS!
426 }
427 
429  int result = n;
430 
431  if (!localDAQ) {
432  if (n % 2 == 0)
433  result = (n + 1);
434  if (n % 2 == 1)
435  result = (n - 1);
436  }
437 
438  return result;
439 }
int robID() const
Definition: DTDDUWords.h:279
void interpretRawData(const unsigned int *index, int datasize, int dduID, edm::ESHandle< DTReadOutMapping > &mapping, std::unique_ptr< DTDigiCollection > &product, std::unique_ptr< DTLocalTriggerCollection > &product2, uint16_t rosList=0) override
void addSCData(const DTSectorCollectorData &scData)
Definition: DTControlData.h:42
int trackQuality(int first) const
Definition: DTDDUWords.h:622
int tdcTime() const
Definition: DTDDUWords.h:492
int TTCEventCounter() const
Definition: DTDDUWords.h:213
void clean()
Definition: DTControlData.h:70
int wire() const
Return the wire number.
Definition: DTWireId.h:42
int errorType() const
Definition: DTDDUWords.h:278
int debugMessage() const
Definition: DTDDUWords.h:311
int tdcChannel() const
Definition: DTDDUWords.h:491
std::pair< int, DTROBHeaderWord > DTROBHeader
Definition: DTControlData.h:17
void addROBHeader(const DTROBHeader &robHeader)
Definition: DTControlData.h:37
__host__ __device__ std::uint32_t channelIndex(fedId_t fed, fedCh_t channel)
void addSCPrivHeader(const DTLocalTriggerSectorCollectorHeaderWord &scPrivHeader)
Definition: DTControlData.h:44
void addSCTrailer(const DTLocalTriggerTrailerWord &scTrailer)
Definition: DTControlData.h:50
~DTROS25Unpacker() override
Destructor.
int eventID() const
Definition: DTDDUWords.h:386
int tdcID() const
<== OBSOLETE!!
Definition: DTDDUWords.h:490
int wordCount() const
Definition: DTDDUWords.h:387
int eventID() const
Definition: DTDDUWords.h:354
T getUntrackedParameter(std::string const &, T const &) const
int getBits(int first) const
Definition: DTDDUWords.h:616
uint64_t word
int robID() const
Definition: DTDDUWords.h:353
DTROS25Unpacker(const edm::ParameterSet &ps)
Constructor.
int bunchID() const
Definition: DTDDUWords.h:355
std::pair< int, DTTDCErrorWord > DTTDCError
Definition: DTControlData.h:19
void print()
Print out the error information >>> FIXME: to be implemented.
void addTDCError(const DTTDCError &tdcError)
Definition: DTControlData.h:41
void addSCPrivSubHeader(const DTLocalTriggerSectorCollectorSubHeaderWord &scPrivSubHeader)
Definition: DTControlData.h:47
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
std::pair< DTLocalTriggerDataWord, int > DTSectorCollectorData
Definition: DTControlData.h:20
void setROSId(const int &ID)
Setters ///////////////////////.
Definition: DTControlData.h:31
void print() const
Print content of trigger.
Definition: DTDigi.h:17
enum wordTypes type()
DDU word type getter.
Definition: DTDDUWords.h:120
#define debug
Definition: HDRShower.cc:19
void addROBTrailer(const DTROBTrailerWord &word)
Definition: DTControlData.h:38
performDataIntegrityMonitor
Definition: DTskim_cfg.py:64
int hasTrigger(int first) const
Definition: DTDDUWords.h:621
int robID() const
Definition: DTDDUWords.h:385
void addROSHeader(const DTROSHeaderWord &word)
Definition: DTControlData.h:33
void addROSError(const DTROSErrorWord &word)
Definition: DTControlData.h:35
int EventWordCount() const
Definition: DTDDUWords.h:249
HLT enums.
int debugType() const
Definition: DTDDUWords.h:310
void addROSTrailer(const DTROSTrailerWord &word)
Definition: DTControlData.h:34
std::pair< int, DTTDCMeasurementWord > DTTDCData
Definition: DTControlData.h:18
void addSCHeader(const DTLocalTriggerHeaderWord &scHeader)
Definition: DTControlData.h:43
DTLayerId layerId() const
Return the corresponding LayerId.
Definition: DTWireId.h:45
Log< level::Warning, false > LogWarning
void addROSDebug(const DTROSDebugWord &word)
Definition: DTControlData.h:36
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
void addTDCData(const DTTDCData &tdcData)
Definition: DTControlData.h:40