Belle II Software development
KLMTrackingModule.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/KLMTracking/KLMTrackingModule.h>
11
12/* KLM headers. */
13#include <klm/bklm/geometry/GeometryPar.h>
14#include <klm/modules/KLMTracking/KLMTrackFinder.h>
15#include <klm/eklm/geometry/TransformDataGlobalAligned.h> //TODO: Is this the right module
16
17/* Basf2 headers. */
18#include <framework/dataobjects/EventMetaData.h>
19#include <framework/datastore/StoreObjPtr.h>
20#include <framework/datastore/StoreArray.h>
21#include <framework/logging/Logger.h>
22#include <framework/utilities/MathHelpers.h>
23#include <tracking/dataobjects/RecoHitInformation.h>
24
25/* C++ standard libraries*/
26#include <set>
27#include <iostream>
28
29using namespace Belle2;
30using namespace Belle2::KLM;
31using namespace CLHEP;
32
33REG_MODULE(KLMTracking);
34
36 m_effiYX(nullptr),
37 m_effiYZ(nullptr),
38 m_passYX(nullptr),
39 m_totalYX(nullptr),
40 m_passYZ(nullptr),
41 m_totalYZ(nullptr),
44{
45 for (int i = 0; i < 8; ++i) {
46 m_total[0][i] = nullptr;
47 m_total[1][i] = nullptr;
48 m_pass[0][i] = nullptr;
49 m_pass[1][i] = nullptr;
50 m_effiVsLayer[0][i] = nullptr;
51 m_effiVsLayer[1][i] = nullptr;
52 }
53 setDescription("Perform standard-alone straight line tracking for KLM. ");
54 addParam("MatchToRecoTrack", m_MatchToRecoTrack, "[bool], whether match KLMTrack to RecoTrack; (default is false)", false);
55 addParam("MaxAngleRequired", m_maxAngleRequired,
56 "[degree], match KLMTrack to RecoTrack; angle between them is required to be smaller than (default 10)", double(10.0));
57 addParam("MaxDistance", m_maxDistance,
58 "[cm], During efficiency calculation, distance between track and 2dhit must be smaller than (default 10)", double(10.0));
59 addParam("MaxSigma", m_maxSigma,
60 "[sigma], During efficiency calculation, uncertainty of 2dhit must be smaller than (default 5); ", double(5));
61 addParam("MinHitList", m_minHitList,
62 ", During track finding, a good track after initial seed hits must be larger than is (default 2); ", unsigned(2));
63 addParam("MaxHitList", m_maxHitList,
64 ", During track finding, a good track after initial seed hits must be smaller than is (default 60); ", unsigned(60));
65 addParam("MinNLayer", m_minNLayer,
66 ", Only look at tracks with more than n number of layers; ", int(4));
67 addParam("StudyEffiMode", m_studyEffi, "[bool], run in efficieny study mode (default is false)", false);
68 addParam("outputName", m_outPath, "[string], output file name containing efficiencies plots ",
69 std::string("standaloneKLMEffi.root"));
70}
71
76
78{
79
80 hits2D.isRequired();
81 m_storeTracks.registerInDataStore();
82 m_storeTracks.registerRelationTo(hits2D);
83 m_storeTracks.registerRelationTo(recoTracks);
84 recoHitInformation.registerRelationTo(hits2D);
85 hits2D.registerRelationTo(recoTracks);
86
87 if (m_studyEffi)
88 B2INFO("KLMTrackingModule::initialize this module is running in efficiency study mode!");
89
90 m_file = new TFile(m_outPath.c_str(), "recreate");
91 TString hname;
92 std::string labelFB[2] = {"BB", "BF"};
93 int Nbin = 16;
94 float gmin = -350;
95 float gmax = 350;
96 int gNbin = 150;
97
98 //TODO: Extend to include EKLM...
99 m_totalYX = new TH2F("totalYX", " denominator Y vs. X", gNbin, gmin, gmax, gNbin, gmin, gmax);
100 m_passYX = new TH2F("passYX", " numerator Y vs. X", gNbin, gmin, gmax, gNbin, gmin, gmax);
101 m_totalYZ = new TH2F("totalYZ", " denominator Y vs. Z", gNbin, gmin, gmax, gNbin, gmin, gmax);
102 m_passYZ = new TH2F("passYZ", " numerator Y vs. Z", gNbin, gmin, gmax, gNbin, gmin, gmax);
103 m_effiYX = new TH2F("effiYX", " effi. Y vs. X", gNbin, gmin, gmax, gNbin, gmin, gmax);
104 m_effiYZ = new TH2F("effiYZ", " effi. Y vs. X", gNbin, gmin, gmax, gNbin, gmin, gmax);
105 m_effiYX->GetXaxis()->SetTitle("x (cm)");
106 m_effiYX->GetYaxis()->SetTitle("y (cm)");
107 m_effiYZ->GetXaxis()->SetTitle("z (cm)");
108 m_effiYZ->GetYaxis()->SetTitle("y (cm)");
109 for (int iF = 0; iF < 2; iF++) {
110 for (int iS = 0; iS < 8; iS++) {
111 hname.Form("effi_%s%i", labelFB[iF].c_str(), iS);
112 m_effiVsLayer[iF][iS] = new TEfficiency(hname, hname, Nbin, 0, 16);
113 hname.Form("total_%s%i", labelFB[iF].c_str(), iS);
114 m_total[iF][iS] = new TH1F(hname, hname, Nbin, 0, 16);
115 hname.Form("pass_%s%i", labelFB[iF].c_str(), iS);
116 m_pass[iF][iS] = new TH1F(hname, hname, Nbin, 0, 16);
117 }
118 }
119
120 //EKLM Plots TODO: Not tested yet
121 /*
122 m_totalYXE = new TH2F("totalYX", " denominator Y vs. X", gNbin, gmin, gmax, gNbin, gmin, gmax);
123 m_passYXE = new TH2F("passYX", " numerator Y vs. X", gNbin, gmin, gmax, gNbin, gmin, gmax);
124 m_totalYZE = new TH2F("totalYZ", " denominator Y vs. Z", gNbin, gmin, gmax, gNbin, gmin, gmax);
125 m_passYZE = new TH2F("passYZ", " numerator Y vs. Z", gNbin, gmin, gmax, gNbin, gmin, gmax);
126 m_effiYXE = new TH2F("effiYX", " effi. Y vs. X", gNbin, gmin, gmax, gNbin, gmin, gmax);
127 m_effiYZE = new TH2F("effiYZ", " effi. Y vs. X", gNbin, gmin, gmax, gNbin, gmin, gmax);
128 m_effiYXE->GetXaxis()->SetTitle("x (cm)");
129 m_effiYXE->GetYaxis()->SetTitle("y (cm)");
130 m_effiYZE->GetXaxis()->SetTitle("z (cm)");
131 m_effiYZE->GetYaxis()->SetTitle("y (cm)");
132 for (int iF = 0; iF < 2; iF++) {
133 for (int iS = 0; iS < 8; iS++) {
134 hname.Form("effi_%s%i", labelFB[iF].c_str(), iS);
135 m_effiVsLayer[iF][iS] = new TEfficiency(hname, hname, Nbin, 0, 16);
136 hname.Form("total_%s%i", labelFB[iF].c_str(), iS);
137 m_total[iF][iS] = new TH1F(hname, hname, Nbin, 0, 16);
138 hname.Form("pass_%s%i", labelFB[iF].c_str(), iS);
139 m_pass[iF][iS] = new TH1F(hname, hname, Nbin, 0, 16);
140 }
141 } //end of EKLM layer info
142 */
143
144}
145
147{
148 StoreObjPtr<EventMetaData> eventMetaData("EventMetaData", DataStore::c_Event);
149 m_runNumber.push_back((int)eventMetaData->getRun());
152}
153
155{
156 m_storeTracks.clear();
157 bool thereIsATrack = false;
158
159 if (!m_studyEffi) {
162 if (m_storeTracks.getEntries() > 0)
163 thereIsATrack = true;
164 } else {
165 for (int iSection = 0; iSection < 2; iSection++) {
166 for (int iSector = 0; iSector < 8; iSector++) {
167 for (int iLayer = 0; iLayer < 15; iLayer++) {
168 runTracking(1, KLMElementNumbers::c_BKLM, iSection, iSector, iLayer);
169 if (m_storeTracks.getEntries() > 0)
170 thereIsATrack = true;
171 generateEffi(KLMElementNumbers::c_BKLM, iSection, iSector, iLayer);
172 //clear tracks so prepare for the next layer efficieny study
173 m_storeTracks.clear();
174 }
175 }
176 }
177 }
178
180 if (thereIsATrack)
182}
183
184void KLMTrackingModule::runTracking(int mode, int iSubdetector, int iSection, int iSector, int iLayer)
185{
186 //m_storeTracks.clear(); //done in event stage
187
188 KLMTrackFitter* m_fitter = new KLMTrackFitter();
189 KLMTrackFinder* m_finder = new KLMTrackFinder();
190 m_finder->registerFitter(m_fitter);
191
192 if (hits2D.getEntries() < 1)
193 return;
194 if (mode == 1) { //efficieny study
195 for (int j = 0; j < hits2D.getEntries(); j++) {
196 if (hits2D[j]->getSubdetector() != iSubdetector) //TODO: shoud we kee?
197 continue;
198 hits2D[j]->isOnStaTrack(false);
199 }
200 }
201
202 for (int hi = 0; hi < hits2D.getEntries() - 1; ++hi) {
203 if (hits2D[hi]->getSubdetector() != iSubdetector) //TODO: Should we keep?
204 continue;
205
206 if (mode == 1 && isLayerUnderStudy(iSection, iSector, iLayer, hits2D[hi]))
207 continue;
208 if (mode == 1 && !isSectorUnderStudy(iSection, iSector, hits2D[hi]))
209 continue;
210 if (hits2D[hi]->isOnStaTrack())
211 continue;
212 if (hits2D[hi]->isOutOfTime())
213 continue;
214 for (int hj = hi + 1; hj < hits2D.getEntries(); ++hj) {
215
216 if (hits2D[hj]->isOnStaTrack())
217 continue;
218 if (hits2D[hj]->isOutOfTime())
219 continue;
220 // at least for track seed, hits should remain in the same subdetector
221 if (hits2D[hi]->getSubdetector() != hits2D[hj]->getSubdetector())
222 continue;
223 if (sameSector(hits2D[hi], hits2D[hj]) &&
224 std::abs(hits2D[hi]->getLayer() - hits2D[hj]->getLayer()) < 3)
225 continue;
226
227 std::list<KLMHit2d*> sectorHitList;
228
229
230 std::list<KLMHit2d*> seed;
231 seed.push_back(hits2D[hi]);
232 seed.push_back(hits2D[hj]);
233
234 for (int ho = 0; ho < hits2D.getEntries(); ++ho) {
235
236 // Exclude seed hits.
237 if (ho == hi || ho == hj)
238 continue;
239 if (mode == 1 && (hits2D[ho]->getSubdetector() != iSubdetector))
240 continue;
241 if (mode == 1 && isLayerUnderStudy(iSection, iSector, iLayer, hits2D[hj]))
242 continue;
243 if (mode == 1 && !isSectorUnderStudy(iSection, iSector, hits2D[hj]))
244 continue;
245 if (hits2D[ho]->isOnStaTrack())
246 continue;
247 //TODO: consider removing the commented lines below
248 if (mode == 1 && !sameSector(hits2D[ho], hits2D[hi]))
249 continue;
250 if (hits2D[ho]->isOutOfTime())
251 continue;
252 sectorHitList.push_back(hits2D[ho]);
253 }
254
255 /* Require at least four hits (minimum for good track, already two as seed, so here we require 2) but
256 * no more than 60 (most likely noise, 60 would be four good tracks).
257 * TODO: Should be tuned since we have EKLM hits now. 60 was from BKLMTracking
258 */
259 if (sectorHitList.size() < m_minHitList || sectorHitList.size() > m_maxHitList)
260 continue;
261
262 std::list<KLMHit2d*> m_hits;
263
264 if (m_finder->filter(seed, sectorHitList, m_hits, iSubdetector)) {
265 KLMTrack* m_track = m_storeTracks.appendNew();
266 m_track->setTrackParam(m_fitter->getTrackParam());
267 m_track->setTrackParamErr(m_fitter->getTrackParamErr());
268 m_track->setTrackChi2(m_fitter->getChi2());
269 m_track->setNumHitOnTrack(m_fitter->getNumHit());
270 m_track->setIsValid(m_fitter->isValid());
271 m_track->setIsGood(m_fitter->isGood());
272 std::list<KLMHit2d*>::iterator j;
273 m_hits.sort(sortByLayer);
274 int nBKLM = 0; int nEKLM = 0;
275 for (j = m_hits.begin(); j != m_hits.end(); ++j) {
276 (*j)->isOnStaTrack(true);
277 m_track->addRelationTo((*j));
278 if ((*j)->getSubdetector() == KLMElementNumbers::c_BKLM)
279 nBKLM += 1;
280 else if ((*j)->getSubdetector() == KLMElementNumbers::c_EKLM)
281 nEKLM += 1;
282 } //end of klmhit2d loop
283 B2DEBUG(31, "KLMTracking::runTracking totalHit " << m_hits.size() << ", nBKLM " << nBKLM << ", nEKLM " << nEKLM);
284 m_track->setInSubdetector(nBKLM, nEKLM);
285
286 //match KLMTrack to RecoTrack
287 if (mode == 0) {
288 RecoTrack* closestTrack = nullptr;
289 B2DEBUG(30, "KLMTracking::runTracking started RecoTrack matching");
290 if (m_MatchToRecoTrack) {
291 if (findClosestRecoTrack(m_track, closestTrack)) {
292 B2DEBUG(30, "KLMTracking::runTracking was able to find ClosestRecoTrack");
293 m_track->addRelationTo(closestTrack);
294 for (j = m_hits.begin(); j != m_hits.end(); ++j) {
295 unsigned int sortingParameter = closestTrack->getNumberOfTotalHits();
296 if ((*j)->getSubdetector() == KLMElementNumbers::c_BKLM)
297 closestTrack->addBKLMHit((*j), sortingParameter, RecoHitInformation::OriginTrackFinder::c_LocalTrackFinder);
298 else if ((*j)->getSubdetector() == KLMElementNumbers::c_EKLM) {
299 for (const EKLMAlignmentHit& alignmentHit : (*j)->getRelationsFrom<EKLMAlignmentHit>()) {
300 closestTrack->addEKLMHit(&(alignmentHit), sortingParameter,
301 RecoHitInformation::OriginTrackFinder::c_LocalTrackFinder);
302 }
303 }
304 } //end of hit loop
305 } //end of closest recotrack
306 }
307 } //end of KLMTrack to RecoTrack
308 } //end of finder loop
309 }
310 }
311
312 delete m_fitter;
313 delete m_finder;
314
315}
316
322
324{
325 for (long unsigned int i = 0; i < m_runNumber.size(); i++) {
326 float ratio = (float)m_totalEventsWithTracks.at(i) / (float)m_totalEvents.at(i);
327 B2INFO("KLMTrackingModule::terminate run " << m_runNumber.at(i) << " --> " << ratio * 100 << "% of events has 1+ KLMTracks");
328 }
329
330 m_file->cd();
331 for (int iF = 0; iF < 2; iF++) {
332 for (int iS = 0; iS < 8; iS++) {
333 m_effiVsLayer[iF][iS]->Write();
334 m_total[iF][iS]->Write();
335 m_pass[iF][iS]->Write();
336 }
337 }
338
339 for (int i = 0; i < m_totalYX->GetNbinsX(); i++) {
340 for (int j = 0; j < m_totalYX->GetNbinsY(); j++) {
341 float num = m_passYX->GetBinContent(i + 1, j + 1);
342 float denom = m_totalYX->GetBinContent(i + 1, j + 1);
343 if (num > 0) {
344 m_effiYX->SetBinContent(i + 1, j + 1, num / denom);
345 m_effiYX->SetBinError(i + 1, j + 1, sqrt(num * (denom - num) / (denom * denom * denom)));
346 } else {
347 m_effiYX->SetBinContent(i + 1, j + 1, 0);
348 m_effiYX->SetBinError(i + 1, j + 1, 0);
349 }
350
351 num = m_passYZ->GetBinContent(i + 1, j + 1);
352 denom = m_totalYZ->GetBinContent(i + 1, j + 1);
353 if (num > 0) {
354 m_effiYZ->SetBinContent(i + 1, j + 1, num / denom);
355 m_effiYZ->SetBinError(i + 1, j + 1, sqrt(num * (denom - num) / (denom * denom * denom)));
356 } else {
357 m_effiYZ->SetBinContent(i + 1, j + 1, 0);
358 m_effiYZ->SetBinError(i + 1, j + 1, 0);
359 }
360 }
361 }
362
363
364 m_totalYX->SetOption("colz");
365 m_passYX->SetOption("colz");
366 m_totalYZ->SetOption("colz");
367 m_passYZ->SetOption("colz");
368 m_effiYX->SetOption("colz");
369 m_effiYZ->SetOption("colz");
370
371 m_totalYX->Write();
372 m_passYX->Write();
373 m_totalYZ->Write();
374 m_passYZ->Write();
375 m_effiYX->Write();
376 m_effiYZ->Write();
377 m_file->Close();
378
379}
380
382{
383 if (hit1->getSection() == hit2->getSection() && hit1->getSector() == hit2->getSector())
384 return true;
385 else return false;
386}
387
388
390{
391
392 //StoreArray<RecoTrack> recoTracks;
394
395 if (klmHits.size() < 1) {
396 B2INFO("KLMTrackingModule::findClosestRecoTrack, something is wrong! there is a KLMTrack but no klmHits");
397 return false;
398 }
399 if (recoTracks.getEntries() < 1) {
400 B2DEBUG(20, "KLMTrackingModule::findClosestRecoTrack, there is no recoTrack");
401 return false;
402 }
403 double oldDistanceSq = INFINITY;
404 double oldAngle = INFINITY;
405 closestTrack = nullptr;
406 //klmHits are already sorted by layer
407 //possible two hits in one layer?
408 //genfit requires TVector3 rather than XYZVector
409
410 TVector3 firstKLMHitPosition(klmHits[0]->getPosition().X(),
411 klmHits[0]->getPosition().Y(),
412 klmHits[0]->getPosition().Z());
413
414 // To get direction (angle) below, we have two points on the klmTrk:
415 // (x1, TrackParam[0]+TrackParam[1]*x1, TrackParam[2]+TrackParam[3]*x1)
416 // (x2, TrackParam[0]+TrackParam[1]*x2, TrackParam[2]+TrackParam[3]*x2)
417 // the difference vector is
418 // (x2-x1, TrackParam[1]*(x2-x1), TrackParam[3]*(x2-x1))
419 // which is proportional to
420 // (1, TrackParam[1], TrackParam[3]).
421 TVector3 klmTrkVec(1.0, klmTrk->getTrackParam()[1], klmTrk->getTrackParam()[3]);
422
423 TMatrixDSym cov(6);
424 TVector3 pos; // initializes to (0,0,0)
425 TVector3 mom; // initializes to (0,0,0)
426
427 for (RecoTrack& track : recoTracks) {
428 if (track.wasFitSuccessful()) {
429 try {
430 genfit::MeasuredStateOnPlane state = track.getMeasuredStateOnPlaneFromLastHit();
431 B2DEBUG(30, "KLMTracking::findClosestRecoTrack, finished MSOP from last hit");
433 state.getPosMomCov(pos, mom, cov);
434 if (mom.Y() * pos.Y() < 0) {
435 state = track.getMeasuredStateOnPlaneFromFirstHit();
436 }
437 const TVector3& distanceVec = firstKLMHitPosition - pos;
438 state.extrapolateToPoint(firstKLMHitPosition);
439 double newDistanceSq = distanceVec.Mag2();
440 double angle = klmTrkVec.Angle(mom);
441 // choose closest distance or minimum open angle ?
442 // overwrite old distance
443 if (newDistanceSq < oldDistanceSq) {
444 oldDistanceSq = newDistanceSq;
445 closestTrack = &track;
446 oldAngle = angle;
447 }
448
449 /* if(angle<oldAngle)
450 {
451 oldAngle=angle;
452 closestTrack = &track;
453 }
454 */
455 B2DEBUG(30, "KLMTracking::findClosestRecoTrack, step one done");
456 } catch (genfit::Exception& e) {
457 }// try
458 }
459 }
460
461 // can not find matched RecoTrack
462 // problem here is the errors of the track parameters are not considered!
463 // best way is the positon or vector direction are required within 5/10 sigma ?
464 if (oldAngle > m_maxAngleRequired)
465 return false;
466 // found matched RecoTrack
467 else {
468 B2DEBUG(28, "KLMTrackingModule::findClosestRecoTrack RecoTrack found! ");
469 return true;
470 }
471
472}
473
474//TODO: GENERALIZE ME [HARDEST PART!? :'( ]
475void KLMTrackingModule::generateEffi(int iSubdetector, int iSection, int iSector, int iLayer)
476{
477 //TODO: let's comment out during testing. remove this later
478
479 std::set<int> m_pointUsed;
480 std::set<int> layerList;
481 m_pointUsed.clear();
482 if (m_storeTracks.getEntries() < 1)
483 return;
484 B2DEBUG(10, "KLMTrackingModule:generateEffi: " << iSection << " " << iSector << " " << iLayer);
485
486 for (int it = 0; it < m_storeTracks.getEntries(); it++) {
487 //if(m_storeTracks[it]->getTrackChi2()>10) continue;
488 //if(m_storeTracks[it]->getNumHitOnTrack()<6) continue;
489 int cnt1 = 0;
490 int cnt2 = 0;
491
492 layerList.clear();
493
494
495 RelationVector<KLMHit2d> relatedHit2D = m_storeTracks[it]->getRelationsTo<KLMHit2d>();
496 for (const KLMHit2d& hit2D : relatedHit2D) {
497 if (hit2D.getSubdetector() != iSubdetector)
498 continue;
499 if (hit2D.getLayer() > iLayer + 1)
500 {cnt1++; layerList.insert(hit2D.getLayer());}
501 if (hit2D.getLayer() < iLayer + 1)
502 {cnt2++; layerList.insert(hit2D.getLayer());}
503 if (hit2D.getLayer() == iLayer + 1) {
504 B2DEBUG(10, "generateEffi: Hit info. Secti/sector/Lay = " << hit2D.getSection()
505 << "/" << hit2D.getSector() - 1 << "/" << hit2D.getLayer() - 1);
506 B2DEBUG(11, "generateEffi: Hit info. x/y/z = " << hit2D.getPositionX()
507 << "/" << hit2D.getPositionY() << "/" << hit2D.getPositionZ());
508 }
509 }
510
511 if ((int)layerList.size() < m_minNLayer)
512 continue;
513
514 if (iLayer != 0 && cnt2 < 1)
515 return;
516 if (iLayer != 14 && cnt1 < 1)
517 return;
518 //TODO: Extend to includ EKLM?
519 //m_GeoPar = GeometryPar::instance(); w/ geometry cuts.
520
521 if (iSubdetector == KLMElementNumbers::c_BKLM) {
522
523 const bklm::GeometryPar* bklmGeo = m_GeoPar->BarrelInstance();
524 const bklm::Module* module = bklmGeo->findModule(iSection, iSector + 1, iLayer + 1);
525 const bklm::Module* refmodule = bklmGeo->findModule(iSection, iSector + 1, 1);
526 int minPhiStrip = module->getPhiStripMin();
527 int maxPhiStrip = module->getPhiStripMax();
528 int minZStrip = module->getZStripMin();
529 int maxZStrip = module->getZStripMax();
530
531 CLHEP::Hep3Vector local = module->getLocalPosition(minPhiStrip, minZStrip);
532 CLHEP::Hep3Vector local2 = module->getLocalPosition(maxPhiStrip, maxZStrip);
533 float minLocalY, maxLocalY;
534 float minLocalZ, maxLocalZ;
535 if (local[1] > local2[1]) {
536 maxLocalY = local[1];
537 minLocalY = local2[1];
538 } else {
539 maxLocalY = local2[1];
540 minLocalY = local[1];
541 }
542 if (local[2] > local2[2]) {
543 maxLocalZ = local[2];
544 minLocalZ = local2[2];
545 } else {
546 maxLocalZ = local2[2];
547 minLocalZ = local[2];
548 }
549
550 //in global coordinates
551 TVectorD trkPar = m_storeTracks[it]->getTrackParam();
552
553 //line in local coordinates
554 Hep3Vector point1(0, trkPar[0], trkPar[2]);
555 Hep3Vector point2(1, trkPar[0] + trkPar[1], trkPar[2] + trkPar[3]);
556
557 Hep3Vector refPoint1(0., 0., 0.); Hep3Vector refPoint2(0., 0., 0.);
558 refPoint1 = refmodule->globalToLocal(point1);
559 refPoint2 = refmodule->globalToLocal(point2);
560
561 Hep3Vector refSlope(refPoint2[0] - refPoint1[0], refPoint2[1] - refPoint1[1], refPoint2[2] - refPoint1[2]);
562
563
564
565 //defined in coordinates relative to layer 1 of this sector.
566 float reflocalX = fabs(bklmGeo->getActiveMiddleRadius(iSection, iSector + 1,
567 iLayer + 1) - bklmGeo->getActiveMiddleRadius(iSection, iSector + 1, 1));
568 if (refmodule->isFlipped())
569 reflocalX = -reflocalX;
570 float X_coord = (reflocalX - refPoint1[0]) / refSlope[0];
571 float reflocalY = refPoint1[1] + refSlope[1] * X_coord;
572 float reflocalZ = refPoint1[2] + refSlope[2] * X_coord;
573
574 //Hep3Vector global(globalX, globalY, globalZ);
575 Hep3Vector reflocal(reflocalX, reflocalY, reflocalZ);
576 Hep3Vector global(0., 0., 0.);
577 global = refmodule->localToGlobal(reflocal);
578
579
580 float localX = module->globalToLocal(global)[0];
581 float localY = module->globalToLocal(global)[1];
582 float localZ = module->globalToLocal(global)[2];
583
584 B2DEBUG(10, "KLMTrackingModule:generateEffi: RefLocal " << reflocalX << " " << reflocalY << " " << reflocalZ);
585 B2DEBUG(10, "KLMTrackingModule:generateEffi: Global " << global[0] << " " << global[1] << " " << global[2]);
586 B2DEBUG(10, "KLMTrackingModule:generateEffi: Local " << localX << " " << localY << " " << localZ);
587
588
589
590 //geometry cut
591 if (localY > minLocalY && localY < maxLocalY && localZ > minLocalZ && localZ < maxLocalZ) {
592
593 bool m_iffound = false;
594 m_total[iSection][iSector]->Fill(iLayer + 1);
595 m_totalYX->Fill(global[0], global[1]);
596 m_totalYZ->Fill(global[2], global[1]);
597
598 for (int he = 0; he < hits2D.getEntries(); ++he) {
599 if (!isLayerUnderStudy(iSection, iSector, iLayer, hits2D[he])) {
600 B2DEBUG(11, "not isLayerUnderStudy");
601 continue;
602 }
603 if (hits2D[he]->isOutOfTime()) {
604 B2DEBUG(11, "hit isOutOfTime");
605 continue;
606 }
607 //if alreday used, skip
608 if (m_pointUsed.find(he) != m_pointUsed.end()) {
609 B2DEBUG(11, "passed unused");
610 continue;
611 }
612 B2DEBUG(11, "KLMTrackingModule:generateEffi: Reached Distance Check");
613 double error, sigma;
614 float distance = distanceToHit(m_storeTracks[it], hits2D[he], error, sigma);
615 float hitX = hits2D[he]->getPositionX();
616 float hitY = hits2D[he]->getPositionY();
617 float hitZ = hits2D[he]->getPositionZ();
618 float deltaX = hitX - global[0]; float deltaY = hitY - global[1]; float deltaZ = hitZ - global[2];
619 float dist = sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
620 B2DEBUG(10, "dist w/ hit = " << dist << ", dist func = " << distance << ", error = " << error);
621 if (distance < m_maxDistance && sigma < m_maxSigma) {
622 m_iffound = true;
623 B2DEBUG(10, "KLMTrackingModule:generateEffi: Hit found!");
624 }
625 if (m_iffound) {
626 m_pointUsed.insert(he);
627 m_pass[iSection][iSector]->Fill(iLayer + 1);
628 m_passYX->Fill(global[0], global[1]);
629 m_passYZ->Fill(global[2], global[1]);
630 break;
631 }
632 }
633
634 m_effiVsLayer[iSection][iSector]->Fill(m_iffound, iLayer + 1);
635 //efficiencies will be defined at terminate stage
636 } //end of BKLM geometry cut
637
638 } //end of BKLM section
639
640
641 }//end of loop tracks
642}
643
644
646{
647
648 return hit1->getLayer() < hit2->getLayer();
649
650}
651
652bool KLMTrackingModule::isLayerUnderStudy(int section, int iSector, int iLayer, KLMHit2d* hit)
653{
654 if (hit->getSection() == section && hit->getSector() == iSector + 1 && hit->getLayer() == iLayer + 1)
655 return true;
656 else return false;
657}
658
659bool KLMTrackingModule::isSectorUnderStudy(int section, int iSector, KLMHit2d* hit)
660{
661 if (hit->getSection() == section && hit->getSector() == iSector + 1)
662 return true;
663 else return false;
664}
665
667 double& error,
668 double& sigma)
669{
670
671 double x, y, z, dx, dy, dz, distance;
672
673 error = DBL_MAX;
674 sigma = DBL_MAX;
675
676 TVectorD m_GlobalPar = track->getTrackParam();
677
678
680
681 const bklm::GeometryPar* bklmGeo = m_GeoPar->BarrelInstance();
682 const Belle2::bklm::Module* corMod = bklmGeo->findModule(hit->getSection(), hit->getSector(), hit->getLayer());
683
684 //x = hit->getPositionX();
685 //y = m_GlobalPar[ 0 ] + x * m_GlobalPar[ 1 ];
686 //z = m_GlobalPar[ 2 ] + x * m_GlobalPar[ 3 ];
687
688 //since there are z-planes, let's exploit this fact.
689 z = hit->getPositionZ();
690 x = (z - m_GlobalPar[ 2 ]) / m_GlobalPar[ 3 ];
691 y = m_GlobalPar[ 0 ] + x * m_GlobalPar[ 1 ];
692
693 dx = x - hit->getPositionX() ;
694 dy = y - hit->getPositionY();
695 dz = z - hit->getPositionZ();
696
697 double x2 = hit->getPositionX();
698 double y2 = m_GlobalPar[ 0 ] + x2 * m_GlobalPar[ 1 ];
699 double z2 = m_GlobalPar[ 2 ] + x2 * m_GlobalPar[ 3 ];
700
701 double dx2 = x2 - hit->getPositionX();
702 double dy2 = y2 - hit->getPositionY();
703 double dz2 = z2 - hit->getPositionZ();
704
705 double dist2 = sqrt(dx2 * dx2 + dy2 * dy2 + dz2 * dz2);
706
707
708 distance = sqrt(dx * dx + dy * dy + dz * dz);
709 double hit_localPhiErr = corMod->getPhiStripWidth() / sqrt(12);
710 double hit_localZErr = corMod->getZStripWidth() / sqrt(12);
711
712 //error from tracking is ignored here
713 error = sqrt(square(hit_localPhiErr) + square(hit_localZErr));
714 B2DEBUG(11, "Dist = " << distance << ", error = " << error);
715 B2DEBUG(11, "Dist2 = " << dist2 << ", error = " << error);
716 } //end of BKLM section
717
718 else if (hit->getSubdetector() == KLMElementNumbers::c_EKLM) {
719
720 const EKLM::GeometryData* eklmGeo = m_GeoPar->EndcapInstance();
721
722
723 // use z coordinate as main point of interest
724 // should be close enough to distance of closest appraoch
725 z = hit->getPositionZ();
726 x = (z - m_GlobalPar[ 2 ]) / m_GlobalPar[ 3 ];
727 y = m_GlobalPar[ 0 ] + x * m_GlobalPar[ 1 ];
728
729 dx = x - hit->getPositionX();
730 dy = y - hit->getPositionY();
731 dz = 0.;
732
733 distance = sqrt(dx * dx + dy * dy + dz * dz);
734
735
736 //here get the resolustion of a hit, repeated several times, ugly. should we store this in KLMHit2d object ?
737 double hit_xErr = (eklmGeo->getStripGeometry()->getWidth()) * (Unit::cm / CLHEP::cm) *
738 (hit->getXStripMax() - hit->getXStripMin()) / sqrt(12);
739 double hit_yErr = (eklmGeo->getStripGeometry()->getWidth()) * (Unit::cm / CLHEP::cm) *
740 (hit->getYStripMax() - hit->getYStripMin()) / sqrt(12);
741
742
743 //error from tracking is ignored here
744 error = sqrt(square(hit_xErr) + square(hit_yErr));
745 } //end of EKLM section
746 else {
747 B2WARNING("KLMTracking::distanceToHit Received KLMHit2d that's not from E/B-KLM. Setting distance to -1");
748 distance = -1.;
749 }
750
751
752 if (error != 0.0) {
753 sigma = distance / error;
754 } else {
755 sigma = DBL_MAX;
756 }
757
758 return distance;
759
760}
761
@ c_Event
Different object in each event, all objects/arrays are invalidated after event() function has been ca...
Definition DataStore.h:59
This dataobject is used only for EKLM alignment.
const StripGeometry * getStripGeometry() const
Get strip geometry data.
EKLM geometry data.
KLM 2d hit.
Definition KLMHit2d.h:33
int getSubdetector() const
Get subdetector number.
Definition KLMHit2d.h:78
int getYStripMin() const
Get first strip number for EKLM hit in the y-measuring plane.
Definition KLMHit2d.h:258
int getLayer() const
Get layer number.
Definition KLMHit2d.h:132
int getSection() const
Get section number.
Definition KLMHit2d.h:96
float getPositionZ() const
Get hit global position z coordinate.
Definition KLMHit2d.h:306
int getSector() const
Get sector number.
Definition KLMHit2d.h:114
float getPositionX() const
Get hit global position x coordinate.
Definition KLMHit2d.h:288
int getXStripMax() const
Get last strip number for EKLM hit in the x-measuring plane.
Definition KLMHit2d.h:250
float getPositionY() const
Get hit global position y coordinate.
Definition KLMHit2d.h:297
int getYStripMax() const
Get last strip number for EKLM hit in the y-measuring plane.
Definition KLMHit2d.h:266
int getXStripMin() const
Get first strip number for EKLM hit in the x-measuring plane.
Definition KLMHit2d.h:242
track finding procedure
bool filter(const std::list< KLMHit2d * > &seed, std::list< KLMHit2d * > &hits, std::list< KLMHit2d * > &track, int iSubdetector)
find associated hits and do fit.
void registerFitter(KLMTrackFitter *fitter)
Register a fitter if not constructed with one.
track fitting procedure
float getChi2()
Chi square of the fit.
bool isGood()
Is fit good.
int getNumHit()
number of the hits on this track
CLHEP::HepSymMatrix getTrackParamErr()
Get invariance matrix of track parameters in the global system.
CLHEP::HepVector getTrackParam()
Get track parameters in the global system. y = p0 + p1 * x; z = p2 + p3 * x.
bool isValid()
Is fit valid.
Store one KLM Track as a ROOT object.
Definition KLMTrack.h:38
void setIsValid(const bool valid)
set the fit valid status
Definition KLMTrack.h:112
void setTrackChi2(const float chi2)
Set the fitted chi2 of the track.
Definition KLMTrack.h:93
void setTrackParamErr(const CLHEP::HepSymMatrix &trkParErr)
Set invariance matrix of track parameters in the global system.
Definition KLMTrack.cc:102
void setNumHitOnTrack(const int NumHit)
Set the number of 2d hits on the track.
Definition KLMTrack.h:99
TVectorD getTrackParam()
Get track parameters in the global system. y = p0 + p1 * x; z = p2 + p3 * x.
Definition KLMTrack.cc:66
void setIsGood(const bool good)
set the fit good status
Definition KLMTrack.h:118
void setInSubdetector(int nBKLM, int nEKLM)
setting whether track passes through E/B-KLM
Definition KLMTrack.h:105
void setTrackParam(const CLHEP::HepVector &trkPar)
Set track parameters in the global system. y = p0 + p1 * x; z = p2 + p3 * x.
Definition KLMTrack.cc:92
void generateEffi(int iSubdetector, int section, int sector, int layer)
calculate efficiency
bool m_MatchToRecoTrack
whether match KLMTrack to RecoTrack
TEfficiency * m_effiVsLayer[2][8]
Efficieny of each layer.
std::vector< int > m_runNumber
run number
TH2F * m_passYZ
passed event at global position Y vs Z
TH2F * m_effiYX
Efficieny at global position Y vs X.
bool m_studyEffi
option for efficieny study mode, in this mode, the layer under study should not be used in tracking
double m_maxSigma
maximum sigma for hit acceptance during efficiency calculation
void runTracking(int mode, int iSubdetector, int section, int sector, int layer)
run the track finding and fitting
double m_maxAngleRequired
angle required between RecoTrack and KLMTrack, if openangle is larger than m_maxAngleRequired,...
int m_minNLayer
minimum number of layers for track finder to run
void initialize() override
Initialize at start of job.
unsigned int m_minHitList
minimum number of hits in sector for track finder to run (-2 from initial seed)
std::string m_outPath
output file name containing efficiencies plots
void event() override
Unpack one event and create digits.
Belle2::KLM::KLMGeometryPar * m_GeoPar
KLMGeometryPar to call on B/E-KLM.
bool findClosestRecoTrack(KLMTrack *klmTrk, RecoTrack *&closestTrack)
find the closest RecoTrack, match KLMTrack to RecoTrack, if the matched RecoTrack is found,...
void endRun() override
end run stuff
StoreArray< RecoTrack > recoTracks
RecoTrack StoreArray.
void terminate() override
Terminate at the end of job.
TH1F * m_pass[2][8]
Numerator of each layer.
TH2F * m_totalYX
total event at global position Y vs X
StoreArray< RecoHitInformation > recoHitInformation
RecoHitInformation StoreArray.
int m_runTotalEventsWithTracks
total number of processed events in the run with at lease one BKLMTrack
void beginRun() override
begin run stuff
double m_maxDistance
maximum distance required between track and KLMHit2d to be accepted for efficiency calculation
StoreArray< KLMTrack > m_storeTracks
KLMTrack StoreArray.
StoreArray< KLMHit2d > hits2D
KLMHit2d StoreArray.
TFile * m_file
TFile that store efficieny plots.
std::vector< int > m_totalEvents
total number of processed events
bool isLayerUnderStudy(int section, int iSector, int iLayer, KLMHit2d *hit)
judge whether the current layer is understudy
TH1F * m_total[2][8]
Denominator of each layer.
double distanceToHit(KLMTrack *track, KLMHit2d *hit, double &error, double &sigma)
calculate distance from track to hit
unsigned int m_maxHitList
max number of hits in sector for track finder to run
std::vector< int > m_totalEventsWithTracks
total number of processed events with at least one BKLMTrack
TH2F * m_effiYZ
Efficieny at global position Y vs Z.
bool isSectorUnderStudy(int section, int iSector, KLMHit2d *hit)
judge whether the hits come from the sctor under study
static bool sortByLayer(KLMHit2d *hit1, KLMHit2d *hit2)
my defined sort function using layer number
TH2F * m_totalYZ
total event at global position Y vs Z
bool sameSector(KLMHit2d *hit1, KLMHit2d *hit2)
Judge if two hits come from the same sector.
int m_runTotalEvents
total number of processed events in the run
TH2F * m_passYX
passed event at global position Y vs X
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
Module()
Constructor.
Definition Module.cc:30
This is the Reconstruction Event-Data Model Track.
Definition RecoTrack.h:79
bool addBKLMHit(const UsedBKLMHit *bklmHit, const unsigned int sortingParameter, OriginTrackFinder foundByTrackFinder=OriginTrackFinder::c_undefinedTrackFinder)
Adds a bklm hit with the given information to the reco track.
Definition RecoTrack.h:286
bool addEKLMHit(const UsedEKLMHit *eklmHit, const unsigned int sortingParameter, OriginTrackFinder foundByTrackFinder=OriginTrackFinder::c_undefinedTrackFinder)
Adds an eklm hit with the given information to the reco track.
Definition RecoTrack.h:300
unsigned int getNumberOfTotalHits() const
Return the number of cdc + svd + pxd + bklm + eklm hits.
Definition RecoTrack.h:436
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of relations.
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).
RelationVector< FROM > getRelationsFrom(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from another store array to this object.
RelationVector< TO > getRelationsTo(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from this object to another store array.
Type-safe access to single objects in the data store.
Definition StoreObjPtr.h:96
static const double cm
Standard units with the value = 1.
Definition Unit.h:47
Provides BKLM geometry parameters for simulation, reconstruction etc (from Gearbox or DataBase)
Definition GeometryPar.h:37
const Module * findModule(int section, int sector, int layer) const
Get the pointer to the definition of a module.
double getActiveMiddleRadius(int section, int sector, int layer) const
Get the radial midpoint of the detector module's active volume of specified layer.
Define the geometry of a BKLM module Each sector [octant] contains Modules.
Definition Module.h:76
const CLHEP::Hep3Vector globalToLocal(const CLHEP::Hep3Vector &v, bool reco=false) const
Transform space-point within this module from global to local coordinates.
Definition Module.cc:339
double getPhiStripWidth() const
Get phi-strip width.
Definition Module.h:137
const CLHEP::Hep3Vector localToGlobal(const CLHEP::Hep3Vector &v, bool reco=false) const
Transform space-point within this module from local to global coordinates.
Definition Module.cc:326
double getZStripWidth() const
Get z-strip width.
Definition Module.h:155
bool isFlipped() const
Determine if this module is flipped by 180 degrees about z axis within its air gap.
Definition Module.h:113
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:559
constexpr T square(const T &x)
Calculate the square of the input.
Definition MathHelpers.h:21
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28
ExpRunEvt getPosition(const std::vector< Evt > &events, double tEdge)
Get the exp-run-evt number from the event time [hours].
Definition Splitter.h:341
Abstract base class for different kinds of events.