10 #include <klm/modules/KLMReconstructor/KLMReconstructorModule.h>
13 #include <klm/bklm/geometry/Module.h>
14 #include <klm/dataobjects/eklm/EKLMElementNumbers.h>
17 #include <framework/gearbox/Const.h>
18 #include <framework/logging/Logger.h>
21 #include <CLHEP/Vector/ThreeVector.h>
27 using namespace Belle2::bklm;
67 m_CoincidenceWindow(0),
72 m_bklmGeoPar(nullptr),
74 m_eklmGeoDat(nullptr),
76 m_eklmTransformData{nullptr}
78 setDescription(
"Create BKLMHit1ds from KLMDigits and then create KLMHit2ds from BKLMHit1ds; create KLMHit2ds from KLMDigits.");
81 "Perform cable delay time correction (true) or not (false).",
true);
83 "Perform EventT0 correction (true) or not (false)",
true);
85 "Perform alignment correction (true) or not (false).",
88 "Ignore scintillators (to debug their electronics mapping).",
91 "Check if segments intersect.",
true);
93 "Use only Normal and Dead (for debugging) channels during 2d hit reconstruction",
125 B2FATAL(
"It is not possible to run EKLM reconstruction with 1 plane.");
133 B2FATAL(
"KLM time constants data are not available.");
135 B2FATAL(
"KLM time cable decay data are not available.");
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.");
142 B2FATAL(
"KLM channel status data are not available.");
144 B2FATAL(
"KLM time window data are not available.");
172 unsigned int cID = d->getUniqueChannelID();
205 B2FATAL(
"Incomplete KLM channel status data.");
214 uint16_t nKLMDigitsMultiStripBarrel{0};
217 std::map<KLMChannelNumber, int> channelDigitMap;
218 for (
int index = 0; index <
m_Digits.getEntries(); ++index) {
223 nKLMDigitsMultiStripBarrel++;
234 channelDigitMap.insert(std::pair<KLMChannelNumber, int>(channel, index));
237 if (channelDigitMap.empty())
239 std::vector<std::pair<const KLMDigit*, double>> digitCluster;
241 double averageTime =
m_Digits[channelDigitMap.begin()->second]->getTime();
244 for (std::map<KLMChannelNumber, int>::iterator it = channelDigitMap.begin(); it != channelDigitMap.end(); ++it) {
246 double digitTime = digit->
getTime();
249 if ((it->first > previousChannel + 1) || (std::fabs(digitTime - averageTime) >
m_CoincidenceWindow)) {
251 digitCluster.clear();
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));
266 for (
int j = i + 1; j <
m_bklmHit1ds.getEntries(); ++j) {
272 int phiIndex = isPhiReadout ? i : j;
273 int zIndex = isPhiReadout ? j : i;
277 CLHEP::Hep3Vector propagationDist;
280 propagationDist = m->getPropagationDistance(
284 propagationDist = m->getPropagationDistance(
289 propagationDist = m->getPropagationTimes(local);
291 double delayPhi, delayZ;
300 double phiTime = phiHit->
getTime() - propagationDist.y() * delayPhi;
301 double zTime = zHit->
getTime() - propagationDist.z() * delayZ;
305 CLHEP::Hep3Vector global = m->localToGlobal(local + m->getLocalReconstructionShift(),
m_bklmIfAlign);
306 double time = 0.5 * (phiTime + zTime);
321 uint16_t nKLMDigitsMultiStripFWD{0};
322 uint16_t nKLMDigitsMultiStripBWD{0};
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;
328 for (i = 0; i < n; i++) {
338 digitVector.push_back(digit);
344 sort(digitVector.begin(), digitVector.end(), compareSector);
345 it1 = digitVector.begin();
346 while (it1 != digitVector.end()) {
350 if (it2 == digitVector.end())
352 if (!sameSector(*it1, *it2))
356 sort(it1, it2, comparePlane);
358 if ((*it1)->getPlane() != 1) {
367 if ((*it3)->getPlane() != (*it1)->getPlane())
379 sort(it1, it3, compareStrip);
380 sort(it3, it2, compareStrip);
389 if ((*it5)->getStrip() != (*it4)->getStrip() ||
390 (*it5)->getPlane() != (*it4)->getPlane())
394 sort(it4, it5, compareTime);
405 if ((*it5)->getStrip() != (*it4)->getStrip())
415 if ((*it7)->getStrip() != (*it6)->getStrip())
422 for (it8 = it4; it8 != it5; ++it8) {
423 for (it9 = it6; it9 != it7; ++it9) {
430 if ((*it8)->isMultiStrip() || (*it9)->isMultiStrip()) {
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++) {
439 for (
int s2 = s2First; s2 <= s2Last; s2++) {
452 plane1Digit.
setStrip((s1First + s1Last) / 2);
453 plane2Digit.
setStrip((s2First + s2Last) / 2);
475 time = (t1 + t2) / 2;
480 (*it9)->getEnergyDeposit());
481 hit2d->
setPosition(crossPoint.x(), crossPoint.y(), crossPoint.z());
482 double timeResolution = 1.0;
485 (*it8)->getUniqueChannelID());
487 (*it9)->getUniqueChannelID());
489 hit2d->
setChiSq((t1 - t2) * (t1 - t2) / timeResolution);
491 hit2d->
setMCTime(((*it8)->getMCTime() + (*it9)->getMCTime()) / 2);
494 for (i = 0; i < 2; i++) {
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.
bool inRPC() const
Determine whether this 1D hit is in RPC or scintillator.
float getTime() const
Get reconstructed hit time.
double getStripAve() const
Get average strip number.
static const double speedOfLight
[cm/ns]
This dataobject is used only for EKLM alignment.
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.
@ c_BackwardSection
Backward.
int getNPlanes() const
Get number of planes.
static const GeometryData & Instance(enum DataSource dataSource=c_Database, const GearDir *gearDir=nullptr)
Instantiation.
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).
bool inRPC() const
Determine whether the hit is in RPC or scintillator.
int getSubdetector() const
Get subdetector number.
int getLayer() const
Get layer number.
bool isGood() const
Whether hit could be used late (if it passed discriminator threshold)
float getTime() const
Get hit time.
int getSection() const
Get section number.
int getPlane() const
Get plane number.
int getStrip() const
Get strip number.
bool isMultiStrip() const
Determine whether this digit is a multi-strip one or not.
int getSector() const
Get sector number.
void setStrip(int strip)
Set strip number.
int getLastStrip() const
Get last strip number (for multi-strip digits).
KLMChannelNumber channelNumber(int subdetector, int section, int sector, int layer, int plane, int strip) const
Get channel number.
void setEnergyDeposit(float energyDeposit)
Set energy deposit.
void setChiSq(float chisq)
Set Chi^2 of the crossing point.
void setTime(float time)
Set hit time.
void setMCTime(float t)
Set MC time.
bool isOutOfTime() const
Determine whether this 2D hit is outside the trigger-coincidence window.
void setPosition(float x, float y, float z)
Set hit global position.
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.
~KLMReconstructorModule()
Destructor.
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.
KLMReconstructorModule()
Constructor.
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.
int m_eklmNStrip
Number of strips.
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.
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).
const Module * findModule(int section, int sector, int layer) const
Get the pointer to the definition of a module.
static GeometryPar * instance(void)
Static method to get a reference to the singleton GeometryPar instance.
Define the geometry of a BKLM module Each sector [octant] contains Modules.
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.
int intersect(const TRGCDCLpar &lp1, const TRGCDCLpar &lp2, CLHEP::HepVector &v1, CLHEP::HepVector &v2)
intersection
Abstract base class for different kinds of events.