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;
28 m_triggerCTimeOfPreviousEvent(0)
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 =
110 klmDigit->
setTime(rpcTimes.second);
118 if (raw->getType() == 0x4) {
129 if (FEEData ==
nullptr)
130 B2FATAL(
"Incomplete KLM scintillator FEE data.");
132 klmDigit->
setFitStatus(KLM::c_ScintillatorFirmwareSuccessfulFit);
134 klmDigit->
setFitStatus(KLM::c_ScintillatorFirmwareNoSignal);
145 klmDigit->
setCTime(raw->getCTime());
146 klmDigit->
setTDC(raw->getTDC());
150 const int* rawData,
int copper,
int hslb,
int daqSubdetector,
157 int subdetector, section, sector, layer, plane, strip;
159 std::vector<ChannelGroup> channelGroups;
160 raw.getChannelGroups(channelGroups);
163 copper, hslb + 1, raw.getLane(), raw.getAxis(), raw.getChannel());
164 bool channelFound =
false;
166 if (channelGroup.lastChannel == 0) {
170 if (detectorChannel !=
nullptr) {
174 *detectorChannel, &subdetector, §ion, §or, &layer, &plane,
176 channelGroup.firstStrip = strip;
177 channelGroup.lastStrip = 0;
182 B2DEBUG(20,
"Channel does not exist in the KLM electronics map."
189 B2ERROR(
"Channel does not exist in the KLM electronics map."
207 bool firstMatchedChannel =
true;
208 for (
int channel = channelGroup.firstChannel;
209 channel <= channelGroup.lastChannel; ++channel) {
214 if (detectorChannel !=
nullptr) {
217 *detectorChannel, &subdetector, §ion, §or, &layer, &plane,
219 if (firstMatchedChannel) {
220 firstMatchedChannel =
false;
221 channelGroup.firstStrip = strip;
222 channelGroup.lastStrip = 0;
224 channelGroup.lastStrip = strip;
229 if (firstMatchedChannel) {
230 B2DEBUG(20,
"No matching channels exist in the KLM electronics map."
235 <<
LogVar(
"First channel", channelGroup.firstChannel)
236 <<
LogVar(
"Last channel", channelGroup.lastChannel)
237 <<
LogVar(
"Trigger bits", raw.getTriggerBits()));
250 detectorChannel =
m_ElectronicsMap->getDetectorChannel(&electronicsChannel);
251 if (detectorChannel ==
nullptr)
255 *detectorChannel, &subdetector, §ion, §or, &layer, &plane,
266 klmDigitOutOfRange->
setLayer(layer);
268 klmDigitOutOfRange->
setPlane(plane);
269 klmDigitOutOfRange->
setStrip(strip);
270 klmDigitOutOfRange->
setCharge(raw.getCharge());
271 klmDigitOutOfRange->
setCTime(raw.getCTime());
272 klmDigitOutOfRange->
setTDC(raw.getTDC());
281 strip = raw.getChannel();
287 strip = raw.getChannel();
291 for (
const ChannelGroup& channelGroup : channelGroups) {
292 if (channelGroup.firstStrip != 0) {
293 createDigit(&raw, klmDigitRaw, klmDigitEventInfo, subdetector, section,
294 sector, layer, plane, channelGroup.firstStrip,
295 channelGroup.lastStrip);
302 if (channel >= 0 && channel < 16) {
303 int id = channel / 4;
304 *copper = BKLM_ID +
id + 1;
305 *hslb = channel -
id * 4;
306 }
else if (channel >= 16 && channel < 32) {
307 int id = (channel - 16) / 4;
308 *copper = EKLM_ID +
id + 1;
309 *hslb = (channel - 16) -
id * 4;
311 B2FATAL(
"The PCIe40 channel is invalid."
312 <<
LogVar(
"Channel", channel));
321 const int hitLength = 2;
322 for (
int i = 0; i <
m_RawKLMs.getEntries(); i++) {
324 B2ERROR(
"RawKLM a wrong number of entries (should be 1)."
325 <<
LogVar(
"RawKLM index", i)
333 for (
int j = 0; j <
m_RawKLMs[i]->GetNumEntries(); j++) {
334 unsigned int copper =
m_RawKLMs[i]->GetNodeID(j);
335 int hslb, subdetector;
337 for (
int channelReadoutBoard = 0; channelReadoutBoard <
m_RawKLMs[i]->GetMaxNumOfCh(j); channelReadoutBoard++) {
338 if (
m_RawKLMs[i]->GetMaxNumOfCh(j) == 4) {
339 hslb = channelReadoutBoard;
340 if ((copper >= EKLM_ID) && (copper <= EKLM_ID + 4))
342 else if ((copper >= BKLM_ID) && (copper <= BKLM_ID + 4))
346 }
else if (
m_RawKLMs[i]->GetMaxNumOfCh(j) == 48) {
347 if (channelReadoutBoard >= 0 && channelReadoutBoard < 16)
349 else if (channelReadoutBoard >= 16 && channelReadoutBoard < 32)
355 B2FATAL(
"The maximum number of channels per readout board is invalid."
363 int numDetNwords =
m_RawKLMs[i]->GetDetectorNwords(j, channelReadoutBoard);
364 int* hslbBuffer =
m_RawKLMs[i]->GetDetectorBuffer(j, channelReadoutBoard);
365 int numHits = numDetNwords / hitLength;
366 if (numDetNwords % hitLength != 1 && numDetNwords != 0) {
367 B2ERROR(
"Incorrect number of data words."
368 <<
LogVar(
"Number of data words", numDetNwords));
372 if (numDetNwords > 0) {
377 unsigned int revo9TriggerWord =
378 (hslbBuffer[numDetNwords - 1] >> 16) & 0xFFFF;
380 unsigned int userWord = hslbBuffer[numDetNwords - 1] & 0xFFFF;
386 for (
int iHit = 0; iHit < numHits; iHit++) {
388 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.
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 setTime(float time)
Set hit time.
void setSubdetector(int subdetector)
Set subdetector number.
void setSector(int sector)
Set sector number.
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.
KLMModuleNumber moduleNumberByChannel(KLMChannelNumber channel) const
Get module number by channel number.
KLMChannelNumber channelNumber(int subdetector, int section, int sector, int layer, int plane, int strip) const
Get channel number.
void channelNumberToElementNumbers(KLMChannelNumber channel, int *subdetector, int *section, int *sector, int *layer, int *plane, int *strip) const
Get element numbers by channel number.
int getThreshold() const
Get threshold.
std::pair< int, double > getRPCTimes(int ctime, int tdc, int triggerTime) const
Get coarse and fine times for RPC.
double getScintillatorTime(int ctime, int tdc, int triggerCTime) const
Get time for scintillator.
void updateConstants()
Update constants from database objects.
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.