9 #include <cdc/modules/cdcUnpacker/CDCUnpackerModule.h>
11 #include <cdc/dbobjects/CDCChannelMap.h>
13 #include <framework/datastore/DataStore.h>
14 #include <framework/logging/Logger.h>
15 #include <framework/utilities/FileSystem.h>
17 #include <framework/database/DBArray.h>
37 setDescription(
"CDCUnpacker generates CDCHit from Raw data.");
38 setPropertyFlags(c_ParallelProcessingCertified);
40 addParam(
"rawCDCName", m_rawCDCName,
"Name of the RawCDC List name..",
string(
""));
41 addParam(
"cdcRawHitWaveFormName", m_cdcRawHitWaveFormName,
"Name of the CDCRawHit (Raw data mode).",
string(
""));
42 addParam(
"cdcRawHitName", m_cdcRawHitName,
"Name of the CDCRawHit (Suppressed mode).",
string(
""));
43 addParam(
"cdcHitName", m_cdcHitName,
"Name of the CDCHit List name..",
string(
""));
44 addParam(
"fadcThreshold", m_fadcThreshold,
"Threshold count.", 1);
46 addParam(
"xmlMapFileName", m_xmlMapFileName,
"path+name of the xml file",
string(
""));
47 addParam(
"enableStoreCDCRawHit", m_enableStoreCDCRawHit,
"Enable to store to the CDCRawHit object",
false);
48 addParam(
"enablePrintOut", m_enablePrintOut,
"Enable to print out the data to the terminal",
false);
49 addParam(
"boardIDTrig", m_boardIDTrig,
"Board ID for the trigger.", 7);
50 addParam(
"channelTrig", m_channelTrig,
"Channel for the trigger.", 1);
51 addParam(
"subtractTrigTiming", m_subtractTrigTiming,
"Enable to subtract the trigger timing from TDCs.",
false);
52 addParam(
"tdcOffset", m_tdcOffset,
"TDC offset (in TDC count).", 0);
53 addParam(
"enableDatabase", m_enableDatabase,
"Enable database to read the channel map.",
true);
54 addParam(
"enable2ndHit", m_enable2ndHit,
"Enable 2nd hit timing as a individual CDCHit object.",
false);
55 addParam(
"tdcAuxOffset", m_tdcAuxOffset,
"TDC auxiliary offset (in TDC count).", 0);
56 addParam(
"pedestalSubtraction", m_pedestalSubtraction,
"Enbale ADC pedestal subtraction.", m_pedestalSubtraction);
60 CDCUnpackerModule::~CDCUnpackerModule()
64 void CDCUnpackerModule::initialize()
66 m_dataLengthError =
false;
67 m_dataSizeError =
false;
69 if ((*m_channelMapFromDB).isValid()) {
72 B2FATAL(
"Channel map is not valid");
75 if (m_enablePrintOut ==
true) {
76 B2INFO(
"CDCUnpacker: initialize() Called.");
79 m_rawCDCs.isRequired(m_rawCDCName);
80 m_CDCRawHitWaveForms.registerInDataStore(m_cdcRawHitWaveFormName);
81 m_CDCRawHits.registerInDataStore(m_cdcRawHitName);
82 m_CDCHits.registerInDataStore(m_cdcHitName);
84 if (m_enablePrintOut ==
true) {
85 B2INFO(
"CDCUnpacker: " <<
LogVar(
"FADC threshold", m_fadcThreshold));
89 void CDCUnpackerModule::beginRun()
91 if (m_enablePrintOut ==
true) {
92 B2INFO(
"CDCUnpacker: beginRun() called.");
100 void CDCUnpackerModule::event()
102 if (m_enablePrintOut ==
true) {
103 B2INFO(
"CDCUnpacker: event() started.");
107 int tdcCountTrig = m_tdcOffset;
112 if (m_enableStoreCDCRawHit ==
true) {
113 m_CDCRawHits.clear();
114 m_CDCRawHitWaveForms.clear();
121 const int nEntries = m_rawCDCs.getEntries();
123 B2DEBUG(99,
"nEntries of RawCDCs : " << nEntries);
124 for (
int i = 0; i < nEntries; ++i) {
125 const int subDetectorId = m_rawCDCs[i]->GetNodeID(0);
126 const int iNode = (subDetectorId & 0xFFFFFF);
127 const int nEntriesRawCDC = m_rawCDCs[i]->GetNumEntries();
129 B2DEBUG(99,
LogVar(
"nEntries of rawCDC[i]", nEntriesRawCDC));
130 for (
int j = 0; j < nEntriesRawCDC; ++j) {
131 int trigType = m_rawCDCs[i]->GetTRGType(j);
134 int MaxNumOfCh = m_rawCDCs[i]->GetMaxNumOfCh(j);
136 if (MaxNumOfCh == 4) readoutName =
"COPPER";
137 else if (MaxNumOfCh == 48) readoutName =
"PCIe40";
139 B2FATAL(
"CDC UnpackerModule: Invalid value of GetMaxNumOfCh from raw data: " <<
LogVar(
"Number of ch: ",
140 m_rawCDCs[i]->GetMaxNumOfCh(j)));
142 for (
int k = 0; k < MaxNumOfCh; ++k) {
143 nWords[k] = m_rawCDCs[i]->GetDetectorNwords(j, k);
144 data32tab[k] = (
int*)m_rawCDCs[i]->GetDetectorBuffer(j, k);
151 for (
int iFiness = 0; iFiness < MaxNumOfCh; ++iFiness) {
152 int* ibuf = data32tab[iFiness];
153 const int nWord = nWords[iFiness];
154 B2DEBUG(99,
LogVar(
"nWords (from " + readoutName +
" header)", nWord));
156 if (m_enablePrintOut ==
true) {
157 B2INFO(
"CDCUnpacker : Print out CDC data block.");
158 printBuffer(ibuf, nWord);
161 const int c_headearWords = 3;
162 if (nWord < c_headearWords) {
163 if (m_enablePrintOut ==
true) {
164 B2WARNING(
"CDCUnpacker : No CDC block header.");
169 if (m_enablePrintOut ==
true) {
170 B2INFO(
"CDCUnpacker : RawDataBlock(CDC) : Block # "
173 <<
LogVar(
"Finness", iFiness));
176 setCDCPacketHeader(ibuf);
178 const int dataType = getDataType();
179 const int dataLength = getDataLength() / 4;
180 const int swDataLength = dataLength * 2;
183 if (dataLength != (nWord - c_headearWords)) {
184 if (m_dataSizeError ==
false) {
185 B2ERROR(
"Inconsistent data size between " + readoutName +
" and CDC FEE."
186 <<
LogVar(
"data length", dataLength) <<
LogVar(
"nWord", nWord)
187 <<
LogVar(
"Node ID", iNode) <<
LogVar(
"Finness ID", iFiness));
188 m_dataSizeError =
true;
190 B2WARNING(
"Inconsistent data size between " + readoutName +
" and CDC FEE."
191 <<
LogVar(
"data length", dataLength) <<
LogVar(
"nWord", nWord)
192 <<
LogVar(
"Node ID", iNode) <<
LogVar(
"Finness ID", iFiness));
196 if (m_enablePrintOut ==
true) {
197 B2INFO(
"CDCUnpacker : " <<
LogVar(
"Data size", dataLength));
200 const int board = getBoardId();
201 const int trgNumber = getTriggerNumber();
202 const int trgTime = getTriggerTime();
204 if (m_enablePrintOut ==
true) {
205 B2INFO(
"CDCUnpacker : " <<
LogVar(
"Board", board) <<
LogVar(
"Trigger number", trgNumber)
206 <<
LogVar(
"Trigger time ", trgTime));
214 if (m_enablePrintOut ==
true) {
215 B2INFO(
"CDCUnpacker : Raw data mode.");
220 for (
int it = 0; it < dataLength; ++it) {
221 int index = it + c_headearWords;
223 m_buffer.push_back(
static_cast<unsigned short>((ibuf[index] & 0xffff0000) >> 16));
224 m_buffer.push_back(
static_cast<unsigned short>(ibuf[index] & 0xffff));
227 const int fadcTdcChannels = 48;
228 const int nSamples = swDataLength / (2 * fadcTdcChannels);
230 std::vector<unsigned short> fadcs;
231 std::vector<unsigned short> tdcs;
233 for (
int iCh = 0; iCh < fadcTdcChannels; ++iCh) {
234 const int offset = fadcTdcChannels;
235 unsigned short fadcSum = 0;
236 unsigned short tdc1 = 0x7fff;
237 unsigned short tdc2 = 0x7fff;
239 for (
int iSample = 0; iSample < nSamples; ++iSample) {
242 unsigned short fadc = m_buffer.at(iCh + 2 * fadcTdcChannels * iSample);
244 if (fadc > m_fadcThreshold) {
249 unsigned short tdc = m_buffer.at(iCh + 2 * fadcTdcChannels * iSample + offset) & 0x7fff;
250 unsigned short tdcIsValid = (m_buffer.at(iCh + 2 * fadcTdcChannels * iSample + offset) & 0x8000) >> 15;
251 if (tdcIsValid == 1) {
260 fadcs.push_back(fadc);
262 if (m_enableStoreCDCRawHit ==
true) {
264 const unsigned short status = 0;
265 m_CDCRawHitWaveForms.appendNew(status, trgNumber, iNode, iFiness, board, iCh, iSample, trgTime, fadc, tdc);
270 if (tdc1 != 0x7fff) {
272 const WireID wireId = getWireID(board, iCh);
274 if (trgTime < tdc1) {
275 tdc1 = (trgTime | 0x8000) - tdc1;
277 tdc1 = trgTime - tdc1;
279 CDCHit* firstHit = m_CDCHits.appendNew(tdc1, fadcSum, wireId);
280 if (m_enable2ndHit ==
true) {
281 CDCHit* secondHit = m_CDCHits.appendNew(tdc2, fadcSum, wireId);
290 if (m_enablePrintOut ==
true) {
295 printf(
"FADC ch %2d : ", iCh);
296 for (
int iSample = 0; iSample < nSamples; ++iSample) {
297 printf(
"%4x ", fadcs.at(iSample));
301 printf(
"TDC ch %2d : ", iCh);
302 for (
int iSample = 0; iSample < nSamples; ++iSample) {
303 printf(
"%4x ", tdcs.at(iSample));
310 }
else if (dataType == 2) {
311 if (m_enablePrintOut ==
true) {
312 B2INFO(
"CDCUnpacker : Suppressed mode.");
317 for (
int it = 0; it < dataLength; ++it) {
318 int index = it + c_headearWords;
319 m_buffer.push_back(
static_cast<unsigned short>((ibuf[index] & 0xffff0000) >> 16));
320 m_buffer.push_back(
static_cast<unsigned short>(ibuf[index] & 0xffff));
323 const int bufSize =
static_cast<int>(m_buffer.size());
324 for (
int it = 0; it < bufSize;) {
325 unsigned short header = m_buffer.at(it);
326 unsigned short ch = (header & 0xff00) >> 8;
327 unsigned short length = (header & 0xff) / 2;
329 if (header == 0xff02) {
334 if (!((length == 4) || (length == 5))) {
335 if (m_dataLengthError ==
false) {
336 B2ERROR(
"CDCUnpacker : data length should be 4 or 5 words."
337 <<
LogVar(
"data length", length)
338 <<
LogVar(
"board id", board)
339 <<
LogVar(
"channel", ch));
340 m_dataLengthError =
true;
342 B2WARNING(
"CDCUnpacker : data length should be 4 or 5 words."
343 <<
LogVar(
"data length", length)
344 <<
LogVar(
"board id", board)
345 <<
LogVar(
"channel", ch));
351 unsigned short tot = m_buffer.at(it + 1);
352 unsigned short fadcSum = m_buffer.at(it + 2);
353 if (m_pedestalSubtraction ==
true) {
354 int diff = fadcSum - (*m_adcPedestalFromDB)->getPedestal(board, ch);
355 if (diff <= m_fadcThreshold) {
358 fadcSum =
static_cast<unsigned short>(diff);
361 unsigned short tdc1 = 0;
362 unsigned short tdc2 = 0;
363 unsigned short tdcFlag = 0;
366 tdc1 = m_buffer.at(it + 3);
367 }
else if (length == 5) {
368 tdc1 = m_buffer.at(it + 3);
369 tdc2 = m_buffer.at(it + 4) & 0x7fff;
370 tdcFlag = (m_buffer.at(it + 4) & 0x8000) >> 15;
372 B2ERROR(
"CDCUnpacker : Undefined data length (should be 4 or 5 short words) ");
375 if (m_enablePrintOut ==
true) {
376 printf(
"%4x %4x %4x %4x %4x %4x %4x \n", ch, length, tot, fadcSum, tdc1, tdc2, tdcFlag);
378 if (length == 4 || length == 5) {
381 const unsigned short status = trigType;
383 const WireID wireId = getWireID(board, ch);
385 if (isValidBoardChannel(wireId)) {
386 if (board == m_boardIDTrig && ch == m_channelTrig) {
389 CDCHit* firstHit = m_CDCHits.appendNew(tdc1, fadcSum, wireId,
392 if (m_enable2ndHit ==
true) {
393 CDCHit* secondHit = m_CDCHits.appendNew(tdc2, fadcSum, wireId,
401 if (m_enableStoreCDCRawHit ==
true) {
403 m_CDCRawHits.appendNew(status, trgNumber, iNode, iFiness, board, ch,
404 trgTime, fadcSum, tdc1, tdc2, tot);
408 B2WARNING(
"Undefined board id is fired: " <<
LogVar(
"board id", board) <<
" " <<
LogVar(
"channel", ch));
411 it +=
static_cast<int>(length);
415 B2WARNING(
"CDCUnpacker : Undefined CDC Data Block : Block # " <<
LogVar(
"block id", i));
424 if (m_subtractTrigTiming ==
true) {
425 for (
auto& hit : m_CDCHits) {
426 int tdc = hit.getTDCCount();
427 if (hit.is2ndHit()) {
429 tdc = tdc - (tdcCountTrig - m_tdcOffset);
432 tdc = tdc - (tdcCountTrig - m_tdcOffset);
435 tdc -= m_tdcAuxOffset;
436 hit.setTDCCount(
static_cast<unsigned short>(tdc));
441 void CDCUnpackerModule::endRun()
443 if (m_enablePrintOut ==
true) {
444 B2INFO(
"CDCUnpacker : End run.");
448 void CDCUnpackerModule::terminate()
450 if (m_enablePrintOut ==
true) {
451 B2INFO(
"CDCUnpacker : Terminated.");
454 if (m_channelMapFromDB)
delete m_channelMapFromDB;
455 if (m_adcPedestalFromDB)
delete m_adcPedestalFromDB;
459 WireID CDCUnpackerModule::getWireID(
int iBoard,
int iCh)
const
461 return m_map[iBoard][iCh];
464 void CDCUnpackerModule::loadMap()
467 if (m_enableDatabase ==
false) {
470 std::string fileName = FileSystem::findFile(m_xmlMapFileName);
471 std::cout << fileName << std::endl;
472 if (fileName ==
"") {
473 B2ERROR(
"CDC unpacker can't find a filename: " <<
LogVar(
"file name", fileName));
479 ifs.open(fileName.c_str());
487 ifs >> isl >> icl >> iw >> iBoard >> iCh;
488 const WireID wireId(isl, icl, iw);
489 m_map[iBoard][iCh] = wireId;
492 for (
const auto& cm : (*m_channelMapFromDB)) {
494 const int il = cm.getILayer();
495 const int iw = cm.getIWire();
496 const int iBoard = cm.getBoardID();
497 const int iCh = cm.getBoardChannel();
498 const WireID wireId(isl, il, iw);
499 m_map[iBoard][iCh] = wireId;
504 void CDCUnpackerModule::setADCPedestal()
506 if (m_pedestalSubtraction ==
true) {
508 if (!(*m_adcPedestalFromDB).isValid()) {
509 m_pedestalSubtraction =
false;
515 void CDCUnpackerModule::printBuffer(
int* buf,
int nwords)
518 for (
int j = 0; j < nwords; ++j) {
519 printf(
" %.8x", buf[j]);
520 if ((j + 1) % 10 == 0) {
Class containing the result of the unpacker in raw data and the result of the digitizer in simulation...
void set2ndHitFlag()
Setter for 2nd hit flag.
void setOtherHitIndices(CDCHit *otherHit)
Setter for the other hit indices.
CDCUnpackerModule: The CDC Raw Hits Decoder.
Class for accessing arrays of objects in the database.
Class for accessing objects in the database.
Class to identify a wire inside the CDC.
unsigned short getISuperLayer() const
Getter for Super-Layer.
Class to store variables with their name which were sent to the logging service.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.