10 #include <klm/modules/KLMDigitizer/KLMDigitizerModule.h>
13 #include <klm/dataobjects/KLMChannelIndex.h>
14 #include <klm/dataobjects/KLMScintillatorFirmwareFitResult.h>
15 #include <klm/simulation/ScintillatorSimulator.h>
18 #include <framework/dataobjects/BackgroundMetaData.h>
19 #include <mdst/dataobjects/MCParticle.h>
32 m_ChannelSpecificSimulation(false),
33 m_EfficiencyMode(c_Plane),
36 setDescription(
"KLM digitization module: create KLMDigits from KLMSimHits.");
39 "Simulation mode (\"Generic\" or \"ChannelSpecific\").",
40 std::string(
"Generic"));
46 "Initial digitization time in CTIME periods.", -5);
47 addParam(
"SaveFPGAFit",
m_SaveFPGAFit,
"Save FPGA fit data and set a relation with KLMDigits.",
false);
49 "Efficiency determination mode (\"Strip\" or \"Plane\").",
50 std::string(
"Plane"));
52 "Whether to create multi-strip digits in Run 1 data (not used for Run 2+).",
true);
54 "Debug mode (generates additional output files with histograms).",
91 klmChannel.getSector(), klmChannel.getLayer(),
92 klmChannel.getPlane(), klmChannel.getStrip());
94 if (FEEData ==
nullptr)
95 B2FATAL(
"Incomplete scintillator FEE data.");
97 B2ERROR(
"Non-positive photoelectron amplitude. The requested "
98 "channel-specific simulation is impossible. "
99 "KLMDigitizer is switched to the generic mode."
100 <<
LogVar(
"Section", klmChannel.getSection())
101 <<
LogVar(
"Layer", klmChannel.getLayer())
102 <<
LogVar(
"Sector", klmChannel.getSector())
103 <<
LogVar(
"Plane", klmChannel.getPlane())
104 <<
LogVar(
"Strip", klmChannel.getStrip()));
114 B2FATAL(
"KLM scintillator digitization parameters are not available.");
116 B2FATAL(
"KLM scintillator FEE parameters are not available.");
118 B2FATAL(
"KLM channel status data are not available.");
120 B2FATAL(
"KLM strip efficiency data are not available.");
122 B2FATAL(
"KLM scintillator firmware version is not available.");
129 if ((fwVersion == KLMScintillatorFirmware::FirmwareVersion::c_Invalid) ||
130 (fwVersion == KLMScintillatorFirmware::FirmwareVersion::c_Phase2) ||
131 (fwVersion == KLMScintillatorFirmware::FirmwareVersion::c_Run1)) {
147 B2FATAL(
"Incomplete KLM channel status data.");
153 if (std::isnan(efficiency))
154 B2FATAL(
"Incomplete KLM efficiency data.");
155 double selection = gRandom->Rndm();
156 return (selection < efficiency);
161 std::multimap<KLMChannelNumber, const KLMSimHit*>::iterator
162 it, it2, lowerBound, upperBound;
168 if (not lowerBound->second->inRPC())
169 B2FATAL(
"KLMDigitizer::digitizeRPC is trying to process a scintillator hit.");
179 const KLMSimHit* hit = lowerBound->second;
180 double time = hit->getTime();
182 while (it2 != upperBound) {
183 if (it2->second->getTime() < time) {
184 time = it2->second->getTime();
191 while (it2 != upperBound) {
205 std::multimap<KLMChannelNumber, const KLMSimHit*>::iterator
206 it, lowerBound, upperBound;
207 for (
int i = 0; i < KLM::c_NChannelsAsic; ++i)
214 if (lowerBound->second->inRPC())
215 B2FATAL(
"KLMDigitizer::digitizeScintillator is trying to process a RPC hit.");
216 const KLMSimHit* simHit = lowerBound->second;
223 FEEData =
m_FEEPar->getFEEData(lowerBound->first);
224 if (FEEData ==
nullptr)
225 B2FATAL(
"Incomplete KLM scintillator FEE data.");
228 simulator.
simulate(lowerBound, upperBound);
233 int channel = (electronicsChannel->
getChannel() - 1) %
234 KLM::c_NChannelsAsic;
244 KLM::c_ScintillatorFirmwareSuccessfulFit) {
257 KLM::c_ScintillatorFirmwareSuccessfulFit)) {
267 std::multimap<KLMElectronicsChannel, const KLMSimHit*>::iterator
269 std::multimap<KLMChannelNumber, const KLMSimHit*>::iterator it3;
274 for (it2 = it; it2 != upperBound; ++it2) {
278 hit->getSubdetector(), hit->getSection(), hit->getSector(),
279 hit->getLayer(), hit->getPlane(), hit->getStrip());
281 std::pair<KLMChannelNumber, const KLMSimHit*>(channel, hit));
286 for (
int i = 0; i < KLM::c_NChannelsAsic; ++i) {
290 bool multiStripMode = (nDigits >= 2);
292 while (i < KLM::c_NChannelsAsic) {
294 if (digit ==
nullptr) {
301 int minGroupChannel = 1;
302 int maxGroupChannel = KLM::c_NChannelsAsic;
306 bool connectedChannelFound =
false;
307 int minStrip, maxStrip;
308 for (
int j = minGroupChannel; j <= maxGroupChannel; ++j) {
309 electronicsChannel.
setChannel(KLM::c_NChannelsAsic * asic + j);
312 if (detectorChannel !=
nullptr) {
313 int subdetector, section, sector, layer, plane, strip;
315 *detectorChannel, &subdetector, §ion, §or, &layer,
317 if (!connectedChannelFound) {
318 connectedChannelFound =
true;
322 if (strip < minStrip)
324 if (strip > maxStrip)
330 if (!connectedChannelFound)
331 B2FATAL(
"Cannot find connected electronics channels.");
332 if (multiStripMode) {
336 for (
int j = i; j < maxGroupChannel; ++j) {
346 for (i = 0; i < KLM::c_NChannelsAsic; ++i) {
351 for (
int i = 0; i < KLM::c_NChannelsAsic; ++i) {
353 if (digit ==
nullptr)
375 for (i = 0; i <
m_SimHits.getEntries(); i++) {
378 if (hit->getStrip() <= 0)
386 if (particle !=
nullptr) {
389 hit->getSubdetector(), hit->getSection(), hit->getSector(),
390 hit->getLayer(), hit->getPlane());
392 std::pair<KLMPlaneNumber, const KLMSimHit*>(plane, hit));
394 B2ASSERT(
"The KLMSimHit is not related to any MCParticle and "
395 "it is also not a beam background hit.",
399 hit->getSubdetector(), hit->getSection(), hit->getSector(),
400 hit->getLayer(), hit->getPlane(), hit->getStrip());
402 bool rpc = hit->inRPC();
404 m_MapChannelSimHit.insert(std::pair<KLMChannelNumber, const KLMSimHit*>(channel, hit));
408 if (electronicsChannel ==
nullptr)
409 B2FATAL(
"Incomplete electronics map.");
411 m_MapAsicSimHit.insert(std::pair<KLMElectronicsChannel, const KLMSimHit*>(asic, hit));
416 std::multimap<KLMPlaneNumber, const KLMSimHit*>::iterator it, it2;
417 std::multimap<const MCParticle*, const KLMSimHit*> particleHitMap;
418 std::multimap<const MCParticle*, const KLMSimHit*>::iterator
419 itParticle, it2Particle;
422 particleHitMap.clear();
427 particleHitMap.insert(
428 std::pair<const MCParticle*, const KLMSimHit*>(particle, hit));
432 if (it2->first != it->first)
435 itParticle = particleHitMap.begin();
436 while (itParticle != particleHitMap.end()) {
437 it2Particle = itParticle;
438 const KLMSimHit* hit = it2Particle->second;
441 hit->getSubdetector(), hit->getSection(), hit->getSector(),
442 hit->getLayer(), hit->getPlane(), hit->getStrip());
446 hit = it2Particle->second;
447 bool rpc = hit->inRPC();
449 for (
int s = hit->getStrip(); s <= hit->getLastStrip(); ++s) {
452 hit->getSubdetector(), hit->getSection(), hit->getSector(),
453 hit->getLayer(), hit->getPlane(), s);
458 std::pair<KLMChannelNumber, const KLMSimHit*>(channel, hit));
462 if (electronicsChannel ==
nullptr)
463 B2FATAL(
"Incomplete electronics map.");
466 std::pair<KLMElectronicsChannel, const KLMSimHit*>(
472 if (it2Particle == particleHitMap.end())
474 if (it2Particle->first != itParticle->first)
477 itParticle = it2Particle;
482 for (i = 0; i <
m_SimHits.getEntries(); i++) {
485 if (hit->getStrip() <= 0)
487 for (
int s = hit->getStrip(); s <= hit->getLastStrip(); ++s) {
489 hit->getSection(), hit->getSector(), hit->getLayer(),
493 std::pair<KLMChannelNumber, const KLMSimHit*>(channel, hit));
498 hit->getSubdetector(), hit->getSection(), hit->getSector(),
499 hit->getLayer(), hit->getPlane(), hit->getStrip());
503 if (electronicsChannel ==
nullptr)
504 B2FATAL(
"Incomplete electronics map.");
507 std::pair<KLMElectronicsChannel, const KLMSimHit*>(asic, hit));
static int getStripByModule(int module)
Get strip number by module identifier.
ChannelStatus
Channel status.
@ c_Dead
Dead channel (no signal).
@ c_Unknown
Unknown status (no data).
KLM digit (class representing a digitized hit in RPCs or scintillators).
void setMCTime(float time)
Set MC time.
void setNGeneratedPhotoelectrons(int nPhotoelectrons)
Set generated number of photoelectrons.
void setLastStrip(int lastStrip)
Set last strip number (for multi-strip digits).
void setSiPMMCTime(float time)
Set SiPM MC time.
void setEnergyDeposit(float eDep)
Set energy deposit.
void setNPhotoelectrons(float nPhotoelectrons)
Set number of photoelectrons.
void setStrip(int strip)
Set strip number.
void setTime(float time)
Set hit time.
void setTDC(uint16_t tdc)
Set TDC.
void setFitStatus(int s)
Set fit status.
void setCharge(uint16_t charge)
Set charge.
std::multimap< KLMChannelNumber, const KLMSimHit * >::iterator m_AsicDigitSimHitsUpperBound[KLM::c_NChannelsAsic]
Simulation hits upper bound for ASIC digit.
std::multimap< KLMElectronicsChannel, const KLMSimHit * > m_MapAsicSimHit
Simulation hit map (by ASIC).
std::multimap< KLMPlaneNumber, const KLMSimHit * > m_MapPlaneSimHit
Simulation hit map (by plane).
std::multimap< KLMChannelNumber, const KLMSimHit * >::iterator m_AsicDigitSimHitsLowerBound[KLM::c_NChannelsAsic]
Simulation hits lower bound for ASIC digit.
KLMDigit * m_AsicDigits[KLM::c_NChannelsAsic]
Digits corresponding to ASIC channels.
EfficiencyMode m_EfficiencyMode
Efficiency determination mode (converted from the string parameter).
StoreArray< KLMDigit > m_Digits
KLM digits.
DBObjPtr< KLMChannelStatus > m_ChannelStatus
Channel status.
DBObjPtr< KLMScintillatorFEEParameters > m_FEEPar
Scintillator FEE parameters.
void initialize() override
Initializer.
bool m_CreateMultiStripDigitsByRun
Whether to create multi-strip digits for one particular run.
bool efficiencyCorrection(float efficiency)
Efficiency correction.
void event() override
This method is called for each event.
const KLMElementNumbers * m_ElementNumbers
Element numbers.
bool m_SaveFPGAFit
Save FPGA fit data (KLMScintillatorFirmwareFitResult).
bool checkActive(KLMChannelNumber channel)
Check if channel is active (status is not KLMChannelStatus::c_Dead).
void endRun() override
This method is called if the current run ends.
DBObjPtr< KLMScintillatorDigitizationParameters > m_DigPar
Scintillator digitization parameters.
std::multimap< KLMChannelNumber, const KLMSimHit * > m_MapChannelSimHit
Simulation hit map (by channel).
void terminate() override
This method is called at the end of the event processing.
bool m_Debug
Use debug mode in EKLM::ScintillatorSimulator or not.
StoreArray< KLMSimHit > m_SimHits
Simulation hits.
void digitizeRPC()
Digitization in RPCs.
int m_DigitizationInitialTime
Initial digitization time in CTIME periods.
void digitizeScintillator()
Digitization in scintillators.
void checkScintillatorFEEParameters()
Check scintillator FEE parameters for channel-specific simulation.
std::string m_Efficiency
Efficiency determination mode ("Strip" or "Plane").
void beginRun() override
Called when entering a new run.
DBObjPtr< KLMScintillatorFirmware > m_ScintillatorFirmware
Scintillator FEE firmware version.
DBObjPtr< KLMElectronicsMap > m_ElectronicsMap
Electronics map.
KLMDigitizerModule()
Constructor.
void digitizeAsic()
Digitization in ASIC.
~KLMDigitizerModule()
Destructor.
StoreArray< KLMScintillatorFirmwareFitResult > m_FPGAFits
FPGA fits.
bool m_ChannelSpecificSimulation
Whether the simulation is channel-specific.
KLMTime * m_Time
Time conversion.
bool m_CreateMultiStripDigits
Whether to create multi-strip digits.
DBObjPtr< KLMStripEfficiency > m_StripEfficiency
Strip efficiency.
KLM::ScintillatorFirmware * m_Fitter
FPGA fitter.
std::string m_SimulationMode
Simulation mode.
BKLM electronics channel.
int getChannel() const
Get channel.
KLMElectronicsChannel getAsic() const
Get ASIC.
void setChannel(int channel)
Set channel.
KLMChannelNumber channelNumberBKLM(int section, int sector, int layer, int plane, int strip) const
Get channel number for BKLM.
KLMChannelNumber channelNumber(int subdetector, int section, int sector, int layer, int plane, int strip) const
Get channel number.
KLMPlaneNumber planeNumber(int subdetector, int section, int sector, int layer, int plane) const
Get plane 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 localChannelNumberBKLM(KLMChannelNumber channel) const
Get local BKLM channel number.
float getPhotoelectronAmplitude() const
Get photoelectron amplitude.
FPGA fit simulation data.
int getMinimalAmplitude() const
Get minimal amplitude (ADC output).
int getStartTime() const
Get signal start time (in TDC counts).
FirmwareVersion
Enumerator for the scintillator firmware version.
double getCTimePeriod() const
Get CTIME period.
double getTimeSimulation(int tdc, bool scintillator) const
Get time for simulation.
void updateConstants()
Update constants from database objects.
Digitize EKLMSim2Hits to get EKLM StripHits.
float getSiPMMCTime() const
Get SiPM MC time.
void setFEEData(const KLMScintillatorFEEData *FEEData)
Set FEE data.
enum ScintillatorFirmwareFitStatus getFitStatus() const
Get fit status.
double getEnergy()
Get total energy deposited in the strip (sum over ssimulation hits).
double getNPhotoelectrons()
Get number of photoelectrons (fit result).
KLMScintillatorFirmwareFitResult * getFPGAFit()
Get fit data.
float getMCTime() const
Get MC time.
int getNGeneratedPhotoelectrons()
Get generated number of photoelectrons.
void simulate(const std::multimap< KLMChannelNumber, const KLMSimHit * >::iterator &firstHit, const std::multimap< KLMChannelNumber, const KLMSimHit * >::iterator &end)
Simulate a strip.
A Class to store the Monte Carlo particle information.
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.
REG_MODULE(arichBtest)
Register the Module.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
uint16_t KLMChannelNumber
Channel number.
uint16_t KLMPlaneNumber
Plane number.
Abstract base class for different kinds of events.