10 #include <klm/modules/KLMTimeCollector/KLMTimeCollectorModule.h>
13 #include <klm/dataobjects/bklm/BKLMHit1d.h>
14 #include <klm/dataobjects/KLMDigit.h>
15 #include <klm/dataobjects/KLMElementNumbers.h>
16 #include <klm/dataobjects/KLMMuidLikelihood.h>
19 #include <analysis/dataobjects/Particle.h>
20 #include <analysis/dataobjects/ParticleList.h>
21 #include <framework/dataobjects/EventT0.h>
22 #include <framework/gearbox/Unit.h>
23 #include <framework/logging/Logger.h>
24 #include <mdst/dataobjects/Track.h>
25 #include <tracking/dataobjects/ExtHit.h>
34 using namespace Belle2::bklm;
35 using namespace Belle2::EKLM;
43 m_TransformData(
nullptr),
44 m_HeventT0_0(
nullptr),
45 m_HeventT0_1(
nullptr),
47 m_HnBHit2dOfTrack(
nullptr),
48 m_HnEHit2dOfTrack(
nullptr),
49 m_HpositionDiff{
nullptr},
50 m_HpositionXDiff(
nullptr),
51 m_HpositionYDiff(
nullptr),
52 m_HpositionZDiff(
nullptr),
55 m_HnumDigit_scint_end(
nullptr),
56 m_HnumDigit_scint(
nullptr),
57 m_HnumDigit_rpc(
nullptr),
60 setDescription(
"Module for KLM time calibration (data collection).");
61 setPropertyFlags(c_ParallelProcessingCertified);
63 addParam(
"debug", m_Debug,
"debug mode.",
false);
64 addParam(
"inputParticleList", m_inputListName,
"input particle list.", std::string(
"mu+:cali"));
65 addParam(
"useEventT0", m_useEvtT0,
"Use event T0 or not.",
true);
66 addParam(
"IgnoreBackwardPropagation", m_IgnoreBackwardPropagation,
67 "Whether to ignore ExtHits with backward propagation.",
false);
74 B2INFO(
"Destructor done..");
89 m_eventT0.isRequired(
"EventT0");
90 m_tracks.isRequired();
93 m_outTree =
new TTree(
"time_calibration_data",
"");
94 m_outTree->Branch(
"t0", &m_Event.t0,
"t0/D");
95 m_outTree->Branch(
"flyTime", &m_Event.flyTime,
"flyTime/D");
96 m_outTree->Branch(
"recTime", &m_Event.recTime,
"recTime/D");
97 m_outTree->Branch(
"dist", &m_Event.dist,
"dist/D");
98 m_outTree->Branch(
"diffDistX", &m_Event.diffDistX,
"diffDistX/D");
99 m_outTree->Branch(
"diffDistY", &m_Event.diffDistY,
"diffDistY/D");
100 m_outTree->Branch(
"diffDistZ", &m_Event.diffDistZ,
"diffDistZ/D");
101 m_outTree->Branch(
"eDep", &m_Event.eDep,
"eDep/D");
102 m_outTree->Branch(
"nPE", &m_Event.nPE,
"nPE/D");
103 m_outTree->Branch(
"channelId", &m_Event.channelId,
"channelId/I");
104 m_outTree->Branch(
"inRPC", &m_Event.inRPC,
"inRPC/O");
105 m_outTree->Branch(
"isFlipped", &m_Event.isFlipped,
"isFlipped/O");
107 registerObject<TTree>(
"time_calibration_data", m_outTree);
109 B2DEBUG(20,
"prepare :: Initialize histgrams..");
110 m_HeventT0_0 =
new TH1D(
"m_HeventT0_0",
"collision time before track number request;t0[ns]", 200, -100, 100);
111 m_HeventT0_1 =
new TH1D(
"m_HeventT0_1",
"collision time after track number request;t0[ns]", 200, -100, 100);
112 m_HnumTrack =
new TH1I(
"m_HnnumTrack",
"Number of Track;nTrack", 30, 0, 30);
114 m_HnBHit2dOfTrack =
new TH1I(
"m_HnBKLMHit2dOfTrack",
"Number of BKLMHit2d belong to recTrack;num of BKLMHit2d", 20, 0, 20);
115 m_HnEHit2dOfTrack =
new TH1I(
"m_HnEKLMHit2dOfTrack",
"Number of EKLMHit2d belong to recTrack;num of EKLMHit2d", 15, 0, 15);
117 m_HpositionDiff =
new TH1D(
"m_HpositionDiff",
"Dist between extHit and KLMHit2d;dist", 160, 0, 8);
118 m_HpositionXDiff =
new TH1D(
"m_HpositionXDiff",
"DistX between extHit and KLMHit2d;distX", 100, 0, 5);
119 m_HpositionYDiff =
new TH1D(
"m_HpositionYDiff",
"DistY between extHit and KLMHit2d;distY", 100, 0, 5);
120 m_HpositionZDiff =
new TH1D(
"m_HpositionZDiff",
"DistZ between extHit and KLMHit2d;distZ", 100, 0, 5);
122 m_HflyTimeB =
new TH2D(
"m_HflyTimeB",
"flyTime;flyTime(wet)/ns;Layer", 40, 0, 20, 20, 0, 20);
123 m_HflyTimeE =
new TH2D(
"m_HflyTimeE",
"flyTime;flyTime(wet)/ns;Layer", 40, 0, 20, 20, 0, 20);
125 m_HnumDigit_rpc =
new TH1I(
"m_HnumDigit_rpc",
"Number of digit per bklmHit1d (RPC);number of digit", 15, 0, 15);
126 m_HnumDigit_scint =
new TH1I(
"m_HnumDigit_scint",
"Number of digit per bklmHit1d (scint);number of digit", 15, 0, 15);
127 m_HnumDigit_scint_end =
new TH1I(
"m_HnumDigit_scint_end",
"Number of eklmDigit per eklmHit2d (scint);number of eklmDigit", 15, 0,
130 registerObject<TH1D>(
"m_HevtT0_0", m_HeventT0_0);
131 registerObject<TH1D>(
"m_HevtT0_1", m_HeventT0_1);
132 registerObject<TH1I>(
"m_HnTrack", m_HnumTrack);
133 registerObject<TH1I>(
"m_HnBHit2d", m_HnBHit2dOfTrack);
134 registerObject<TH1I>(
"m_HnEHit2d", m_HnEHit2dOfTrack);
136 registerObject<TH1D>(
"m_HposiDiff", m_HpositionDiff);
137 registerObject<TH1D>(
"m_HposiXDiff", m_HpositionXDiff);
138 registerObject<TH1D>(
"m_HposiYDiff", m_HpositionYDiff);
139 registerObject<TH1D>(
"m_HposiZDiff", m_HpositionZDiff);
141 registerObject<TH2D>(
"m_HfTimeB", m_HflyTimeB);
142 registerObject<TH2D>(
"m_HfTimeE", m_HflyTimeE);
144 registerObject<TH1I>(
"m_HnDigit_rpc", m_HnumDigit_rpc);
145 registerObject<TH1I>(
"m_HnDigit_scint", m_HnumDigit_scint);
146 registerObject<TH1I>(
"m_HnDigit_scint_end", m_HnumDigit_scint_end);
156 if (!m_eventT0.isValid())
158 if (!m_eventT0->hasTemporaryEventT0(Const::EDetector::CDC))
160 const std::vector<EventT0::EventT0Component> evtT0C = m_eventT0->getTemporaryEventT0s(Const::EDetector::CDC);
161 m_Event.t0 = evtT0C.back().eventT0;
165 int runId = eventMetaData->getRun();
166 int evtId = eventMetaData->getEvent();
168 getObjectPtr<TH1D>(
"m_HevtT0_0")->Fill(m_Event.t0);
171 unsigned n_track = inputList->getListSize();
173 B2DEBUG(20,
"No necessary tracks in" <<
LogVar(
"run", runId) <<
LogVar(
"event", evtId));
177 B2DEBUG(20,
"debug infor for" <<
LogVar(
"run", runId) <<
LogVar(
"event", evtId) <<
LogVar(
"number of rec tracks", n_track));
179 getObjectPtr<TH1D>(
"m_HevtT0_1")->Fill(m_Event.t0);
180 getObjectPtr<TH1I>(
"m_HnTrack")->Fill(n_track);
183 B2DEBUG(20,
"Collect :: Track loop begins.");
186 for (
unsigned iT = 0; iT < n_track; ++iT) {
188 const Particle* particle = inputList->getParticle(iT);
189 const Track* track = particle->getTrack();
196 getObjectPtr<TH1I>(
"m_HnBHit2d")->Fill(
int(bklmHit2ds.size()));
197 getObjectPtr<TH1I>(
"m_HnEHit2d")->Fill(
int(eklmHit2ds.size()));
199 B2DEBUG(20,
"Track" <<
LogVar(
"exthits", extHits.
size())
200 <<
LogVar(
"BKLMHit2d", bklmHit2ds.size()) <<
LogVar(
"EKLMHit2d", eklmHit2ds.size()));
201 if (eklmHit2ds.size() < 2 && bklmHit2ds.size() < 2)
206 m_vExtHits_RPC.clear();
207 B2DEBUG(20,
"Collect :: extHits loop begins.");
208 for (
const ExtHit& eHit : extHits) {
209 if (eHit.getStatus() != EXT_EXIT)
212 if (m_IgnoreBackwardPropagation) {
213 if (eHit.isBackwardPropagated())
217 bool bklmCover = (eHit.getDetectorID() == Const::EDetector::BKLM);
218 bool eklmCover = (eHit.getDetectorID() == Const::EDetector::EKLM);
219 if (!bklmCover && !eklmCover)
222 int copyId = eHit.getCopyID();
223 int tFor, tSec, tLay, tPla, tStr;
236 B2DEBUG(20,
"Collect :: Assign elementNum based on copyId for extHits." <<
LogVar(
"Sub from elementNumber",
237 tSub) <<
LogVar(
"bklmCover", bklmCover) <<
LogVar(
"eklmCover", eklmCover));
239 bool crossed =
false;
245 unsigned int tModule = m_elementNum->moduleNumber(tSub, tFor, tSec, tLay);
246 m_vExtHits_RPC.insert(std::pair<unsigned int, ExtHit>(tModule, eHit));
248 unsigned int tChannel = m_elementNum->channelNumber(tSub, tFor, tSec, tLay, tPla, tStr);
251 m_vExtHits.insert(std::pair<unsigned int, ExtHit>(tChannel, eHit));
258 unsigned int tChannel = m_elementNum->channelNumber(tSub, tFor, tSec, tLay, tPla, tStr);
261 m_vExtHits.insert(std::pair<unsigned int, ExtHit>(tChannel, eHit));
270 if (m_vExtHits.size() > 0) {
271 collectScintEnd(eklmHit2ds);
272 collectScint(bklmHit2ds);
274 if (m_vExtHits_RPC.size() > 0) {
275 collectRPC(bklmHit2ds);
282 const HepGeom::Transform3D* tr;
286 for (
const EKLMHit2d& hit2d : eklmHit2ds) {
288 unsigned nDigit = digits.size();
289 getObjectPtr<TH1I>(
"m_HnDigit_scint_end")->Fill(nDigit);
291 B2FATAL(
"Wrong number of related KLMDigits.");
293 if (!digits[0]->isGood() || !digits[1]->isGood())
297 m_Event.channelId = digitHit.getUniqueChannelID();
302 std::pair<ExtHit*, ExtHit*> pair_extHits = matchExt(m_Event.channelId, m_vExtHits);
303 if (pair_extHits.first ==
nullptr || pair_extHits.second ==
nullptr)
305 ExtHit& entryHit = *(pair_extHits.first);
306 ExtHit& exitHit = *(pair_extHits.second);
308 m_Event.flyTime = 0.5 * (entryHit.
getTOF() + exitHit.
getTOF());
311 TVector3 positionGlobal_digit = hit2d.
getPosition();
312 TVector3 positionGlobal_diff = positionGlobal_extHit - positionGlobal_digit;
314 storeDistDiff(positionGlobal_diff);
316 l = m_geoParE->getStripLength(digitHit.getStrip()) / CLHEP::mm *
Unit::mm;
317 hitGlobal_extHit.setX(positionGlobal_extHit.X() /
Unit::mm * CLHEP::mm);
318 hitGlobal_extHit.setY(positionGlobal_extHit.Y() /
Unit::mm * CLHEP::mm);
319 hitGlobal_extHit.setZ(positionGlobal_extHit.Z() /
Unit::mm * CLHEP::mm);
320 tr = m_TransformData->getStripGlobalToLocal(&digitHit);
321 hitLocal_extHit = (*tr) * hitGlobal_extHit;
323 m_Event.dist = 0.5 * l - hitLocal_extHit.x() / CLHEP::mm *
Unit::mm;
324 m_Event.recTime = digitHit.getTime();
325 m_Event.eDep = digitHit.getEnergyDeposit();
326 m_Event.nPE = digitHit.getNPhotoelectrons();
328 getObjectPtr<TH2D>(
"m_HfTimeE")->Fill(m_Event.flyTime, digitHit.getLayer());
329 getObjectPtr<TTree>(
"time_calibration_data")->Fill();
336 double stripWidtm_HZ, stripWidtm_HPhi;
340 if (hit2d.isOutOfTime())
344 if (bklmHit1ds.
size() != 2)
347 TVector3 positionGlobal_hit2d = hit2d.getGlobalPosition();
348 const bklm::Module* corMod = m_geoParB->findModule(hit2d.getSection(), hit2d.getSector(), hit2d.getLayer());
352 for (
const BKLMHit1d& hit1d : bklmHit1ds) {
354 getObjectPtr<TH1I>(
"m_HnDigit_scint")->Fill(digits.size());
355 if (digits.size() > 3)
358 for (
const KLMDigit& digitHit : digits) {
359 if (digitHit.inRPC() || !digitHit.isGood())
366 std::pair<ExtHit*, ExtHit*> pair_extHits = matchExt(channelId_digit, m_vExtHits);
367 if (pair_extHits.first ==
nullptr || pair_extHits.second ==
nullptr)
369 ExtHit& entryHit = *(pair_extHits.first);
370 ExtHit& exitHit = *(pair_extHits.second);
372 m_Event.inRPC = digitHit.inRPC();
373 m_Event.flyTime = 0.5 * (entryHit.
getTOF() + exitHit.
getTOF());
376 TVector3 positionGlobal_diff = positionGlobal_extHit - positionGlobal_hit2d;
377 B2DEBUG(20,
LogVar(
"Distance between digit and hit2d", positionGlobal_diff.Mag()));
379 storeDistDiff(positionGlobal_diff);
380 const CLHEP::Hep3Vector positionLocal_extHit = corMod->
globalToLocal(CLHEP::Hep3Vector(
381 positionGlobal_extHit.X(), positionGlobal_extHit.Y(), positionGlobal_extHit.Z()),
true);
382 const CLHEP::Hep3Vector positionLocal_hit2d = corMod->
globalToLocal(CLHEP::Hep3Vector(
383 positionGlobal_hit2d.X(), positionGlobal_hit2d.Y(), positionGlobal_hit2d.Z()),
true);
384 const CLHEP::Hep3Vector diffLocal = positionLocal_extHit - positionLocal_hit2d;
385 if (fabs(diffLocal.z()) > stripWidtm_HZ || fabs(diffLocal.y()) > stripWidtm_HPhi)
388 double propaLength = corMod->
getPropagationDistance(positionLocal_extHit, digitHit.getStrip(), digitHit.isPhiReadout());
391 m_Event.recTime = digitHit.getTime();
392 m_Event.dist = propaLength;
393 m_Event.eDep = digitHit.getEnergyDeposit();
394 m_Event.nPE = digitHit.getNPhotoelectrons();
395 m_Event.channelId = channelId_digit;
397 getObjectPtr<TH2D>(
"m_HfTimeB")->Fill(m_Event.flyTime, digitHit.getLayer());
398 getObjectPtr<TTree>(
"time_calibration_data")->Fill();
409 if (hit2d.isOutOfTime())
412 if (bklmHit1ds.
size() != 2)
415 TVector3 positionGlobal_hit2d = hit2d.getGlobalPosition();
416 const bklm::Module* corMod = m_geoParB->findModule(hit2d.getSection(), hit2d.getSector(), hit2d.getLayer());
420 for (
const BKLMHit1d& hit1d : bklmHit1ds) {
422 getObjectPtr<TH1I>(
"m_HnDigit_rpc")->Fill(digits.size());
423 if (digits.size() > 5)
426 for (
const KLMDigit& digitHit : digits) {
428 m_Event.inRPC = digitHit.inRPC();
431 unsigned int tModule = m_elementNum->moduleNumber(digitHit.getSubdetector(), digitHit.getSection(), digitHit.getSector(),
432 digitHit.getLayer());
434 std::pair<ExtHit*, ExtHit*> pair_extHits = matchExt(tModule, m_vExtHits_RPC);
435 if (pair_extHits.first ==
nullptr || pair_extHits.second ==
nullptr)
437 ExtHit& entryHit = *(pair_extHits.first);
438 ExtHit& exitHit = *(pair_extHits.second);
440 m_Event.flyTime = 0.5 * (entryHit.
getTOF() + exitHit.
getTOF());
442 TVector3 positionGlobal_diff = positionGlobal_extHit - positionGlobal_hit2d;
443 B2DEBUG(20,
LogVar(
"Distance between digit and hit2d", positionGlobal_diff.Mag()));
445 storeDistDiff(positionGlobal_diff);
446 const CLHEP::Hep3Vector positionLocal_extHit = corMod->
globalToLocal(CLHEP::Hep3Vector(
447 positionGlobal_extHit.X(), positionGlobal_extHit.Y(), positionGlobal_extHit.Z()),
true);
448 const CLHEP::Hep3Vector positionLocal_hit2d = corMod->
globalToLocal(CLHEP::Hep3Vector(
449 positionGlobal_hit2d.X(), positionGlobal_hit2d.Y(), positionGlobal_hit2d.Z()),
true);
450 const CLHEP::Hep3Vector diffLocal = positionLocal_extHit - positionLocal_hit2d;
451 if (fabs(diffLocal.z()) > stripWidtm_HZ || fabs(diffLocal.y()) > stripWidtm_HPhi)
455 double propaLength = propaLengthV3[2 - int(hit1d.isPhiReadout())];
458 m_Event.recTime = digitHit.getTime();
459 m_Event.dist = propaLength;
460 m_Event.eDep = digitHit.getEnergyDeposit();
461 m_Event.nPE = digitHit.getNPhotoelectrons();
462 m_Event.channelId = channelId_digit;
464 getObjectPtr<TH2D>(
"m_HfTimeB")->Fill(m_Event.flyTime, digitHit.getLayer());
465 getObjectPtr<TTree>(
"time_calibration_data")->Fill();
474 ExtHit* entryHit =
nullptr;
475 ExtHit* exitHit =
nullptr;
476 std::multimap<unsigned int, ExtHit>::iterator it, itlow, itup;
477 itlow = v_ExtHits.lower_bound(channelID);
478 itup = v_ExtHits.upper_bound(channelID);
480 for (it = itlow; it != itup; ++it) {
481 if (entryHit ==
nullptr) {
482 entryHit = &(it->second);
483 }
else if ((it->second).getTOF() < entryHit->
getTOF()) {
484 entryHit = &(it->second);
486 if (exitHit ==
nullptr) {
487 exitHit = &(it->second);
488 }
else if ((it->second).getTOF() > exitHit->
getTOF()) {
489 exitHit = &(it->second);
514 std::pair<ExtHit*, ExtHit*> p_extHits = std::make_pair(entryHit, exitHit);
520 double diffM = pDiff.Mag();
521 double diffX = pDiff.X();
522 double diffY = pDiff.Y();
523 double diffZ = pDiff.Z();
524 getObjectPtr<TH1D>(
"m_HposiDiff")->Fill(diffM);
525 getObjectPtr<TH1D>(
"m_HposiXDiff")->Fill(diffX);
526 getObjectPtr<TH1D>(
"m_HposiYDiff")->Fill(diffY);
527 getObjectPtr<TH1D>(
"m_HposiZDiff")->Fill(diffZ);
528 m_Event.diffDistX = diffX;
529 m_Event.diffDistY = diffY;
530 m_Event.diffDistZ = diffZ;
535 B2INFO(
"Data Collection Done.");
static void channelNumberToElementNumbers(KLMChannelNumber channel, int *section, int *sector, int *layer, int *plane, int *strip)
Get element numbers by channel number.
Store one reconstructed BKLM 1D hit as a ROOT object.
Store one BKLM strip hit as a ROOT object.
Calibration collector module base class.
@ c_Event
Different object in each event, all objects/arrays are invalidated after event() function has been ca...
static const EKLMElementNumbers & Instance()
Instantiation.
void stripNumberToElementNumbers(int stripGlobal, int *section, int *layer, int *sector, int *plane, int *strip) const
Get element numbers by strip global number.
Class for 2d hits handling.
static const GeometryData & Instance(enum DataSource dataSource=c_Database, const GearDir *gearDir=nullptr)
Instantiation.
Store one Ext hit as a ROOT object.
TVector3 getPosition() const
Get position of this extrapolation hit.
double getTOF() const
Get time of flight from the point of closest approach near the origin to this hit.
@ c_Normal
Normally operating channel.
KLM digit (class representing a digitized hit in RPCs or scintillators).
unsigned int getUniqueChannelID() const override
Get unique channel identifier.
static const KLMElementNumbers & Instance()
Instantiation.
Class to store the likelihoods from KLM with additional informations related to the extrapolation.
bool isExtrapolatedEndcapLayerCrossed(int layer) const
Check whether the given EKLM layer is crossed during extrapolation.
bool isExtrapolatedBarrelLayerCrossed(int layer) const
Check whether the given BKLM layer is crossed during extrapolation.
Collect hit information for KLM time calibration with CAF.
void collectScintEnd(RelationVector< EKLMHit2d > &)
Collect hits information for scintillator of EKLM.
std::pair< ExtHit *, ExtHit * > matchExt(KLMChannelNumber channelID, std::multimap< unsigned int, ExtHit > &)
Match KLM hit and extHit.
void collectScint(RelationVector< BKLMHit2d > &)
Collect hits information for scintillator of BKLM.
void collectRPC(RelationVector< BKLMHit2d > &)
Collect hits information for RPC of BKLM.
void storeDistDiff(TVector3 &)
Save position difference betwen matched kLMHit and ExtHit.
void collect() override
Event action, collect information for calibration.
virtual ~KLMTimeCollectorModule()
Destructor.
void prepare() override
Initializes the module.
void finish() override
Termination action.
Class to store reconstructed particles.
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of relations.
Type-safe access to single objects in the data store.
Class that bundles various TrackFitResults.
static const double mm
[millimeters]
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.
const CLHEP::Hep3Vector globalToLocal(const CLHEP::Hep3Vector &v, bool reco=false) const
Transform space-point within this module from global to local coordinates.
double getPhiStripWidth() const
Get phi-strip width.
const CLHEP::Hep3Vector getPropagationDistance(const CLHEP::Hep3Vector &) const
Convert local coordinates to signal-propagation distance (cm).
double getZStripWidth() const
Get z-strip width.
bool isFlipped() const
Determine if this module is flipped by 180 degrees about z axis within its air gap.
Class to store variables with their name which were sent to the logging service.
#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.