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 BKLMHit2ds from BKLMHit1ds; create EKLMHit2ds 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",
121 B2FATAL(
"It is not possible to run EKLM reconstruction with 1 plane.");
129 B2FATAL(
"KLM time constants data are not available.");
131 B2FATAL(
"KLM time cable decay data are not available.");
133 B2ERROR(
"KLM time resolution data are not available. "
134 "The error is non-fatal because the data are only used to set "
135 "chi^2 of 2d hit, which is informational only now.");
138 B2FATAL(
"KLM channel status data are not available.");
140 B2FATAL(
"KLM time window data are not available.");
166 unsigned int cID = d->getUniqueChannelID();
199 B2FATAL(
"Incomplete KLM channel status data.");
209 std::map<KLMChannelNumber, int> channelDigitMap;
210 for (
int index = 0; index <
m_Digits.getEntries(); ++index) {
225 channelDigitMap.insert(std::pair<KLMChannelNumber, int>(channel, index));
228 if (channelDigitMap.empty())
230 std::vector<std::pair<const KLMDigit*, double>> digitCluster;
232 double averageTime =
m_Digits[channelDigitMap.begin()->second]->getTime();
235 for (std::map<KLMChannelNumber, int>::iterator it = channelDigitMap.begin(); it != channelDigitMap.end(); ++it) {
237 double digitTime = digit->
getTime();
240 if ((it->first > previousChannel + 1) || (std::fabs(digitTime - averageTime) >
m_CoincidenceWindow)) {
242 digitCluster.clear();
244 previousChannel = it->first;
245 double n = (double)(digitCluster.size());
246 averageTime = (n * averageTime + digitTime) / (n + 1.0);
247 digitCluster.emplace_back(std::make_pair(digit, digitTime));
257 for (
int j = i + 1; j <
m_bklmHit1ds.getEntries(); ++j) {
263 int phiIndex = isPhiReadout ? i : j;
264 int zIndex = isPhiReadout ? j : i;
268 CLHEP::Hep3Vector propagationDist;
271 propagationDist = m->getPropagationDistance(
275 propagationDist = m->getPropagationDistance(
280 propagationDist = m->getPropagationTimes(local);
282 double delayPhi, delayZ;
291 double phiTime = phiHit->
getTime() - propagationDist.y() * delayPhi;
292 double zTime = zHit->
getTime() - propagationDist.z() * delayZ;
296 CLHEP::Hep3Vector global = m->localToGlobal(local + m->getLocalReconstructionShift(),
m_bklmIfAlign);
297 double time = 0.5 * (phiTime + zTime);
311 double d1, d2, time, t1, t2, sd;
312 std::vector<KLMDigit*> digitVector;
313 std::vector<KLMDigit*>::iterator it1, it2, it3, it4, it5, it6, it7, it8, it9;
315 for (i = 0; i < n; i++) {
324 digitVector.push_back(digit);
327 sort(digitVector.begin(), digitVector.end(), compareSector);
328 it1 = digitVector.begin();
329 while (it1 != digitVector.end()) {
333 if (it2 == digitVector.end())
335 if (!sameSector(*it1, *it2))
339 sort(it1, it2, comparePlane);
341 if ((*it1)->getPlane() != 1) {
350 if ((*it3)->getPlane() != (*it1)->getPlane())
362 sort(it1, it3, compareStrip);
363 sort(it3, it2, compareStrip);
372 if ((*it5)->getStrip() != (*it4)->getStrip() ||
373 (*it5)->getPlane() != (*it4)->getPlane())
377 sort(it4, it5, compareTime);
388 if ((*it5)->getStrip() != (*it4)->getStrip())
398 if ((*it7)->getStrip() != (*it6)->getStrip())
413 for (it8 = it4; it8 != it5; ++it8) {
414 for (it9 = it6; it9 != it7; ++it9) {
425 time = (t1 + t2) / 2;
430 (*it9)->getEnergyDeposit());
431 hit2d->
setPosition(crossPoint.x(), crossPoint.y(), crossPoint.z());
432 double timeResolution = 1.0;
435 (*it8)->getUniqueChannelID());
437 (*it9)->getUniqueChannelID());
439 hit2d->
setChiSq((t1 - t2) * (t1 - t2) / timeResolution);
441 hit2d->
setMCTime(((*it8)->getMCTime() + (*it9)->getMCTime()) / 2);
444 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.
Store one BKLM strip hit as a ROOT object.
bool isOutOfTime()
Determine whether this 2D hit is outside the trigger-coincidence window.
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.
int getNPlanes() const
Get number of planes.
Class for 2d hits handling.
void setChiSq(float chisq)
Set Chi^2 of the crossing point.
void setEnergyDeposit(float eDep)
Set EnergyDeposit.
void setTime(float time)
Set hit time.
void setPosition(float x, float y, float z)
Set hit global position.
void setMCTime(float t)
Set MC time.
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.
KLMChannelNumber channelNumber(int subdetector, int section, int sector, int layer, int plane, int strip) const
Get channel number.
OptionalDBObjPtr< KLMTimeResolution > m_TimeResolution
KLM time resolution.
void reconstructEKLMHits()
Reconstruct EKLMHit2d.
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.
StoreArray< BKLMHit2d > m_bklmHit2ds
BKLM 2d 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).
double m_EventT0Value
Value of the EventT0.
void reconstructBKLMHits()
Reconstruct BKLMHit1d and BKLMHit2d.
double m_PromptTime
Nominal time of prompt BKLMHit2ds.
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 BKLMHit2ds.
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.
StoreArray< EKLMHit2d > m_eklmHit2ds
EKLM 2d hits.
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.
@ 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.
Abstract base class for different kinds of events.