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);
133 nWords[0] = m_rawCDCs[i]->Get1stDetectorNwords(j);
134 nWords[1] = m_rawCDCs[i]->Get2ndDetectorNwords(j);
135 nWords[2] = m_rawCDCs[i]->Get3rdDetectorNwords(j);
136 nWords[3] = m_rawCDCs[i]->Get4thDetectorNwords(j);
139 data32tab[0] = (
int*)m_rawCDCs[i]->Get1stDetectorBuffer(j);
140 data32tab[1] = (
int*)m_rawCDCs[i]->Get2ndDetectorBuffer(j);
141 data32tab[2] = (
int*)m_rawCDCs[i]->Get3rdDetectorBuffer(j);
142 data32tab[3] = (
int*)m_rawCDCs[i]->Get4thDetectorBuffer(j);
150 for (
int iFiness = 0; iFiness < 4; ++iFiness) {
151 int* ibuf = data32tab[iFiness];
152 const int nWord = nWords[iFiness];
153 B2DEBUG(99,
LogVar(
"nWords (from COPPER header)", nWord));
155 if (m_enablePrintOut ==
true) {
156 B2INFO(
"CDCUnpacker : Print out CDC data block.");
157 printBuffer(ibuf, nWord);
160 const int c_headearWords = 3;
161 if (nWord < c_headearWords) {
162 if (m_enablePrintOut ==
true) {
163 B2WARNING(
"CDCUnpacker : No CDC block header.");
168 if (m_enablePrintOut ==
true) {
169 B2INFO(
"CDCUnpacker : RawDataBlock(CDC) : Block # "
172 <<
LogVar(
"Finness", iFiness));
175 setCDCPacketHeader(ibuf);
177 const int dataType = getDataType();
178 const int dataLength = getDataLength() / 4;
179 const int swDataLength = dataLength * 2;
182 if (dataLength != (nWord - c_headearWords)) {
183 if (m_dataSizeError ==
false) {
184 B2ERROR(
"Inconsistent data size between COPPER and CDC FEE."
185 <<
LogVar(
"data length", dataLength) <<
LogVar(
"nWord", nWord)
186 <<
LogVar(
"Node ID", iNode) <<
LogVar(
"Finness ID", iFiness));
187 m_dataSizeError =
true;
189 B2WARNING(
"Inconsistent data size between COPPER and CDC FEE."
190 <<
LogVar(
"data length", dataLength) <<
LogVar(
"nWord", nWord)
191 <<
LogVar(
"Node ID", iNode) <<
LogVar(
"Finness ID", iFiness));
195 if (m_enablePrintOut ==
true) {
196 B2INFO(
"CDCUnpacker : " <<
LogVar(
"Data size", dataLength));
199 const int board = getBoardId();
200 const int trgNumber = getTriggerNumber();
201 const int trgTime = getTriggerTime();
203 if (m_enablePrintOut ==
true) {
204 B2INFO(
"CDCUnpacker : " <<
LogVar(
"Board", board) <<
LogVar(
"Trigger number", trgNumber)
205 <<
LogVar(
"Trigger time ", trgTime));
213 if (m_enablePrintOut ==
true) {
214 B2INFO(
"CDCUnpacker : Raw data mode.");
219 for (
int it = 0; it < dataLength; ++it) {
220 int index = it + c_headearWords;
222 m_buffer.push_back(
static_cast<unsigned short>((ibuf[index] & 0xffff0000) >> 16));
223 m_buffer.push_back(
static_cast<unsigned short>(ibuf[index] & 0xffff));
226 const int fadcTdcChannels = 48;
227 const int nSamples = swDataLength / (2 * fadcTdcChannels);
229 std::vector<unsigned short> fadcs;
230 std::vector<unsigned short> tdcs;
232 for (
int iCh = 0; iCh < fadcTdcChannels; ++iCh) {
233 const int offset = fadcTdcChannels;
234 unsigned short fadcSum = 0;
235 unsigned short tdc1 = 0x7fff;
236 unsigned short tdc2 = 0x7fff;
238 for (
int iSample = 0; iSample < nSamples; ++iSample) {
241 unsigned short fadc = m_buffer.at(iCh + 2 * fadcTdcChannels * iSample);
243 if (fadc > m_fadcThreshold) {
248 unsigned short tdc = m_buffer.at(iCh + 2 * fadcTdcChannels * iSample + offset) & 0x7fff;
249 unsigned short tdcIsValid = (m_buffer.at(iCh + 2 * fadcTdcChannels * iSample + offset) & 0x8000) >> 15;
250 if (tdcIsValid == 1) {
259 fadcs.push_back(fadc);
261 if (m_enableStoreCDCRawHit ==
true) {
263 const unsigned short status = 0;
264 m_CDCRawHitWaveForms.appendNew(status, trgNumber, iNode, iFiness, board, iCh, iSample, trgTime, fadc, tdc);
269 if (tdc1 != 0x7fff) {
271 const WireID wireId = getWireID(board, iCh);
273 if (trgTime < tdc1) {
274 tdc1 = (trgTime | 0x8000) - tdc1;
276 tdc1 = trgTime - tdc1;
278 CDCHit* firstHit = m_CDCHits.appendNew(tdc1, fadcSum, wireId);
279 if (m_enable2ndHit ==
true) {
280 CDCHit* secondHit = m_CDCHits.appendNew(tdc2, fadcSum, wireId);
289 if (m_enablePrintOut ==
true) {
294 printf(
"FADC ch %2d : ", iCh);
295 for (
int iSample = 0; iSample < nSamples; ++iSample) {
296 printf(
"%4x ", fadcs.at(iSample));
300 printf(
"TDC ch %2d : ", iCh);
301 for (
int iSample = 0; iSample < nSamples; ++iSample) {
302 printf(
"%4x ", tdcs.at(iSample));
309 }
else if (dataType == 2) {
310 if (m_enablePrintOut ==
true) {
311 B2INFO(
"CDCUnpacker : Suppressed mode.");
316 for (
int it = 0; it < dataLength; ++it) {
317 int index = it + c_headearWords;
318 m_buffer.push_back(
static_cast<unsigned short>((ibuf[index] & 0xffff0000) >> 16));
319 m_buffer.push_back(
static_cast<unsigned short>(ibuf[index] & 0xffff));
322 const int bufSize =
static_cast<int>(m_buffer.size());
323 for (
int it = 0; it < bufSize;) {
324 unsigned short header = m_buffer.at(it);
325 unsigned short ch = (header & 0xff00) >> 8;
326 unsigned short length = (header & 0xff) / 2;
328 if (header == 0xff02) {
333 if (!((length == 4) || (length == 5))) {
334 if (m_dataLengthError ==
false) {
335 B2ERROR(
"CDCUnpacker : data length should be 4 or 5 words."
336 <<
LogVar(
"data length", length)
337 <<
LogVar(
"board id", board)
338 <<
LogVar(
"channel", ch));
339 m_dataLengthError =
true;
341 B2WARNING(
"CDCUnpacker : data length should be 4 or 5 words."
342 <<
LogVar(
"data length", length)
343 <<
LogVar(
"board id", board)
344 <<
LogVar(
"channel", ch));
350 unsigned short tot = m_buffer.at(it + 1);
351 unsigned short fadcSum = m_buffer.at(it + 2);
352 if (m_pedestalSubtraction ==
true) {
353 int diff = fadcSum - (*m_adcPedestalFromDB)->getPedestal(board, ch);
354 if (diff <= m_fadcThreshold) {
357 fadcSum =
static_cast<unsigned short>(diff);
360 unsigned short tdc1 = 0;
361 unsigned short tdc2 = 0;
362 unsigned short tdcFlag = 0;
365 tdc1 = m_buffer.at(it + 3);
366 }
else if (length == 5) {
367 tdc1 = m_buffer.at(it + 3);
368 tdc2 = m_buffer.at(it + 4) & 0x7fff;
369 tdcFlag = (m_buffer.at(it + 4) & 0x8000) >> 15;
371 B2ERROR(
"CDCUnpacker : Undefined data length (should be 4 or 5 short words) ");
374 if (m_enablePrintOut ==
true) {
375 printf(
"%4x %4x %4x %4x %4x %4x %4x \n", ch, length, tot, fadcSum, tdc1, tdc2, tdcFlag);
377 if (length == 4 || length == 5) {
380 const unsigned short status = trigType;
382 const WireID wireId = getWireID(board, ch);
384 if (isValidBoardChannel(wireId)) {
385 if (board == m_boardIDTrig && ch == m_channelTrig) {
388 CDCHit* firstHit = m_CDCHits.appendNew(tdc1, fadcSum, wireId,
391 if (m_enable2ndHit ==
true) {
392 CDCHit* secondHit = m_CDCHits.appendNew(tdc2, fadcSum, wireId,
400 if (m_enableStoreCDCRawHit ==
true) {
402 m_CDCRawHits.appendNew(status, trgNumber, iNode, iFiness, board, ch,
403 trgTime, fadcSum, tdc1, tdc2, tot);
407 B2WARNING(
"Undefined board id is fired: " <<
LogVar(
"board id", board) <<
" " <<
LogVar(
"channel", ch));
410 it +=
static_cast<int>(length);
414 B2WARNING(
"CDCUnpacker : Undefined CDC Data Block : Block # " <<
LogVar(
"block id", i));
423 if (m_subtractTrigTiming ==
true) {
424 for (
auto& hit : m_CDCHits) {
425 int tdc = hit.getTDCCount();
426 if (hit.is2ndHit()) {
428 tdc = tdc - (tdcCountTrig - m_tdcOffset);
431 tdc = tdc - (tdcCountTrig - m_tdcOffset);
434 tdc -= m_tdcAuxOffset;
435 hit.setTDCCount(
static_cast<unsigned short>(tdc));
440 void CDCUnpackerModule::endRun()
442 if (m_enablePrintOut ==
true) {
443 B2INFO(
"CDCUnpacker : End run.");
447 void CDCUnpackerModule::terminate()
449 if (m_enablePrintOut ==
true) {
450 B2INFO(
"CDCUnpacker : Terminated.");
453 if (m_channelMapFromDB)
delete m_channelMapFromDB;
454 if (m_adcPedestalFromDB)
delete m_adcPedestalFromDB;
458 WireID CDCUnpackerModule::getWireID(
int iBoard,
int iCh)
const
460 return m_map[iBoard][iCh];
463 void CDCUnpackerModule::loadMap()
466 if (m_enableDatabase ==
false) {
469 std::string fileName = FileSystem::findFile(m_xmlMapFileName);
470 std::cout << fileName << std::endl;
471 if (fileName ==
"") {
472 B2ERROR(
"CDC unpacker can't find a filename: " <<
LogVar(
"file name", fileName));
478 ifs.open(fileName.c_str());
486 ifs >> isl >> icl >> iw >> iBoard >> iCh;
487 const WireID wireId(isl, icl, iw);
488 m_map[iBoard][iCh] = wireId;
491 for (
const auto& cm : (*m_channelMapFromDB)) {
493 const int il = cm.getILayer();
494 const int iw = cm.getIWire();
495 const int iBoard = cm.getBoardID();
496 const int iCh = cm.getBoardChannel();
497 const WireID wireId(isl, il, iw);
498 m_map[iBoard][iCh] = wireId;
503 void CDCUnpackerModule::setADCPedestal()
505 if (m_pedestalSubtraction ==
true) {
507 if (!(*m_adcPedestalFromDB).isValid()) {
508 m_pedestalSubtraction =
false;
514 void CDCUnpackerModule::printBuffer(
int* buf,
int nwords)
517 for (
int j = 0; j < nwords; ++j) {
518 printf(
" %.8x", buf[j]);
519 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.