BmnRoot 26.10.0-210-gc52d34b0
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
L1AlgoEfficiencyPerformance.h
Go to the documentation of this file.
1#ifndef L1AlgoEfficiencyPerformance_h
2#define L1AlgoEfficiencyPerformance_h
3
4/**
5 * Class for tracklets reconstruction efficiency calculation. Used for debug of CATrackFinder.
6 *
7 * Reconstructed tracklet is one, which has all 3 hits from one mcTrack.
8 * Reconstructable mcTracklet is one, which has all 3 hits and momentum bigger than fL1->MinRecoMom.
9 */
10
11#include "CbmL1.h"
12#include "CbmL1Counters.h"
13#include "CbmL1Def.h"
14#include "L1Algo/L1Algo.h"
15#include "L1Algo/L1StsHit.h"
16
17#include <iostream>
18#include <vector>
19
20using std::cout;
21using std::endl;
22using std::vector;
23
24const int MaxNStations = 10;
25
26template<int NHits>
28{
29 public:
31 : mcTrackId(-1)
32 , iStation(-1) {};
33
34 static bool compare(const L1Tracklet<NHits>& a, const L1Tracklet<NHits>& b)
35 {
36 return (a.mcTrackId < b.mcTrackId) || ((a.mcTrackId == b.mcTrackId) && (a.iStation < b.iStation));
37 }
38
39 bool operator==(const L1Tracklet<NHits>& a) { return ((a.mcTrackId == mcTrackId) && (a.iStation == iStation)); }
40 bool operator!=(const L1Tracklet<NHits>& a) { return !operator==(a); }
41 bool operator<(const L1Tracklet<NHits>& a) { return compare(*this, a); }
42
45};
46
47// reconstructed Tracklet
48template<int NHits>
49class L1RTracklet : public L1Tracklet<NHits>
50{
51 public:
54 : L1Tracklet<NHits>()
55 {
56 for (int iih = 0; iih < NHits; iih++) {
57 i[iih] = ih_[iih];
58 }
59 };
60
61 bool IsGhost() { return L1Tracklet<NHits>::mcTrackId < 0; }; // is it ghost or reconstructed
62
64
66 {
67 bool flag = 1;
68 // flag &= L1Tracklet<NHits>::operator==(a);
69 for (int ih = 0; ih < NHits; ih++) {
70 flag &= (a.i[ih] == i[ih]);
71 }
72 return flag;
73 }
74 bool operator!=(const L1RTracklet<NHits>& a) { return !operator==(a); }
75
76 THitI i[NHits]; // indices of left, middle and right hits
77};
78
79// MC Tracklet
80template<int NHits>
81class L1MTracklet : public L1Tracklet<NHits>
82{
83 public:
85 : isReconstructable(false)
86 {}
87
88 void AddReconstructed(int recoId) { recoIds.push_back(recoId); };
90
91 int GetNClones() { return (recoIds.size() > 1) ? recoIds.size() - 1 : 0; }; // number of created clones
92 bool IsReconstructed() { return recoIds.size(); }; // is it reconstructed
93 bool IsReconstructable() { return isReconstructable; }; // is it possible to reconstruct
94 bool IsPrimary() { return mcMotherTrackId < 0; }; // is it primary or secondary
95
97 float p; // momentum
98 vector<int> recoIds; // indices of reco tracklets in sorted recoArray
99
100 vector<int> hitIds[NHits]; // indices of hits in L1::vStsHits. Separated by stations
101 private:
102 bool isReconstructable; // is it reconstructed
103};
104
105// tracklets categories
107{
110 {
111 AddCounter("total", "Allset efficiency");
112 AddCounter("fast", "Refset efficiency");
113 AddCounter("fast_prim", "RefPrim efficiency");
114 AddCounter("fast_sec", "RefSec efficiency");
115 AddCounter("slow", "Extra efficiency");
116 AddCounter("slow_prim", "ExtraPrim efficiency");
117 AddCounter("slow_sec", "ExtraSec efficiency");
118 }
119};
120
121template<int NHits = 3>
123{
124 public:
128 void Init();
129
130 bool AddOne(THitI* ih_); // add one recoTracklets. Return is it reconstructed or not
131 void CalculateEff();
132 void Print(); // Print efficiencies
133 void Print(TString title = "Triplets performance statistic", bool station = 0); // Print efficiencies
134
135 private:
136 void FillMC(); // collect mcTracklets from mcTracks
137 void MatchTracks();
138
140
141 vector<L1RecoTracklet> recoTracklets;
142 vector<L1MCTracklet> mcTracklets;
143
144 TL1AlgoEfficiencies ntra; // current event efficiencies
145 TL1AlgoEfficiencies NTRA; // efficiencies statistic
146
147 TL1AlgoEfficiencies ntra_sta[MaxNStations]; // for each station separately
149};
150
151// ===================================================================================
152
153template<int NHits>
155{
157 recoTracklets.clear();
158 mcTracklets.clear();
160 for (int iSta = 0; iSta < MaxNStations; iSta++) {
161 ntra_sta[iSta] = ntra;
162 }
163
164 FillMC();
165};
166
167template<int NHits>
169{
170 for (vector<CbmL1MCTrack>::iterator mtraIt = fL1->vMCTracks.begin(); mtraIt != fL1->vMCTracks.end(); mtraIt++) {
171 CbmL1MCTrack& mtra = *(mtraIt);
172 // if( ! mtra.IsReconstructable() ) continue;
173
174 const int NMCPoints = mtra.Points.size();
175 // const int NIter = mtra.NStations()-NHits+1; // number of possible tracklets
176 int lastIterSta = -1;
177 for (int iterOffset = 0; iterOffset < NMCPoints; iterOffset++) { // first mcPoint on the station
178 // const int iterMcId = mtra.Points[iterOffset];
179 int iterSta = fL1->vMCPoints[mtra.Points[iterOffset]].iStation;
180 if (iterSta == lastIterSta)
181 continue; // find offset for next station
182 lastIterSta = iterSta;
183
184 // read hits
185 // take all points on each station
186 // TODO: Should we create all possible tracklets?
187 L1MCTracklet trlet; // TODO: don't use hits in mcTracklet
188 for (int is = 0, offset = iterOffset; ((offset < NMCPoints) && (is < NHits)); offset++) {
189 const int mcId = mtra.Points[offset];
190 CbmL1MCPoint* mcPs = &(fL1->vMCPoints[mcId]);
191 is = mcPs->iStation - iterSta;
192
193 if (is < NHits) {
194 const int NPointHits = mcPs->hitIds.size();
195 for (int ih = 0; ih < NPointHits; ih++) {
196 trlet.hitIds[is].push_back(mcPs->hitIds[ih]);
197 }
198 }
199 } // for is
200 // check tracklet
201 bool good = 1;
202 for (int is = 0; is < NHits; is++) {
203 good &= trlet.hitIds[is].size();
204 }
205 if (!good)
206 continue; // can't create tracklet
207
208 trlet.iStation = iterSta;
209 trlet.mcTrackId = mtra.ID;
210 trlet.mcMotherTrackId = mtra.mother_ID;
211 trlet.p = mtra.p;
212 if (mtra.p > fL1->MinRecoMom)
213 trlet.SetAsReconstructable();
214
215 mcTracklets.push_back(trlet);
216 } // for Iter = stations
217 } // for mcTracks
218} // void L1AlgoEfficiencyPerformance::FillMC()
219
220template<int NHits>
222{
223 L1RecoTracklet trlet(iHits);
224
225 // --- check is all hits belong to one mcTrack ---
226 vector<int> mcIds[NHits];
227
228 // obtain mc data
229 for (int iih = 0; iih < NHits; iih++) {
230 int nMC = fL1->vStsHits[iHits[iih]].mcPointIds.size();
231 for (int iMC = 0; iMC < nMC; iMC++) {
232 const int iMCP = fL1->vStsHits[iHits[iih]].mcPointIds[iMC];
233 int mcId = fL1->vMCPoints[iMCP].ID;
234 mcIds[iih].push_back(mcId);
235 } // for mcPoints
236 } // for hits
237
238 // find all reconstructed track id-s
239 for (int level = 0; level < NHits - 1; level++) {
240 vector<int>& mcs1 = mcIds[level];
241 vector<int>& mcs2 = mcIds[level + 1];
242
243 // leave only matched ID-s.
244 for (unsigned int i2 = 0; i2 < mcs2.size(); i2++) {
245 int& mc2 = mcs2[i2];
246 bool flag = 0;
247 // is the same ID on prev station?
248 for (unsigned int i1 = 0; i1 < mcs1.size(); i1++) {
249 flag |= (mcs1[i1] == mc2);
250 }
251 if (!flag)
252 mc2 = -2;
253 } // for i2
254 }
255
256 // use first found // TODO: save all!!!
257 vector<int>& mcsN = mcIds[NHits - 1];
258 for (unsigned int i = 0; i < mcsN.size(); i++) {
259 if (mcsN[i] >= 0) {
260 trlet.mcTrackId = mcsN[i];
261 trlet.iStation = fL1->vMCPoints[fL1->vStsHits[iHits[0]].mcPointIds[0]].iStation;
262 break;
263 }
264 }
265
266 // --- save ---
267 // if ( std::find(recoTracklets.begin(), recoTracklets.end(), trlet) == recoTracklets.end() )
268 recoTracklets.push_back(trlet);
269
270 return (trlet.mcTrackId >= 0);
271}; // inline bool L1AlgoEfficiencyPerformance::AddOne(THitI ihl, THitI ihm, THitI ihr)
272
273template<int NHits>
275{ // TODO: If we create all possible tracklets on NHits station - addapt to it.
276 std::sort(recoTracklets.begin(), recoTracklets.end(), L1Tracklet<NHits>::compare);
277 std::sort(mcTracklets.begin(), mcTracklets.end(), L1Tracklet<NHits>::compare);
278
279 const int NRecoTrlets = recoTracklets.size();
280 const int NMCTrlets = mcTracklets.size();
281 // cout << NMCTrlets << " " << NRecoTrlets << " " << endl;
282 for (int iReco = 0, iMC = 0; (iReco < NRecoTrlets) && (iMC < NMCTrlets);) {
283 L1MCTracklet& mcTrlet = mcTracklets[iMC];
284 L1RecoTracklet& recoTrlet = recoTracklets[iReco];
285
286 // if (recoTrlet.mcTrackId >= 0)
287 // cout << iMC << " " << mcTrlet.iStation << " " << mcTrlet.mcTrackId << " " << mcTrlet.p << " | "
288 // << iReco << " " << recoTrlet.iStation << " " << recoTrlet.mcTrackId << " " << endl;
289
290 if (recoTrlet != mcTrlet) {
291 if (recoTrlet < mcTrlet)
292 iReco++;
293 else
294 iMC++;
295 } else {
296 // cout << iMC << " " << mcTrlet.iStation << " " << mcTrlet.mcTrackId << " " << mcTrlet.p << " | "
297 // << iReco << " " << recoTrlet.iStation << " " << recoTrlet.mcTrackId << " " << endl;
298 // check if same tracklet has been matched, and save it if not.
299 bool flag = 1;
300 const int nReco = mcTrlet.recoIds.size();
301 for (int iR = 0; iR < nReco; iR++) {
302 flag &= (recoTrlet != recoTracklets[mcTrlet.recoIds[iR]]);
303 }
304 if (flag)
305 mcTrlet.AddReconstructed(iReco);
306
307 iReco++; // suppose we have only one tracklet with certain (Id,Station)
308 }
309 };
310} // void L1AlgoEfficiencyPerformance::MatchTracks()
311
312template<int NHits>
314{
315 MatchTracks();
316
317 const int NRecoTrlets = recoTracklets.size();
318 for (int iReco = 0; iReco < NRecoTrlets; iReco++) {
319 L1RecoTracklet& reco = recoTracklets[iReco];
320 ntra /*_sta[reco.iStation]*/.ghosts += reco.IsGhost();
321 }
322
323 const int NMCTrlets = mcTracklets.size();
324 for (int iMC = 0; iMC < NMCTrlets; iMC++) {
325 L1MCTracklet& mtra = mcTracklets[iMC];
326 if (!mtra.IsReconstructable())
327 continue;
328 int iSta = mtra.iStation;
329
330 // find used constans
331 const bool reco = mtra.IsReconstructed();
332
333 // count tracklets
334 ntra_sta[iSta].Inc(reco, "total");
335
336 if (mtra.p > fL1->MinRefMom) { // reference tracks
337 ntra_sta[iSta].Inc(reco, "fast");
338 if (mtra.IsPrimary()) { // reference primary
339 ntra_sta[iSta].Inc(reco, "fast_prim");
340
341 // // Debug
342 // if (!reco){
343 // cout << "iMC/N " << iMC << "/" << NMCTrlets << " sta " << mtra.iStation << " trackId " <<
344 // mtra.mcTrackId << " momentum " << mtra.p << ". MotherTrackId " << mtra.mcMotherTrackId <<
345 // endl; for (int iSta2 = 0; iSta2 < NHits; iSta2++){
346 // cout << iSta2 << ": ";
347 // const int NPointHits = mtra.hitIds[iSta2].size();
348 // for (int iH = 0; iH < NPointHits; iH++){
349 // cout << mtra.hitIds[iSta2][iH] << "";
350 // cout << "(" << fL1->vHitStore[mtra.hitIds[iSta2][iH]].x << "\\" <<
351 // fL1->vHitStore[mtra.hitIds[iSta2][iH]].y << "= " <<
352 // fL1->vHitStore[mtra.hitIds[iSta2][iH]].x/fL1->vHitStore[mtra.hitIds[iSta2][iH]].y << "
353 // ) ";
354 // }
355 // cout << endl;
356 // }
357 // }
358
359 } else { // reference secondary
360 ntra_sta[iSta].Inc(reco, "fast_sec");
361 }
362 } else { // extra set of tracks
363 ntra_sta[iSta].Inc(reco, "slow");
364 if (mtra.IsPrimary()) { // extra primary
365 ntra_sta[iSta].Inc(reco, "slow_prim");
366 } else {
367 ntra_sta[iSta].Inc(reco, "slow_sec");
368 }
369 } // if extra
370 ntra_sta[iSta].clones += mtra.GetNClones(); // TODO:check if works
371 }; // for mcTracklets
372
373 for (int iSta = 0; iSta < MaxNStations; iSta++) {
374 ntra += ntra_sta[iSta];
375 NTRA_STA[iSta] += ntra_sta[iSta];
376 ntra_sta[iSta].CalcEff();
377 NTRA_STA[iSta].CalcEff();
378 }
379 NTRA += ntra;
380 ntra.CalcEff();
381 NTRA.CalcEff();
382} // void L1AlgoEfficiencyPerformance::CalculateEff()
383
384template<int NHits>
385inline void L1AlgoEfficiencyPerformance<NHits>::Print(TString title, bool stations)
386{
387 // cout << endl;
388 // cout << "-------- Triplets performance ----------" << endl;
389 // ntra.PrintEff();
390
391 cout << endl;
392 cout << "-------- " << title << " ----------" << endl;
393 NTRA.PrintEff();
394 cout << endl;
395
396 if (stations) {
397 for (int iSta = 0; iSta < fL1->NStation - NHits + 1; iSta++) {
398 TString title_sta = title;
399 title_sta += " station ";
400 title_sta += iSta;
401 cout << endl;
402 cout << "-------- " << title_sta << " ----------" << endl;
403 NTRA_STA[iSta].PrintEff();
404 cout << endl;
405 }
406 }
407};
408
409#endif
const int MaxNStations
unsigned int THitI
Definition L1StsHit.h:6
int i
Definition P4_F32vec4.h:22
vector< int > Points
Definition CbmL1.h:48
static CbmL1 * Instance()
reconstructed tracks
Definition CbmL1.h:59
TL1AlgoEfficiencies NTRA_STA[MaxNStations]
TL1AlgoEfficiencies ntra_sta[MaxNStations]
void AddReconstructed(int recoId)
vector< int > hitIds[NHits]
bool operator!=(const L1Tracklet< NHits > &a)
bool operator!=(const L1RTracklet< NHits > &a)
bool operator==(const L1RTracklet< NHits > &a)
static bool compare(const L1Tracklet< NHits > &a, const L1Tracklet< NHits > &b)
bool operator!=(const L1Tracklet< NHits > &a)
bool operator<(const L1Tracklet< NHits > &a)
bool operator==(const L1Tracklet< NHits > &a)
vector< int > hitIds
virtual void AddCounter(TString shortname, TString name)