10#include <klm/modules/KLMUnpacker/KLMUnpackerModule.h>
13#include <klm/dataobjects/bklm/BKLMElementNumbers.h>
14#include <klm/dataobjects/KLMScintillatorFirmwareFitResult.h>
15#include <klm/rawdata/RawData.h>
18#include <framework/logging/Logger.h>
21using namespace Belle2::KLM;
33 "Name of KLMDigit store array.", std::string(
""));
35 "Record raw data in dataobject format (e.g. for debugging).",
false);
37 "Record wrong hits (e.g. for debugging).",
false);
39 "Debug electronics map (record DAQ channel instead of strip).",
42 "Record DAQ channel for BKLM scintillators.",
false);
44 "Record DAQ channel for specific module.", -1);
46 "Ignore wrong hits (i.e. no B2ERROR).",
false);
48 "Ignore hits with strip = 0 (normally expected for certain firmware "
51 "Keep packages that have even length normally indicating that "
52 "data was corrupted ",
false);
80 B2FATAL(
"KLM electronics map is not available.");
82 B2FATAL(
"KLM scintillator FEE parameters are not available.");
90 int sector,
int layer,
int plane,
int strip,
int lastStrip)
108 std::pair<int, double> rpcTimes =
109 m_Time->getRPCTimes(raw->getCTime(), raw->getTDC(), triggerTime);
110 klmDigit->
setTime(rpcTimes.second);
120 if (raw->getType() == 0x4) {
121 time =
m_Time->getScintillatorTime(raw->getCTime(), 0,
124 time =
m_Time->getScintillatorTime(raw->getCTime(), raw->getTDC(),
131 if (FEEData ==
nullptr)
132 B2FATAL(
"Incomplete KLM scintillator FEE data.");
134 klmDigit->
setFitStatus(KLM::c_ScintillatorFirmwareSuccessfulFit);
136 klmDigit->
setFitStatus(KLM::c_ScintillatorFirmwareNoSignal);
147 klmDigit->
setCTime(raw->getCTime());
148 klmDigit->
setTDC(raw->getTDC());
152 const int* rawData,
int copper,
int hslb,
int daqSubdetector,
159 int subdetector, section, sector, layer, plane, strip;
161 std::vector<ChannelGroup> channelGroups;
162 raw.getChannelGroups(channelGroups);
165 copper, hslb + 1, raw.getLane(), raw.getAxis(), raw.getChannel());
166 bool channelFound =
false;
168 if (channelGroup.lastChannel == 0) {
172 if (detectorChannel !=
nullptr) {
176 *detectorChannel, &subdetector, §ion, §or, &layer, &plane,
178 channelGroup.firstStrip = strip;
179 channelGroup.lastStrip = 0;
184 B2DEBUG(20,
"Channel does not exist in the KLM electronics map."
191 B2ERROR(
"Channel does not exist in the KLM electronics map."
209 bool firstMatchedChannel =
true;
210 for (
int channel = channelGroup.firstChannel;
211 channel <= channelGroup.lastChannel; ++channel) {
216 if (detectorChannel !=
nullptr) {
219 *detectorChannel, &subdetector, §ion, §or, &layer, &plane,
221 if (firstMatchedChannel) {
222 firstMatchedChannel =
false;
223 channelGroup.firstStrip = strip;
224 channelGroup.lastStrip = 0;
226 channelGroup.lastStrip = strip;
231 if (firstMatchedChannel) {
232 B2DEBUG(20,
"No matching channels exist in the KLM electronics map."
237 <<
LogVar(
"First channel", channelGroup.firstChannel)
238 <<
LogVar(
"Last channel", channelGroup.lastChannel)
239 <<
LogVar(
"Trigger bits", raw.getTriggerBits()));
252 detectorChannel =
m_ElectronicsMap->getDetectorChannel(&electronicsChannel);
253 if (detectorChannel ==
nullptr)
257 *detectorChannel, &subdetector, §ion, §or, &layer, &plane,
268 klmDigitOutOfRange->
setLayer(layer);
270 klmDigitOutOfRange->
setPlane(plane);
271 klmDigitOutOfRange->
setStrip(strip);
272 klmDigitOutOfRange->
setCharge(raw.getCharge());
273 klmDigitOutOfRange->
setCTime(raw.getCTime());
274 klmDigitOutOfRange->
setTDC(raw.getTDC());
283 strip = raw.getChannel();
289 strip = raw.getChannel();
293 for (
const ChannelGroup& channelGroup : channelGroups) {
294 if (channelGroup.firstStrip != 0) {
295 createDigit(&raw, klmDigitRaw, klmDigitEventInfo, subdetector, section,
296 sector, layer, plane, channelGroup.firstStrip,
297 channelGroup.lastStrip);
304 if (channel >= 0 && channel < 16) {
305 int id = channel / 4;
306 *copper = BKLM_ID +
id + 1;
307 *hslb = channel -
id * 4;
308 }
else if (channel >= 16 && channel < 32) {
309 int id = (channel - 16) / 4;
310 *copper = EKLM_ID +
id + 1;
311 *hslb = (channel - 16) -
id * 4;
313 B2FATAL(
"The PCIe40 channel is invalid."
314 <<
LogVar(
"Channel", channel));
323 const int hitLength = 2;
324 for (
int i = 0; i <
m_RawKLMs.getEntries(); i++) {
326 B2ERROR(
"RawKLM a wrong number of entries (should be 1)."
327 <<
LogVar(
"RawKLM index", i)
335 for (
int j = 0; j <
m_RawKLMs[i]->GetNumEntries(); j++) {
336 unsigned int copper =
m_RawKLMs[i]->GetNodeID(j);
337 int hslb, subdetector;
339 for (
int channelReadoutBoard = 0; channelReadoutBoard <
m_RawKLMs[i]->GetMaxNumOfCh(j); channelReadoutBoard++) {
340 if (
m_RawKLMs[i]->GetMaxNumOfCh(j) == 4) {
341 hslb = channelReadoutBoard;
342 if ((copper >= EKLM_ID) && (copper <= EKLM_ID + 4))
344 else if ((copper >= BKLM_ID) && (copper <= BKLM_ID + 4))
348 }
else if (
m_RawKLMs[i]->GetMaxNumOfCh(j) == 48) {
349 if (channelReadoutBoard >= 0 && channelReadoutBoard < 16)
351 else if (channelReadoutBoard >= 16 && channelReadoutBoard < 32)
357 B2FATAL(
"The maximum number of channels per readout board is invalid."
365 int numDetNwords =
m_RawKLMs[i]->GetDetectorNwords(j, channelReadoutBoard);
366 int* hslbBuffer =
m_RawKLMs[i]->GetDetectorBuffer(j, channelReadoutBoard);
367 int numHits = numDetNwords / hitLength;
368 if (numDetNwords % hitLength != 1 && numDetNwords != 0) {
369 B2ERROR(
"Incorrect number of data words."
370 <<
LogVar(
"Number of data words", numDetNwords));
374 if (numDetNwords > 0) {
379 unsigned int revo9TriggerWord =
380 (hslbBuffer[numDetNwords - 1] >> 16) & 0xFFFF;
382 unsigned int userWord = hslbBuffer[numDetNwords - 1] & 0xFFFF;
388 for (
int iHit = 0; iHit < numHits; iHit++) {
390 subdetector, klmDigitEventInfo);
@ c_FirstRPCLayer
First RPC layer.
Class to store debugging information from the unpacker (event based).
void increaseOutOfRangeHits()
Increase by 1 the number of outOfRange-flagged hits in the event.
int getRPCHits() const
Returns the number of RPC hits in the event.
unsigned int getTriggerCTime() const
Get trigger CTIME.
void increaseSciHits()
Increase by 1 the number of scintillator hits in the event.
void setUserWord(unsigned int userWord)
Set user word (from DCs).
void setRevo9TriggerWord(unsigned int revo9TriggerWord)
Set Revo9 trigger word (from DCs).
void setPreviousEventTriggerCTime(unsigned int triggerCTimeOfPreviousEvent)
Set trigger CTime of previous event.
unsigned int getRevo9TriggerWord() const
Get revo9 trigger word (from DCs).
void increaseRPCHits()
Increase by 1 the number of RPC hits in the event.
Class to store the raw words from the unpacker, digit-by-digit.
KLM digit (class representing a digitized hit in RPCs or scintillators).
void setLastStrip(int lastStrip)
Set last strip number (for multi-strip digits).
void setSection(int section)
Set section number.
void setCTime(uint16_t ctime)
Set CTIME.
void setStrip(int strip)
Set strip number.
void setRPCHitIndex(int rpcHitIndex)
Set hit index for RPCs.
void setTime(float time)
Set hit time.
void setSubdetector(int subdetector)
Set subdetector number.
void setSector(int sector)
Set sector number.
void setRevo9DCArrivalTime(int revo9DCArrivalTime)
Set Revo9 DC arrival time for RPC hits.
void setTDC(uint16_t tdc)
Set TDC.
void setFitStatus(int s)
Set fit status.
void setCharge(uint16_t charge)
Set charge.
void setPlane(int plane)
Set plane number.
void setLayer(int layer)
Set layer number.
BKLM electronics channel.
int getSlot() const
Get slot.
int getCopper() const
Get copper.
int getChannel() const
Get channel.
int getAxis() const
Get axis.
int getLane() const
Get lane.
void setChannel(int channel)
Set channel.
int getThreshold() const
Get threshold.
DBObjPtr< KLMScintillatorFEEParameters > m_FEEParameters
Scintillator FEE parameters.
unsigned int m_triggerCTimeOfPreviousEvent
Trigger ctime of the previous event.
StoreArray< KLMDigit > m_Digits
Digits.
void initialize() override
Initializer.
void unpackKLMDigit(const int *rawData, int copper, int hslb, int daqSubdetector, KLMDigitEventInfo *klmDigitEventInfo)
Unpack KLM digit.
void event() override
This method is called for each event.
int m_DAQChannelModule
Record DAQ channel for specific module.
const KLMElementNumbers * m_ElementNumbers
Element numbers.
void createDigit(const KLM::RawData *raw, const KLMDigitRaw *klmDigitRaw, KLMDigitEventInfo *klmDigitEventInfo, int subdetector, int section, int sector, int layer, int plane, int strip, int lastStrip)
Create KLM digit.
KLMUnpackerModule()
Constructor.
void endRun() override
This method is called if the current run ends.
bool m_WriteWrongHits
Record wrong hits (for debugging).
bool m_IgnoreWrongHits
Do not issue B2ERROR on wrong hits, with certain firmware versions wrong strip numbers are expected.
void terminate() override
This method is called at the end of the event processing.
StoreArray< KLMDigitEventInfo > m_DigitEventInfos
Event information.
void convertPCIe40ToCOPPER(int channel, unsigned int *copper, int *hslb) const
Map a PCIe40 channel to the old and corresponding (COPPER, HSLB) address.
StoreArray< KLMDigit > m_klmDigitsOutOfRange
Out-of-range digits.
bool m_IgnoreStrip0
Ignore hits with strip = 0.
void beginRun() override
Called when entering a new run.
DBObjPtr< KLMElectronicsMap > m_ElectronicsMap
Electronics map.
StoreArray< RawKLM > m_RawKLMs
Raw data.
bool m_DAQChannelBKLMScintillators
Record DAQ channel for BKLM scintillators.
std::string m_outputKLMDigitsName
Name of KLMDigit store array.
bool m_keepEvenPackages
Flag to keep the even packages.
bool m_WriteDigitRaws
Record raw data in dataobject format (for debugging).
bool m_DebugElectronicsMap
Debug electronics map (record DAQ channel instead of strip).
KLMTime * m_Time
Time conversion.
StoreArray< KLMDigitRaw > m_klmDigitRaws
Raw digits.
~KLMUnpackerModule()
Destructor.
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
Class to store variables with their name which were sent to the logging service.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
uint16_t KLMChannelNumber
Channel number.
uint16_t KLMModuleNumber
Module number.
Abstract base class for different kinds of events.