Belle II Software  release-08-01-10
eclUnpackerModule.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 //This module
10 #include <ecl/modules/eclUnpacker/eclUnpackerModule.h>
11 
12 //STL
13 #include <iomanip>
14 
15 //Framework
16 #include <framework/dataobjects/EventMetaData.h>
17 
18 //Rawdata
19 #include <rawdata/dataobjects/RawECL.h>
20 
21 //ECL
22 #include <ecl/dataobjects/ECLDigit.h>
23 #include <ecl/dataobjects/ECLDsp.h>
24 #include <ecl/utility/ECLDspUtilities.h>
25 
26 using namespace std;
27 using namespace Belle2;
28 using namespace ECL;
29 
30 #define B2DEBUG_eclunpacker(level, msg) \
31  if (m_debugLevel >= level) {\
32  B2DEBUG(level, msg); \
33  }
34 
35 /*
36 
37 Data format of data packet from shaperDSP (32 bit words)
38 
39 ---------------------------------------------------------------------------------------
40 Offset | MSW(16 bits) | LSW(16 bits) |
41 --------------------------------------------------------------------------------------|
42  | | |
43 0 | 0x10 | 4+DSP_NUM+ADC_NUM*SAMPLES_NUM |
44  | | (Packet length) |
45 --------------------------------------------------------------------------------------|
46  | |
47 1 | b[28..24] – number of active ADC data channels (ADC_NUM) |
48  | b[22..16] – ADC samples per channel (SAMPLES_NUM) |
49  | b[12..8] – number of active DSP channels (DSP_NUM |
50  | b[7..0] – trigger phase |
51  | |
52 --------------------------------------------------------------------------------------|
53 2 | b[31…16] – dsp_mask | b[15…0] – trigger tag |
54  | | |
55 --------------------------------------------------------------------------------------|
56 3 | 0 | b[15…0] – adc_mask |
57  | | |
58 --------------------------------------------------------------------------------------|
59 4…3+DSP_NUM | b[31..30] – quality flag |
60  | quality = 0 : good fit |
61  | quality = 1 : internal error of approximation |
62  | quality = 2 : A < A_th, |
63  | time is replace with chi2 |
64  | quality = 3 : bad fit, A > A_thr |
65  | b[29..18] – reconstructed time (chi2 if qality = 2) |
66  | chi2 = m<<(p*2), m = b[29:27], p = b[26:18] |
67  | b[17..0] – reconstructed amplitude |
68  | |
69 --------------------------------------------------------------------------------------|
70 4+DSP_NUM… | |
71 3+DSP_NUM+ | ADC_NUM*SAMPLES_NUM -- ADC samples |
72 ADC_NUM*SAMPLES_NUM | |
73 --------------------------------------------------------------------------------------|
74 
75 */
76 
77 
78 REG_MODULE(ECLUnpacker);
79 
80 ECLUnpackerModule::ECLUnpackerModule() :
81  m_globalEvtNum(0),
82  m_localEvtNum(0),
83  m_bufPtr(0),
84  m_bufPos(0),
85  m_bufLength(0),
86  m_bitPos(0),
87  m_storeTrigTime(0),
88  m_storeUnmapped(0),
89  m_unpackingParams("ECLUnpackingParameters", false),
90  m_eclDigits("", DataStore::c_Event),
91  m_debugLevel(0)
92 {
93  setDescription("The module reads RawECL data from the DataStore and writes the ECLDigit data");
94 
96 
97  addParam("InitFileName", m_eclMapperInitFileName, "Initialization file", string("/ecl/data/ecl_channels_map.txt"));
98  addParam("ECLDigitsName", m_eclDigitsName, "Name of the ECLDigits container", string("ECLDigits"));
99  addParam("ECLDspsName", m_eclDspsName, "Name of the ECLDsp container", string("ECLDsps"));
100  addParam("ECLTrigsName", m_eclTrigsName, "Name of the ECLTrig container", string("ECLTrigs"));
101  // flag to store trigger times needed for calibration with pulse generator only, so false by default
102  addParam("storeTrigTime", m_storeTrigTime, "Store trigger time", false);
103  addParam("storeUnmapped", m_storeUnmapped, "Store ECLDsp for channels that don't "
104  "exist in ECL mapping", false);
105  addParam("useUnpackingParameters", m_useUnpackingParameters,
106  "Use ECLUnpackingParameters payload", true);
107 }
108 
110 {
111  // Get cached debug level to improve performance
112  auto& config = LogSystem::Instance().getCurrentLogConfig(PACKAGENAME());
113  m_debugLevel = config.getLogLevel() == LogConfig::c_Debug ? config.getDebugLevel() : 0;
114 
115  // require input data
116  m_rawEcl.isRequired();
117 
118  // register output containers in data store
119  m_eclDigits.registerInDataStore(m_eclDigitsName);
120  if (m_storeTrigTime) {
121  m_eclTrigs.registerInDataStore(m_eclTrigsName);
123  }
124  m_eclDsps.registerInDataStore(m_eclDspsName);
126  m_eclDsps.registerRelationTo(m_eclDigits);
127 
128 }
129 
131 {
133  m_tagsReportedMask = 0;
136  // Initialize channel mapper at run start to account for possible
137  // changes in ECL mapping between runs.
138  if (!m_eclMapper.initFromDB()) {
139  B2FATAL("ECL Unpacker: Can't initialize eclChannelMapper!");
140  }
141  if (!m_unpackingParams.isValid() && m_useUnpackingParameters) {
142  B2FATAL("ECL Unpacker: Can't access ECLUnpackingParameters payload");
143  }
144 }
145 
147 {
148  // output data
149  m_eclDigits.clear();
150  m_eclDsps.clear();
151  m_eclTrigs.clear();
152  // clear relations arrays
155 
156  if (m_eventMetaData.isValid()) {
157  m_globalEvtNum = m_eventMetaData->getEvent();
158  } else {
159  m_globalEvtNum = -1;
160  }
161 
162  for (int i = 0; i < ECL_CRATES; i++) {
164  }
165 
166  //=== Read raw event data
167 
168  int nRawEclEntries = m_rawEcl.getEntries();
169 
170  B2DEBUG_eclunpacker(22, "Ecl unpacker event called N_RAW = " << nRawEclEntries);
171 
172  for (int i = 0; i < nRawEclEntries; i++) {
173  for (int n = 0; n < m_rawEcl[i]->GetNumEntries(); n++) {
174  readRawECLData(m_rawEcl[ i ], n); // read data from RawECL and put into the m_eclDigits container
175  }
176  }
177 
178  //=== Add created ECLTrig objects to the StoreArray
179 
180  ECLTrig* new_ecl_trigs[ECL_CRATES] = {};
181  for (int i = 0; i < ECL_CRATES; i++) {
182  if (m_eclTrigsBuffer[i].getTrigId() > 0) {
183  new_ecl_trigs[i] = m_eclTrigs.appendNew(m_eclTrigsBuffer[i]);
184  }
185  }
186 
187  for (int i = 0; i < m_eclDigits.getEntries(); i++) {
188  int cid = m_eclDigits[i]->getCellId();
189  int crate0 = m_eclMapper.getCrateID(cid) - 1;
190  if (new_ecl_trigs[crate0]) {
191  m_relDigitToTrig.add(i, crate0);
192  }
193  }
194 
195  m_localEvtNum++;
196 
197 }
198 
200 {
201 }
202 
204 {
205 }
206 
207 // meathod to read collector data by 32-bit words
209 {
210  if (m_bufPos == m_bufLength) {
211  B2DEBUG_eclunpacker(22, "Reached the end of the FINESSE buffer");
212  throw Unexpected_end_of_FINESSE_buffer();
213  }
214  unsigned int value = m_bufPtr[m_bufPos];
215  m_bufPos++;
216  return value;
217 }
218 
219 // read given number of bits from the buffer (in order to read compressed ADC data)
220 unsigned int ECLUnpackerModule::readNBits(int bitsToRead)
221 {
222  unsigned int val = 0;
223 
224  val = m_bufPtr[m_bufPos] >> m_bitPos;
225  if (m_bitPos + bitsToRead > 31)
226  if (m_bufPos == m_bufLength) {
227  B2ERROR("Reached the end of the FINESSE buffer while read compressed ADC data");
228 
229  throw Unexpected_end_of_FINESSE_buffer();
230  } else {
231  m_bufPos++;
232  val += m_bufPtr[m_bufPos] << (32 - m_bitPos);
233  m_bitPos += bitsToRead;
234  m_bitPos -= 32;
235  } else {
236  m_bitPos += bitsToRead;
237  if (m_bitPos == 32) {
238  m_bufPos++;
239  m_bitPos -= 32;
240  }
241  }
242 
243  val &= (1 << bitsToRead) - 1;
244 
245  return val;
246 }
247 
248 void ECLUnpackerModule::readRawECLData(RawECL* rawCOPPERData, int n)
249 {
250  int iCrate, iShaper, iChannel, cellID;
251 
252  int shapersMask;
253  int adcDataBase, adcDataDiffWidth;
254  int compressMode, shaperDataLength;
255  unsigned int value = 0;
256  unsigned int nRead = 0, ind = 0, indSample = 0;
257  unsigned int nActiveChannelsWithADCData, nADCSamplesPerChannel, nActiveDSPChannels;
258  int triggerPhase;
259  int dspMask = 0, triggerTag = 0;
260  int nShapers;
261  int adcMask, adcHighMask, dspTime, dspAmplitude, dspQualityFlag;
262  // Mask of shapers that discarded waveform data due to beam burst suppression
263  int burstSuppressionMask;
264 
265 
266  std::vector <int> eclWaveformSamples;
267 
268  int nodeID = rawCOPPERData->GetNodeID(n);
269  int channelsCount = rawCOPPERData->GetMaxNumOfCh(n);
270 
271  int collectorsInNode = -1;
272 
273  bool pcie40Data = false;
274  if (channelsCount == 4) { // COPPER data
275  pcie40Data = false;
276  collectorsInNode = 2;
277  } else if (channelsCount == 48) { // PCIe40 data
278  pcie40Data = true;
279  collectorsInNode = 18;
280  if (nodeID == BECL_ID + 3) {
281  collectorsInNode = 16;
282  }
283  } else {
284  B2FATAL("The maximum number of channels per readout board is invalid."
285  << LogVar("Number of channels", channelsCount));
286  }
287 
288  // loop over FINESSEs in the COPPER
289  for (int iFINESSE = 0; iFINESSE < collectorsInNode; iFINESSE++) {
290 
291  m_bitPos = 0;
292  m_bufPos = 0;
293 
294  m_bufLength = rawCOPPERData->GetDetectorNwords(n, iFINESSE);
295 
296  if (m_bufLength <= 0) continue;
297 
298  // get Number of Collector/Crate connected to the FINESSE
299  iCrate = m_eclMapper.getCrateID(nodeID, iFINESSE, pcie40Data);
300 
301  // pointer to data from COPPER/FINESSE
302  m_bufPtr = (unsigned int*)rawCOPPERData->GetDetectorBuffer(n, iFINESSE);
303 
304  B2DEBUG_eclunpacker(21, "***** iEvt " << m_localEvtNum << " node " << std::hex << nodeID);
305 
306  // dump buffer data
307  for (int i = 0; i < m_bufLength; i++) {
308  B2DEBUG_eclunpacker(29, "" << std::hex << setfill('0') << setw(8) << m_bufPtr[i]);
309  }
310  B2DEBUG_eclunpacker(21, "***** ");
311 
312 
313  m_bufPos = 0; // set read position to the 1-st word
314 
315  // get number of shapers depending on the subsystem this crate belongs to(barrel/forward/backward)
316  int eclSubSystem = m_eclMapper.getSubSystem(iCrate);
317  switch (eclSubSystem) {
318  case 0 : nShapers = ECL_BARREL_SHAPERS_IN_CRATE; break;
319  case 1 : nShapers = ECL_FWD_SHAPERS_IN_CRATE; break;
320  case 2 : nShapers = ECL_BKW_SHAPERS_IN_CRATE; break;
321  default : nShapers = ECL_BARREL_SHAPERS_IN_CRATE;
322  }
323 
324  try {
325  burstSuppressionMask = 0;
326 
327  // trigger phase of the Collector connected to this FINESSE
328  // -1 if there are no triggered shapers
329  int triggerPhase0 = -1;
330  int triggerTag0 = -1;
331 
332  // read the collector header
333  value = readNextCollectorWord();
334  shapersMask = value & 0xFFF; // mask of active shapers
335  compressMode = (value & 0xF000) >> 12; // compression mode for ADC data, 0 -- disabled, 1 -- enabled
336 
337  B2DEBUG_eclunpacker(22, "ShapersMask = " << std::hex << shapersMask << " compressMode = " << compressMode);
338 
339  // loop over all shapers in crate
340  for (iShaper = 1; iShaper <= nShapers; iShaper++) {
341 
342  // check if shaper is active
343  int thisShaperMask = (1 << (iShaper - 1)) & shapersMask;
344  if (thisShaperMask != (1 << (iShaper - 1))) continue;
345 
346  // read the shaper header
347  value = readNextCollectorWord();
348  shaperDataLength = value & 0xFFFF; // amount of words in DATA section (without COLLECTOR HEADER)
349  B2DEBUG_eclunpacker(22, "iCrate = " << iCrate << " iShaper = " << iShaper);
350  B2DEBUG_eclunpacker(22, "Shaper HEADER = 0x" << std::hex << value << " dataLength = " << std::dec << shaperDataLength);
351  // check shaperDSP header
352  if ((value & 0x00FF0000) != 0x00100000) {
353  doBadHeaderReport(iCrate);
354  throw Bad_ShaperDSP_header();
355  }
356 
357  value = readNextCollectorWord();
358  burstSuppressionMask |= ((value >> 29) & 1) << (iShaper - 1); // burst suppression bit
359  nActiveChannelsWithADCData = (value >> 24) & 0x1F;//number of channels with ADC data
360  nADCSamplesPerChannel = (value >> 16) & 0x7F; //ADC samples per channel
361  nActiveDSPChannels = (value >> 8) & 0x1F; //number of active channels in DSP
362  triggerPhase = value & 0xFF; //trigger phase
363 
364  // check that trigger phases for all shapers in the crate are equal
365  if (triggerPhase0 == -1) triggerPhase0 = triggerPhase;
366  else if (triggerPhase != triggerPhase0) {
367  doPhasesReport(iCrate, triggerPhase0, triggerPhase);
368  }
369 
370  B2DEBUG_eclunpacker(22, "nActiveADCChannels = " << nActiveChannelsWithADCData << " samples " << nADCSamplesPerChannel <<
371  " nActiveDSPChannels "
372  << nActiveDSPChannels);
373 
374  value = readNextCollectorWord();
375 
376  dspMask = (value >> 16) & 0xFFFF; // Active DSP channels mask
377  triggerTag = value & 0xFFFF; // trigger tag
378  B2DEBUG_eclunpacker(22, "DSPMASK = 0x" << std::hex << dspMask << " triggerTag " << std::dec << triggerTag);
379 
380  if (triggerTag0 == -1) triggerTag0 = triggerTag;
381  else if (triggerTag != triggerTag0) {
382  doTagsReport(iCrate, triggerTag0, triggerTag);
383  triggerTag0 |= (1 << 16);
384  }
385 
386  if (m_globalEvtNum >= 0) {
387  if (triggerTag != (m_globalEvtNum & 0xFFFF)) {
388  doEvtNumReport(iCrate, triggerTag, m_globalEvtNum);
389  }
390  }
391 
392  value = readNextCollectorWord();
393  adcMask = value & 0xFFFF; // mask for channels with ADC data
394  adcHighMask = (value >> 16) & 0xFFFF;
395  B2DEBUG_eclunpacker(22, "ADCMASK = 0x" << std::hex << adcMask << " adcHighMask = 0x" << adcHighMask);
396 
397  ECLDigit* newEclDigits[ECL_CHANNELS_IN_SHAPER] = {};
398  int newEclDigitsIdx[ECL_CHANNELS_IN_SHAPER] = {};
399 
400  nRead = 0;
401  // read DSP data (quality, fitted time, amplitude)
402  for (ind = 0; ind < ECL_CHANNELS_IN_SHAPER; ind++) {
403  // check if DSP channel is active
404  if (((1 << ind) & dspMask) != (1 << ind)) continue;
405  iChannel = ind + 1;
406  value = readNextCollectorWord();
407  dspTime = (int)(value << 2) >> 20;
408  dspQualityFlag = (value >> 30) & 0x3;
409  dspAmplitude = (value & 0x3FFFF) - 128;
410  nRead++;
411 
412  cellID = m_eclMapper.getCellId(iCrate, iShaper, iChannel);
413 
414  if (!isDSPValid(cellID, iCrate, iShaper, iChannel, dspAmplitude, dspTime, dspQualityFlag)) continue;
415 
416  // fill eclDigits data object
417  B2DEBUG_eclunpacker(23, "New eclDigit: cid = " << cellID << " amp = " << dspAmplitude << " time = " << dspTime << " qflag = " <<
418  dspQualityFlag);
419 
420  // construct eclDigit object and save it in DataStore
421  ECLDigit* newEclDigit = m_eclDigits.appendNew();
422  newEclDigitsIdx[ind] = m_eclDigits.getEntries() - 1;
423  newEclDigits[ind] = newEclDigit;
424  newEclDigit->setCellId(cellID);
425  newEclDigit->setAmp(dspAmplitude);
426  newEclDigit->setQuality(dspQualityFlag);
427  if (dspQualityFlag == 2) {
428  // amplitude is lower than threshold value time = trg_time => fit_time = 0
429  newEclDigit->setTimeFit(0);
430  // the time data is replaced with chi2 data
431  const int chi_mantissa = dspTime & 0x1FF;
432  const int chi_exponent = (dspTime >> 9) & 7;
433  const int chi2 = chi_mantissa << (chi_exponent * 2);
434  newEclDigit->setChi(chi2);
435 
436  } else {
437  // otherwise we do not have chi2 information
438  newEclDigit->setTimeFit(dspTime);
439  newEclDigit->setChi(0);
440  }
441 
442  }
443 
444 
445 
446  if (nRead != nActiveDSPChannels) {
447  B2ERROR("Number of active DSP channels and number of read channels don't match (Corrupted data?)"
448  << LogVar("nRead", nRead) << LogVar("nActiveDSP", nActiveDSPChannels));
449  // do something (throw an exception etc.) TODO
450  }
451 
452  //read ADC data
453  eclWaveformSamples.resize(nADCSamplesPerChannel);
454  nRead = 0;
455  for (ind = 0; ind < ECL_CHANNELS_IN_SHAPER; ind++) {
456  //check if there is ADC data for this channel
457  if (((1 << ind) & adcMask) != (1 << ind)) continue;
458  iChannel = ind + 1;
459  adcDataBase = 0;
460  adcDataDiffWidth = 0;
461  for (indSample = 0; indSample < nADCSamplesPerChannel; indSample++) {
462  if (compressMode == 0) value = readNextCollectorWord();
463  else {
464  if (indSample == 0) {
465  value = readNBits(18);
466  adcDataBase = value;
467  B2DEBUG_eclunpacker(24, "adcDataBase = " << adcDataBase);
468  value = readNBits(5);
469  adcDataDiffWidth = value;
470  B2DEBUG_eclunpacker(24, "adcDataDiffWidth = " << adcDataDiffWidth);
471  }
472  value = readNBits(adcDataDiffWidth);
473  B2DEBUG_eclunpacker(24, "adcDataOffset = " << value);
474  value += adcDataBase;
475  }
476  // fill waveform data for single channel
477  eclWaveformSamples[indSample] = value;
478  }
479 
480  // save ADC data to the eclDsp DataStore object if any
481  if (nADCSamplesPerChannel > 0) {
482 
483  cellID = m_eclMapper.getCellId(iCrate, iShaper, iChannel);
484 
485  if (cellID > 0 || m_storeUnmapped) {
486  m_eclDsps.appendNew(cellID, eclWaveformSamples);
487 
489  // Check run-dependent unpacking parameters
490  auto params = m_unpackingParams->get(iCrate, iShaper, iChannel);
491  if (params & ECL_OFFLINE_ADC_FIT) {
492  auto result = ECLDspUtilities::shapeFitter(cellID, eclWaveformSamples, triggerPhase0);
493  if (result.quality == 2) result.time = 0;
494 
495  if (!newEclDigits[ind]) {
496  ECLDigit* newEclDigit = m_eclDigits.appendNew();
497  newEclDigits[ind] = newEclDigit;
498  newEclDigit->setCellId(cellID);
499  newEclDigit->setAmp(result.amp);
500  newEclDigit->setTimeFit(result.time);
501  newEclDigit->setQuality(result.quality);
502  newEclDigit->setChi(result.chi2);
503  }
504  }
505  }
506  // Add relation from ECLDigit to ECLDsp
507  if (newEclDigits[ind]) {
508  int eclDspIdx = m_eclDsps.getEntries() - 1;
509  m_relDigitToDsp.add(newEclDigitsIdx[ind], eclDspIdx);
510  }
511  }
512 
513  }
514 
515  nRead++;
516  } // read ADC data loop
517 
518  if (m_bitPos > 0) {
519  m_bufPos++;
520  m_bitPos = 0;
521  }
522 
523  if (nRead != nActiveChannelsWithADCData) {
524  B2ERROR("Number of channels with ADC data and "
525  "number of read channels don't match (Corrupted data?)"
526  << LogVar("active channels", nActiveChannelsWithADCData)
527  << LogVar("read channels", nRead));
528  // do something (throw an exception etc.) TODO
529  }
530 
531 
532 
533  } // loop over shapers
534 
535  // make new eclTrig oject to store trigger time for crate if there are triggered shapers in the crate
536  if (m_storeTrigTime && shapersMask != 0) {
537  int trigId = iCrate & 0x3F;
538  ECLTrig* eclTrig = &m_eclTrigsBuffer[trigId - 1];
539  // fill trigid, trgtime for eclTrig object
540  trigId |= (burstSuppressionMask & 0xFFF) << 6;
541  eclTrig->setTrigId(trigId);
542  eclTrig->setTimeTrig(triggerPhase0);
543  eclTrig->setTrigTag(triggerTag0);
544  }
545 
546  } // try
547  catch (...) {
548  // errors while reading data block
549  // do something (count errors etc) TODO
550  B2ERROR("Corrupted data from ECL collector");
551  }
552 
553  }// loop over FINESSEs
554 
555 }
556 
557 bool ECLUnpackerModule::isDSPValid(int cellID, int crate, int shaper, int channel, int, int, int quality)
558 {
559  // Channel is not connected to crystal
560  if (cellID < 1) return false;
561 
563  // Check if data for this channel should be discarded in current run.
564  auto params = m_unpackingParams->get(crate, shaper, channel);
565  if (params & ECL_DISCARD_DSP_DATA) {
566  if (params & ECL_KEEP_GOOD_DSP_DATA) {
567  if (quality == 0) return true;
568  }
569  return false;
570  }
571  }
572 
573  return true;
574 }
575 
576 void ECLUnpackerModule::doEvtNumReport(unsigned int iCrate, int tag, int evt_number)
577 {
578  if (!evtNumReported(iCrate)) {
579  B2ERROR("ECL trigger tag is inconsistent with event number."
580  << LogVar("crate", iCrate)
581  << LogVar("trigger tag", tag)
582  << LogVar("event number", evt_number));
583  m_evtNumReportedMask |= 1L << (iCrate - 1);
584  }
585 }
586 void ECLUnpackerModule::doTagsReport(unsigned int iCrate, int tag0, int tag1)
587 {
588  if (!tagsReported(iCrate)) {
589  B2ERROR("Different trigger tags. ECL data is corrupted for whole run probably."
590  << LogVar("crate", iCrate)
591  << LogVar("trigger tag0", tag0) << LogVar("trigger tag1", tag1));
592  m_tagsReportedMask |= 1L << (iCrate - 1);
593  }
594 }
595 void ECLUnpackerModule::doPhasesReport(unsigned int iCrate, int phase0, int phase1)
596 {
597  if (!phasesReported(iCrate)) {
598  B2ERROR("Different trigger phases. ECL data is corrupted for whole run probably."
599  << LogVar("crate", iCrate)
600  << LogVar("trigger phase0", phase0) << LogVar("trigger phase1", phase1));
601  m_phasesReportedMask |= 1L << (iCrate - 1);
602  }
603 }
604 void ECLUnpackerModule::doBadHeaderReport(unsigned int iCrate)
605 {
606  if (!badHeaderReported(iCrate)) {
607  B2ERROR("Bad shaper header."
608  << LogVar("crate", iCrate));
609  m_badHeaderReportedMask |= 1L << (iCrate - 1);
610  }
611 }
612 
In the store you can park objects that have to be accessed by various modules.
Definition: DataStore.h:51
Class to store ECL digitized hits (output of ECLDigi) relation to ECLHit filled in ecl/modules/eclDig...
Definition: ECLDigit.h:24
void setAmp(int Amp)
Set Fitting Amplitude.
Definition: ECLDigit.h:44
void setTimeFit(int TimeFit)
Set Fitting Time.
Definition: ECLDigit.h:49
void setCellId(int CellId)
Set Cell ID.
Definition: ECLDigit.h:40
void setQuality(int Quality)
Set Fitting Quality.
Definition: ECLDigit.h:54
void setChi(int Chi)
Set Chi-squared.
Definition: ECLDigit.h:58
Class to store ECLTrig, still need to be study relation to ECLHit filled in ecl/modules/eclDigitizer/...
Definition: ECLTrig.h:25
void setTrigTag(int TrigTag)
Set Trig Time (crate Id)
Definition: ECLTrig.h:41
void setTrigId(int TrigId)
Set TrigID.
Definition: ECLTrig.h:38
void setTimeTrig(double TimeTrig)
Set Triger Tag (crate Id)
Definition: ECLTrig.h:44
StoreArray< RawECL > m_rawEcl
store array for RawECL
StoreArray< ECLDsp > m_eclDsps
store array for waveforms
int m_debugLevel
Cached debug level from LogSystem.
bool isDSPValid(int cellID, int crate, int shaper, int channel, int amp, int time, int quality)
Check if DSP data should be saved to datastore.
unsigned int readNBits(int bitsToRead)
read N bits from COPPER buffer (needed for reading the compressed ADC data)
bool badHeaderReported(unsigned int iCrate)
Check if the problem with bad shaper header was already reported for crate iCrate.
void doPhasesReport(unsigned int iCrate, int phase0, int phase1)
Report the problem with trigger phases and exclude the crate from further reports of this type.
ECL::ECLChannelMapper m_eclMapper
ECL channel mapper.
bool phasesReported(unsigned int iCrate)
Check if the problem with different trigger phases was already reported for crate iCrate.
virtual void initialize() override
initialize
int m_bufPos
position in the COPPER data array
bool evtNumReported(unsigned int iCrate)
Check if the problem with trg tag <-> evt number inconsistency was already reported for crate iCrate.
std::string m_eclTrigsName
name of output collection for ECLTrig
virtual void event() override
event
void doEvtNumReport(unsigned int iCrate, int tag, int evt_number)
Report the problem with inconsistency between trg tag and evt number.
long m_badHeaderReportedMask
report only once per crate about problem with shaper header
bool m_storeUnmapped
flag for whether or not to store ECLDsp data for unmapped channels
StoreArray< ECLTrig > m_eclTrigs
store array for eclTrigs data (trigger time and tag)
void readRawECLData(RawECL *rawCOPPERData, int n)
read raw data from COPPER and fill output m_eclDigits container
virtual void endRun() override
endRun
int m_bitPos
bit position for bit-by-bit data read
virtual void terminate() override
terminate
DBObjPtr< ECLChannelMap > m_unpackingParams
Run-dependent unpacking parameters for each channel.
StoreArray< ECLDigit > m_eclDigits
store array for digitized gits
RelationArray m_relDigitToTrig
ECLDigit->ECLTrig relation array.
StoreObjPtr< EventMetaData > m_eventMetaData
store objptr for EventMetaData
std::string m_eclMapperInitFileName
name of the file with correspondence between cellID and crate/shaper/channel numbers
int m_globalEvtNum
event number from EventMetaData
long m_evtNumReportedMask
report only once per crate about inconsistency between trg tag and evt number
void doTagsReport(unsigned int iCrate, int tag0, int tag1)
Report the problem with trigger tags and exclude the crate from further reports of this type.
std::string m_eclDspsName
name of output collection for ECLDsp
virtual void beginRun() override
beginRun
bool m_storeTrigTime
flag for whether or not to store collection with trigger times
unsigned int readNextCollectorWord()
read nex word from COPPER data, check if the end of data is reached
RelationArray m_relDigitToDsp
ECLDigit->ECLTrig relation array.
int m_bufLength
length of COPPER data
int m_localEvtNum
Internally counted event number.
bool tagsReported(unsigned int iCrate)
Check if the problem with different trigger tags was already reported for crate iCrate.
@ ECL_OFFLINE_ADC_FIT
Get ECLDigits from offline waveform fit.
@ ECL_DISCARD_DSP_DATA
Skip ECLDigit unpacking.
@ ECL_KEEP_GOOD_DSP_DATA
Keep ECLDigits for quality flag 0 even if ECL_DISCARD_DSP_DATA is set.
bool m_useUnpackingParameters
Use ECLUnpackingParameters payload for run-dependent unpacking.
void doBadHeaderReport(unsigned int iCrate)
Report the problem with bad shaper header and exclude the crate from further reports of this type.
std::string m_eclDigitsName
name of output collection for ECLDigits
ECLTrig m_eclTrigsBuffer[ECL::ECL_CRATES]
ECLTrigs objects before they are added to m_eclTrigs array.
long m_phasesReportedMask
report only once per crate about problem with different trg phases
unsigned int * m_bufPtr
pointer to data from COPPER
long m_tagsReportedMask
report only once per crate about problem with different trg tags
int getSubSystem(int iCrate)
Get ECL subsystem ID by given crate number: 0 – barrel, 1 – forward. 2 – backward endcap.
bool initFromDB()
Initialize channel mapper from the conditions database.
int getCellId(int iCrate, int iShaper, int iChannel)
Get CellId by given crate number, shaper position in the crate and DSP channel number in the shaper.
int getCrateID(int iCOPPERNode, int iFINESSE, bool pcie40=false)
Get crate number by given COPPER node number and FINESSE number.
static ECLShapeFit shapeFitter(int cid, std::vector< int > adc, int ttrig, bool adjusted_timing=true)
Emulate shape fitting algorithm from ShaperDSP using algorithm from ecl/utility/src/ECLDspEmulator....
@ c_Debug
Debug: for code development.
Definition: LogConfig.h:26
static LogSystem & Instance()
Static method to get a reference to the LogSystem instance.
Definition: LogSystem.cc:31
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
The Raw ECL class Class for RawCOPPER class data taken by ECL Currently, this class is almost same as...
Definition: RawECL.h:26
void add(index_type from, index_type to, weight_type weight=1.0)
Add a new element to the relation.
void clear() override
Clear all elements from the relation.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Class to store variables with their name which were sent to the logging service.
const LogConfig & getCurrentLogConfig(const char *package=nullptr) const
Returns the current LogConfig object used by the logging system.
Definition: LogSystem.h:258
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
int GetDetectorNwords(int n, int finesse_num)
get Detector buffer length
Definition: RawCOPPER.h:657
int * GetDetectorBuffer(int n, int finesse_num)
get Detector buffer
Definition: RawCOPPER.h:681
unsigned int GetNodeID(int n)
get node-ID from data
Definition: RawCOPPER.h:397
int GetMaxNumOfCh(int n)
Get the max number of channels in a readout board.
Definition: RawCOPPER.h:750
Abstract base class for different kinds of events.