Belle II Software release-09-00-00
KLMReconstructorModule.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/KLMReconstructor/KLMReconstructorModule.h>
11
12/* KLM headers. */
13#include <klm/bklm/geometry/Module.h>
14#include <klm/dataobjects/eklm/EKLMElementNumbers.h>
15
16/* Basf2 headers. */
17#include <framework/gearbox/Const.h>
18#include <framework/logging/Logger.h>
19
20/* CLHEP headers. */
21#include <CLHEP/Vector/ThreeVector.h>
22
23/* C++ headers. */
24#include <utility>
25
26using namespace Belle2;
27using namespace Belle2::bklm;
28
29REG_MODULE(KLMReconstructor)
30
31static bool compareSector(KLMDigit* d1, KLMDigit* d2)
32{
33 int s1, s2;
34 static const EKLMElementNumbers& elementNumbers =
36 s1 = elementNumbers.sectorNumber(d1->getSection(), d1->getLayer(),
37 d1->getSector());
38 s2 = elementNumbers.sectorNumber(d2->getSection(), d2->getLayer(),
39 d2->getSector());
40 return s1 < s2;
41}
42
43static bool comparePlane(KLMDigit* d1, KLMDigit* d2)
44{
45 return d1->getPlane() < d2->getPlane();
46}
47
48static bool compareStrip(KLMDigit* d1, KLMDigit* d2)
49{
50 return d1->getStrip() < d2->getStrip();
51}
52
53static bool compareTime(KLMDigit* d1, KLMDigit* d2)
54{
55 return d1->getTime() < d2->getTime();
56}
57
58static bool sameSector(KLMDigit* d1, KLMDigit* d2)
59{
60 return ((d1->getSection() == d2->getSection()) &&
61 (d1->getLayer() == d2->getLayer()) &&
62 (d1->getSector() == d2->getSector()));
63}
64
66 Module(),
67 m_CoincidenceWindow(0),
68 m_PromptTime(0),
69 m_PromptWindow(0),
70 m_EventT0Value(0.),
71 m_ElementNumbers(&(KLMElementNumbers::Instance())),
72 m_bklmGeoPar(nullptr),
73 m_eklmElementNumbers(&(EKLMElementNumbers::Instance())),
74 m_eklmGeoDat(nullptr),
75 m_eklmNStrip(0),
76 m_eklmTransformData{nullptr}
77{
78 setDescription("Create BKLMHit1ds from KLMDigits and then create KLMHit2ds from BKLMHit1ds; create KLMHit2ds from KLMDigits.");
80 addParam("TimeCableDelayCorrection", m_TimeCableDelayCorrection,
81 "Perform cable delay time correction (true) or not (false).", true);
82 addParam("EventT0Correction", m_EventT0Correction,
83 "Perform EventT0 correction (true) or not (false)", true);
84 addParam("IfAlign", m_bklmIfAlign,
85 "Perform alignment correction (true) or not (false).",
86 bool(true));
87 addParam("IgnoreScintillators", m_bklmIgnoreScintillators,
88 "Ignore scintillators (to debug their electronics mapping).",
89 false);
90 addParam("CheckSegmentIntersection", m_eklmCheckSegmentIntersection,
91 "Check if segments intersect.", true);
92 addParam("IgnoreHotChannels", m_IgnoreHotChannels,
93 "Use only Normal and Dead (for debugging) channels during 2d hit reconstruction",
94 true);
95}
96
98{
99}
100
102{
103 m_Digits.isRequired();
105 m_EventT0.isRequired();
106 // This object is registered by both ECL and KLM packages. Let's be agnostic about the
107 // execution order of ecl and klm modules: the first package run registers the module
108 m_EventLevelClusteringInfo.isOptional() ?
109 m_EventLevelClusteringInfo.isRequired() :
110 m_EventLevelClusteringInfo.registerInDataStore();
111 m_Hit2ds.registerInDataStore();
112 m_Hit2ds.registerRelationTo(m_bklmHit1ds);
113 m_Hit2ds.registerRelationTo(m_Digits);
114 /* BKLM. */
115 m_bklmHit1ds.registerInDataStore();
116 m_bklmHit1ds.registerRelationTo(m_Digits);
118 /* EKLM. */
119 m_eklmAlignmentHits.registerInDataStore();
120 m_eklmAlignmentHits.registerRelationTo(m_Hit2ds);
124 if (m_eklmGeoDat->getNPlanes() != 2)
125 B2FATAL("It is not possible to run EKLM reconstruction with 1 plane.");
127}
128
130{
132 if (!m_TimeConstants.isValid())
133 B2FATAL("KLM time constants data are not available.");
134 if (!m_TimeCableDelay.isValid())
135 B2FATAL("KLM time cable decay data are not available.");
136 if (!m_TimeResolution.isValid())
137 B2ERROR("KLM time resolution data are not available. "
138 "The error is non-fatal because the data are only used to set "
139 "chi^2 of 2d hit, which is informational only now.");
140 }
141 if (!m_ChannelStatus.isValid())
142 B2FATAL("KLM channel status data are not available.");
143 if (!m_TimeWindow.isValid())
144 B2FATAL("KLM time window data are not available.");
145 m_CoincidenceWindow = m_TimeWindow->getCoincidenceWindow();
146 m_PromptTime = m_TimeWindow->getPromptTime();
147 m_PromptWindow = m_TimeWindow->getPromptWindow();
155 }
156}
157
159{
160 m_EventT0Value = 0.;
161 if (m_EventT0.isValid())
162 if (m_EventT0->hasEventT0())
163 m_EventT0Value = m_EventT0->getEventT0();
164 if (not m_EventLevelClusteringInfo.isValid())
165 m_EventLevelClusteringInfo.construct();
168}
169
171{
172 unsigned int cID = d->getUniqueChannelID();
173 ct -= m_TimeCableDelay->getTimeDelay(cID);
174}
175
176/*
177double KLMReconstructorModule::getTime(KLMDigit* d, double dist)
178{
179 int strip;
180 strip = m_eklmElementNumbers->stripNumber(
181 d->getSection(), d->getLayer(), d->getSector(),
182 d->getPlane(), d->getStrip()) - 1;
183 return d->getTime() -
184 (dist / m_eklmTimeCalibration->getEffectiveLightSpeed() +
185 m_eklmTimeCalibrationData[strip]->getTimeShift());
186
187 // TODO: Subtract time correction given by
188 // m_eklmTimeCalibration->getAmplitudeTimeConstant() / sqrt(d->getNPhotoelectrons()).
189 // It requires a new firmware version that will be able to extract amplitude.
190
191}
192*/
193
195{
196 int subdetector = digit->getSubdetector();
197 int section = digit->getSection();
198 int sector = digit->getSector();
199 int layer = digit->getLayer();
200 int plane = digit->getPlane();
201 int strip = digit->getStrip();
202 KLMChannelNumber channel = m_ElementNumbers->channelNumber(subdetector, section, sector, layer, plane, strip);
203 enum KLMChannelStatus::ChannelStatus status = m_ChannelStatus->getChannelStatus(channel);
204 if (status == KLMChannelStatus::c_Unknown)
205 B2FATAL("Incomplete KLM channel status data.");
206 if (status == KLMChannelStatus::c_Normal || status == KLMChannelStatus::c_Dead)
207 return true;
208 return false;
209}
210
212{
213 /* Let's count the multi-strip KLMDigits. */
214 uint16_t nKLMDigitsMultiStripBarrel{0};
215 /* Construct BKLMHit1Ds from KLMDigits. */
216 /* Sort KLMDigits by module and strip number. */
217 std::map<KLMChannelNumber, int> channelDigitMap;
218 for (int index = 0; index < m_Digits.getEntries(); ++index) {
219 const KLMDigit* digit = m_Digits[index];
221 continue;
222 if (digit->isMultiStrip()) {
223 nKLMDigitsMultiStripBarrel++;
224 }
225 if (m_bklmIgnoreScintillators && !digit->inRPC())
226 continue;
227 if (m_IgnoreHotChannels && !isNormal(digit))
228 continue;
229 if (digit->inRPC() || digit->isGood()) {
231 digit->getSection(), digit->getSector(),
232 digit->getLayer(), digit->getPlane(),
233 digit->getStrip());
234 channelDigitMap.insert(std::pair<KLMChannelNumber, int>(channel, index));
235 }
236 }
237 if (channelDigitMap.empty())
238 return;
239 std::vector<std::pair<const KLMDigit*, double>> digitCluster;
240 KLMChannelNumber previousChannel = channelDigitMap.begin()->first;
241 double averageTime = m_Digits[channelDigitMap.begin()->second]->getTime();
243 correctCableDelay(averageTime, m_Digits[channelDigitMap.begin()->second]);
244 for (std::map<KLMChannelNumber, int>::iterator it = channelDigitMap.begin(); it != channelDigitMap.end(); ++it) {
245 const KLMDigit* digit = m_Digits[it->second];
246 double digitTime = digit->getTime();
248 correctCableDelay(digitTime, digit);
249 if ((it->first > previousChannel + 1) || (std::fabs(digitTime - averageTime) > m_CoincidenceWindow)) {
250 m_bklmHit1ds.appendNew(digitCluster); // Also sets relation BKLMHit1d -> KLMDigit
251 digitCluster.clear();
252 }
253 previousChannel = it->first;
254 double n = (double)(digitCluster.size());
255 averageTime = (n * averageTime + digitTime) / (n + 1.0);
256 digitCluster.emplace_back(std::make_pair(digit, digitTime));
257 }
258 m_bklmHit1ds.appendNew(digitCluster); // Also sets relation BKLMHit1d -> KLMDigit
259
260 /* Construct BKLMHit2Ds from orthogonal same-module BKLMHit1Ds. */
261 for (int i = 0; i < m_bklmHit1ds.getEntries(); ++i) {
262 int moduleID = m_bklmHit1ds[i]->getModuleID();
263 const bklm::Module* m = m_bklmGeoPar->findModule(m_bklmHit1ds[i]->getSection(), m_bklmHit1ds[i]->getSector(),
264 m_bklmHit1ds[i]->getLayer());
265 bool isPhiReadout = m_bklmHit1ds[i]->isPhiReadout();
266 for (int j = i + 1; j < m_bklmHit1ds.getEntries(); ++j) {
268 moduleID, m_bklmHit1ds[j]->getModuleID()))
269 continue;
270 if (isPhiReadout == m_bklmHit1ds[j]->isPhiReadout())
271 continue;
272 int phiIndex = isPhiReadout ? i : j;
273 int zIndex = isPhiReadout ? j : i;
274 const BKLMHit1d* phiHit = m_bklmHit1ds[phiIndex];
275 const BKLMHit1d* zHit = m_bklmHit1ds[zIndex];
276 CLHEP::Hep3Vector local = m->getLocalPosition(phiHit->getStripAve(), zHit->getStripAve());
277 CLHEP::Hep3Vector propagationDist;
279 if (isPhiReadout) {
280 propagationDist = m->getPropagationDistance(
281 local, m_bklmHit1ds[j]->getStripMin(),
282 m_bklmHit1ds[i]->getStripMin());
283 } else {
284 propagationDist = m->getPropagationDistance(
285 local, m_bklmHit1ds[i]->getStripMin(),
286 m_bklmHit1ds[j]->getStripMin());
287 }
288 } else {
289 propagationDist = m->getPropagationTimes(local);
290 }
291 double delayPhi, delayZ;
292 if (phiHit->inRPC())
293 delayPhi = m_DelayRPCPhi;
294 else
295 delayPhi = m_DelayBKLMScintillators;
296 if (zHit->inRPC())
297 delayZ = m_DelayRPCZ;
298 else
300 double phiTime = phiHit->getTime() - propagationDist.y() * delayPhi;
301 double zTime = zHit->getTime() - propagationDist.z() * delayZ;
302 if (std::fabs(phiTime - zTime) > m_CoincidenceWindow)
303 continue;
304 // The second param in localToGlobal is whether do the alignment correction (true) or not (false)
305 CLHEP::Hep3Vector global = m->localToGlobal(local + m->getLocalReconstructionShift(), m_bklmIfAlign);
306 double time = 0.5 * (phiTime + zTime);
308 time -= m_EventT0Value;
309 KLMHit2d* hit2d = m_Hit2ds.appendNew(phiHit, zHit, global, time); // Also sets relation KLMHit2d -> BKLMHit1d
310 if (std::fabs(time - m_PromptTime) > m_PromptWindow)
311 hit2d->isOutOfTime(true);
312 }
313 }
314 m_EventLevelClusteringInfo->setNKLMDigitsMultiStripBarrel(nKLMDigitsMultiStripBarrel);
315}
316
317
319{
320 /* Let's count the multi-strip KLMDigits. */
321 uint16_t nKLMDigitsMultiStripFWD{0};
322 uint16_t nKLMDigitsMultiStripBWD{0};
323 int i, n;
324 double d1, d2, time, t1, t2, sd;
325 std::vector<KLMDigit*> digitVector;
326 std::vector<KLMDigit*>::iterator it1, it2, it3, it4, it5, it6, it7, it8, it9;
327 n = m_Digits.getEntries();
328 for (i = 0; i < n; i++) {
329 KLMDigit* digit = m_Digits[i];
331 continue;
332 if (digit->isMultiStrip()) {
333 digit->getSection() == EKLMElementNumbers::c_BackwardSection ? nKLMDigitsMultiStripBWD++ : nKLMDigitsMultiStripFWD++;
334 }
335 if (m_IgnoreHotChannels && !isNormal(digit))
336 continue;
337 if (digit->isGood())
338 digitVector.push_back(digit);
339 }
340 KLMDigit plane1Digit; // to look for geometric intersection of a multi-strip hit
341 KLMDigit plane2Digit; // to look for geometric intersection of a multi-strip hit
342 HepGeom::Point3D<double> crossPoint(0, 0, 0); // (x,y,z) of geometric intersection
343 /* Sort by sector. */
344 sort(digitVector.begin(), digitVector.end(), compareSector);
345 it1 = digitVector.begin();
346 while (it1 != digitVector.end()) {
347 it2 = it1;
348 while (1) {
349 ++it2;
350 if (it2 == digitVector.end())
351 break;
352 if (!sameSector(*it1, *it2))
353 break;
354 }
355 /* Now it1 .. it2 - hits in a sector. Sort by plane. */
356 sort(it1, it2, comparePlane);
357 /* If all hits are form the second plane, then continue. */
358 if ((*it1)->getPlane() != 1) {
359 it1 = it2;
360 continue;
361 }
362 it3 = it1;
363 while (1) {
364 ++it3;
365 if (it3 == it2)
366 break;
367 if ((*it3)->getPlane() != (*it1)->getPlane())
368 break;
369 }
370 /*
371 * Now it1 .. it3 - hits from the first plane, it3 .. it2 - hits from the
372 * second plane. If there are no hits from the second plane, then continue.
373 */
374 if (it3 == it2) {
375 it1 = it2;
376 continue;
377 }
378 /* Sort by strip. */
379 sort(it1, it3, compareStrip);
380 sort(it3, it2, compareStrip);
381 it4 = it1;
382 while (it4 != it2) {
383 it5 = it4;
384 while (1) {
385 ++it5;
386 if (it5 == it2)
387 break;
388 /* This loop is for both planes so it is necessary to compare planes. */
389 if ((*it5)->getStrip() != (*it4)->getStrip() ||
390 (*it5)->getPlane() != (*it4)->getPlane())
391 break;
392 }
393 /* Now it4 .. it5 - hits from the same strip. Sort by time. */
394 sort(it4, it5, compareTime);
395 it4 = it5;
396 }
397 /* Strip loop. */
398 it4 = it1;
399 while (it4 != it3) {
400 it5 = it4;
401 while (1) {
402 ++it5;
403 if (it5 == it3)
404 break;
405 if ((*it5)->getStrip() != (*it4)->getStrip())
406 break;
407 }
408 it6 = it3;
409 while (it6 != it2) {
410 it7 = it6;
411 while (1) {
412 ++it7;
413 if (it7 == it2)
414 break;
415 if ((*it7)->getStrip() != (*it6)->getStrip())
416 break;
417 }
418 /*
419 * Now it4 .. it5 - hits from a single first-plane strip and
420 * it6 .. it7 - hits from a single second-plane strip.
421 */
422 for (it8 = it4; it8 != it5; ++it8) {
423 for (it9 = it6; it9 != it7; ++it9) {
424 /*
425 * Check for intersection of the two orthogonal strips. On one strip,
426 * one hit might be multi-strip and another single-strip, so the
427 * intersection check must be done here rather than before the loop.
428 */
429 bool intersect = false;
430 if ((*it8)->isMultiStrip() || (*it9)->isMultiStrip()) {
431 plane1Digit = **it8;
432 plane2Digit = **it9;
433 int s1First = plane1Digit.getStrip();
434 int s1Last = std::max(s1First, plane1Digit.getLastStrip());
435 int s2First = plane2Digit.getStrip();
436 int s2Last = std::max(s2First, plane2Digit.getLastStrip());
437 for (int s1 = s1First; s1 <= s1Last; s1++) {
438 plane1Digit.setStrip(s1);
439 for (int s2 = s2First; s2 <= s2Last; s2++) {
440 plane2Digit.setStrip(s2);
441 intersect = m_eklmTransformData->intersection(&plane1Digit, &plane2Digit, &crossPoint,
442 &d1, &d2, &sd,
444 if (intersect)
445 break;
446 }
447 if (intersect)
448 break;
449 }
450 if (intersect) {
451 // use the middle strip in the multi-strip group to get the 2D intersection point
452 plane1Digit.setStrip((s1First + s1Last) / 2);
453 plane2Digit.setStrip((s2First + s2Last) / 2);
454 intersect = m_eklmTransformData->intersection(&plane1Digit, &plane2Digit, &crossPoint,
455 &d1, &d2, &sd,
456 false); // crossPoint MIGHT be outside fiducial area
457 }
458 } else {
459 intersect = m_eklmTransformData->intersection(*it8, *it9, &crossPoint,
460 &d1, &d2, &sd,
462 }
463 if (!intersect)
464 continue;
465 t1 = (*it8)->getTime() - d1 * m_DelayEKLMScintillators
466 + 0.5 * sd / Const::speedOfLight;
467 t2 = (*it9)->getTime() - d2 * m_DelayEKLMScintillators
468 - 0.5 * sd / Const::speedOfLight;
470 correctCableDelay(t1, *it8);
471 correctCableDelay(t2, *it9);
472 }
473 if (std::fabs(t1 - t2) > m_CoincidenceWindow)
474 continue;
475 time = (t1 + t2) / 2;
477 time -= m_EventT0Value;
478 KLMHit2d* hit2d = m_Hit2ds.appendNew(*it8, *it9);
479 hit2d->setEnergyDeposit((*it8)->getEnergyDeposit() +
480 (*it9)->getEnergyDeposit());
481 hit2d->setPosition(crossPoint.x(), crossPoint.y(), crossPoint.z());
482 double timeResolution = 1.0;
483 if (m_TimeResolution.isValid()) {
484 timeResolution *= m_TimeResolution->getTimeResolution(
485 (*it8)->getUniqueChannelID());
486 timeResolution *= m_TimeResolution->getTimeResolution(
487 (*it9)->getUniqueChannelID());
488 }
489 hit2d->setChiSq((t1 - t2) * (t1 - t2) / timeResolution);
490 hit2d->setTime(time);
491 hit2d->setMCTime(((*it8)->getMCTime() + (*it9)->getMCTime()) / 2);
492 hit2d->addRelationTo(*it8);
493 hit2d->addRelationTo(*it9);
494 for (i = 0; i < 2; i++) {
495 EKLMAlignmentHit* alignmentHit = m_eklmAlignmentHits.appendNew(i);
496 alignmentHit->addRelationTo(hit2d);
497 }
498 /* Exit the loop. Equivalent to selection of the earliest hit. */
499 break;
500 }
501 /* Exit the loop. Equivalent to selection of the earliest hit. */
502 break;
503 }
504 it6 = it7;
505 }
506 it4 = it5;
507 }
508 it1 = it2;
509 }
510 m_EventLevelClusteringInfo->setNKLMDigitsMultiStripBWD(nKLMDigitsMultiStripBWD);
511 m_EventLevelClusteringInfo->setNKLMDigitsMultiStripFWD(nKLMDigitsMultiStripFWD);
512}
513
515{
516}
517
519{
520 delete m_eklmTransformData;
521}
static KLMChannelNumber channelNumber(int section, int sector, int layer, int plane, int strip)
Get channel number.
@ c_FirstRPCLayer
First RPC layer.
static bool hitsFromSameModule(int module1, int module2)
Check whether the hits are from the same module.
Store one reconstructed BKLM 1D hit as a ROOT object.
Definition: BKLMHit1d.h:30
bool inRPC() const
Determine whether this 1D hit is in RPC or scintillator.
Definition: BKLMHit1d.h:54
float getTime() const
Get reconstructed hit time.
Definition: BKLMHit1d.h:126
double getStripAve() const
Get average strip number.
Definition: BKLMHit1d.h:111
static const double speedOfLight
[cm/ns]
Definition: Const.h:695
This dataobject is used only for EKLM alignment.
EKLM element numbers.
static const EKLMElementNumbers & Instance()
Instantiation.
int sectorNumber(int section, int layer, int sector) const
Get sector number.
static constexpr int getMaximalStripGlobalNumber()
Get maximal strip global number.
int getNPlanes() const
Get number of planes.
static const GeometryData & Instance(enum DataSource dataSource=c_Database, const GearDir *gearDir=nullptr)
Instantiation.
Definition: GeometryData.cc:33
Transformation data.
Definition: TransformData.h:35
@ c_Alignment
Use alignment data (for everything else).
Definition: TransformData.h:45
bool intersection(KLMDigit *hit1, KLMDigit *hit2, HepGeom::Point3D< double > *cross, double *d1, double *d2, double *sd, bool segments=true) const
Check if strips intersect, and find intersection point if yes.
ChannelStatus
Channel status.
@ c_Normal
Normally operating channel.
@ 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
bool inRPC() const
Determine whether the hit is in RPC or scintillator.
Definition: KLMDigit.h:206
int getSubdetector() const
Get subdetector number.
Definition: KLMDigit.h:72
int getLayer() const
Get layer number.
Definition: KLMDigit.h:126
bool isGood() const
Whether hit could be used late (if it passed discriminator threshold)
Definition: KLMDigit.h:348
float getTime() const
Get hit time.
Definition: KLMDigit.h:276
int getSection() const
Get section number.
Definition: KLMDigit.h:90
int getPlane() const
Get plane number.
Definition: KLMDigit.h:144
int getStrip() const
Get strip number.
Definition: KLMDigit.h:162
bool isMultiStrip() const
Determine whether this digit is a multi-strip one or not.
Definition: KLMDigit.h:197
int getSector() const
Get sector number.
Definition: KLMDigit.h:108
void setStrip(int strip)
Set strip number.
Definition: KLMDigit.h:171
int getLastStrip() const
Get last strip number (for multi-strip digits).
Definition: KLMDigit.h:180
KLM element numbers.
KLMChannelNumber channelNumber(int subdetector, int section, int sector, int layer, int plane, int strip) const
Get channel number.
KLM 2d hit.
Definition: KLMHit2d.h:33
void setEnergyDeposit(float energyDeposit)
Set energy deposit.
Definition: KLMHit2d.h:369
void setChiSq(float chisq)
Set Chi^2 of the crossing point.
Definition: KLMHit2d.h:387
void setTime(float time)
Set hit time.
Definition: KLMHit2d.h:333
void setMCTime(float t)
Set MC time.
Definition: KLMHit2d.h:342
bool isOutOfTime() const
Determine whether this 2D hit is outside the trigger-coincidence window.
Definition: KLMHit2d.h:395
void setPosition(float x, float y, float z)
Set hit global position.
Definition: KLMHit2d.h:277
OptionalDBObjPtr< KLMTimeResolution > m_TimeResolution
KLM time resolution.
void reconstructEKLMHits()
Reconstruct EKLNM 2d hits.
bool m_TimeCableDelayCorrection
Perform cable delay time correction (true) or not (false).
StoreArray< KLMDigit > m_Digits
KLM digits.
DBObjPtr< KLMChannelStatus > m_ChannelStatus
Channel status.
EKLM::TransformData * m_eklmTransformData
Transformation data.
void initialize() override
Initializer.
void event() override
Called for each event.
const KLMElementNumbers * m_ElementNumbers
KLM element numbers.
bklm::GeometryPar * m_bklmGeoPar
BKLM GeometryPar singleton.
StoreArray< EKLMAlignmentHit > m_eklmAlignmentHits
Alignment Hits.
double m_CoincidenceWindow
Half-width of the time coincidence window used to create a 2D hit from 1D digits/hits.
void endRun() override
Called if the current run ends.
const EKLMElementNumbers * m_eklmElementNumbers
EKLM element numbers.
double m_DelayBKLMScintillators
Delay (ns / cm) for BKLM scintillators.
void terminate() override
Called at the end of the event processing.
bool m_bklmIfAlign
Perform alignment correction (true) or not (false).
StoreObjPtr< EventLevelClusteringInfo > m_EventLevelClusteringInfo
EventLevelClusteringInfo.
double m_EventT0Value
Value of the EventT0.
void reconstructBKLMHits()
Reconstruct BKLM 2d hits.
double m_PromptTime
Nominal time of prompt KLMHit2ds.
double m_DelayRPCPhi
Delay (ns / cm) for RPC phi plane.
void beginRun() override
Called when entering a new run.
bool isNormal(const KLMDigit *digit) const
Check if channel is normal or dead.
OptionalDBObjPtr< KLMTimeCableDelay > m_TimeCableDelay
KLM time cable delay.
void correctCableDelay(double &td, const KLMDigit *digit)
Time correction by subtract cable delay.
double m_PromptWindow
Half-width of the time window relative to the prompt time for KLMHit2ds.
StoreArray< BKLMHit1d > m_bklmHit1ds
BKLM 1d hits.
const EKLM::GeometryData * m_eklmGeoDat
Geometry data.
double m_DelayEKLMScintillators
Delay (ns / cm) for EKLM scintillators.
StoreObjPtr< EventT0 > m_EventT0
EventT0.
bool m_EventT0Correction
Perform EventT0 correction (true) or not (false).
bool m_bklmIgnoreScintillators
Ignore scintillators (to debug their electronics mapping).
bool m_IgnoreHotChannels
Use only normal and dead (for debugging) channels during 2d hit reconstruction.
OptionalDBObjPtr< KLMTimeConstants > m_TimeConstants
KLM time constants.
double m_DelayRPCZ
Delay (ns / cm) for RPC Z plane.
DBObjPtr< KLMTimeWindow > m_TimeWindow
KLM time window.
bool m_eklmCheckSegmentIntersection
Check if segments intersect.
StoreArray< KLMHit2d > m_Hit2ds
KLM 2d hits.
@ c_BKLM
BKLM scintillator.
@ c_EKLM
EKLM scintillator.
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).
const Module * findModule(int section, int sector, int layer) const
Get the pointer to the definition of a module.
Definition: GeometryPar.cc:721
static GeometryPar * instance(void)
Static method to get a reference to the singleton GeometryPar instance.
Definition: GeometryPar.cc:27
Define the geometry of a BKLM module Each sector [octant] contains Modules.
Definition: Module.h:76
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
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
uint16_t KLMChannelNumber
Channel number.
int intersect(const TRGCDCLpar &lp1, const TRGCDCLpar &lp2, CLHEP::HepVector &v1, CLHEP::HepVector &v2)
intersection
Definition: Lpar.cc:249
Abstract base class for different kinds of events.