12 #include <klm/modules/KLMUnpacker/KLMUnpackerModule.h>
15 #include <klm/dataobjects/bklm/BKLMElementNumbers.h>
16 #include <klm/dataobjects/KLMScintillatorFirmwareFitResult.h>
17 #include <klm/rawdata/RawData.h>
20 #include <framework/logging/Logger.h>
27 using namespace Belle2::KLM;
33 m_triggerCTimeOfPreviousEvent(0),
36 setDescription(
"KLM unpacker (creates KLMDigits from RawKLM).");
37 setPropertyFlags(c_ParallelProcessingCertified);
38 addParam(
"outputKLMDigitsName", m_outputKLMDigitsName,
39 "Name of KLMDigit store array.",
string(
""));
40 addParam(
"WriteDigitRaws", m_WriteDigitRaws,
41 "Record raw data in dataobject format (e.g. for debugging).",
false);
42 addParam(
"WriteWrongHits", m_WriteWrongHits,
43 "Record wrong hits (e.g. for debugging).",
false);
44 addParam(
"DebugElectronicsMap", m_DebugElectronicsMap,
45 "Debug electronics map (record DAQ channel instead of strip).",
47 addParam(
"DAQChannelBKLMScintillators", m_DAQChannelBKLMScintillators,
48 "Record DAQ channel for BKLM scintillators.",
false);
49 addParam(
"DAQChannelModule", m_DAQChannelModule,
50 "Record DAQ channel for specific module.", -1);
51 addParam(
"IgnoreWrongHits", m_IgnoreWrongHits,
52 "Ignore wrong hits (i.e. no B2ERROR).",
false);
53 addParam(
"IgnoreStrip0", m_IgnoreStrip0,
54 "Ignore hits with strip = 0 (normally expected for certain firmware "
56 addParam(
"keepEvenPackages", m_keepEvenPackages,
57 "Keep packages that have even length normally indicating that "
58 "data was corrupted ",
false);
59 addParam(
"SciThreshold", m_scintThreshold,
60 "Scintillator strip hits with charge lower this value will be "
61 "marked as bad.",
double(140.0));
62 addParam(
"loadThresholdFromDB", m_loadThresholdFromDB,
63 "Load threshold from database (true) or not (false)",
true);
66 KLMUnpackerModule::~KLMUnpackerModule()
70 void KLMUnpackerModule::initialize()
72 m_RawKLMs.isRequired();
74 m_Digits.registerInDataStore(m_outputKLMDigitsName);
75 m_klmDigitsOutOfRange.registerInDataStore(
"KLMDigitsOutOfRange");
77 m_DigitEventInfos.registerInDataStore();
78 m_Digits.registerRelationTo(m_DigitEventInfos);
79 m_klmDigitsOutOfRange.registerRelationTo(m_DigitEventInfos);
81 if (m_WriteDigitRaws) {
82 m_klmDigitRaws.registerInDataStore();
83 m_Digits.registerRelationTo(m_klmDigitRaws);
84 m_klmDigitsOutOfRange.registerRelationTo(m_klmDigitRaws);
88 void KLMUnpackerModule::beginRun()
90 if (!m_ElectronicsMap.isValid())
91 B2FATAL(
"KLM electronics map is not available.");
92 if (!m_TimeConversion.isValid())
93 B2FATAL(
"EKLM time conversion parameters are not available.");
94 if (!m_eklmChannels.isValid())
95 B2FATAL(
"EKLM channel data are not available.");
96 if (m_loadThresholdFromDB) {
97 if (!m_bklmADCParams.isValid())
98 B2FATAL(
"BKLM ADC threshold paramenters are not available.");
99 m_scintThreshold = m_bklmADCParams->getADCThreshold();
101 m_triggerCTimeOfPreviousEvent = 0;
104 void KLMUnpackerModule::createDigit(
107 int sector,
int layer,
int plane,
int strip,
int lastStrip)
109 KLMDigit* klmDigit = m_Digits.appendNew();
111 if (m_WriteDigitRaws)
113 bool isRPC = (subdetector == KLMElementNumbers::c_BKLM) &&
114 (layer >= BKLMElementNumbers::c_FirstRPCLayer);
125 std::pair<int, double> rpcTimes =
126 m_TimeConversion->getRPCTimes(raw->getCTime(), raw->getTDC(),
128 klmDigit->
setTime(rpcTimes.second);
135 double time = m_TimeConversion->getScintillatorTime(
138 if (subdetector == KLMElementNumbers::c_BKLM) {
139 if (raw->getCharge() < m_scintThreshold)
140 klmDigit->
setFitStatus(KLM::c_ScintillatorFirmwareSuccessfulFit);
142 klmDigit->
setFitStatus(KLM::c_ScintillatorFirmwareNoSignal);
144 int stripGlobal = m_eklmElementNumbers->stripNumber(
145 section, layer, sector, plane, strip);
147 m_eklmChannels->getChannelData(stripGlobal);
148 if (channelData ==
nullptr)
149 B2FATAL(
"Incomplete EKLM channel data.");
151 klmDigit->
setFitStatus(KLM::c_ScintillatorFirmwareSuccessfulFit);
153 klmDigit->
setFitStatus(KLM::c_ScintillatorFirmwareNoSignal);
165 klmDigit->
setCTime(raw->getCTime());
166 klmDigit->
setTDC(raw->getTDC());
169 void KLMUnpackerModule::unpackKLMDigit(
170 const int* rawData,
int copper,
int hslb,
int daqSubdetector,
175 &m_klmDigitRaws, &klmDigitRaw, m_WriteDigitRaws);
176 const uint16_t* detectorChannel;
177 int subdetector, section, sector, layer, plane, strip;
179 std::vector<ChannelGroup> channelGroups;
180 raw.getChannelGroups(channelGroups);
183 copper, hslb + 1, raw.getLane(), raw.getAxis(), raw.getChannel());
184 bool channelFound =
false;
186 if (channelGroup.lastChannel == 0) {
189 m_ElectronicsMap->getDetectorChannel(&electronicsChannel);
190 if (detectorChannel !=
nullptr) {
193 m_ElementNumbers->channelNumberToElementNumbers(
194 *detectorChannel, &subdetector, §ion, §or, &layer, &plane,
196 channelGroup.firstStrip = strip;
197 channelGroup.lastStrip = 0;
200 if (!(m_IgnoreWrongHits || (raw.getChannel() == 0 && m_IgnoreStrip0))) {
201 if (daqSubdetector == KLMElementNumbers::c_BKLM) {
202 B2DEBUG(20,
"Channel does not exist in the KLM electronics map."
209 B2ERROR(
"Channel does not exist in the KLM electronics map."
220 if (m_DebugElectronicsMap)
227 bool firstMatchedChannel =
true;
228 for (
int channel = channelGroup.firstChannel;
229 channel <= channelGroup.lastChannel; ++channel) {
232 m_ElectronicsMap->getDetectorChannel(&electronicsChannel);
234 if (detectorChannel !=
nullptr) {
236 m_ElementNumbers->channelNumberToElementNumbers(
237 *detectorChannel, &subdetector, §ion, §or, &layer, &plane,
239 if (firstMatchedChannel) {
240 firstMatchedChannel =
false;
241 channelGroup.firstStrip = strip;
242 channelGroup.lastStrip = 0;
244 channelGroup.lastStrip = strip;
249 if (firstMatchedChannel) {
250 B2DEBUG(20,
"No matching channels exist in the KLM electronics map."
255 <<
LogVar(
"First channel", channelGroup.firstChannel)
256 <<
LogVar(
"Last channel", channelGroup.lastChannel)
257 <<
LogVar(
"Trigger bits", raw.getTriggerBits()));
263 if (!(m_WriteWrongHits || m_DebugElectronicsMap))
270 detectorChannel = m_ElectronicsMap->getDetectorChannel(&electronicsChannel);
271 if (detectorChannel ==
nullptr)
274 m_ElementNumbers->channelNumberToElementNumbers(
275 *detectorChannel, &subdetector, §ion, §or, &layer, &plane,
277 if (m_WriteWrongHits) {
280 m_klmDigitsOutOfRange.appendNew();
282 if (m_WriteDigitRaws)
286 klmDigitOutOfRange->
setLayer(layer);
288 klmDigitOutOfRange->
setPlane(plane);
289 klmDigitOutOfRange->
setStrip(strip);
290 klmDigitOutOfRange->
setCharge(raw.getCharge());
291 klmDigitOutOfRange->
setCTime(raw.getCTime());
292 klmDigitOutOfRange->
setTDC(raw.getTDC());
297 if (m_DebugElectronicsMap) {
298 if (m_DAQChannelBKLMScintillators) {
299 if ((subdetector == KLMElementNumbers::c_BKLM) &&
300 (layer < BKLMElementNumbers::c_FirstRPCLayer))
301 strip = raw.getChannel();
303 if (m_DAQChannelModule >= 0) {
305 m_ElementNumbers->moduleNumberByChannel(*detectorChannel);
306 if (klmModule == m_DAQChannelModule)
307 strip = raw.getChannel();
311 for (
const ChannelGroup& channelGroup : channelGroups) {
312 if (channelGroup.firstStrip != 0) {
313 createDigit(&raw, klmDigitRaw, klmDigitEventInfo, subdetector, section,
314 sector, layer, plane, channelGroup.firstStrip,
315 channelGroup.lastStrip);
320 void KLMUnpackerModule::event()
326 const int hitLength = 2;
327 for (
int i = 0; i < m_RawKLMs.getEntries(); i++) {
328 if (m_RawKLMs[i]->GetNumEvents() != 1) {
329 B2ERROR(
"RawKLM a wrong number of entries (should be 1)."
330 <<
LogVar(
"RawKLM index", i)
331 <<
LogVar(
"Number of entries", m_RawKLMs[i]->GetNumEvents()));
338 for (
int j = 0; j < m_RawKLMs[i]->GetNumEntries(); j++) {
339 unsigned int copperId = m_RawKLMs[i]->GetNodeID(j);
341 if ((copperId >= EKLM_ID) && (copperId <= EKLM_ID + 4))
342 subdetector = KLMElementNumbers::c_EKLM;
343 else if ((copperId >= BKLM_ID) && (copperId <= BKLM_ID + 4))
344 subdetector = KLMElementNumbers::c_BKLM;
347 m_RawKLMs[i]->GetBuffer(j);
348 for (
int hslb = 0; hslb < 4; hslb++) {
350 m_DigitEventInfos.appendNew(m_RawKLMs[i], j);
352 m_triggerCTimeOfPreviousEvent);
354 int numDetNwords = m_RawKLMs[i]->GetDetectorNwords(j, hslb);
355 int* hslbBuffer = m_RawKLMs[i]->GetDetectorBuffer(j, hslb);
356 int numHits = numDetNwords / hitLength;
357 if (numDetNwords % hitLength != 1 && numDetNwords != 0) {
358 B2ERROR(
"Incorrect number of data words."
359 <<
LogVar(
"Number of data words", numDetNwords));
360 if (!m_keepEvenPackages)
363 if (numDetNwords > 0) {
368 unsigned int revo9TriggerWord =
369 (hslbBuffer[numDetNwords - 1] >> 16) & 0xFFFF;
371 unsigned int userWord = hslbBuffer[numDetNwords - 1] & 0xFFFF;
377 for (
int iHit = 0; iHit < numHits; iHit++) {
378 unpackKLMDigit(&hslbBuffer[iHit * hitLength], copperId, hslb,
379 subdetector, klmDigitEventInfo);
386 void KLMUnpackerModule::endRun()
390 void KLMUnpackerModule::terminate()