Belle II Software development
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#include <ecl/utility/ECLRawDataHadron.h>
26
27using namespace std;
28using namespace Belle2;
29using namespace ECL;
30
31#define B2DEBUG_eclunpacker(level, msg) \
32 if (m_debugLevel >= level) {\
33 B2DEBUG(level, msg); \
34 }
35
36/*
37
38Data format of data packet from shaperDSP (32 bit words)
39
40---------------------------------------------------------------------------------------
41Offset | MSW(16 bits) | LSW(16 bits) |
42--------------------------------------------------------------------------------------|
43 | | |
440 | b[31..24] - package ID | 4+DSP_NUM+ADC_NUM*SAMPLES_NUM |
45 | b[23..21] - data format | (Packet length) |
46 | (0x0 - standard data) | (maxlen = 2052) |
47 | (0x4 - hadron component data) | |
48 | | |
49 | b[20..16] - package type | |
50 | (type = 0x10) | |
51 | | |
52--------------------------------------------------------------------------------------|
53 | |
541 | b[31..30] – 0
55 | b[ 29 ] – Burst suppression bit |
56 | b[28..24] – number of active ADC data channels (ADC_NUM) |
57 | b[22..16] – ADC samples per channel (SAMPLES_NUM) |
58 | b[12..8] – number of active DSP channels (DSP_NUM) |
59 | b[7..0] – trigger phase |
60 | |
61--------------------------------------------------------------------------------------|
622 | b[31…16] – dsp_mask | b[15..0] – trigger tag |
63 | | |
64--------------------------------------------------------------------------------------|
653 | 0 | b[15..0] – adc_mask |
66 | | |
67--------------------------------------------------------------------------------------|
684…3+DSP_NUM | b[31..30] – quality flag |
69 | quality = 0 : good fit |
70 | quality = 1 : internal error of approximation |
71 | (e.g. integer overflow/underflow) |
72 | quality = 2 : A < A_thr, |
73 | time is replaced with chi2 |
74 | quality = 3 : bad fit, χ2 > χ2_thr, A > A_thr |
75 | b[29..18] – reconstructed time (or chi2 if quality = 2) |
76 | chi2 = m<<(p*2), m = b[29:27], p = b[26:18] |
77 | b[17..0] – reconstructed amplitude |
78 | |
79--------------------------------------------------------------------------------------|
804+DSP_NUM… | |
813+DSP_NUM+ | ADC_NUM*SAMPLES_NUM -- ADC samples |
82ADC_NUM*SAMPLES_NUM | |
83--------------------------------------------------------------------------------------|
84
85*/
86
87
88REG_MODULE(ECLUnpacker);
89
93 m_bufPtr(0),
94 m_bufPos(0),
95 m_bufLength(0),
96 m_bitPos(0),
99 m_unpackingParams("ECLUnpackingParameters", false),
100 m_eclDigits("", DataStore::c_Event),
101 m_debugLevel(0)
102{
103 setDescription("The module reads RawECL data from the DataStore and writes the ECLDigit data");
104
106
107 addParam("InitFileName", m_eclMapperInitFileName, "Initialization file", string("/ecl/data/ecl_channels_map.txt"));
108 addParam("ECLDigitsName", m_eclDigitsName, "Name of the ECLDigits container", string("ECLDigits"));
109 addParam("ECLDspsName", m_eclDspsName, "Name of the ECLDsp container", string("ECLDsps"));
110 addParam("ECLTrigsName", m_eclTrigsName, "Name of the ECLTrig container", string("ECLTrigs"));
111 // flag to store trigger times needed for calibration with pulse generator only, so false by default
112 addParam("storeTrigTime", m_storeTrigTime, "Store trigger time", false);
113 addParam("storeUnmapped", m_storeUnmapped, "Store ECLDsp for channels that don't "
114 "exist in ECL mapping", false);
115 addParam("useUnpackingParameters", m_useUnpackingParameters,
116 "Use ECLUnpackingParameters payload", true);
117}
118
120{
121 // Get cached debug level to improve performance
122 auto& config = LogSystem::Instance().getCurrentLogConfig(PACKAGENAME());
123 m_debugLevel = config.getLogLevel() == LogConfig::c_Debug ? config.getDebugLevel() : 0;
124
125 // require input data
126 m_rawEcl.isRequired();
127
128 // register output containers in data store
129 m_eclDigits.registerInDataStore(m_eclDigitsName);
130 if (m_storeTrigTime) {
131 m_eclTrigs.registerInDataStore(m_eclTrigsName);
132 m_relDigitToTrig.registerInDataStore();
133 }
134 m_eclDsps.registerInDataStore(m_eclDspsName);
135 m_relDigitToDsp.registerInDataStore();
136 m_eclDsps.registerRelationTo(m_eclDigits);
137
138}
139
141{
146 // Initialize channel mapper at run start to account for possible
147 // changes in ECL mapping between runs.
148 if (!m_eclMapper.initFromDB()) {
149 B2FATAL("ECL Unpacker: Can't initialize eclChannelMapper!");
150 }
152 B2FATAL("ECL Unpacker: Can't access ECLUnpackingParameters payload");
153 }
154}
155
157{
158 // output data
159 m_eclDigits.clear();
160 m_eclDsps.clear();
161 m_eclTrigs.clear();
162 // clear relations arrays
164 if (m_relDigitToDsp) m_relDigitToDsp.clear();
165
166 if (m_eventMetaData.isValid()) {
167 m_globalEvtNum = m_eventMetaData->getEvent();
168 } else {
169 m_globalEvtNum = -1;
170 }
171
172 for (int i = 0; i < ECL_CRATES; i++) {
173 m_eclTrigsBuffer[i].setTrigId(0);
174 }
175
176 //=== Read raw event data
177
178 int nRawEclEntries = m_rawEcl.getEntries();
179
180 B2DEBUG_eclunpacker(22, "Ecl unpacker event called N_RAW = " << nRawEclEntries);
181
182 for (int i = 0; i < nRawEclEntries; i++) {
183 for (int n = 0; n < m_rawEcl[i]->GetNumEntries(); n++) {
184 readRawECLData(m_rawEcl[ i ], n); // read data from RawECL and put into the m_eclDigits container
185 }
186 }
187
188 //=== Add created ECLTrig objects to the StoreArray
189
190 ECLTrig* new_ecl_trigs[ECL_CRATES] = {};
191 for (int i = 0; i < ECL_CRATES; i++) {
192 if (m_eclTrigsBuffer[i].getTrigId() > 0) {
193 new_ecl_trigs[i] = m_eclTrigs.appendNew(m_eclTrigsBuffer[i]);
194 }
195 }
196
197 for (int i = 0; i < m_eclDigits.getEntries(); i++) {
198 int cid = m_eclDigits[i]->getCellId();
199 int crate0 = m_eclMapper.getCrateID(cid) - 1;
200 if (new_ecl_trigs[crate0]) {
201 m_relDigitToTrig.add(i, crate0);
202 }
203 }
204
206
207}
208
212
216
217// method to read collector data by 32-bit words
219{
220 if (m_bufPos == m_bufLength) {
221 B2DEBUG_eclunpacker(22, "Reached the end of the FINESSE buffer");
222 throw Unexpected_end_of_FINESSE_buffer();
223 }
224 unsigned int value = m_bufPtr[m_bufPos];
225 m_bufPos++;
226 return value;
227}
228
229// read given number of bits from the buffer (in order to read compressed ADC data)
230unsigned int ECLUnpackerModule::readNBits(int bitsToRead)
231{
232 unsigned int val = 0;
233
234 val = m_bufPtr[m_bufPos] >> m_bitPos;
235 if (m_bitPos + bitsToRead > 31)
236 if (m_bufPos == m_bufLength) {
237 B2ERROR("Reached the end of the FINESSE buffer while read compressed ADC data");
238
239 throw Unexpected_end_of_FINESSE_buffer();
240 } else {
241 m_bufPos++;
242 val += m_bufPtr[m_bufPos] << (32 - m_bitPos);
243 m_bitPos += bitsToRead;
244 m_bitPos -= 32;
245 } else {
246 m_bitPos += bitsToRead;
247 if (m_bitPos == 32) {
248 m_bufPos++;
249 m_bitPos -= 32;
250 }
251 }
252
253 val &= (1 << bitsToRead) - 1;
254
255 return val;
256}
257
258void ECLUnpackerModule::readRawECLData(RawECL* rawCOPPERData, int n)
259{
260 int iCrate, iShaper, iChannel, cellID;
261
262 int shapersMask;
263 int adcDataBase, adcDataDiffWidth;
264 int compressMode, shaperDataLength;
265 unsigned int value = 0;
266 unsigned int nRead = 0, ind = 0, indSample = 0;
267 unsigned int nActiveChannelsWithADCData, nADCSamplesPerChannel, nActiveDSPChannels;
268 int triggerPhase;
269 int dspMask = 0, triggerTag = 0;
270 int nShapers;
271 int adcMask, adcHighMask, dspTime, dspAmplitude, dspQualityFlag;
272 int dspHadronFraction;
273 unsigned int dataFormat;
274 // Mask of shapers that discarded waveform data due to beam burst suppression
275 int burstSuppressionMask;
276
277
278 std::vector <int> eclWaveformSamples;
279
280 int nodeID = rawCOPPERData->GetNodeID(n);
281 int channelsCount = rawCOPPERData->GetMaxNumOfCh(n);
282
283 int collectorsInNode = -1;
284
285 bool pcie40Data = false;
286 if (channelsCount == 4) { // COPPER data
287 pcie40Data = false;
288 collectorsInNode = 2;
289 } else if (channelsCount == 48) { // PCIe40 data
290 pcie40Data = true;
291 collectorsInNode = 18;
292 if (nodeID == BECL_ID + 3) {
293 collectorsInNode = 16;
294 }
295 } else {
296 B2FATAL("The maximum number of channels per readout board is invalid."
297 << LogVar("Number of channels", channelsCount));
298 }
299
300 // loop over FINESSEs in the COPPER
301 for (int iFINESSE = 0; iFINESSE < collectorsInNode; iFINESSE++) {
302
303 m_bitPos = 0;
304 m_bufPos = 0;
305
306 m_bufLength = rawCOPPERData->GetDetectorNwords(n, iFINESSE);
307
308 if (m_bufLength <= 0) continue;
309
310 // get Number of Collector/Crate connected to the FINESSE
311 iCrate = m_eclMapper.getCrateID(nodeID, iFINESSE, pcie40Data);
312
313 // pointer to data from COPPER/FINESSE
314 m_bufPtr = (unsigned int*)rawCOPPERData->GetDetectorBuffer(n, iFINESSE);
315
316 B2DEBUG_eclunpacker(21, "***** iEvt " << m_localEvtNum << " node " << std::hex << nodeID);
317
318 // dump buffer data
319 for (int i = 0; i < m_bufLength; i++) {
320 B2DEBUG_eclunpacker(29, "" << std::hex << setfill('0') << setw(8) << m_bufPtr[i]);
321 }
322 B2DEBUG_eclunpacker(21, "***** ");
323
324
325 m_bufPos = 0; // set read position to the 1-st word
326
327 // get number of shapers depending on the subsystem this crate belongs to(barrel/forward/backward)
328 int eclSubSystem = m_eclMapper.getSubSystem(iCrate);
329 switch (eclSubSystem) {
330 case 0 : nShapers = ECL_BARREL_SHAPERS_IN_CRATE; break;
331 case 1 : nShapers = ECL_FWD_SHAPERS_IN_CRATE; break;
332 case 2 : nShapers = ECL_BKW_SHAPERS_IN_CRATE; break;
333 default : nShapers = ECL_BARREL_SHAPERS_IN_CRATE;
334 }
335
336 try {
337 burstSuppressionMask = 0;
338
339 // trigger phase of the Collector connected to this FINESSE
340 // -1 if there are no triggered shapers
341 int triggerPhase0 = -1;
342 int triggerTag0 = -1;
343
344 // read the collector header
345 value = readNextCollectorWord();
346 shapersMask = value & 0xFFF; // mask of active shapers
347 compressMode = (value & 0xF000) >> 12; // compression mode for ADC data, 0 -- disabled, 1 -- enabled
348
349 B2DEBUG_eclunpacker(22, "ShapersMask = " << std::hex << shapersMask << " compressMode = " << compressMode);
350
351 // loop over all shapers in crate
352 for (iShaper = 1; iShaper <= nShapers; iShaper++) {
353
354 // check if shaper is active
355 int thisShaperMask = (1 << (iShaper - 1)) & shapersMask;
356 if (thisShaperMask != (1 << (iShaper - 1))) continue;
357
358 // read the shaper header
359 value = readNextCollectorWord();
360 shaperDataLength = value & 0xFFFF; // amount of words in DATA section (without COLLECTOR HEADER)
361 B2DEBUG_eclunpacker(22, "iCrate = " << iCrate << " iShaper = " << iShaper);
362 B2DEBUG_eclunpacker(22, "Shaper HEADER = 0x" << std::hex << value << " dataLength = " << std::dec << shaperDataLength);
363 // check shaperDSP header
364 if ((value & 0x001F0000) != 0x00100000) {
365 doBadHeaderReport(iCrate);
366 throw Bad_ShaperDSP_header();
367 }
368 dataFormat = (value >> 21) & 0x7;
369
370 value = readNextCollectorWord();
371 burstSuppressionMask |= ((value >> 29) & 1) << (iShaper - 1); // burst suppression bit
372 nActiveChannelsWithADCData = (value >> 24) & 0x1F;//number of channels with ADC data
373 nADCSamplesPerChannel = (value >> 16) & 0x7F; //ADC samples per channel
374 nActiveDSPChannels = (value >> 8) & 0x1F; //number of active channels in DSP
375 triggerPhase = value & 0xFF; //trigger phase
376
377 // check that trigger phases for all shapers in the crate are equal
378 if (triggerPhase0 == -1) triggerPhase0 = triggerPhase;
379 else if (triggerPhase != triggerPhase0) {
380 doPhasesReport(iCrate, triggerPhase0, triggerPhase);
381 }
382
383 B2DEBUG_eclunpacker(22, "nActiveADCChannels = " << nActiveChannelsWithADCData << " samples " << nADCSamplesPerChannel <<
384 " nActiveDSPChannels "
385 << nActiveDSPChannels);
386
387 value = readNextCollectorWord();
388
389 dspMask = (value >> 16) & 0xFFFF; // Active DSP channels mask
390 triggerTag = value & 0xFFFF; // trigger tag
391 B2DEBUG_eclunpacker(22, "DSPMASK = 0x" << std::hex << dspMask << " triggerTag " << std::dec << triggerTag);
392
393 if (triggerTag0 == -1) triggerTag0 = triggerTag;
394 else if (triggerTag != triggerTag0) {
395 doTagsReport(iCrate, triggerTag0, triggerTag);
396 triggerTag0 |= (1 << 16);
397 }
398
399 if (m_globalEvtNum >= 0) {
400 if (triggerTag != (m_globalEvtNum & 0xFFFF)) {
401 doEvtNumReport(iCrate, triggerTag, m_globalEvtNum);
402 }
403 }
404
405 value = readNextCollectorWord();
406 adcMask = value & 0xFFFF; // mask for channels with ADC data
407 adcHighMask = (value >> 16) & 0xFFFF;
408 B2DEBUG_eclunpacker(22, "ADCMASK = 0x" << std::hex << adcMask << " adcHighMask = 0x" << adcHighMask);
409
410 ECLDigit* newEclDigits[ECL_CHANNELS_IN_SHAPER] = {};
411 int newEclDigitsIdx[ECL_CHANNELS_IN_SHAPER] = {};
412
413 nRead = 0;
414 dspHadronFraction = 0;
415 // read DSP data (quality, fitted time, amplitude)
416 for (ind = 0; ind < ECL_CHANNELS_IN_SHAPER; ind++) {
417 // check if DSP channel is active
418 if (((1 << ind) & dspMask) != (1 << ind)) continue;
419 iChannel = ind + 1;
420 value = readNextCollectorWord();
421 if ((dataFormat & 4) == 0) {
422 // Standard data format
423 // bits 31..30
424 dspQualityFlag = (value >> 30) & 0x3;
425 // bits 29..18
426 dspTime = (int)(value << 2) >> 20;
427 // bits 17..0
428 dspAmplitude = (value & 0x3FFFF) - 128;
429 } else {
430 // Data format with hadron component
431 using namespace Belle2::ECL::RawDataHadron;
432 // bits 31..30
433 dspQualityFlag = (value >> 30) & 0x3;
434 // bits 29..19
435 dspTime = unpackTime((value >> 19) & 0x7FF);
436 // bits 18..5
437 dspAmplitude = unpackAmplitude((value >> 5) & 0x3FFF);
438 // bits 4..0
439 dspHadronFraction = unpackHadronFraction(value & 0x1F);
440 }
441 nRead++;
442
443 cellID = m_eclMapper.getCellId(iCrate, iShaper, iChannel);
444
445 if (!isDSPValid(cellID, iCrate, iShaper, iChannel, dspAmplitude, dspTime, dspQualityFlag)) continue;
446
447 // fill eclDigits data object
448 B2DEBUG_eclunpacker(23, "New eclDigit: cid = " << cellID << " amp = " << dspAmplitude << " time = " << dspTime << " qflag = " <<
449 dspQualityFlag);
450
451 // construct eclDigit object and save it in DataStore
452 ECLDigit* newEclDigit = m_eclDigits.appendNew();
453 newEclDigitsIdx[ind] = m_eclDigits.getEntries() - 1;
454 newEclDigits[ind] = newEclDigit;
455 newEclDigit->setCellId(cellID);
456 newEclDigit->setAmp(dspAmplitude);
457 newEclDigit->setQuality(dspQualityFlag);
458 newEclDigit->setPackedHadronFraction(dspHadronFraction);
459 newEclDigit->setDataFormat(dataFormat);
460 if (dspQualityFlag == 2) {
461 // amplitude is lower than threshold value time = trg_time => fit_time = 0
462 newEclDigit->setTimeFit(0);
463 // the time data is replaced with chi2 data
464 const int chi_mantissa = dspTime & 0x1FF;
465 const int chi_exponent = (dspTime >> 9) & 7;
466 const int chi2 = chi_mantissa << (chi_exponent * 2);
467 newEclDigit->setChi(chi2);
468
469 } else {
470 // otherwise we do not have chi2 information
471 newEclDigit->setTimeFit(dspTime);
472 newEclDigit->setChi(0);
473 }
474
475 }
476
477
478
479 if (nRead != nActiveDSPChannels) {
480 B2ERROR("Number of active DSP channels and number of read channels don't match (Corrupted data?)"
481 << LogVar("nRead", nRead) << LogVar("nActiveDSP", nActiveDSPChannels));
482 // do something (throw an exception etc.) TODO
483 }
484
485 //read ADC data
486 eclWaveformSamples.resize(nADCSamplesPerChannel);
487 nRead = 0;
488 for (ind = 0; ind < ECL_CHANNELS_IN_SHAPER; ind++) {
489 //check if there is ADC data for this channel
490 if (((1 << ind) & adcMask) != (1 << ind)) continue;
491 iChannel = ind + 1;
492 adcDataBase = 0;
493 adcDataDiffWidth = 0;
494 for (indSample = 0; indSample < nADCSamplesPerChannel; indSample++) {
495 if (compressMode == 0) value = readNextCollectorWord();
496 else {
497 if (indSample == 0) {
498 value = readNBits(18);
499 adcDataBase = value;
500 B2DEBUG_eclunpacker(24, "adcDataBase = " << adcDataBase);
501 value = readNBits(5);
502 adcDataDiffWidth = value;
503 B2DEBUG_eclunpacker(24, "adcDataDiffWidth = " << adcDataDiffWidth);
504 }
505 value = readNBits(adcDataDiffWidth);
506 B2DEBUG_eclunpacker(24, "adcDataOffset = " << value);
507 value += adcDataBase;
508 }
509 // fill waveform data for single channel
510 eclWaveformSamples[indSample] = value;
511 }
512
513 // save ADC data to the eclDsp DataStore object if any
514 if (nADCSamplesPerChannel > 0) {
515
516 cellID = m_eclMapper.getCellId(iCrate, iShaper, iChannel);
517
518 if (cellID > 0 || m_storeUnmapped) {
519 m_eclDsps.appendNew(cellID, eclWaveformSamples);
520
522 // Check run-dependent unpacking parameters
523 auto params = m_unpackingParams->get(iCrate, iShaper, iChannel);
524 if (params & ECL_OFFLINE_ADC_FIT) {
525 auto result = ECLDspUtilities::shapeFitter(cellID, eclWaveformSamples, triggerPhase0);
526 if (result.quality == 2) result.time = 0;
527
528 if (!newEclDigits[ind]) {
529 ECLDigit* newEclDigit = m_eclDigits.appendNew();
530 newEclDigits[ind] = newEclDigit;
531 newEclDigit->setCellId(cellID);
532 newEclDigit->setAmp(result.amp);
533 newEclDigit->setTimeFit(result.time);
534 newEclDigit->setQuality(result.quality);
535 newEclDigit->setChi(result.chi2);
536 }
537 }
538 }
539 // Add relation from ECLDigit to ECLDsp
540 if (newEclDigits[ind]) {
541 int eclDspIdx = m_eclDsps.getEntries() - 1;
542 m_relDigitToDsp.add(newEclDigitsIdx[ind], eclDspIdx);
543 }
544 }
545
546 }
547
548 nRead++;
549 } // read ADC data loop
550
551 if (m_bitPos > 0) {
552 m_bufPos++;
553 m_bitPos = 0;
554 }
555
556 if (nRead != nActiveChannelsWithADCData) {
557 B2ERROR("Number of channels with ADC data and "
558 "number of read channels don't match (Corrupted data?)"
559 << LogVar("active channels", nActiveChannelsWithADCData)
560 << LogVar("read channels", nRead));
561 // do something (throw an exception etc.) TODO
562 }
563
564
565
566 } // loop over shapers
567
568 // make new eclTrig object to store trigger time for crate if there are triggered shapers in the crate
569 if (m_storeTrigTime && shapersMask != 0) {
570 int trigId = iCrate & 0x3F;
571 ECLTrig* eclTrig = &m_eclTrigsBuffer[trigId - 1];
572 // fill trigid, trgtime for eclTrig object
573 trigId |= (burstSuppressionMask & 0xFFF) << 6;
574 eclTrig->setTrigId(trigId);
575 eclTrig->setTimeTrig(triggerPhase0);
576 eclTrig->setTrigTag(triggerTag0);
577 }
578
579 } // try
580 catch (...) {
581 // errors while reading data block
582 // do something (count errors etc) TODO
583 B2ERROR("Corrupted data from ECL collector");
584 }
585
586 }// loop over FINESSEs
587
588}
589
590bool ECLUnpackerModule::isDSPValid(int cellID, int crate, int shaper, int channel, int, int, int quality)
591{
592 // Channel is not connected to crystal
593 if (cellID < 1) return false;
594
596 // Check if data for this channel should be discarded in current run.
597 auto params = m_unpackingParams->get(crate, shaper, channel);
598 if (params & ECL_DISCARD_DSP_DATA) {
599 if (params & ECL_KEEP_GOOD_DSP_DATA) {
600 if (quality == 0) return true;
601 }
602 return false;
603 }
604 }
605
606 return true;
607}
608
609void ECLUnpackerModule::doEvtNumReport(unsigned int iCrate, int tag, int evt_number)
610{
611 if (!evtNumReported(iCrate)) {
612 B2ERROR("ECL trigger tag is inconsistent with event number."
613 << LogVar("crate", iCrate)
614 << LogVar("trigger tag", tag)
615 << LogVar("event number", evt_number));
616 m_evtNumReportedMask |= 1L << (iCrate - 1);
617 }
618}
619void ECLUnpackerModule::doTagsReport(unsigned int iCrate, int tag0, int tag1)
620{
621 if (!tagsReported(iCrate)) {
622 B2ERROR("Different trigger tags. ECL data is corrupted for whole run probably."
623 << LogVar("crate", iCrate)
624 << LogVar("trigger tag0", tag0) << LogVar("trigger tag1", tag1));
625 m_tagsReportedMask |= 1L << (iCrate - 1);
626 }
627}
628void ECLUnpackerModule::doPhasesReport(unsigned int iCrate, int phase0, int phase1)
629{
630 if (!phasesReported(iCrate)) {
631 B2ERROR("Different trigger phases. ECL data is corrupted for whole run probably."
632 << LogVar("crate", iCrate)
633 << LogVar("trigger phase0", phase0) << LogVar("trigger phase1", phase1));
634 m_phasesReportedMask |= 1L << (iCrate - 1);
635 }
636}
638{
639 if (!badHeaderReported(iCrate)) {
640 B2ERROR("Bad shaper header."
641 << LogVar("crate", iCrate));
642 m_badHeaderReportedMask |= 1L << (iCrate - 1);
643 }
644}
645
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:25
void setQuality(unsigned int NewQuality)
Set Fitting Quality.
Definition ECLDigit.h:55
void setAmp(int Amp)
Set Fitting Amplitude.
Definition ECLDigit.h:45
void setTimeFit(int TimeFit)
Set Fitting Time.
Definition ECLDigit.h:50
void setCellId(int CellId)
Set Cell ID.
Definition ECLDigit.h:41
void setChi(int Chi)
Set Chi-squared.
Definition ECLDigit.h:66
void setPackedHadronFraction(unsigned int packed_fraction)
Set hadron fraction See ecl/utility/include/ECLRawDataHadron.h for details.
Definition ECLDigit.h:71
void setDataFormat(unsigned int format)
Set ShaperDSP data format.
Definition ECLDigit.h:83
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 Trigger 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
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:28
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
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:269
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:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
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
This is a set of function for packing/unpacking the data produced by the new ShaperDSP firmware that ...
int unpackTime(int time_packed)
Time unpacking (from 11 bits float to 12 bits int)
unsigned long long unpackAmplitude(unsigned long long amp_packed)
Amplitude unpacking (from 14 bits float to 18 bit int)
double unpackHadronFraction(int fraction_packed)
Hadron fraction unpacking.
Abstract base class for different kinds of events.
STL namespace.