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/datastore/RelationArray.h>
21 #include <framework/logging/Logger.h>
22 #include <framework/utilities/FileSystem.h>
24 #include <framework/database/DBArray.h>
44 setDescription(
"CDCUnpacker generates CDCHit from Raw data.");
45 setPropertyFlags(c_ParallelProcessingCertified);
47 addParam(
"rawCDCName", m_rawCDCName,
"Name of the RawCDC List name..",
string(
""));
48 addParam(
"cdcRawHitWaveFormName", m_cdcRawHitWaveFormName,
"Name of the CDCRawHit (Raw data mode).",
string(
""));
49 addParam(
"cdcRawHitName", m_cdcRawHitName,
"Name of the CDCRawHit (Suppressed mode).",
string(
""));
50 addParam(
"cdcHitName", m_cdcHitName,
"Name of the CDCHit List name..",
string(
""));
51 addParam(
"fadcThreshold", m_fadcThreshold,
"Threshold count.", 1);
53 addParam(
"xmlMapFileName", m_xmlMapFileName,
"path+name of the xml file",
string(
""));
54 addParam(
"enableStoreCDCRawHit", m_enableStoreCDCRawHit,
"Enable to store to the CDCRawHit object",
false);
55 addParam(
"enablePrintOut", m_enablePrintOut,
"Enable to print out the data to the terminal",
false);
56 addParam(
"boardIDTrig", m_boardIDTrig,
"Board ID for the trigger.", 7);
57 addParam(
"channelTrig", m_channelTrig,
"Channel for the trigger.", 1);
58 addParam(
"subtractTrigTiming", m_subtractTrigTiming,
"Enable to subtract the trigger timing from TDCs.",
false);
59 addParam(
"tdcOffset", m_tdcOffset,
"TDC offset (in TDC count).", 0);
60 addParam(
"enableDatabase", m_enableDatabase,
"Enable database to read the channel map.",
true);
61 addParam(
"enable2ndHit", m_enable2ndHit,
"Enable 2nd hit timing as a individual CDCHit object.",
false);
62 addParam(
"tdcAuxOffset", m_tdcAuxOffset,
"TDC auxiliary offset (in TDC count).", 0);
63 addParam(
"pedestalSubtraction", m_pedestalSubtraction,
"Enbale ADC pedestal subtraction.", m_pedestalSubtraction);
67 CDCUnpackerModule::~CDCUnpackerModule()
71 void CDCUnpackerModule::initialize()
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);
88 storeCDCRawHitWFs.registerInDataStore();
91 storeCDCRawHits.registerInDataStore();
94 storeDigit.registerInDataStore();
101 m_relCDCRawHitToCDCHitName = DataStore::relationName(
102 DataStore::arrayName<CDCRawHit>(m_cdcRawHitName),
103 DataStore::arrayName<CDCHit>(m_cdcHitName));
105 m_relCDCRawHitWFToCDCHitName = DataStore::relationName(
106 DataStore::arrayName<CDCRawHitWaveForm>(m_cdcRawHitWaveFormName),
107 DataStore::arrayName<CDCHit>(m_cdcHitName));
109 if (m_enablePrintOut ==
true) {
110 B2INFO(
"CDCUnpacker: FADC threshold: " << m_fadcThreshold);
114 void CDCUnpackerModule::beginRun()
116 if (m_enablePrintOut ==
true) {
117 B2INFO(
"CDCUnpacker: beginRun() called.");
125 void CDCUnpackerModule::event()
127 if (m_enablePrintOut ==
true) {
128 B2INFO(
"CDCUnpacker: event() started.");
132 int tdcCountTrig = m_tdcOffset;
141 RelationArray rawCDCsToCDCHits(cdcRawHits, cdcHits, m_relCDCRawHitToCDCHitName);
142 RelationArray rawCDCWFsToCDCHits(cdcRawHitWFs, cdcHits, m_relCDCRawHitWFToCDCHitName);
144 if (m_enableStoreCDCRawHit ==
true) {
146 cdcRawHitWFs.
clear();
153 const int nEntries = m_rawCDCs.getEntries();
155 B2DEBUG(99,
"nEntries of RawCDCs : " << nEntries);
156 for (
int i = 0; i < nEntries; ++i) {
157 const int subDetectorId = m_rawCDCs[i]->GetNodeID(0);
158 const int iNode = (subDetectorId & 0xFFFFFF);
159 const int nEntriesRawCDC = m_rawCDCs[i]->GetNumEntries();
161 B2DEBUG(99,
"nEntries of rawCDC[i] : " << nEntriesRawCDC);
162 for (
int j = 0; j < nEntriesRawCDC; ++j) {
163 int trigType = m_rawCDCs[i]->GetTRGType(j);
165 nWords[0] = m_rawCDCs[i]->Get1stDetectorNwords(j);
166 nWords[1] = m_rawCDCs[i]->Get2ndDetectorNwords(j);
167 nWords[2] = m_rawCDCs[i]->Get3rdDetectorNwords(j);
168 nWords[3] = m_rawCDCs[i]->Get4thDetectorNwords(j);
171 data32tab[0] = (
int*)m_rawCDCs[i]->Get1stDetectorBuffer(j);
172 data32tab[1] = (
int*)m_rawCDCs[i]->Get2ndDetectorBuffer(j);
173 data32tab[2] = (
int*)m_rawCDCs[i]->Get3rdDetectorBuffer(j);
174 data32tab[3] = (
int*)m_rawCDCs[i]->Get4thDetectorBuffer(j);
182 for (
int iFiness = 0; iFiness < 4; ++iFiness) {
183 int* ibuf = data32tab[iFiness];
184 const int nWord = nWords[iFiness];
185 B2DEBUG(99,
"nWords (from COPPER header) : " << nWord);
187 if (m_enablePrintOut ==
true) {
188 B2INFO(
"CDCUnpacker : Print out CDC data block.");
189 printBuffer(ibuf, nWord);
192 const int c_headearWords = 3;
193 if (nWord < c_headearWords) {
194 if (m_enablePrintOut ==
true) {
195 B2WARNING(
"CDCUnpacker : No CDC block header.");
200 if (m_enablePrintOut ==
true) {
201 B2INFO(
"CDCUnpacker : RawDataBlock(CDC) : Block # " << i);
202 B2INFO(
"CDCUnpacker : Node ID " << iNode <<
", Finness ID " << iFiness);
205 setCDCPacketHeader(ibuf);
207 const int dataType = getDataType();
208 const int dataLength = getDataLength() / 4;
209 const int swDataLength = dataLength * 2;
212 if (dataLength != (nWord - c_headearWords)) {
213 B2ERROR(
"Inconsistent data size between COPPER and CDC FEE."
214 <<
LogVar(
"data length", dataLength) <<
LogVar(
"nWord", nWord)
215 <<
LogVar(
"Node ID", iNode) <<
LogVar(
"Finness ID", iFiness));
219 if (m_enablePrintOut ==
true) {
220 B2INFO(
"CDCUnpacker : Data size " << dataLength <<
" words.");
223 const int board = getBoardId();
224 const int trgNumber = getTriggerNumber();
225 const int trgTime = getTriggerTime();
227 if (m_enablePrintOut ==
true) {
228 B2INFO(
"CDCUnpacker : Board ID " << board <<
", Trigger number " << trgNumber <<
", Trigger time " << trgTime);
236 if (m_enablePrintOut ==
true) {
237 B2INFO(
"CDCUnpacker : Raw data mode.");
242 for (
int it = 0; it < dataLength; ++it) {
243 int index = it + c_headearWords;
245 m_buffer.push_back(
static_cast<unsigned short>((ibuf[index] & 0xffff0000) >> 16));
246 m_buffer.push_back(
static_cast<unsigned short>(ibuf[index] & 0xffff));
249 const int fadcTdcChannels = 48;
250 const int nSamples = swDataLength / (2 * fadcTdcChannels);
252 std::vector<unsigned short> fadcs;
253 std::vector<unsigned short> tdcs;
255 for (
int iCh = 0; iCh < fadcTdcChannels; ++iCh) {
256 const int offset = fadcTdcChannels;
257 unsigned short fadcSum = 0;
258 unsigned short tdc1 = 0x7fff;
259 unsigned short tdc2 = 0x7fff;
261 for (
int iSample = 0; iSample < nSamples; ++iSample) {
264 unsigned short fadc = m_buffer.at(iCh + 2 * fadcTdcChannels * iSample);
266 if (fadc > m_fadcThreshold) {
271 unsigned short tdc = m_buffer.at(iCh + 2 * fadcTdcChannels * iSample + offset) & 0x7fff;
272 unsigned short tdcIsValid = (m_buffer.at(iCh + 2 * fadcTdcChannels * iSample + offset) & 0x8000) >> 15;
273 if (tdcIsValid == 1) {
282 fadcs.push_back(fadc);
284 if (m_enableStoreCDCRawHit ==
true) {
286 const unsigned short status = 0;
287 cdcRawHitWFs.
appendNew(status, trgNumber, iNode, iFiness, board, iCh, iSample, trgTime, fadc, tdc);
292 if (tdc1 != 0x7fff) {
294 const WireID wireId = getWireID(board, iCh);
296 if (trgTime < tdc1) {
297 tdc1 = (trgTime | 0x8000) - tdc1;
299 tdc1 = trgTime - tdc1;
302 if (m_enable2ndHit ==
true) {
307 if (m_enableStoreCDCRawHit ==
true) {
308 for (
int iSample = 0; iSample < nSamples; ++iSample) {
309 cdcHits[cdcHits.
getEntries() - 1]->addRelationTo(cdcRawHitWFs[cdcRawHitWFs.
getEntries() - 1 + iSample - (nSamples - 1) ]);
317 if (m_enablePrintOut ==
true) {
322 printf(
"FADC ch %2d : ", iCh);
323 for (
int iSample = 0; iSample < nSamples; ++iSample) {
324 printf(
"%4x ", fadcs.at(iSample));
328 printf(
"TDC ch %2d : ", iCh);
329 for (
int iSample = 0; iSample < nSamples; ++iSample) {
330 printf(
"%4x ", tdcs.at(iSample));
337 }
else if (dataType == 2) {
338 if (m_enablePrintOut ==
true) {
339 B2INFO(
"CDCUnpacker : Suppressed mode.");
344 for (
int it = 0; it < dataLength; ++it) {
345 int index = it + c_headearWords;
346 m_buffer.push_back(
static_cast<unsigned short>((ibuf[index] & 0xffff0000) >> 16));
347 m_buffer.push_back(
static_cast<unsigned short>(ibuf[index] & 0xffff));
350 const int bufSize =
static_cast<int>(m_buffer.size());
351 for (
int it = 0; it < bufSize;) {
352 unsigned short header = m_buffer.at(it);
353 unsigned short ch = (header & 0xff00) >> 8;
354 unsigned short length = (header & 0xff) / 2;
356 if (header == 0xff02) {
361 if (!((length == 4) || (length == 5))) {
362 B2ERROR(
"CDCUnpacker : data length should be 4 or 5 words.");
363 B2ERROR(
"CDCUnpacker : length " <<
LogVar(
"data length", length) <<
" words.");
364 B2ERROR(
"board= " <<
LogVar(
"board id", board) <<
" ch= " <<
LogVar(
"channel", ch));
369 unsigned short tot = m_buffer.at(it + 1);
370 unsigned short fadcSum = m_buffer.at(it + 2);
371 if (m_pedestalSubtraction ==
true) {
372 int diff = fadcSum - (*m_adcPedestalFromDB)->getPedestal(board, ch);
373 if (diff <= m_fadcThreshold) {
376 fadcSum =
static_cast<unsigned short>(diff);
379 unsigned short tdc1 = 0;
380 unsigned short tdc2 = 0;
381 unsigned short tdcFlag = 0;
384 tdc1 = m_buffer.at(it + 3);
385 }
else if (length == 5) {
386 tdc1 = m_buffer.at(it + 3);
387 tdc2 = m_buffer.at(it + 4) & 0x7fff;
388 tdcFlag = (m_buffer.at(it + 4) & 0x8000) >> 15;
390 B2ERROR(
"CDCUnpacker : Undefined data length (should be 4 or 5 short words) ");
393 if (m_enablePrintOut ==
true) {
394 printf(
"%4x %4x %4x %4x %4x %4x %4x \n", ch, length, tot, fadcSum, tdc1, tdc2, tdcFlag);
396 if (length == 4 || length == 5) {
399 const unsigned short status = trigType;
401 const WireID wireId = getWireID(board, ch);
403 if (isValidBoardChannel(wireId)) {
404 if (board == m_boardIDTrig && ch == m_channelTrig) {
410 if (m_enable2ndHit ==
true) {
419 if (m_enableStoreCDCRawHit ==
true) {
421 CDCRawHit* rawHit = cdcRawHits.
appendNew(status, trgNumber, iNode, iFiness, board, ch,
422 trgTime, fadcSum, tdc1, tdc2, tot);
423 cdcHits[cdcHits.
getEntries() - 1]->addRelationTo(rawHit);
424 if (m_enable2ndHit ==
true) {
425 cdcHits[cdcHits.
getEntries() - 2]->addRelationTo(rawHit);
430 B2WARNING(
"Undefined board id is fired: " <<
LogVar(
"board id", board) <<
" " <<
LogVar(
"channel", ch));
433 it +=
static_cast<int>(length);
437 B2WARNING(
"CDCUnpacker : Undefined CDC Data Block : Block # " <<
LogVar(
"block id", i));
446 if (m_subtractTrigTiming ==
true) {
447 for (
auto& hit : cdcHits) {
448 int tdc = hit.getTDCCount();
449 if (hit.is2ndHit()) {
451 tdc = tdc - (tdcCountTrig - m_tdcOffset);
454 tdc = tdc - (tdcCountTrig - m_tdcOffset);
457 tdc -= m_tdcAuxOffset;
458 hit.setTDCCount(
static_cast<unsigned short>(tdc));
463 void CDCUnpackerModule::endRun()
465 if (m_enablePrintOut ==
true) {
466 B2INFO(
"CDCUnpacker : End run.");
470 void CDCUnpackerModule::terminate()
472 if (m_enablePrintOut ==
true) {
473 B2INFO(
"CDCUnpacker : Terminated.");
476 if (m_channelMapFromDB)
delete m_channelMapFromDB;
477 if (m_adcPedestalFromDB)
delete m_adcPedestalFromDB;
481 WireID CDCUnpackerModule::getWireID(
int iBoard,
int iCh)
const
483 return m_map[iBoard][iCh];
486 void CDCUnpackerModule::loadMap()
489 if (m_enableDatabase ==
false) {
492 std::string fileName = FileSystem::findFile(m_xmlMapFileName);
493 std::cout << fileName << std::endl;
494 if (fileName ==
"") {
495 B2ERROR(
"CDC unpacker can't find a filename: " <<
LogVar(
"file name", fileName));
501 ifs.open(fileName.c_str());
509 ifs >> isl >> icl >> iw >> iBoard >> iCh;
510 const WireID wireId(isl, icl, iw);
511 m_map[iBoard][iCh] = wireId;
514 for (
const auto& cm : (*m_channelMapFromDB)) {
516 const int il = cm.getILayer();
517 const int iw = cm.getIWire();
518 const int iBoard = cm.getBoardID();
519 const int iCh = cm.getBoardChannel();
520 const WireID wireId(isl, il, iw);
521 m_map[iBoard][iCh] = wireId;
526 void CDCUnpackerModule::setADCPedestal()
528 if (m_pedestalSubtraction ==
true) {
530 if (!(*m_adcPedestalFromDB).isValid()) {
531 m_pedestalSubtraction =
false;
537 void CDCUnpackerModule::printBuffer(
int* buf,
int nwords)
540 for (
int j = 0; j < nwords; ++j) {
541 printf(
" %.8x", buf[j]);
542 if ((j + 1) % 10 == 0) {