12 #include <cdc/modules/cdcUnpacker/CDCUnpackerModule.h>
13 #include <cdc/dataobjects/CDCHit.h>
14 #include <cdc/dataobjects/CDCRawHit.h>
15 #include <cdc/dataobjects/CDCRawHitWaveForm.h>
17 #include <cdc/dbobjects/CDCChannelMap.h>
19 #include <framework/datastore/DataStore.h>
20 #include <framework/logging/Logger.h>
21 #include <framework/utilities/FileSystem.h>
23 #include <framework/database/DBArray.h>
43 setDescription(
"CDCUnpacker generates CDCHit from Raw data.");
44 setPropertyFlags(c_ParallelProcessingCertified);
46 addParam(
"rawCDCName", m_rawCDCName,
"Name of the RawCDC List name..",
string(
""));
47 addParam(
"cdcRawHitWaveFormName", m_cdcRawHitWaveFormName,
"Name of the CDCRawHit (Raw data mode).",
string(
""));
48 addParam(
"cdcRawHitName", m_cdcRawHitName,
"Name of the CDCRawHit (Suppressed mode).",
string(
""));
49 addParam(
"cdcHitName", m_cdcHitName,
"Name of the CDCHit List name..",
string(
""));
50 addParam(
"fadcThreshold", m_fadcThreshold,
"Threshold count.", 1);
52 addParam(
"xmlMapFileName", m_xmlMapFileName,
"path+name of the xml file",
string(
""));
53 addParam(
"enableStoreCDCRawHit", m_enableStoreCDCRawHit,
"Enable to store to the CDCRawHit object",
false);
54 addParam(
"enablePrintOut", m_enablePrintOut,
"Enable to print out the data to the terminal",
false);
55 addParam(
"boardIDTrig", m_boardIDTrig,
"Board ID for the trigger.", 7);
56 addParam(
"channelTrig", m_channelTrig,
"Channel for the trigger.", 1);
57 addParam(
"subtractTrigTiming", m_subtractTrigTiming,
"Enable to subtract the trigger timing from TDCs.",
false);
58 addParam(
"tdcOffset", m_tdcOffset,
"TDC offset (in TDC count).", 0);
59 addParam(
"enableDatabase", m_enableDatabase,
"Enable database to read the channel map.",
true);
60 addParam(
"enable2ndHit", m_enable2ndHit,
"Enable 2nd hit timing as a individual CDCHit object.",
false);
61 addParam(
"tdcAuxOffset", m_tdcAuxOffset,
"TDC auxiliary offset (in TDC count).", 0);
62 addParam(
"pedestalSubtraction", m_pedestalSubtraction,
"Enbale ADC pedestal subtraction.", m_pedestalSubtraction);
66 CDCUnpackerModule::~CDCUnpackerModule()
70 void CDCUnpackerModule::initialize()
72 m_dataLengthError =
false;
73 m_dataSizeError =
false;
75 if ((*m_channelMapFromDB).isValid()) {
78 B2FATAL(
"Channel map is not valid");
81 if (m_enablePrintOut ==
true) {
82 B2INFO(
"CDCUnpacker: initialize() Called.");
86 m_rawCDCs.isRequired(m_rawCDCName);
87 m_CDCRawHitWaveForms.registerInDataStore(m_cdcRawHitWaveFormName);
88 m_CDCRawHits.registerInDataStore(m_cdcRawHitName);
89 m_CDCHits.registerInDataStore(m_cdcHitName);
91 if (m_enablePrintOut ==
true) {
92 B2INFO(
"CDCUnpacker: " <<
LogVar(
"FADC threshold", m_fadcThreshold));
96 void CDCUnpackerModule::beginRun()
98 if (m_enablePrintOut ==
true) {
99 B2INFO(
"CDCUnpacker: beginRun() called.");
107 void CDCUnpackerModule::event()
109 if (m_enablePrintOut ==
true) {
110 B2INFO(
"CDCUnpacker: event() started.");
114 int tdcCountTrig = m_tdcOffset;
119 if (m_enableStoreCDCRawHit ==
true) {
120 m_CDCRawHits.clear();
121 m_CDCRawHitWaveForms.clear();
128 const int nEntries = m_rawCDCs.getEntries();
130 B2DEBUG(99,
"nEntries of RawCDCs : " << nEntries);
131 for (
int i = 0; i < nEntries; ++i) {
132 const int subDetectorId = m_rawCDCs[i]->GetNodeID(0);
133 const int iNode = (subDetectorId & 0xFFFFFF);
134 const int nEntriesRawCDC = m_rawCDCs[i]->GetNumEntries();
136 B2DEBUG(99,
LogVar(
"nEntries of rawCDC[i]", nEntriesRawCDC));
137 for (
int j = 0; j < nEntriesRawCDC; ++j) {
138 int trigType = m_rawCDCs[i]->GetTRGType(j);
140 nWords[0] = m_rawCDCs[i]->Get1stDetectorNwords(j);
141 nWords[1] = m_rawCDCs[i]->Get2ndDetectorNwords(j);
142 nWords[2] = m_rawCDCs[i]->Get3rdDetectorNwords(j);
143 nWords[3] = m_rawCDCs[i]->Get4thDetectorNwords(j);
146 data32tab[0] = (
int*)m_rawCDCs[i]->Get1stDetectorBuffer(j);
147 data32tab[1] = (
int*)m_rawCDCs[i]->Get2ndDetectorBuffer(j);
148 data32tab[2] = (
int*)m_rawCDCs[i]->Get3rdDetectorBuffer(j);
149 data32tab[3] = (
int*)m_rawCDCs[i]->Get4thDetectorBuffer(j);
157 for (
int iFiness = 0; iFiness < 4; ++iFiness) {
158 int* ibuf = data32tab[iFiness];
159 const int nWord = nWords[iFiness];
160 B2DEBUG(99,
LogVar(
"nWords (from COPPER header)", nWord));
162 if (m_enablePrintOut ==
true) {
163 B2INFO(
"CDCUnpacker : Print out CDC data block.");
164 printBuffer(ibuf, nWord);
167 const int c_headearWords = 3;
168 if (nWord < c_headearWords) {
169 if (m_enablePrintOut ==
true) {
170 B2WARNING(
"CDCUnpacker : No CDC block header.");
175 if (m_enablePrintOut ==
true) {
176 B2INFO(
"CDCUnpacker : RawDataBlock(CDC) : Block # "
179 <<
LogVar(
"Finness", iFiness));
182 setCDCPacketHeader(ibuf);
184 const int dataType = getDataType();
185 const int dataLength = getDataLength() / 4;
186 const int swDataLength = dataLength * 2;
189 if (dataLength != (nWord - c_headearWords)) {
190 if (m_dataSizeError ==
false) {
191 B2ERROR(
"Inconsistent data size between COPPER and CDC FEE."
192 <<
LogVar(
"data length", dataLength) <<
LogVar(
"nWord", nWord)
193 <<
LogVar(
"Node ID", iNode) <<
LogVar(
"Finness ID", iFiness));
194 m_dataSizeError =
true;
196 B2WARNING(
"Inconsistent data size between COPPER and CDC FEE."
197 <<
LogVar(
"data length", dataLength) <<
LogVar(
"nWord", nWord)
198 <<
LogVar(
"Node ID", iNode) <<
LogVar(
"Finness ID", iFiness));
202 if (m_enablePrintOut ==
true) {
203 B2INFO(
"CDCUnpacker : " <<
LogVar(
"Data size", dataLength));
206 const int board = getBoardId();
207 const int trgNumber = getTriggerNumber();
208 const int trgTime = getTriggerTime();
210 if (m_enablePrintOut ==
true) {
211 B2INFO(
"CDCUnpacker : " <<
LogVar(
"Board", board) <<
LogVar(
"Trigger number", trgNumber)
212 <<
LogVar(
"Trigger time ", trgTime));
220 if (m_enablePrintOut ==
true) {
221 B2INFO(
"CDCUnpacker : Raw data mode.");
226 for (
int it = 0; it < dataLength; ++it) {
227 int index = it + c_headearWords;
229 m_buffer.push_back(
static_cast<unsigned short>((ibuf[index] & 0xffff0000) >> 16));
230 m_buffer.push_back(
static_cast<unsigned short>(ibuf[index] & 0xffff));
233 const int fadcTdcChannels = 48;
234 const int nSamples = swDataLength / (2 * fadcTdcChannels);
236 std::vector<unsigned short> fadcs;
237 std::vector<unsigned short> tdcs;
239 for (
int iCh = 0; iCh < fadcTdcChannels; ++iCh) {
240 const int offset = fadcTdcChannels;
241 unsigned short fadcSum = 0;
242 unsigned short tdc1 = 0x7fff;
243 unsigned short tdc2 = 0x7fff;
245 for (
int iSample = 0; iSample < nSamples; ++iSample) {
248 unsigned short fadc = m_buffer.at(iCh + 2 * fadcTdcChannels * iSample);
250 if (fadc > m_fadcThreshold) {
255 unsigned short tdc = m_buffer.at(iCh + 2 * fadcTdcChannels * iSample + offset) & 0x7fff;
256 unsigned short tdcIsValid = (m_buffer.at(iCh + 2 * fadcTdcChannels * iSample + offset) & 0x8000) >> 15;
257 if (tdcIsValid == 1) {
266 fadcs.push_back(fadc);
268 if (m_enableStoreCDCRawHit ==
true) {
270 const unsigned short status = 0;
271 m_CDCRawHitWaveForms.appendNew(status, trgNumber, iNode, iFiness, board, iCh, iSample, trgTime, fadc, tdc);
276 if (tdc1 != 0x7fff) {
278 const WireID wireId = getWireID(board, iCh);
280 if (trgTime < tdc1) {
281 tdc1 = (trgTime | 0x8000) - tdc1;
283 tdc1 = trgTime - tdc1;
285 CDCHit* firstHit = m_CDCHits.appendNew(tdc1, fadcSum, wireId);
286 if (m_enable2ndHit ==
true) {
287 CDCHit* secondHit = m_CDCHits.appendNew(tdc2, fadcSum, wireId);
296 if (m_enablePrintOut ==
true) {
301 printf(
"FADC ch %2d : ", iCh);
302 for (
int iSample = 0; iSample < nSamples; ++iSample) {
303 printf(
"%4x ", fadcs.at(iSample));
307 printf(
"TDC ch %2d : ", iCh);
308 for (
int iSample = 0; iSample < nSamples; ++iSample) {
309 printf(
"%4x ", tdcs.at(iSample));
316 }
else if (dataType == 2) {
317 if (m_enablePrintOut ==
true) {
318 B2INFO(
"CDCUnpacker : Suppressed mode.");
323 for (
int it = 0; it < dataLength; ++it) {
324 int index = it + c_headearWords;
325 m_buffer.push_back(
static_cast<unsigned short>((ibuf[index] & 0xffff0000) >> 16));
326 m_buffer.push_back(
static_cast<unsigned short>(ibuf[index] & 0xffff));
329 const int bufSize =
static_cast<int>(m_buffer.size());
330 for (
int it = 0; it < bufSize;) {
331 unsigned short header = m_buffer.at(it);
332 unsigned short ch = (header & 0xff00) >> 8;
333 unsigned short length = (header & 0xff) / 2;
335 if (header == 0xff02) {
340 if (!((length == 4) || (length == 5))) {
341 if (m_dataLengthError ==
false) {
342 B2ERROR(
"CDCUnpacker : data length should be 4 or 5 words."
343 <<
LogVar(
"data length", length)
344 <<
LogVar(
"board id", board)
345 <<
LogVar(
"channel", ch));
346 m_dataLengthError =
true;
348 B2WARNING(
"CDCUnpacker : data length should be 4 or 5 words."
349 <<
LogVar(
"data length", length)
350 <<
LogVar(
"board id", board)
351 <<
LogVar(
"channel", ch));
357 unsigned short tot = m_buffer.at(it + 1);
358 unsigned short fadcSum = m_buffer.at(it + 2);
359 if (m_pedestalSubtraction ==
true) {
360 int diff = fadcSum - (*m_adcPedestalFromDB)->getPedestal(board, ch);
361 if (diff <= m_fadcThreshold) {
364 fadcSum =
static_cast<unsigned short>(diff);
367 unsigned short tdc1 = 0;
368 unsigned short tdc2 = 0;
369 unsigned short tdcFlag = 0;
372 tdc1 = m_buffer.at(it + 3);
373 }
else if (length == 5) {
374 tdc1 = m_buffer.at(it + 3);
375 tdc2 = m_buffer.at(it + 4) & 0x7fff;
376 tdcFlag = (m_buffer.at(it + 4) & 0x8000) >> 15;
378 B2ERROR(
"CDCUnpacker : Undefined data length (should be 4 or 5 short words) ");
381 if (m_enablePrintOut ==
true) {
382 printf(
"%4x %4x %4x %4x %4x %4x %4x \n", ch, length, tot, fadcSum, tdc1, tdc2, tdcFlag);
384 if (length == 4 || length == 5) {
387 const unsigned short status = trigType;
389 const WireID wireId = getWireID(board, ch);
391 if (isValidBoardChannel(wireId)) {
392 if (board == m_boardIDTrig && ch == m_channelTrig) {
395 CDCHit* firstHit = m_CDCHits.appendNew(tdc1, fadcSum, wireId,
398 if (m_enable2ndHit ==
true) {
399 CDCHit* secondHit = m_CDCHits.appendNew(tdc2, fadcSum, wireId,
407 if (m_enableStoreCDCRawHit ==
true) {
409 m_CDCRawHits.appendNew(status, trgNumber, iNode, iFiness, board, ch,
410 trgTime, fadcSum, tdc1, tdc2, tot);
414 B2WARNING(
"Undefined board id is fired: " <<
LogVar(
"board id", board) <<
" " <<
LogVar(
"channel", ch));
417 it +=
static_cast<int>(length);
421 B2WARNING(
"CDCUnpacker : Undefined CDC Data Block : Block # " <<
LogVar(
"block id", i));
430 if (m_subtractTrigTiming ==
true) {
431 for (
auto& hit : m_CDCHits) {
432 int tdc = hit.getTDCCount();
433 if (hit.is2ndHit()) {
435 tdc = tdc - (tdcCountTrig - m_tdcOffset);
438 tdc = tdc - (tdcCountTrig - m_tdcOffset);
441 tdc -= m_tdcAuxOffset;
442 hit.setTDCCount(
static_cast<unsigned short>(tdc));
447 void CDCUnpackerModule::endRun()
449 if (m_enablePrintOut ==
true) {
450 B2INFO(
"CDCUnpacker : End run.");
454 void CDCUnpackerModule::terminate()
456 if (m_enablePrintOut ==
true) {
457 B2INFO(
"CDCUnpacker : Terminated.");
460 if (m_channelMapFromDB)
delete m_channelMapFromDB;
461 if (m_adcPedestalFromDB)
delete m_adcPedestalFromDB;
465 WireID CDCUnpackerModule::getWireID(
int iBoard,
int iCh)
const
467 return m_map[iBoard][iCh];
470 void CDCUnpackerModule::loadMap()
473 if (m_enableDatabase ==
false) {
476 std::string fileName = FileSystem::findFile(m_xmlMapFileName);
477 std::cout << fileName << std::endl;
478 if (fileName ==
"") {
479 B2ERROR(
"CDC unpacker can't find a filename: " <<
LogVar(
"file name", fileName));
485 ifs.open(fileName.c_str());
493 ifs >> isl >> icl >> iw >> iBoard >> iCh;
494 const WireID wireId(isl, icl, iw);
495 m_map[iBoard][iCh] = wireId;
498 for (
const auto& cm : (*m_channelMapFromDB)) {
500 const int il = cm.getILayer();
501 const int iw = cm.getIWire();
502 const int iBoard = cm.getBoardID();
503 const int iCh = cm.getBoardChannel();
504 const WireID wireId(isl, il, iw);
505 m_map[iBoard][iCh] = wireId;
510 void CDCUnpackerModule::setADCPedestal()
512 if (m_pedestalSubtraction ==
true) {
514 if (!(*m_adcPedestalFromDB).isValid()) {
515 m_pedestalSubtraction =
false;
521 void CDCUnpackerModule::printBuffer(
int* buf,
int nwords)
524 for (
int j = 0; j < nwords; ++j) {
525 printf(
" %.8x", buf[j]);
526 if ((j + 1) % 10 == 0) {