Belle II Software  release-08-02-06
KLMDigitizerModule.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 /* Own header. */
10 #include <klm/modules/KLMDigitizer/KLMDigitizerModule.h>
11 
12 /* KLM headers. */
13 #include <klm/dataobjects/KLMChannelIndex.h>
14 #include <klm/dataobjects/KLMScintillatorFirmwareFitResult.h>
15 #include <klm/simulation/ScintillatorSimulator.h>
16 
17 /* Basf2 headers. */
18 #include <framework/dataobjects/BackgroundMetaData.h>
19 #include <mdst/dataobjects/MCParticle.h>
20 
21 /* ROOT headers. */
22 #include <TRandom.h>
23 
24 using namespace Belle2;
25 
26 REG_MODULE(KLMDigitizer);
27 
32 
33 public:
34 
41  bool operator()(const MCParticle* particle1, const MCParticle* particle2) const
42  {
43  return particle1->getIndex() < particle2->getIndex();
44  }
45 };
46 
48  Module(),
49  m_Time(&(KLMTime::Instance())),
50  m_ElementNumbers(&(KLMElementNumbers::Instance())),
51  m_ChannelSpecificSimulation(false),
52  m_EfficiencyMode(c_Plane),
53  m_Fitter(nullptr)
54 {
55  setDescription("KLM digitization module: create KLMDigits from KLMSimHits.");
57  addParam("SimulationMode", m_SimulationMode,
58  "Simulation mode (\"Generic\" or \"ChannelSpecific\").",
59  std::string("Generic"));
60  /*
61  * Initial digitization time is negative to work with cosmic events (the part
62  * of the track directed to the interaction pointhas a negative time).
63  */
64  addParam("DigitizationInitialTime", m_DigitizationInitialTime,
65  "Initial digitization time in CTIME periods.", -5);
66  addParam("SaveFPGAFit", m_SaveFPGAFit, "Save FPGA fit data and set a relation with KLMDigits.", false);
67  addParam("Efficiency", m_Efficiency,
68  "Efficiency determination mode (\"Strip\" or \"Plane\").",
69  std::string("Plane"));
70  addParam("CreateMultiStripDigits", m_CreateMultiStripDigits,
71  "Whether to create multi-strip digits in Run 1 data (not used for Run 2+).", true);
72  addParam("Debug", m_Debug,
73  "Debug mode (generates additional output files with histograms).",
74  false);
75 }
76 
78 {
79 }
80 
82 {
83  m_SimHits.isRequired();
84  m_Digits.registerInDataStore();
85  m_Digits.registerRelationTo(m_SimHits);
86  if (m_SaveFPGAFit) {
87  m_FPGAFits.registerInDataStore();
88  m_Digits.registerRelationTo(m_FPGAFits);
89  }
90  if (m_SimulationMode == "Generic") {
91  /* Nothing to do. */
92  } else if (m_SimulationMode == "ChannelSpecific") {
94  } else {
95  B2FATAL("Unknown simulation mode: " << m_SimulationMode);
96  }
97  if (m_Efficiency == "Strip")
99  else if (m_Efficiency == "Plane")
101  else
102  B2FATAL("Unknown efficiency mode: " << m_EfficiencyMode);
103 }
104 
106 {
107  KLMChannelIndex klmChannels;
108  for (KLMChannelIndex& klmChannel : klmChannels) {
109  KLMChannelNumber channel = m_ElementNumbers->channelNumber(klmChannel.getSubdetector(), klmChannel.getSection(),
110  klmChannel.getSector(), klmChannel.getLayer(),
111  klmChannel.getPlane(), klmChannel.getStrip());
112  const KLMScintillatorFEEData* FEEData = m_FEEPar->getFEEData(channel);
113  if (FEEData == nullptr)
114  B2FATAL("Incomplete scintillator FEE data.");
115  if (FEEData->getPhotoelectronAmplitude() <= 0) {
116  B2ERROR("Non-positive photoelectron amplitude. The requested "
117  "channel-specific simulation is impossible. "
118  "KLMDigitizer is switched to the generic mode."
119  << LogVar("Section", klmChannel.getSection())
120  << LogVar("Layer", klmChannel.getLayer())
121  << LogVar("Sector", klmChannel.getSector())
122  << LogVar("Plane", klmChannel.getPlane())
123  << LogVar("Strip", klmChannel.getStrip()));
125  return;
126  }
127  }
128 }
129 
131 {
132  if (!m_DigPar.isValid())
133  B2FATAL("KLM scintillator digitization parameters are not available.");
134  if (!m_FEEPar.isValid())
135  B2FATAL("KLM scintillator FEE parameters are not available.");
136  if (!m_ChannelStatus.isValid())
137  B2FATAL("KLM channel status data are not available.");
138  if (!m_StripEfficiency.isValid())
139  B2FATAL("KLM strip efficiency data are not available.");
140  if (!m_ScintillatorFirmware.isValid())
141  B2FATAL("KLM scintillator firmware version is not available.");
145  m_Fitter = new KLM::ScintillatorFirmware(m_DigPar->getNDigitizations());
146  KLMScintillatorFirmware::FirmwareVersion fwVersion = m_ScintillatorFirmware->getFirmwareVersion();
147  m_CreateMultiStripDigitsByRun = false; // do not make multi-strip KLMDigits for Run 2+ events
148  if ((fwVersion == KLMScintillatorFirmware::FirmwareVersion::c_Invalid) || // this should never happen!
149  (fwVersion == KLMScintillatorFirmware::FirmwareVersion::c_Phase2) || // for very early data (deprecated)
150  (fwVersion == KLMScintillatorFirmware::FirmwareVersion::c_Run1)) { // for data up to and including 2022b
152  }
153  B2INFO("KLM multi-strip digits are " << (m_CreateMultiStripDigitsByRun ? "" : "NOT") << " simulated");
154 }
155 
156 /*
157  * Digitization. Light propagation into the fiber, SiPM and electronics effects
158  * are simulated in KLM::ScintillatorSimulator class.
159  */
160 
162 {
163  enum KLMChannelStatus::ChannelStatus status =
164  m_ChannelStatus->getChannelStatus(channel);
165  if (status == KLMChannelStatus::c_Unknown)
166  B2FATAL("Incomplete KLM channel status data.");
167  return (status != KLMChannelStatus::c_Dead);
168 }
169 
171 {
172  if (std::isnan(efficiency))
173  B2FATAL("Incomplete KLM efficiency data.");
174  double selection = gRandom->Rndm();
175  return (selection < efficiency);
176 }
177 
179 {
180  std::multimap<KLMChannelNumber, const KLMSimHit*>::iterator
181  it, it2, lowerBound, upperBound;
182  it = m_MapChannelSimHit.begin();
183  while (it != m_MapChannelSimHit.end()) {
184  lowerBound = it;
185  upperBound = m_MapChannelSimHit.upper_bound(it->first);
186  it = upperBound;
187  if (not lowerBound->second->inRPC())
188  B2FATAL("KLMDigitizer::digitizeRPC is trying to process a scintillator hit.");
189  if (m_EfficiencyMode == c_Strip) {
190  float efficiency = m_StripEfficiency->getEfficiency(lowerBound->first);
191  if (!efficiencyCorrection(efficiency))
192  continue;
193  }
195  m_ElementNumbers->localChannelNumberBKLM(lowerBound->first));
196  /* Select hit that has the smallest time. */
197  it2 = lowerBound;
198  const KLMSimHit* hit = lowerBound->second;
199  double time = hit->getTime();
200  ++it2;
201  while (it2 != upperBound) {
202  if (it2->second->getTime() < time) {
203  time = it2->second->getTime();
204  hit = it2->second;
205  }
206  ++it2;
207  }
208  KLMDigit* digit = m_Digits.appendNew(hit, strip);
209  it2 = lowerBound;
210  while (it2 != upperBound) {
211  digit->addRelationTo(it2->second);
212  ++it2;
213  }
214  }
215 }
216 
218 {
219  uint16_t tdc;
220  KLM::ScintillatorSimulator simulator(
221  &(*m_DigPar), m_Fitter,
223  const KLMScintillatorFEEData* FEEData;
224  std::multimap<KLMChannelNumber, const KLMSimHit*>::iterator
225  it, lowerBound, upperBound;
226  for (int i = 0; i < KLM::c_NChannelsAsic; ++i)
227  m_AsicDigits[i] = nullptr;
228  it = m_MapChannelSimHit.begin();
229  while (it != m_MapChannelSimHit.end()) {
230  lowerBound = it;
231  upperBound = m_MapChannelSimHit.upper_bound(it->first);
232  it = upperBound;
233  if (lowerBound->second->inRPC())
234  B2FATAL("KLMDigitizer::digitizeScintillator is trying to process a RPC hit.");
235  const KLMSimHit* simHit = lowerBound->second;
236  if (m_EfficiencyMode == c_Strip) {
237  float efficiency = m_StripEfficiency->getEfficiency(lowerBound->first);
238  if (!efficiencyCorrection(efficiency))
239  continue;
240  }
242  FEEData = m_FEEPar->getFEEData(lowerBound->first);
243  if (FEEData == nullptr)
244  B2FATAL("Incomplete KLM scintillator FEE data.");
245  simulator.setFEEData(FEEData);
246  }
247  simulator.simulate(lowerBound, upperBound);
248  if (simulator.getNGeneratedPhotoelectrons() == 0)
249  continue;
250  const KLMElectronicsChannel* electronicsChannel =
251  m_ElectronicsMap->getElectronicsChannel(lowerBound->first);
252  int channel = (electronicsChannel->getChannel() - 1) %
253  KLM::c_NChannelsAsic;
254  KLMDigit* digit = new KLMDigit(simHit);
255  m_AsicDigits[channel] = digit;
256  m_AsicDigitSimHitsLowerBound[channel] = lowerBound;
257  m_AsicDigitSimHitsUpperBound[channel] = upperBound;
258  digit->setMCTime(simulator.getMCTime());
259  digit->setSiPMMCTime(simulator.getSiPMMCTime());
261  simulator.getNGeneratedPhotoelectrons());
262  if (simulator.getFitStatus() ==
263  KLM::c_ScintillatorFirmwareSuccessfulFit) {
264  tdc = simulator.getFPGAFit()->getStartTime();
265  digit->setCharge(simulator.getFPGAFit()->getMinimalAmplitude());
266  } else {
267  tdc = 0;
268  digit->setCharge(m_DigPar->getADCRange() - 1);
269  }
270  digit->setTDC(tdc);
271  digit->setTime(m_Time->getTimeSimulation(tdc, true));
272  digit->setFitStatus(simulator.getFitStatus());
273  digit->setNPhotoelectrons(simulator.getNPhotoelectrons());
274  digit->setEnergyDeposit(simulator.getEnergy());
275  if (m_SaveFPGAFit && (simulator.getFitStatus() ==
276  KLM::c_ScintillatorFirmwareSuccessfulFit)) {
278  m_FPGAFits.appendNew(*simulator.getFPGAFit());
279  digit->addRelationTo(fit);
280  }
281  }
282 }
283 
285 {
286  std::multimap<KLMElectronicsChannel, const KLMSimHit*>::iterator
287  it, it2, upperBound;
288  std::multimap<KLMChannelNumber, const KLMSimHit*>::iterator it3;
289  it = m_MapAsicSimHit.begin();
290  while (it != m_MapAsicSimHit.end()) {
291  upperBound = m_MapAsicSimHit.upper_bound(it->first);
292  m_MapChannelSimHit.clear();
293  for (it2 = it; it2 != upperBound; ++it2) {
294  const KLMSimHit* hit = it2->second;
295  KLMChannelNumber channel =
297  hit->getSubdetector(), hit->getSection(), hit->getSector(),
298  hit->getLayer(), hit->getPlane(), hit->getStrip());
299  m_MapChannelSimHit.insert(
300  std::pair<KLMChannelNumber, const KLMSimHit*>(channel, hit));
301  }
304  int nDigits = 0;
305  for (int i = 0; i < KLM::c_NChannelsAsic; ++i) {
306  if (m_AsicDigits[i] != nullptr)
307  nDigits += 1;
308  }
309  bool multiStripMode = (nDigits >= 2);
310  int i = 0;
311  while (i < KLM::c_NChannelsAsic) {
312  KLMDigit* digit = m_AsicDigits[i];
313  if (digit == nullptr) {
314  ++i;
315  continue;
316  }
317  // Firmware bug (used OR of struck channel numbers in range 1..15) defeated the
318  // expected by-4 grouping so we assume the worst case: all 15 channels are struck.
319  // This will be reduced for BKLM scintillators if there are missing detectorChannels.
320  int minGroupChannel = 1;
321  int maxGroupChannel = KLM::c_NChannelsAsic;
322  KLMDigit* arrayDigit = m_Digits.appendNew(*digit);
323  KLMElectronicsChannel electronicsChannel(it->first);
324  int asic = electronicsChannel.getChannel();
325  bool connectedChannelFound = false;
326  int minStrip, maxStrip;
327  for (int j = minGroupChannel; j <= maxGroupChannel; ++j) {
328  electronicsChannel.setChannel(KLM::c_NChannelsAsic * asic + j);
329  const KLMChannelNumber* detectorChannel =
330  m_ElectronicsMap->getDetectorChannel(&electronicsChannel);
331  if (detectorChannel != nullptr) {
332  int subdetector, section, sector, layer, plane, strip;
334  *detectorChannel, &subdetector, &section, &sector, &layer,
335  &plane, &strip);
336  if (!connectedChannelFound) {
337  connectedChannelFound = true;
338  minStrip = strip;
339  maxStrip = strip;
340  } else {
341  if (strip < minStrip)
342  minStrip = strip;
343  if (strip > maxStrip)
344  maxStrip = strip;
345  }
346  }
347  }
348  /* This should never happen. */
349  if (!connectedChannelFound)
350  B2FATAL("Cannot find connected electronics channels.");
351  if (multiStripMode) {
352  arrayDigit->setStrip(minStrip);
353  arrayDigit->setLastStrip(maxStrip);
354  }
355  for (int j = i; j < maxGroupChannel; ++j) {
356  if (m_AsicDigits[j] == nullptr)
357  continue;
358  for (it3 = m_AsicDigitSimHitsLowerBound[j];
359  it3 != m_AsicDigitSimHitsUpperBound[j]; ++it3) {
360  arrayDigit->addRelationTo(it3->second);
361  }
362  }
363  i = maxGroupChannel;
364  }
365  for (i = 0; i < KLM::c_NChannelsAsic; ++i) {
366  if (m_AsicDigits[i] != nullptr)
367  delete m_AsicDigits[i];
368  }
369  } else {
370  for (int i = 0; i < KLM::c_NChannelsAsic; ++i) {
371  KLMDigit* digit = m_AsicDigits[i];
372  if (digit == nullptr)
373  continue;
374  KLMDigit* arrayDigit = m_Digits.appendNew(*digit);
375  for (it3 = m_AsicDigitSimHitsLowerBound[i];
376  it3 != m_AsicDigitSimHitsUpperBound[i]; ++it3) {
377  arrayDigit->addRelationTo(it3->second);
378  }
379  delete digit;
380  }
381  }
382  it = upperBound;
383  }
384 }
385 
387 {
388  int i;
389  KLMChannelNumber channel;
390  m_MapChannelSimHit.clear();
391  m_MapAsicSimHit.clear();
392  if (m_EfficiencyMode == c_Plane) {
393  m_MapPlaneSimHit.clear();
394  for (i = 0; i < m_SimHits.getEntries(); i++) {
395  const KLMSimHit* hit = m_SimHits[i];
396  /* For RPCs. */
397  if (hit->getStrip() <= 0)
398  continue;
399  const MCParticle* particle = hit->getRelatedFrom<MCParticle>();
400  /*
401  * We do not simulate the plane efficiency for KLMSimHits
402  * from beam background because there are no MCParticles associated
403  * to them.
404  */
405  if (particle != nullptr) {
406  KLMPlaneNumber plane =
408  hit->getSubdetector(), hit->getSection(), hit->getSector(),
409  hit->getLayer(), hit->getPlane());
410  m_MapPlaneSimHit.insert(
411  std::pair<KLMPlaneNumber, const KLMSimHit*>(plane, hit));
412  } else {
413  B2ASSERT("The KLMSimHit is not related to any MCParticle and "
414  "it is also not a beam background hit.",
415  hit->getBackgroundTag() != BackgroundMetaData::bg_none);
416  channel =
418  hit->getSubdetector(), hit->getSection(), hit->getSector(),
419  hit->getLayer(), hit->getPlane(), hit->getStrip());
420  if (checkActive(channel)) {
421  bool rpc = hit->inRPC();
422  if (rpc) {
423  m_MapChannelSimHit.insert(std::pair<KLMChannelNumber, const KLMSimHit*>(channel, hit));
424  } else {
425  const KLMElectronicsChannel* electronicsChannel =
426  m_ElectronicsMap->getElectronicsChannel(channel);
427  if (electronicsChannel == nullptr)
428  B2FATAL("Incomplete electronics map.");
429  KLMElectronicsChannel asic = electronicsChannel->getAsic();
430  m_MapAsicSimHit.insert(std::pair<KLMElectronicsChannel, const KLMSimHit*>(asic, hit));
431  }
432  }
433  }
434  }
435  std::multimap<KLMPlaneNumber, const KLMSimHit*>::iterator it, it2;
441  std::multimap<const MCParticle*, const KLMSimHit*,
442  CompareMCParticlesByIndex> particleHitMap;
443  std::multimap<const MCParticle*, const KLMSimHit*>::iterator
444  itParticle, it2Particle;
445  it = m_MapPlaneSimHit.begin();
446  while (it != m_MapPlaneSimHit.end()) {
447  particleHitMap.clear();
448  it2 = it;
449  while (true) {
450  const KLMSimHit* hit = it2->second;
451  const MCParticle* particle = hit->getRelatedFrom<MCParticle>();
452  particleHitMap.insert(
453  std::pair<const MCParticle*, const KLMSimHit*>(particle, hit));
454  ++it2;
455  if (it2 == m_MapPlaneSimHit.end())
456  break;
457  if (it2->first != it->first)
458  break;
459  }
460  itParticle = particleHitMap.begin();
461  while (itParticle != particleHitMap.end()) {
462  it2Particle = itParticle;
463  const KLMSimHit* hit = it2Particle->second;
464  channel =
466  hit->getSubdetector(), hit->getSection(), hit->getSector(),
467  hit->getLayer(), hit->getPlane(), hit->getStrip());
468  float efficiency = m_StripEfficiency->getEfficiency(channel);
469  bool hitSelected = efficiencyCorrection(efficiency);
470  while (true) {
471  hit = it2Particle->second;
472  bool rpc = hit->inRPC();
473  if (hitSelected) {
474  for (int s = hit->getStrip(); s <= hit->getLastStrip(); ++s) {
475  channel =
477  hit->getSubdetector(), hit->getSection(), hit->getSector(),
478  hit->getLayer(), hit->getPlane(), s);
479  if (!checkActive(channel))
480  continue;
481  if (rpc) {
482  m_MapChannelSimHit.insert(
483  std::pair<KLMChannelNumber, const KLMSimHit*>(channel, hit));
484  } else {
485  const KLMElectronicsChannel* electronicsChannel =
486  m_ElectronicsMap->getElectronicsChannel(channel);
487  if (electronicsChannel == nullptr)
488  B2FATAL("Incomplete electronics map.");
489  KLMElectronicsChannel asic = electronicsChannel->getAsic();
490  m_MapAsicSimHit.insert(
491  std::pair<KLMElectronicsChannel, const KLMSimHit*>(
492  asic, hit));
493  }
494  }
495  }
496  ++it2Particle;
497  if (it2Particle == particleHitMap.end())
498  break;
499  if (it2Particle->first != itParticle->first)
500  break;
501  }
502  itParticle = it2Particle;
503  }
504  it = it2;
505  }
506  } else {
507  for (i = 0; i < m_SimHits.getEntries(); i++) {
508  const KLMSimHit* hit = m_SimHits[i];
509  if (hit->inRPC()) {
510  if (hit->getStrip() <= 0)
511  continue;
512  for (int s = hit->getStrip(); s <= hit->getLastStrip(); ++s) {
514  hit->getSection(), hit->getSector(), hit->getLayer(),
515  hit->getPlane(), s);
516  if (checkActive(channel)) {
517  m_MapChannelSimHit.insert(
518  std::pair<KLMChannelNumber, const KLMSimHit*>(channel, hit));
519  }
520  }
521  } else {
522  channel = m_ElementNumbers->channelNumber(
523  hit->getSubdetector(), hit->getSection(), hit->getSector(),
524  hit->getLayer(), hit->getPlane(), hit->getStrip());
525  if (checkActive(channel)) {
526  const KLMElectronicsChannel* electronicsChannel =
527  m_ElectronicsMap->getElectronicsChannel(channel);
528  if (electronicsChannel == nullptr)
529  B2FATAL("Incomplete electronics map.");
530  KLMElectronicsChannel asic = electronicsChannel->getAsic();
531  m_MapAsicSimHit.insert(
532  std::pair<KLMElectronicsChannel, const KLMSimHit*>(asic, hit));
533  }
534  }
535  }
536  }
537  digitizeRPC();
538  digitizeAsic();
539 }
540 
542 {
543  delete m_Fitter;
544 }
545 
547 {
548 }
static int getStripByModule(int module)
Get strip number by module identifier.
KLM channel index.
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).
Definition: KLMDigit.h:29
void setMCTime(float time)
Set MC time.
Definition: KLMDigit.h:384
void setNGeneratedPhotoelectrons(int nPhotoelectrons)
Set generated number of photoelectrons.
Definition: KLMDigit.h:339
void setLastStrip(int lastStrip)
Set last strip number (for multi-strip digits).
Definition: KLMDigit.h:189
void setSiPMMCTime(float time)
Set SiPM MC time.
Definition: KLMDigit.h:402
void setEnergyDeposit(float eDep)
Set energy deposit.
Definition: KLMDigit.h:303
void setNPhotoelectrons(float nPhotoelectrons)
Set number of photoelectrons.
Definition: KLMDigit.h:321
void setStrip(int strip)
Set strip number.
Definition: KLMDigit.h:171
void setTime(float time)
Set hit time.
Definition: KLMDigit.h:285
void setTDC(uint16_t tdc)
Set TDC.
Definition: KLMDigit.h:267
void setFitStatus(int s)
Set fit status.
Definition: KLMDigit.h:366
void setCharge(uint16_t charge)
Set charge.
Definition: KLMDigit.h:231
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.
void digitizeAsic()
Digitization in ASIC.
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.
KLM element numbers.
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.
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.
KLM simulation hit.
Definition: KLMSimHit.h:31
KLM time conversion.
Definition: KLMTime.h:27
double getCTimePeriod() const
Get CTIME period.
Definition: KLMTime.h:53
double getTimeSimulation(int tdc, bool scintillator) const
Get time for simulation.
Definition: KLMTime.cc:66
void updateConstants()
Update constants from database objects.
Definition: KLMTime.cc:20
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.
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.
Definition: MCParticle.h:32
int getIndex() const
Get 1-based index of the particle in the corresponding MCParticle list.
Definition: MCParticle.h:230
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
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).
Comparison of MCParticles by index.
bool operator()(const MCParticle *particle1, const MCParticle *particle2) const
Compare MCParticles by index.
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 &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
uint16_t KLMChannelNumber
Channel number.
uint16_t KLMPlaneNumber
Plane number.
Abstract base class for different kinds of events.