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>
27using 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",
124 B2FATAL(
"It is not possible to run EKLM reconstruction with 1 plane.");
132 B2FATAL(
"KLM time constants data are not available.");
134 B2FATAL(
"KLM time cable decay data are not available.");
136 B2ERROR(
"KLM time resolution data are not available. "
137 "The error is non-fatal because the data are only used to set "
138 "chi^2 of 2d hit, which is informational only now.");
141 B2FATAL(
"KLM channel status data are not available.");
143 B2FATAL(
"KLM time window data are not available.");
171 unsigned int cID = d->getUniqueChannelID();
204 B2FATAL(
"Incomplete KLM channel status data.");
213 uint16_t nKLMDigitsMultiStripBarrel{0};
216 std::map<KLMChannelNumber, int> channelDigitMap;
217 for (
int index = 0; index <
m_Digits.getEntries(); ++index) {
222 nKLMDigitsMultiStripBarrel++;
233 channelDigitMap.insert(std::pair<KLMChannelNumber, int>(channel, index));
236 if (channelDigitMap.empty())
238 std::vector<std::pair<const KLMDigit*, double>> digitCluster;
240 double averageTime =
m_Digits[channelDigitMap.begin()->second]->getTime();
243 for (std::map<KLMChannelNumber, int>::iterator it = channelDigitMap.begin(); it != channelDigitMap.end(); ++it) {
245 double digitTime = digit->
getTime();
248 if ((it->first > previousChannel + 1) || (std::fabs(digitTime - averageTime) >
m_CoincidenceWindow)) {
250 digitCluster.clear();
252 previousChannel = it->first;
253 double n = (double)(digitCluster.size());
254 averageTime = (n * averageTime + digitTime) / (n + 1.0);
255 digitCluster.emplace_back(std::make_pair(digit, digitTime));
265 for (
int j = i + 1; j <
m_bklmHit1ds.getEntries(); ++j) {
271 int phiIndex = isPhiReadout ? i : j;
272 int zIndex = isPhiReadout ? j : i;
276 CLHEP::Hep3Vector propagationDist;
279 propagationDist = m->getPropagationDistance(
283 propagationDist = m->getPropagationDistance(
288 propagationDist = m->getPropagationTimes(local);
290 double delayPhi, delayZ;
299 double phiTime = phiHit->
getTime() - propagationDist.y() * delayPhi;
300 double zTime = zHit->
getTime() - propagationDist.z() * delayZ;
304 CLHEP::Hep3Vector global = m->localToGlobal(local + m->getLocalReconstructionShift(),
m_bklmIfAlign);
305 double time = 0.5 * (phiTime + zTime);
320 uint16_t nKLMDigitsMultiStripFWD{0};
321 uint16_t nKLMDigitsMultiStripBWD{0};
323 double d1, d2, time, t1, t2, sd;
324 std::vector<KLMDigit*> digitVector;
325 std::vector<KLMDigit*>::iterator it1, it2, it3, it4, it5, it6, it7, it8, it9;
327 for (i = 0; i < n; i++) {
337 digitVector.push_back(digit);
343 sort(digitVector.begin(), digitVector.end(), compareSector);
344 it1 = digitVector.begin();
345 while (it1 != digitVector.end()) {
349 if (it2 == digitVector.end())
351 if (!sameSector(*it1, *it2))
355 sort(it1, it2, comparePlane);
357 if ((*it1)->getPlane() != 1) {
366 if ((*it3)->getPlane() != (*it1)->getPlane())
378 sort(it1, it3, compareStrip);
379 sort(it3, it2, compareStrip);
388 if ((*it5)->getStrip() != (*it4)->getStrip() ||
389 (*it5)->getPlane() != (*it4)->getPlane())
393 sort(it4, it5, compareTime);
404 if ((*it5)->getStrip() != (*it4)->getStrip())
414 if ((*it7)->getStrip() != (*it6)->getStrip())
421 for (it8 = it4; it8 != it5; ++it8) {
422 for (it9 = it6; it9 != it7; ++it9) {
429 if ((*it8)->isMultiStrip() || (*it9)->isMultiStrip()) {
432 int s1First = plane1Digit.
getStrip();
433 int s1Last = std::max(s1First, plane1Digit.
getLastStrip());
434 int s2First = plane2Digit.
getStrip();
435 int s2Last = std::max(s2First, plane2Digit.
getLastStrip());
436 for (
int s1 = s1First; s1 <= s1Last; s1++) {
438 for (
int s2 = s2First; s2 <= s2Last; s2++) {
451 plane1Digit.
setStrip((s1First + s1Last) / 2);
452 plane2Digit.
setStrip((s2First + s2Last) / 2);
474 time = (t1 + t2) / 2;
479 (*it9)->getEnergyDeposit());
480 hit2d->
setPosition(crossPoint.x(), crossPoint.y(), crossPoint.z());
481 double timeResolution = 1.0;
484 (*it8)->getUniqueChannelID());
486 (*it9)->getUniqueChannelID());
488 hit2d->
setChiSq((t1 - t2) * (t1 - t2) / timeResolution);
490 hit2d->
setMCTime(((*it8)->getMCTime() + (*it9)->getMCTime()) / 2);
493 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.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
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.