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 BKLMSimHits and EKLMSimHits.");
37 setPropertyFlags(c_ParallelProcessingCertified);
38 addParam(
"SimulationMode", m_SimulationMode,
39 "Simulation mode (\"Generic\" or \"ChannelSpecific\").",
40 std::string(
"Generic"));
45 addParam(
"DigitizationInitialTime", m_DigitizationInitialTime,
46 "Initial digitization time in CTIME periods.", -5);
47 addParam(
"SaveFPGAFit", m_SaveFPGAFit,
"Save FPGA fit data and set a relation with KLMDigits.",
false);
48 addParam(
"Efficiency", m_Efficiency,
49 "Efficiency determination mode (\"Strip\" or \"Plane\").",
50 std::string(
"Plane"));
51 addParam(
"Debug", m_Debug,
52 "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.");
137 B2FATAL(
"Incomplete KLM channel status data.");
143 if (isnan(efficiency))
144 B2FATAL(
"Incomplete KLM efficiency data.");
145 double selection = gRandom->Rndm();
146 return (selection < efficiency);
156 std::multimap<KLMChannelNumber, const BKLMSimHit*>::iterator it, it2, ub;
161 bool rpc = simHit->
inRPC();
176 double time = hit->getTime();
179 if (it2->second->getTime() < time) {
180 time = it2->second->getTime();
193 FEEData =
m_FEEPar->getFEEData(channel);
194 if (FEEData ==
nullptr)
195 B2FATAL(
"Incomplete KLM scintillator FEE data.");
207 KLM::c_ScintillatorFirmwareSuccessfulFit) {
219 if (simulator.
getFitStatus() == KLM::c_ScintillatorFirmwareSuccessfulFit &&
236 std::multimap<KLMChannelNumber, const EKLMSimHit*>::iterator it, ub;
253 FEEData =
m_FEEPar->getFEEData(channel);
254 if (FEEData ==
nullptr)
255 B2FATAL(
"Incomplete KLM scintillator FEE data.");
267 if (simulator.
getFitStatus() == KLM::c_ScintillatorFirmwareSuccessfulFit) {
279 if (simulator.
getFitStatus() == KLM::c_ScintillatorFirmwareSuccessfulFit &&
300 if (hit->getStripMin() <= 0)
308 if (particle !=
nullptr) {
310 hit->getSection(), hit->getSector(),
311 hit->getLayer(), hit->getPlane());
313 std::pair<KLMPlaneNumber, const BKLMSimHit*>(plane, hit));
315 B2ASSERT(
"The BKLMSimHit is not related to any MCParticle and "
316 "it is also not a beam background hit.",
319 hit->getSection(), hit->getSector(), hit->getLayer(),
320 hit->getPlane(), hit->getStrip());
323 std::pair<KLMChannelNumber, const BKLMSimHit*>(channel, hit));
326 std::multimap<KLMPlaneNumber, const BKLMSimHit*>::iterator it, it2;
327 std::multimap<const MCParticle*, const BKLMSimHit*> particleHitMap;
328 std::multimap<const MCParticle*, const BKLMSimHit*>::iterator
329 itParticle, it2Particle;
332 particleHitMap.clear();
337 particleHitMap.insert(
338 std::pair<const MCParticle*, const BKLMSimHit*>(particle, hit));
342 if (it2->first != it->first)
345 itParticle = particleHitMap.begin();
346 while (itParticle != particleHitMap.end()) {
347 it2Particle = itParticle;
350 hit->getSection(), hit->getSector(),
351 hit->getLayer(), hit->getPlane(),
355 hit = it2Particle->second;
357 for (
int s = hit->getStripMin(); s <= hit->getStripMax(); ++s) {
359 hit->getSection(), hit->getSector(), hit->getLayer(),
363 std::pair<KLMChannelNumber, const BKLMSimHit*>(channel, hit));
368 if (it2Particle == particleHitMap.end())
370 if (it2Particle->first != itParticle->first)
373 itParticle = it2Particle;
389 if (particle !=
nullptr) {
391 hit->getSection(), hit->getSector(),
392 hit->getLayer(), hit->getPlane());
394 std::pair<KLMPlaneNumber, const EKLMSimHit*>(plane, hit));
396 B2ASSERT(
"The EKLMSimHit is not related to any MCParticle and "
397 "it is also not a beam background hit.",
400 hit->getSection(), hit->getSector(), hit->getLayer(),
401 hit->getPlane(), hit->getStrip());
404 std::pair<KLMChannelNumber, const EKLMSimHit*>(channel, hit));
407 std::multimap<KLMPlaneNumber, const EKLMSimHit*>::iterator it, it2;
408 std::multimap<const MCParticle*, const EKLMSimHit*> particleHitMap;
409 std::multimap<const MCParticle*, const EKLMSimHit*>::iterator
410 itParticle, it2Particle;
413 particleHitMap.clear();
418 particleHitMap.insert(
419 std::pair<const MCParticle*, const EKLMSimHit*>(particle, hit));
423 if (it2->first != it->first)
426 itParticle = particleHitMap.begin();
427 while (itParticle != particleHitMap.end()) {
428 it2Particle = itParticle;
431 hit->getSection(), hit->getSector(),
432 hit->getLayer(), hit->getPlane(),
436 hit = it2Particle->second;
439 hit->getSection(), hit->getSector(), hit->getLayer(),
440 hit->getPlane(), hit->getStrip());
443 std::pair<KLMChannelNumber, const EKLMSimHit*>(channel, hit));
447 if (it2Particle == particleHitMap.end())
449 if (it2Particle->first != itParticle->first)
452 itParticle = it2Particle;
461 if (hit->getStripMin() <= 0)
463 for (
int s = hit->getStripMin(); s <= hit->getStripMax(); ++s) {
465 hit->getSection(), hit->getSector(), hit->getLayer(),
469 std::pair<KLMChannelNumber, const BKLMSimHit*>(channel, hit));
474 hit->getSection(), hit->getSector(), hit->getLayer(),
475 hit->getPlane(), hit->getStrip());
478 std::pair<KLMChannelNumber, const BKLMSimHit*>(channel, hit));
485 hit->getSection(), hit->getSector(), hit->getLayer(),
486 hit->getPlane(), hit->getStrip());
489 std::pair<KLMChannelNumber, const EKLMSimHit*>(channel, hit));
static int getStripByModule(int module)
Get strip number by module identifier.
Store one simulation hit as a ROOT object.
bool inRPC() const
Determine whether this hit is in an RPC or scintillator.
int getLayer() const
Get layer number.
int getSection() const
Get section number.
int getPlane() const
Get plane number.
int getStrip() const
Get strip number of this hit.
int getSector() const
Get sector number.
int getLayer() const
Get layer number.
int getSection() const
Get section number.
int getSector() const
Get sector number.
Class EKLMSimHit stores information on particular Geant step; using information from TrackID and Pare...
int getPlane() const
Get plane number.
int getStrip() const
Get strip number.
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 setSiPMMCTime(float time)
Set SiPM MC time.
void setEnergyDeposit(float eDep)
Set EnergyDeposit.
void setNPhotoelectrons(float nPhotoelectrons)
Set number of photoelectrons.
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< KLMPlaneNumber, const BKLMSimHit * > m_bklmSimHitPlaneMap
Simulation hit map for BKLM (by plane).
StoreArray< EKLMSimHit > m_eklmSimHits
EKLM simulation hits.
std::multimap< KLMPlaneNumber, const EKLMSimHit * > m_eklmSimHitPlaneMap
Simulation hit map for EKLM (by plane).
EfficiencyMode m_EfficiencyMode
Efficiency determination mode (converted from the string parameter).
StoreArray< KLMDigit > m_Digits
KLM digits.
DBObjPtr< KLMChannelStatus > m_ChannelStatus
Channel status.
void digitizeBKLM()
Digitization in BKLM.
DBObjPtr< KLMScintillatorFEEParameters > m_FEEPar
Scintillator FEE parameters.
void initialize() override
Initializer.
bool efficiencyCorrection(float efficiency)
Efficiency correction.
std::multimap< KLMChannelNumber, const BKLMSimHit * > m_bklmSimHitChannelMap
Simulation hit map for BKLM (by channel).
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.
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.
void digitizeEKLM()
Digitization in EKLM.
int m_DigitizationInitialTime
Initial digitization time in CTIME periods.
std::multimap< KLMChannelNumber, const EKLMSimHit * > m_eklmSimHitChannelMap
Simulation hit map for EKLM (by channel).
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.
~KLMDigitizerModule()
Destructor.
StoreArray< KLMScintillatorFirmwareFitResult > m_FPGAFits
FPGA fits.
StoreArray< BKLMSimHit > m_bklmSimHits
BKLM simulation hits.
bool m_ChannelSpecificSimulation
Whether the simulation is channel-specific.
KLMTime * m_Time
Time conversion.
DBObjPtr< KLMStripEfficiency > m_StripEfficiency
Strip efficiency.
KLM::ScintillatorFirmware * m_Fitter
FPGA fitter.
std::string m_SimulationMode
Simulation mode.
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 planeNumberEKLM(int section, int sector, int layer, int plane) const
Get channel number for EKLM.
KLMPlaneNumber planeNumberBKLM(int section, int sector, int layer, int plane) const
Get plane number for BKLM.
int localChannelNumberBKLM(KLMChannelNumber channel) const
Get local BKLM channel number.
KLMChannelNumber channelNumberEKLM(int section, int sector, int layer, int plane, int strip) const
Get channel number for EKLM.
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).
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.
void simulate(const std::multimap< KLMChannelNumber, const BKLMSimHit * >::iterator &firstHit, const std::multimap< KLMChannelNumber, const BKLMSimHit * >::iterator &end)
Simulate BKLM strip.
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.
A Class to store the Monte Carlo particle information.
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.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
uint16_t KLMChannelNumber
Channel number.
uint16_t KLMPlaneNumber
Plane number.
Abstract base class for different kinds of events.