ATLAS Offline Software
Loading...
Searching...
No Matches
ITkTrackClusterAssValidation.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "GaudiKernel/ServiceHandle.h"
16
17#include <cmath>
18
20// Constructor
22
24(const std::string& name,ISvcLocator* pSvcLocator)
25 : AthReentrantAlgorithm(name,pSvcLocator)
26{
27}
28
30
31
33// Initialisation
35
37{
38
39 StatusCode sc;
40
41 if (m_rapcut == 0) {
42 m_tcut = 0;
43 }
44 else {
45 double den = tan(2.*atan(exp(-m_rapcut)));
46 if (den > 0) {
47 m_tcut = 1./den;
48 }
49 else {
50 m_tcut = std::numeric_limits<double>::max();
51 }
52 }
53
54 // Erase statistic information
55 //
56 m_pdg = std::abs(m_pdg) ;
57
58 m_trackCollectionStat.resize(m_tracklocation.size());
59 m_eventStat = InDet::EventStat_t();
60
61 // Read Handle Key
65
69
71
72 ATH_CHECK( m_tracklocation.initialize());
73
74 // Read Cond Handle Key
75 ATH_CHECK(m_pixelDetEleCollKey.initialize());
76 ATH_CHECK(m_StripDetEleCollKey.initialize());
77
78 if (msgLvl(MSG::DEBUG)) {
79 dumptools(msg(),MSG::DEBUG);
80 msg() << endmsg;
81 }
82
83 return sc;
84}
85
87// Execute
89
90StatusCode ITk::TrackClusterAssValidation::execute(const EventContext& ctx) const
91{
92
93 if(!m_usePix && !m_useStrip) return StatusCode::SUCCESS;
94 EventData_t event_data(m_tracklocation.size() );
95
96 std::vector<SG::ReadHandle<PRD_MultiTruthCollection> > read_handle;
97 read_handle.reserve(3);
98 if(m_usePix) {
99 read_handle.emplace_back(m_truth_locationPixel,ctx);
100 if (not read_handle.back().isValid()) {
101 ATH_MSG_FATAL( "Could not find TruthPix" );
102 return StatusCode::FAILURE;
103 }
104 event_data.m_truthPix = &(*read_handle.back());
105 }
106
107 if(m_useStrip) {
108 read_handle.emplace_back(m_truth_locationStrip,ctx);
109 if (not read_handle.back().isValid()) {
110 ATH_MSG_FATAL( "Could not find TruthStrip" );
111 return StatusCode::FAILURE;
112 }
113 event_data.m_truthStrip = &(*read_handle.back());
114 }
115
116 newClustersEvent (ctx,event_data);
117 newSpacePointsEvent (ctx,event_data);
118 event_data.m_nqtracks = qualityTracksSelection(event_data);
119 tracksComparison (ctx,event_data);
120 if(!event_data.m_particles[0].empty()) {
121
122 efficiencyReconstruction(event_data);
123 if(msgLvl(MSG::DEBUG)) noReconstructedParticles(event_data);
124
125 }
126
127 {
128 std::lock_guard<std::mutex> lock(m_statMutex);
129 assert( event_data.m_trackCollectionStat.size() == m_trackCollectionStat.size());
130 for (unsigned int i=0; i< m_trackCollectionStat.size(); ++i ) {
131 m_trackCollectionStat[i] += event_data.m_trackCollectionStat[i];
132 }
133 m_eventStat += event_data.m_eventStat;
134 }
135
136 if (msgLvl(MSG::DEBUG)) {
137 dumpevent(msg(),event_data);
138 msg() << endmsg;
139 }
140 return StatusCode::SUCCESS;
141}
142
144// Finalize
146
148 if(m_eventStat.m_events<=0) return StatusCode::SUCCESS;
149 const auto & w13 = std::setw(13);
150 const auto & p5 = std::setprecision(5);
151 const auto topNtail=[](const std::string & str){return "|" + str + "|";};
152 const std::string lineSeparator(83,'-');
153 const std::string spaceSeparator(83,' ');
154 std::stringstream out;
155 out<<std::fixed;
156 out<<topNtail(lineSeparator)<<"\n";
157 out<<"| TrackClusterAssValidation statistic for charge truth particles with |\n";
158 out<<topNtail(spaceSeparator)<<"\n";
159
160 out<<"| eta bins for eta dependent variables = [0.0, ";
161 for (unsigned int etabin = 1; etabin<(m_etabins.size()-1); etabin++)
162 out << std::setw(2) << std::setprecision(1) << m_etabins.value().at(etabin) << ", ";
163 out << std::setw(2) << m_etabins.value().back() << "] |\n";
164 out<<"| eta dependent pT [MeV] >= [";
165 for (unsigned int ptbin = 0; ptbin<(m_ptcuts.size()-1); ptbin++)
166 out<<std::setw(6)<<std::setprecision(2)<<m_ptcuts.value().at(ptbin)<<", ";
167 out<<std::setw(6)<<std::setprecision(2)<<m_ptcuts.value().back()<<"] |\n";
168 if(m_ptcutmax < 1000000.) {
169 out<<"| pT <="<<w13<<p5<<m_ptcutmax<<" MeV"<<" |\n";
170 }
171 out<<"| |rapidity| <="<<w13<<p5<<m_rapcut<<" |\n";
172 out<<"| max vertex radius <="<<w13<<p5<<m_rmax<<" mm"<<" |\n";
173 out<<"| min vertex radius >="<<w13<<p5<<m_rmin<<" mm"<<" |\n";
174 out<<"| particles pdg ="<<std::setw(8)<<m_pdg<<" |\n";
175
176 auto yesNo=[](const bool predicate){return predicate ? "yes" : "no ";};
177 out<<"| use Pixels information "<<yesNo(m_usePix)<<" |\n";
178 out<<"| use Strip information "<<yesNo(m_useStrip)<<" |\n";
179 out<<"| take into account outliers "<<yesNo(m_useOutliers)<<" |\n";
180 out<<topNtail(spaceSeparator)<<"\n";
181 if(!m_usePix && !m_useStrip) return StatusCode::SUCCESS;
182 enum Regions{Barrel, Transition, Endcap, Forward, NRegions};
183 auto incrementArray=[](auto & array, const int idx){for (int j{};j!=NRegions;++j) array[idx][j] += array[idx+1][j];};
184 for(int i=48; i>=0; --i) {
185 m_eventStat.m_particleClusters [i] +=m_eventStat.m_particleClusters [i+1];
186 incrementArray(m_eventStat.m_particleClustersBTE, i);
187 m_eventStat.m_particleSpacePoints [i] +=m_eventStat.m_particleSpacePoints [i+1];
188 incrementArray(m_eventStat.m_particleSpacePointsBTE, i);
189 }
190 auto coerceToOne=[](const double & initialVal)->double {return (initialVal<1.) ? 1. : initialVal; };
191 /* Note that in all cases below, the dimension of the target (i.e. result) array is 10
192 * whereas the dimension of the source, or input, array is 50. The first index of the source
193 * is used for totals, to act as a denominator(coerced to 1 if necessary). Bin 49 is used for overflows.
194 * Stats for single clusters (index 1) appear to be unused in printout.
195 */
196 //all
197 double pa = coerceToOne(m_eventStat.m_particleClusters[0]);
198 std::array<double, 10> pc2ff{};
199 size_t clusterIdx = 2;
200 for (auto & thisCluster: pc2ff){
201 thisCluster = double(m_eventStat.m_particleClusters[ clusterIdx++ ])/ pa;
202 }
203 //barrel
204 pa = coerceToOne(m_eventStat.m_particleClustersBTE[0][Barrel]);
205 std::array<double, 10> pcBarrel2ff{};
206 size_t clusterBarrelIdx = 2;
207 for (auto & thisClusterB: pcBarrel2ff){
208 thisClusterB = double(m_eventStat.m_particleClustersBTE[ clusterBarrelIdx++ ][Barrel])/ pa;
209 }
210 //transition
211 pa = coerceToOne(m_eventStat.m_particleClustersBTE[0][Transition]);
212 std::array<double, 10> pcTransition2ff{};
213 size_t clusterTransitionIdx = 2;
214 for (auto & thisClusterT: pcTransition2ff){
215 thisClusterT = double(m_eventStat.m_particleClustersBTE[ clusterTransitionIdx++ ][Transition])/ pa;
216 }
217 //endcap
218 pa = coerceToOne(m_eventStat.m_particleClustersBTE[0][Endcap]);
219 std::array<double, 10> pcEndcap2ff{};
220 size_t clusterEndcapIdx = 2;
221 for (auto & thisClusterE: pcEndcap2ff){
222 thisClusterE = double(m_eventStat.m_particleClustersBTE[ clusterEndcapIdx++ ][Endcap])/ pa;
223 }
224 //fwd
225 pa = coerceToOne(m_eventStat.m_particleClustersBTE[0][3]);
226 std::array<double, 10> pcFwd2ff{};
227 size_t clusterFwdIdx = 2;
228 for (auto & thisClusterD: pcFwd2ff){
229 thisClusterD = double(m_eventStat.m_particleClustersBTE[ clusterFwdIdx++ ][Forward])/ pa;
230 }
231 //
232 //*** SPACE POINTS ***
233 //
234 //all
235 pa = coerceToOne(m_eventStat.m_particleSpacePoints[0]);
236 std::array<double, 10> sp2ff{};
237 size_t spacepointIdx = 2;
238 for (auto & thisSpacepoint: sp2ff){
239 thisSpacepoint = double(m_eventStat.m_particleSpacePoints[ spacepointIdx++ ])/ pa;
240 }
241 //barrel
242 pa = coerceToOne(m_eventStat.m_particleSpacePointsBTE[0][Barrel]);
243 std::array<double, 10> spBarrel2ff{};
244 size_t spacepointBarrelIdx = 2;
245 for (auto & thisSpacepoint: spBarrel2ff){
246 thisSpacepoint = double(m_eventStat.m_particleSpacePointsBTE[ spacepointBarrelIdx++ ][Barrel])/ pa;
247 }
248 //transition
249 pa = coerceToOne(m_eventStat.m_particleSpacePointsBTE[0][Transition]);
250 std::array<double, 10> spTransition2ff{};
251 size_t spacepointTransitionIdx = 2;
252 for (auto & thisSpacepoint: spTransition2ff){
253 thisSpacepoint = double(m_eventStat.m_particleSpacePointsBTE[ spacepointTransitionIdx++ ][Transition])/ pa;
254 }
255 //endcap
256 pa = coerceToOne(m_eventStat.m_particleSpacePointsBTE[0][Endcap]);
257 std::array<double, 10> spEndcap2ff{};
258 size_t spacepointEndcapIdx = 2;
259 for (auto & thisSpacepoint: spEndcap2ff){
260 thisSpacepoint = double(m_eventStat.m_particleSpacePointsBTE[ spacepointEndcapIdx++ ][Endcap])/ pa;
261 }
262 //Fwd
263 pa = coerceToOne(m_eventStat.m_particleSpacePointsBTE[0][Forward]);
264 std::array<double, 10> spFwd2ff{};
265 size_t spacepointFwdIdx = 2;
266 for (auto & thisSpacepoint: spFwd2ff){
267 thisSpacepoint = double(m_eventStat.m_particleSpacePointsBTE[ spacepointFwdIdx++ ][Forward])/ pa;
268 }
269 auto w8=std::setw(8);
270 out<<"| Probability for such charge particles to have some number silicon |\n";
271 out<<"| clusters | space points |\n";
272 out<<"| Total Barrel Transi Endcap Forward | Total Barrel Transi Endcap Forward |\n";
273
274 for (size_t idx{0};idx != 10;++idx){
275 out<<"| >= "<<idx+2<< std::string((idx<8)?" ":" ")
276 <<w8<<p5<<pc2ff[idx]
277 <<w8<<p5<<pcBarrel2ff[idx]
278 <<w8<<p5<<pcTransition2ff[idx]
279 <<w8<<p5<<pcEndcap2ff[idx]
280 <<w8<<p5<<pcFwd2ff[idx]<<" | "
281
282 <<w8<<p5<<sp2ff[idx]
283 <<w8<<p5<<spBarrel2ff[idx]
284 <<w8<<p5<<spTransition2ff[idx]
285 <<w8<<p5<<spEndcap2ff[idx]
286 <<w8<<p5<<spFwd2ff[idx]
287 <<" |\n";
288 }
289
290 out<<topNtail(spaceSeparator)<<"\n";
291 out<<"| Additional cuts for truth particles are |\n";
292 out<<"| eta dependent number of silicon clusters >= [";
293 for (unsigned int clbin = 0; clbin<(m_clcuts.size()-1); clbin++)
294 out<<std::setw(2)<<m_clcuts.value().at(clbin)<<", ";
295 out<<std::setw(2)<<m_clcuts.value().back()<<"] |\n";
296 out<<"| number space points >="<<w13<<m_spcut.value()<<" |\n";
297
298 pa = coerceToOne(m_eventStat.m_particleClusters[0]);
299 out<<"| Probability find truth particles with this cuts is "<<w8<<p5<<double(m_eventStat.m_events)/pa<<" |\n";
300 pa = coerceToOne(m_eventStat.m_particleClustersBTE[0][Barrel]);
301 out<<"| For barrel region "<<w8<<p5<<double(m_eventStat.m_eventsBTE[Barrel])/pa<<" |\n";
302 pa = coerceToOne(m_eventStat.m_particleClustersBTE[0][Transition]);
303 out<<"| For transition region "<<w8<<p5<<double(m_eventStat.m_eventsBTE[Transition])/pa<<" |\n";
304 pa = coerceToOne(m_eventStat.m_particleClustersBTE[0][Endcap]);
305 out<<"| For endcap region "<<w8<<p5<<double(m_eventStat.m_eventsBTE[Endcap])/pa<<" |\n";
306 pa = coerceToOne(m_eventStat.m_particleClustersBTE[0][Forward]);
307 out<<"| For forward region "<<w8<<p5<<double(m_eventStat.m_eventsBTE[Forward])/pa<<" |\n";
308 out<<"| |\n";
309 pa = coerceToOne(m_eventStat.m_nclustersNegBP);
310 double ratio = double(m_eventStat.m_nclustersPosBP)/pa;
311 double eratio = std::sqrt(ratio*(1.+ratio)/pa);
312 out<<"| Ratio barrel pixels clusters for +/- particles ="<<w8<<p5<<ratio<<" +-"<<w8<<p5<<eratio<<" |\n";
313 pa = coerceToOne(m_eventStat.m_nclustersNegEP);
314 ratio = double(m_eventStat.m_nclustersPosEP)/pa;
315 eratio = std::sqrt(ratio*(1.+ratio)/pa);
316 out<<"| Ratio endcap pixels clusters for +/- particles ="<<w8<<p5<<ratio<<" +-"<<w8<<p5<<eratio<<" |\n";
317 pa = coerceToOne(m_eventStat.m_nclustersNegBS);
318 ratio = double(m_eventStat.m_nclustersPosBS)/pa;
319 eratio = std::sqrt(ratio*(1.+ratio)/pa);
320 out<<"| Ratio barrel Strip clusters for +/- particles ="<<w8<<p5<<ratio<<" +-"<<w8<<p5<<eratio<<" |\n";
321 pa = coerceToOne(m_eventStat.m_nclustersNegES);
322 ratio = double(m_eventStat.m_nclustersPosES)/pa;
323 eratio = std::sqrt(ratio*(1.+ratio)/pa);
324 out<<"| Ratio endcap Strip clusters for +/- particles ="<<w8<<p5<<ratio<<" +-"<<w8<<p5<<eratio<<" |\n";
325 pa = double(m_eventStat.m_eventsNEG); if(pa < 1.) pa = 1.;
326 ratio = double(m_eventStat.m_eventsPOS)/pa;
327 eratio = std::sqrt(ratio*(1.+ratio)/pa);
328 out<<"| Number truth particles and +/- ratio ="<<std::setw(10)<<m_eventStat.m_events<<w8<<p5<<ratio<<" +-"<<w8<<p5<<eratio<<" |\n";
329 ratio = 0.;
330 if(m_eventStat.m_nclustersPTOT!=0) ratio = double(m_eventStat.m_nclustersPTOTt)/double(m_eventStat.m_nclustersPTOT);
331
332 out<<"| Number pix clusters, truth clusters and ratio = "
333 <<std::setw(10)<<m_eventStat.m_nclustersPTOT
334 <<std::setw(10)<<m_eventStat.m_nclustersPTOTt
335 <<std::setw(12)<<std::setprecision(5)<<ratio<<" |\n";
336 ratio = 0.;
337 if(m_eventStat.m_nclustersSTOT!=0) ratio = double(m_eventStat.m_nclustersSTOTt)/double(m_eventStat.m_nclustersSTOT);
338 out<<"| Number strip clusters, truth clusters and ratio = "
339 <<std::setw(10)<<m_eventStat.m_nclustersSTOT
340 <<std::setw(10)<<m_eventStat.m_nclustersSTOTt
341 <<std::setw(12)<<std::setprecision(5)<<ratio<<" |\n";
342
343 out<<"|-----------------------------------------------------------------------------------|\n\n";
344
345 SG::ReadHandleKeyArray<TrackCollection>::const_iterator t=m_tracklocation.begin(),te=m_tracklocation.end();
346 int nc = 0;
347 for(; t!=te; ++t) {
348 int n = 47-(t->key().size());
349 std::string s1; for(int i=0; i<n; ++i) s1.append(" "); s1.append("|");
350
351
352 out<<"|-----------------------------------------------------------------------------------|\n";
353 out<<"| Statistic for "<<(t->key())<<s1<<"\n";
354
355 double ne = double(m_eventStat.m_events); if(ne < 1.) ne = 1.;
356 double ef [6]; for(int i=0; i!=6; ++i) ef [i] = double(m_trackCollectionStat[nc].m_efficiency [i]) /ne;
357 double ef0[6]; for(int i=0; i!=6; ++i) ef0[i] = double(m_trackCollectionStat[nc].m_efficiencyN [i][0])/ne;
358 double ef1[6]; for(int i=0; i!=6; ++i) ef1[i] = double(m_trackCollectionStat[nc].m_efficiencyN [i][1])/ne;
359 double ef2[6]; for(int i=0; i!=6; ++i) ef2[i] = double(m_trackCollectionStat[nc].m_efficiencyN [i][2])/ne;
360
361
362 using EffArray_t = std::array<double, 6>;
363 //
364 auto makeEffArray = [](const auto & threeDimArray, const size_t secondIdx, const size_t thirdIdx, const double denom){
365 EffArray_t result{};
366 size_t idx{0};
367 auto invDenom = 1./denom;
368 for (auto & entry: result){
369 entry = threeDimArray[idx++][secondIdx][thirdIdx]*invDenom;
370 }
371 return result;
372 };
373 //
374 const auto & efficiencyArrayInput = m_trackCollectionStat[nc].m_efficiencyBTE;
375 //
376 double neBTE = coerceToOne(m_eventStat.m_eventsBTE[Barrel]);
377 const EffArray_t efB0 = makeEffArray(efficiencyArrayInput,0,Barrel,neBTE);
378 const EffArray_t efB1 = makeEffArray(efficiencyArrayInput,1,Barrel,neBTE);
379 const EffArray_t efB2 = makeEffArray(efficiencyArrayInput,2,Barrel,neBTE);
380 const EffArray_t efB3 = makeEffArray(efficiencyArrayInput,3,Barrel,neBTE);
381 const EffArray_t efB4 = makeEffArray(efficiencyArrayInput,4,Barrel,neBTE);
382 //
383 neBTE = coerceToOne(m_eventStat.m_eventsBTE[Transition]);
384 const EffArray_t efT0 = makeEffArray(efficiencyArrayInput,0,Transition,neBTE);
385 const EffArray_t efT1 = makeEffArray(efficiencyArrayInput,1,Transition,neBTE);
386 const EffArray_t efT2 = makeEffArray(efficiencyArrayInput,2,Transition,neBTE);
387 const EffArray_t efT3 = makeEffArray(efficiencyArrayInput,3,Transition,neBTE);
388 const EffArray_t efT4 = makeEffArray(efficiencyArrayInput,4,Transition,neBTE);
389 //
390 neBTE = coerceToOne(m_eventStat.m_eventsBTE[Endcap]);
391 const EffArray_t efE0 = makeEffArray(efficiencyArrayInput,0,Endcap,neBTE);
392 const EffArray_t efE1 = makeEffArray(efficiencyArrayInput,1,Endcap,neBTE);
393 const EffArray_t efE2 = makeEffArray(efficiencyArrayInput,2,Endcap,neBTE);
394 const EffArray_t efE3 = makeEffArray(efficiencyArrayInput,3,Endcap,neBTE);
395 const EffArray_t efE4 = makeEffArray(efficiencyArrayInput,4,Endcap,neBTE);
396 //
397 neBTE = coerceToOne(m_eventStat.m_eventsBTE[Forward]);
398 const EffArray_t efD0 = makeEffArray(efficiencyArrayInput,0,Forward,neBTE);
399 const EffArray_t efD1 = makeEffArray(efficiencyArrayInput,1,Forward,neBTE);
400 const EffArray_t efD2 = makeEffArray(efficiencyArrayInput,2,Forward,neBTE);
401 const EffArray_t efD3 = makeEffArray(efficiencyArrayInput,3,Forward,neBTE);
402 const EffArray_t efD4 = makeEffArray(efficiencyArrayInput,4,Forward,neBTE);
403
404
405 double efrec = ef0[0]+ef0[1]+ef0[2]+ef1[0]+ef1[1]+ef2[0];
406 double efrecB = efB0[0]+efB0[1]+efB0[2]+efB1[0]+efB1[1]+efB2[0];
407 double efrecT = efT0[0]+efT0[1]+efT0[2]+efT1[0]+efT1[1]+efT2[0];
408 double efrecE = efE0[0]+efE0[1]+efE0[2]+efE1[0]+efE1[1]+efE2[0];
409 double efrecD = efD0[0]+efD0[1]+efD0[2]+efD1[0]+efD1[1]+efD2[0];
410
411 ne = coerceToOne(m_eventStat.m_eventsPOS);
412 double efP[6]; for(int i=0; i!=6; ++i) efP[i] = double(m_trackCollectionStat[nc].m_efficiencyPOS[i])/ne;
413 ne = coerceToOne(m_eventStat.m_eventsNEG);
414 double efN[6]; for(int i=0; i!=6; ++i) efN[i] = double(m_trackCollectionStat[nc].m_efficiencyNEG[i])/ne;
415
416 out<<"|-----------------------------------------------------------------------------------|\n";
417 out<<"| Probability to lose 0 1 2 3 4 >=5 clusters |\n";
418 out<<"|-----------------------------------------------------------------------------------|\n";
419
420 auto formattedOutput=[&out](auto & effArray){
421 for (size_t i{};i!=6;++i){
422 out<<std::setw(9)<<std::setprecision(4)<<effArray[i];
423 }
424 out<<" |\n";
425 };
426
427 out<<"| For all particles ";
428 formattedOutput(ef);
429 out<<"| For + particles ";
430 formattedOutput(efP);
431 out<<"| For - particles ";
432 formattedOutput(efN);
433 out<<"|-----------------------------------------------------------------------------------|\n";
434 out<<"| Barrel region |\n";
435 out<<"| 0 wrong clusters ";
436 formattedOutput(efB0);
437 out<<"| 1 wrong clusters ";
438 formattedOutput(efB1);
439 out<<"| 2 wrong clusters ";
440 formattedOutput(efB2);
441 out<<"| 3 wrong clusters ";
442 formattedOutput(efB3);
443 out<<"| >=4 wrong clusters ";
444 formattedOutput(efB4);
445 out<<"|-----------------------------------------------------------------------------------|\n";
446 out<<"| Transition region |\n";
447 out<<"| 0 wrong clusters ";
448 formattedOutput(efT0);
449 out<<"| 1 wrong clusters ";
450 formattedOutput(efT1);
451 out<<"| 2 wrong clusters ";
452 formattedOutput(efT2);
453 out<<"| 3 wrong clusters ";
454 formattedOutput(efT3);
455 out<<"| >=4 wrong clusters ";
456 formattedOutput(efT4);
457 out<<"|-----------------------------------------------------------------------------------|\n";
458 out<<"| Endcap region |\n";
459 out<<"| 0 wrong clusters ";
460 formattedOutput(efE0);
461 out<<"| 1 wrong clusters ";
462 formattedOutput(efE1);
463 out<<"| 2 wrong clusters ";
464 formattedOutput(efE2);
465 out<<"| 3 wrong clusters ";
466 formattedOutput(efE3);
467 out<<"| >=4 wrong clusters ";
468 formattedOutput(efE4);
469 out<<"|-----------------------------------------------------------------------------------|\n";
470 out<<"| Forward region |\n";
471 out<<"| 0 wrong clusters ";
472 formattedOutput(efD0);
473 out<<"| 1 wrong clusters ";
474 formattedOutput(efD1);
475 out<<"| 2 wrong clusters ";
476 formattedOutput(efD2);
477 out<<"| 3 wrong clusters ";
478 formattedOutput(efD3);
479 out<<"| >=4 wrong clusters ";
480 formattedOutput(efD4);
481
482 out<<"|-----------------------------------------------------------------------------------|\n";
483 pa = coerceToOne(m_eventStat.m_particleClusters[0]);
484 out<<"| Efficiency reconstruction (number lose+wrong < 3) = "
485 <<std::setw(9)<<std::setprecision(5)<<efrec
486 <<" ("
487 <<std::setw(9)<<std::setprecision(5)<<efrec*double(m_eventStat.m_events)/pa
488 <<" ) "
489 <<" |\n";
490 pa = coerceToOne(m_eventStat.m_particleClustersBTE[0][Barrel]);
491 out<<"| For barrel region = "
492 <<std::setw(9)<<std::setprecision(5)<<efrecB
493 <<" ("
494 <<std::setw(9)<<std::setprecision(5)<<efrecB*double(m_eventStat.m_eventsBTE[Barrel])/pa
495 <<" ) "
496 <<" |\n";
497 pa = coerceToOne(m_eventStat.m_particleClustersBTE[0][Transition]);
498 out<<"| For transition region = "
499 <<std::setw(9)<<std::setprecision(5)<<efrecT
500 <<" ("
501 <<std::setw(9)<<std::setprecision(5)<<efrecT*double(m_eventStat.m_eventsBTE[Transition])/pa
502 <<" ) "
503 <<" |\n";
504 pa = coerceToOne(m_eventStat.m_particleClustersBTE[0][Endcap]);
505 out<<"| For endcap region = "
506 <<std::setw(9)<<std::setprecision(5)<<efrecE
507 <<" ("
508 <<std::setw(9)<<std::setprecision(5)<<efrecE*double(m_eventStat.m_eventsBTE[Endcap])/pa
509 <<" ) "
510 <<" |\n";
511 pa = coerceToOne(m_eventStat.m_particleClustersBTE[0][Forward]);
512 out<<"| For forward region = "
513 <<std::setw(9)<<std::setprecision(5)<<efrecD
514 <<" ("
515 <<std::setw(9)<<std::setprecision(5)<<efrecD*double(m_eventStat.m_eventsBTE[Forward])/pa
516 <<" ) "
517 <<" |\n";
518
519 out<<"|-----------------------------------------------------------------------------------|\n";
520 out<<"| Reconstructed tracks + - +/-ratio error |\n";
521 out<<"|-----------------------------------------------------------------------------------|\n";
522
523 pa = coerceToOne(m_trackCollectionStat[nc].m_ntracksNEGB);
524 ratio = double(m_trackCollectionStat[nc].m_ntracksPOSB)/pa;
525 eratio = std::sqrt(ratio*(1.+ratio)/pa);
526
527 out<<"| Barrel "
528 <<std::setw(10)<<m_trackCollectionStat[nc].m_ntracksPOSB
529 <<std::setw(11)<<m_trackCollectionStat[nc].m_ntracksNEGB
530 <<std::setw(11)<<std::setprecision(5)<<ratio
531 <<std::setw(11)<<std::setprecision(5)<<eratio<<" |\n";
532 pa = coerceToOne(m_trackCollectionStat[nc].m_ntracksNEGE);
533 ratio = double(m_trackCollectionStat[nc].m_ntracksPOSE)/pa;
534 eratio = std::sqrt(ratio*(1.+ratio)/pa);
535
536 out<<"| Endcap "
537 <<std::setw(10)<<m_trackCollectionStat[nc].m_ntracksPOSE
538 <<std::setw(11)<<m_trackCollectionStat[nc].m_ntracksNEGE
539 <<std::setw(11)<<std::setprecision(5)<<ratio
540 <<std::setw(11)<<std::setprecision(5)<<eratio<<" |\n";
541 pa = coerceToOne(m_trackCollectionStat[nc].m_ntracksNEGFWD);
542 ratio = double(m_trackCollectionStat[nc].m_ntracksPOSFWD)/pa;
543 eratio = std::sqrt(ratio*(1.+ratio)/pa);
544
545 out<<"| Forward "
546 <<std::setw(10)<<m_trackCollectionStat[nc].m_ntracksPOSFWD
547 <<std::setw(11)<<m_trackCollectionStat[nc].m_ntracksNEGFWD
548 <<std::setw(11)<<std::setprecision(5)<<ratio
549 <<std::setw(11)<<std::setprecision(5)<<eratio<<" |\n";
550
551
552
553 int nt=0;
554 int ft=0;
555 int kf=0;
556 for(int k = 0; k!=50; ++k) {
557 nt+=m_trackCollectionStat[nc].m_total[k];
558 ft+=m_trackCollectionStat[nc].m_fake [k];
559 if(!kf && nt) kf = k;
560 }
561
562 if(kf) {
563
564 out<<"|-----------------------------------------------------------------------------------|\n";
565 out<<"| Fake tracks rate for different number of clusters on track |\n";
566 out<<"|-----------------------------------------------------------------------------------|\n";
567
568 for(int k = kf; k!=kf+6; ++k) {
569 out<<"| >= "<<std::setw(2)<<k<<" ";
570 }
571 out<<"|\n";
572
573 for(int k = kf; k!=kf+6; ++k) {
574 double eff = 0.; if(nt>0) eff = double(ft)/double(nt);
575 out<<"|"<<std::setw(12)<<std::setprecision(5)<<eff<<" ";
576 nt-=m_trackCollectionStat[nc].m_total[k];
577 ft-=m_trackCollectionStat[nc].m_fake [k];
578 }
579 out<<"|\n";
580 out<<"|-----------------------------------------------------------------------------------|\n";
581 }
582 ++nc;
583 }
584 ATH_MSG_INFO("\n"<<out.str());
585 return StatusCode::SUCCESS;
586}
587
589// Dumps conditions information into the MsgStream
591
592MsgStream& ITk::TrackClusterAssValidation::dumptools( MsgStream& out, MSG::Level level) const
593{
594 SG::ReadHandleKeyArray<TrackCollection>::const_iterator t=m_tracklocation.begin(),te=m_tracklocation.end();
595
596 int n;
597 out << level <<"\n";
598 out<<"|--------------------------------------------------------------------------------------------------------------------|\n";
599 for(; t!=te; ++t) {
600 n = 65-t->key().size();
601 std::string s1; for(int i=0; i<n; ++i) s1.append(" "); s1.append("|");
602 out<<"| Location of input tracks | "<<t->key()<<s1<<"\n";
603 }
604 auto padString = [](const std::string & s){
605 const int n = 65 - s.size();
606 return s + std::string(n, ' ');
607 };
608 std::string s2 = padString(m_spacepointsPixelname.key());
609 std::string s3 = padString(m_spacepointsStripname.key());
610 std::string s4 = padString(m_spacepointsOverlapname.key());
611 std::string s5 = padString(m_clustersPixelname.key());
612 std::string s6 = padString(m_clustersStripname.key());
613 //
614 std::string s7 = padString(m_truth_locationPixel.key());
615 std::string s8 = padString(m_truth_locationStrip.key());
616
617 out<<"| Pixel space points | "<<s2<<"|\n";
618 out<<"| Strip space points | "<<s3<<"|\n";
619 out<<"| Overlap space points | "<<s4<<"|\n";
620 out<<"| Pixel clusters | "<<s5<<"|\n";
621 out<<"| Strip clusters | "<<s6<<"|\n";
622 out<<"| Truth location for pixels | "<<s7<<"|\n";
623 out<<"| Truth location for strips | "<<s8<<"|\n";
624 out<<"| max pT cut | "
625 <<std::setw(14)<<std::setprecision(5)<<m_ptcutmax
626 <<" |\n";
627 out<<"| rapidity cut | "
628 <<std::setw(14)<<std::setprecision(5)<<m_rapcut
629 <<" |\n";
630 out<<"| min Radius | "
631 <<std::setw(14)<<std::setprecision(5)<<m_rmin
632 <<" |\n";
633 out<<"| max Radius | "
634 <<std::setw(14)<<std::setprecision(5)<<m_rmax
635 <<" |\n";
636 out<<"| Min. number sp.points for generated track | "
637 <<std::setw(14)<<std::setprecision(5)<<m_spcut
638 <<" |\n";
639 out<<"|--------------------------------------------------------------------------------------------------------------------|\n";
640 return out;
641}
642
644// Dumps event information into the ostream
646
648{
649 out << MSG::DEBUG << "\n";
650 auto formatOutput = [&out](const auto val){
651 out<<std::setw(12)<<val
652 <<" |\n";
653 };
654 out<<"|---------------------------------------------------------------------|\n";
655 out<<"| m_nspacepoints | ";
656 formatOutput(event_data.m_nspacepoints);
657 out<<"| m_nclusters | ";
658 formatOutput(event_data.m_nclusters);
659 out<<"| Kine-Clusters size | ";
660 formatOutput(event_data.m_kinecluster.size());
661 out<<"| Kine-SpacePoints size | ";
662 formatOutput(event_data.m_kinespacepoint.size());
663 out<<"| Number good kine tracks | ";
664 formatOutput(event_data.m_nqtracks);
665 out<<"|---------------------------------------------------------------------|\n";
666 return out;
667}
668
669
671// New event for clusters information
673
675{
676 std::lock_guard<std::mutex> lock(m_statMutex);
677
678 // Get pixel clusters container
679 //
680 std::unique_ptr<SG::ReadHandle<InDet::SiClusterContainer> > pixelcontainer;
681 std::unique_ptr<SG::ReadHandle<InDet::SiClusterContainer> > stripcontainer;
682
683 if(m_usePix) {
684 pixelcontainer = std::make_unique<SG::ReadHandle<InDet::SiClusterContainer> >(m_clustersPixelname,ctx);
685 if (!pixelcontainer->isValid()) ATH_MSG_DEBUG("Failed to create Pixel clusters container read handle with key " << m_clustersPixelname.key());
686 }
687
688 // Get strip clusters container
689 //
690 if(m_useStrip) {
691 stripcontainer = std::make_unique<SG::ReadHandle<InDet::SiClusterContainer> >(m_clustersStripname,ctx);
692 if (!stripcontainer->isValid()) ATH_MSG_DEBUG("Failed to create Strip clusters container read handle with key " << m_clustersStripname.key());
693 }
694
695 int Kine[1000];
696
697 event_data.m_clusterHandles.reserve(3);
698 // Loop through all pixel clusters
699 //
700 if(pixelcontainer && pixelcontainer->isValid()) {
701 InDet::SiClusterContainer::const_iterator w = (*pixelcontainer)->begin();
702 InDet::SiClusterContainer::const_iterator we = (*pixelcontainer)->end ();
703
704 for(; w!=we; ++w) {
705
706 InDet::SiClusterCollection::const_iterator c = (*w)->begin();
707 InDet::SiClusterCollection::const_iterator ce = (*w)->end ();
708
709 for(; c!=ce; ++c) {
710
711 ++event_data.m_nclusters;
712 ++m_eventStat.m_nclustersPTOT;
713 if(isTruth(event_data,(*c))) ++m_eventStat.m_nclustersPTOTt;
714
715
716 int nk = kine(event_data,(*c),Kine,999);
717 for(int i=0; i!=nk; ++i) {
718 if(!isTheSameDetElement(event_data,Kine[i],(*c))) {
719 event_data.m_kinecluster.insert(std::make_pair(Kine[i],(*c)));
720 }
721 }
722 }
723 }
724 event_data.m_clusterHandles.push_back(std::move(pixelcontainer));
725
726 }
727
728 // Loop through all strip clusters
729 //
730 if(stripcontainer && stripcontainer->isValid()) {
731 InDet::SiClusterContainer::const_iterator w = (*stripcontainer)->begin();
732 InDet::SiClusterContainer::const_iterator we = (*stripcontainer)->end ();
733
734 for(; w!=we; ++w) {
735
736 InDet::SiClusterCollection::const_iterator c = (*w)->begin();
737 InDet::SiClusterCollection::const_iterator ce = (*w)->end ();
738
739 for(; c!=ce; ++c) {
740
741 ++event_data.m_nclusters;
742 ++m_eventStat.m_nclustersSTOT;
743 if(isTruth(event_data,(*c))) ++m_eventStat.m_nclustersSTOTt;
744
745 int nk = kine(event_data,(*c),Kine,999);
746 for(int i=0; i!=nk; ++i) {
747 if(!isTheSameDetElement(event_data,Kine[i],(*c))) event_data.m_kinecluster.insert(std::make_pair(Kine[i],(*c)));
748 }
749 }
750 }
751 event_data.m_clusterHandles.push_back(std::move(stripcontainer));
752 }
753
754}
755
757// New event for space points information
759
761{
762
763 int Kine[1000];
764
765 if(m_usePix && !m_spacepointsPixelname.key().empty()) {
766 event_data.m_spacePointContainer.emplace_back(m_spacepointsPixelname,ctx);
767 if (!event_data.m_spacePointContainer.back().isValid()) {
768 ATH_MSG_DEBUG( "Invalid Pixels space points container read handle for key " << m_spacepointsPixelname.key() );
769 }
770 else {
771 SpacePointContainer::const_iterator spc = event_data.m_spacePointContainer.back()->begin();
772 SpacePointContainer::const_iterator spce = event_data.m_spacePointContainer.back()->end ();
773 for(; spc != spce; ++spc) {
775 SpacePointCollection::const_iterator spe = (*spc)->end ();
776
777 for(; sp != spe; ++sp) {
778
779 ++event_data.m_nspacepoints;
780 int nk = kine(event_data,(*sp)->clusterList().first,Kine,999);
781 for(int i=0; i!=nk; ++i) {
782
783 if(!isTheSameDetElement(event_data,Kine[i],(*sp))) {
784 event_data.m_kinespacepoint.insert(std::make_pair(Kine[i],(*sp)));
785 }
786 }
787 }
788 }
789 }
790 }
791
792 // Get strip space points containers from store gate
793 //
794 if(m_useStrip && !m_spacepointsStripname.key().empty()) {
795 event_data.m_spacePointContainer.emplace_back(m_spacepointsStripname,ctx);
796 if (!event_data.m_spacePointContainer.back().isValid()) {
797 ATH_MSG_DEBUG( "Invalid Strip space points container read handle for key " << m_spacepointsStripname.key() );
798 }
799 else {
800 SpacePointContainer::const_iterator spc = event_data.m_spacePointContainer.back()->begin();
801 SpacePointContainer::const_iterator spce = event_data.m_spacePointContainer.back()->end ();
802
803 for(; spc != spce; ++spc) {
804
806 SpacePointCollection::const_iterator spe = (*spc)->end ();
807
808 for(; sp != spe; ++sp) {
809
810
811 ++event_data.m_nspacepoints;
812 int nk = kine(event_data,(*sp)->clusterList().first,(*sp)->clusterList().second,Kine,999);
813 for(int i=0; i!=nk; ++i) {
814 if(!isTheSameDetElement(event_data,Kine[i],(*sp))) {
815 event_data.m_kinespacepoint.insert(std::make_pair(Kine[i],(*sp)));
816 }
817 }
818 }
819 }
820 }
821 }
822
823 // Get strip overlap space points containers from store gate
824 //
825 if(m_useStrip && !m_spacepointsOverlapname.key().empty()) {
826 event_data.m_spacepointsOverlap=std::make_unique< SG::ReadHandle<SpacePointOverlapCollection> >(m_spacepointsOverlapname,ctx);
827 if (!event_data.m_spacepointsOverlap->isValid()) {
828 ATH_MSG_DEBUG( "Invalid overlap space points container read handle for key " << m_spacepointsOverlapname.key() );
829 }
830 else {
833
834 for (; sp!=spe; ++sp) {
835
836 ++event_data.m_nspacepoints;
837 int nk = kine(event_data,(*sp)->clusterList().first,(*sp)->clusterList().second,Kine,999);
838 for(int i=0; i!=nk; ++i) {
839 if(!isTheSameDetElement(event_data,Kine[i],(*sp))) {
840 event_data.m_kinespacepoint.insert(std::make_pair(Kine[i],(*sp)));
841 }
842 }
843 }
844 }
845 }
846}
847
848// Good kine tracks selection
850
852{
853 std::multimap<int,const Trk::PrepRawData*>::iterator c = event_data.m_kinecluster .begin();
854 std::multimap<int,const Trk::SpacePoint*>::iterator s = event_data.m_kinespacepoint.begin();
855
856 if( c == event_data.m_kinecluster.end()) {
857 return 0;
858 }
859
860 if( s == event_data.m_kinespacepoint.end()) {
861 return 0;
862 }
863
864 std::list<int> worskine;
865
866 int rp = 0;
867 double eta = 0.;
868 int t = 0;
869 int k0 = (*c).first;
870 int q0 = k0*charge(event_data,(*c),rp);
871 unsigned int nc = 1 ;
872
873 auto coerceTo49 = [] (const size_t idx){
874 return (idx<50) ? idx : 49;
875 };
876
877 for(++c; c!=event_data.m_kinecluster.end(); ++c) {
878
879 if((*c).first==k0) {++nc; continue;}
880 q0 = charge(event_data,(*c),rp,eta)*k0;
881 //
882 const size_t clusterIdx =coerceTo49(nc);
883 ++event_data.m_eventStat.m_particleClusters [clusterIdx];
884 ++event_data.m_eventStat.m_particleClustersBTE[clusterIdx][rp];
885 //
886 int ns = event_data.m_kinespacepoint.count(k0);
887 const size_t spacepointIdx =coerceTo49(ns);
888 ++event_data.m_eventStat.m_particleSpacePoints [spacepointIdx];
889 ++event_data.m_eventStat.m_particleSpacePointsBTE[spacepointIdx][rp];
890
891 if (nc < minclusters(eta) ) worskine.push_back(k0);
892 else if(event_data.m_kinespacepoint.count(k0)< m_spcut ) worskine.push_back(k0);
893 else {
894 event_data.m_particles[0].push_back(InDet::PartPropCache(q0,rp)); ++t;
895 }
896
897 k0 = (*c).first;
898 q0 =charge(event_data,(*c),rp,eta)*k0;
899 nc = 1 ;
900 }
901
902 ++event_data.m_eventStat.m_particleClusters [coerceTo49(nc)];
903 ++event_data.m_eventStat.m_particleClustersBTE[coerceTo49(nc)][rp];
904 int ns = event_data.m_kinespacepoint.count(k0);
905 ++event_data.m_eventStat.m_particleSpacePoints [coerceTo49(ns)];
906 ++event_data.m_eventStat.m_particleSpacePointsBTE[coerceTo49(ns)][rp];
907
908 if (nc < minclusters(eta) ) worskine.push_back(k0);
909 else if(event_data.m_kinespacepoint.count(k0)< m_spcut ) worskine.push_back(k0);
910 else {
911 event_data.m_particles[0].push_back(InDet::PartPropCache(q0,rp)); ++t;
912 }
913 for(auto & pThisCluster: worskine) {
914 event_data.m_kinecluster .erase(pThisCluster);
915 event_data.m_kinespacepoint.erase(pThisCluster);
916 }
917
918 for(c = event_data.m_kinecluster.begin(); c!= event_data.m_kinecluster.end(); ++c) {
919 const Trk::PrepRawData*
920 d = (*c).second;
922 de= dynamic_cast<const InDetDD::SiDetectorElement*>(d->detectorElement());
923 if (not de) continue;
924 int q = charge(event_data,*c,rp);
925
926 if (q<0) {
927 if(de->isBarrel()) {
928 de->isPixel() ? ++event_data.m_eventStat.m_nclustersNegBP : ++event_data.m_eventStat.m_nclustersNegBS;
929 }
930 else {
931 de->isPixel() ? ++event_data.m_eventStat.m_nclustersNegEP : ++event_data.m_eventStat.m_nclustersNegES;
932 }
933
934 }
935 else if(q>0) {
936 if(de->isBarrel()) {
937 de->isPixel() ? ++event_data.m_eventStat.m_nclustersPosBP : ++event_data.m_eventStat.m_nclustersPosBS;
938 }
939 else {
940 de->isPixel() ? ++event_data.m_eventStat.m_nclustersPosEP : ++event_data.m_eventStat.m_nclustersPosES;
941 }
942 }
943 }
944
945
946
947 for(const auto& p: event_data.m_particles[0]) {
948 for(SG::ReadHandleKeyArray<TrackCollection>::size_type nc=1; nc<m_tracklocation.size(); ++nc) event_data.m_particles[nc].push_back(p);
949 }
950 return t;
951}
952
954// Recontructed track comparison with kine information
956
958{
959 if(!event_data.m_nqtracks) return;
960
961
962 int nc = -1;
963 event_data.m_trackcontainer.reserve(m_tracklocation.size());
964 for(const SG::ReadHandleKey<TrackCollection> &track_key : m_tracklocation ) {
965 if(++nc >= 100) return;
966 event_data.m_tracks[nc].clear();
967
968 event_data.m_trackcontainer.emplace_back(track_key,ctx );
969 if (!event_data.m_trackcontainer.back().isValid()) {
970 continue;
971 }
972
973 // Loop through all found tracks
974 //
975 TrackCollection::const_iterator t,te = event_data.m_trackcontainer.back()->end();
976
977 int KINE[200],NKINE[200];
978
979 for (t=event_data.m_trackcontainer.back()->begin(); t!=te; ++t) {
980
981 Trk::TrackStates::const_iterator s = (*t)->trackStateOnSurfaces()->begin(),
982 se = (*t)->trackStateOnSurfaces()->end();
983
984 int NK = 0;
985 int NC = 0;
986 int N0 = 0;
987 int nkm = 0;
988 bool qp = false;
989
990 const Trk::TrackParameters* tpf = (*s)->trackParameters(); if(!tpf) continue;
991 const AmgVector(5)& Vpf = tpf ->parameters ();
992 double pTf = std::abs(std::sin(Vpf[3])/Vpf[4]);
993 double etaf = std::abs(log(tan(.5*Vpf[3])));
994 bool qTf = pTf > minpT(etaf);
995 for(; s!=se; ++s) {
996
997 if(!qp) {
998
999 const Trk::TrackParameters* tp = (*s)->trackParameters();
1000
1001 if(tp) {
1002 qp = true;
1003 const AmgVector(5)& Vp = tp->parameters();
1004 double pT = std::sin(Vp[3])/Vp[4] ;
1005 double rap = std::abs(std::log(std::tan(.5*Vp[3])));
1006 double minpt = minpT(rap);
1007 if (pT > minpt && pT < m_ptcutmax) {
1008 if (rap < 1. ) ++event_data.m_trackCollectionStat[nc].m_ntracksPOSB;
1009 else if(rap < 3.0) ++event_data.m_trackCollectionStat[nc].m_ntracksPOSE;
1010 else if(rap < m_rapcut) ++event_data.m_trackCollectionStat[nc].m_ntracksPOSFWD;
1011 }
1012 else if(pT < -minpt && pT > -m_ptcutmax) {
1013 if (rap < 1. ) ++event_data.m_trackCollectionStat[nc].m_ntracksNEGB;
1014 else if(rap < 3.0) ++event_data.m_trackCollectionStat[nc].m_ntracksNEGE;
1015 else if(rap < m_rapcut) ++event_data.m_trackCollectionStat[nc].m_ntracksNEGFWD;
1016 }
1017 }
1018 }
1019
1020 if(!m_useOutliers && !(*s)->type(Trk::TrackStateOnSurface::Measurement)) continue;
1021
1022 const Trk::MeasurementBase* mb = (*s)->measurementOnTrack();
1023 if(!mb) continue;
1024
1025 const Trk::RIO_OnTrack* ri = dynamic_cast<const Trk::RIO_OnTrack*>(mb);
1026 if(!ri) continue;
1027
1028 const Trk::PrepRawData* rd = ri->prepRawData();
1029 if(!rd) continue;
1030
1031 const InDet::SiCluster* si = dynamic_cast<const InDet::SiCluster*>(rd);
1032 if(!si) continue;
1033
1034 if(!m_usePix && dynamic_cast<const InDet::PixelCluster*>(si)) continue;
1035 if(!m_useStrip && dynamic_cast<const InDet::SCT_Cluster*> (si)) continue;
1036
1037
1038 int Kine[1000], nk=kine0(event_data,rd,Kine,999); ++NC; if(!nk) ++N0;
1039
1040 for(int k = 0; k!=nk; ++k) {
1041
1042 int n = 0;
1043 for(; n!=NK; ++n) {if(Kine[k]==KINE[n]) {++NKINE[n]; break;}}
1044 if(n==NK) {KINE[NK] = Kine[k]; NKINE[NK] = 1; if (NK < 200) ++NK;}
1045 }
1046 for(int n=0; n!=NK; ++n) {if(NKINE[n]>nkm) nkm = NKINE[n];}
1047 }
1048
1049 for(int n=0; n!=NK; ++n) {
1050 if(NKINE[n]==nkm) {
1051 int NQ = 1000*NKINE[n]+(NC-NKINE[n]);
1052
1053 event_data.m_tracks[nc].insert(std::make_pair(KINE[n],NQ));
1054 if(qTf) {
1055 if(NC-N0 > 2) {
1056 ++event_data.m_trackCollectionStat[nc].m_total[NC]; if(NC-NKINE[n] > 2) {++event_data.m_trackCollectionStat[nc].m_fake[NC];}
1057 }
1058 }
1059 }
1060 }
1061 }
1062
1063 }
1064}
1065
1067// Particles and reconstructed tracks comparision
1069
1071{
1073
1074 event_data.m_difference[nc].clear();
1075 auto p = event_data.m_particles[nc].begin(), pe =event_data.m_particles[nc].end();
1076 if(p==pe) return;
1077 std::multimap<int,int>::const_iterator t, te = event_data.m_tracks[nc].end();
1078
1079 while (p!=pe) {
1080
1081 const int uniqueID = HepMC::uniqueID(*p);
1082 int n = event_data.m_kinecluster.count(uniqueID);
1083 int m = 0;
1084 int w = 0;
1085 t = event_data.m_tracks[nc].find(uniqueID);
1086 for(; t!=te; ++t) {
1087 if((*t).first!=uniqueID) break;
1088 int ts = (*t).second/1000;
1089 int ws = (*t).second%1000;
1090 if (ts > m ) {m = ts; w = ws;}
1091 else if(ts==m && w > ws) { w = ws;}
1092 }
1093 int d = n-m; if(d<0) d = 0; else if(d > 5) d=5; if(w>4) w = 4;
1094 if(m) {
1095 ++event_data.m_trackCollectionStat[nc].m_efficiency [d];
1096 ++event_data.m_trackCollectionStat[nc].m_efficiencyN[d][w];
1097 }
1098 int ch = (*p).charge();
1099 if(m) {
1100 ++event_data.m_trackCollectionStat[nc].m_efficiencyBTE[d][w][(*p).rapidity()];
1101 ch > 0 ? ++event_data.m_trackCollectionStat[nc].m_efficiencyPOS[d] : ++event_data.m_trackCollectionStat[nc].m_efficiencyNEG[d];
1102 }
1103 if(nc==0) {
1104 ++event_data.m_eventStat.m_events; ch > 0 ? ++event_data.m_eventStat.m_eventsPOS : ++event_data.m_eventStat.m_eventsNEG;
1105 ++event_data.m_eventStat.m_eventsBTE[(*p).rapidity()];
1106 }
1107 if(d==0) event_data.m_particles[nc].erase(p++);
1108 else {event_data.m_difference[nc].push_back(n-m); ++p;}
1109 }
1110 }
1111}
1112
1114// Pointer to particle production for space point
1116
1118(const ITk::TrackClusterAssValidation::EventData_t &event_data,const Trk::PrepRawData* d1,const Trk::PrepRawData* d2,int* Kine,int nmax) const
1119{
1120 int nkine = 0;
1121 int Kine1[1000],Kine2[1000];
1122 int n1 = kine(event_data,d1,Kine1,nmax); if(!n1) return nkine;
1123 int n2 = kine(event_data,d2,Kine2,nmax); if(!n2) return nkine;
1124
1125 for(int i = 0; i!=n1; ++i) {
1126 for(int j = 0; j!=n2; ++j) {
1127 if(Kine1[i]==Kine2[j]) {Kine[nkine++] = Kine1[i]; break;}
1128 }
1129 }
1130 return nkine;
1131}
1132
1134// Pointer to particle production for cluster
1136
1138(const ITk::TrackClusterAssValidation::EventData_t &event_data,const Trk::PrepRawData* d,int* Kine,int nmax) const
1139{
1140
1141 PRD_MultiTruthCollection::const_iterator mce;
1142 PRD_MultiTruthCollection::const_iterator mc = findTruth(event_data,d,mce);
1143
1144 Identifier ID = d->identify();
1145 int nkine = 0;
1146
1147 for(; mc!=mce; ++mc) {
1148
1149 if( (*mc).first != ID ) return nkine;
1150
1151 const int uniqueID = HepMC::uniqueID((*mc).second); if(uniqueID<=0) continue;
1152
1153 const HepMC::ConstGenParticlePtr pa = (*mc).second.cptr();
1154 if(!pa or !pa->production_vertex()) continue;
1155
1156 int pdg = std::abs(pa->pdg_id()); if(m_pdg && m_pdg != pdg ) continue;
1157 if (MC::isNucleus(pdg)) continue; // ignore nuclei from hadronic interactions
1158 if ( std::abs(MC::charge(pdg)) < .5 ) continue;
1159
1160 // pT cut
1161 //
1162 double px = pa->momentum().px();
1163 double py = pa->momentum().py();
1164 double pz = pa->momentum().pz();
1165 double pt = std::sqrt(px*px+py*py);
1166 if( pt < m_ptcut || pt > m_ptcutmax) continue;
1167
1168 // Rapidity cut
1169 //
1170 double t = std::abs(pz)/pt;
1171 if( t > m_tcut ) continue;
1172
1173 // Radius cut
1174 //
1175 double vx = pa->production_vertex()->position().x();
1176 double vy = pa->production_vertex()->position().y();
1177 double r = std::sqrt(vx*vx+vy*vy);
1178 if( r < m_rmin || r > m_rmax) continue;
1179
1180 Kine[nkine] = uniqueID; if(++nkine >= nmax) break;
1181 }
1182 return nkine;
1183}
1184
1186// Pointer to particle production for cluster
1188
1190(const ITk::TrackClusterAssValidation::EventData_t &event_data,const Trk::PrepRawData* d,int* Kine,int nmax)
1191{
1192
1193 PRD_MultiTruthCollection::const_iterator mce;
1194 PRD_MultiTruthCollection::const_iterator mc = findTruth(event_data, d,mce);
1195
1196 Identifier ID = d->identify();
1197 int nkine = 0;
1198
1199 for(; mc!=mce; ++mc) {
1200
1201 if( (*mc).first != ID ) return nkine;
1202
1203 const int uniqueID = HepMC::uniqueID((*mc).second); if(uniqueID<=0) continue;
1204 Kine[nkine] = uniqueID; if(++nkine >= nmax) break;
1205 }
1206 return nkine;
1207}
1208
1210// Test for cluster association with truth particles
1212
1215{
1216 PRD_MultiTruthCollection::const_iterator mce;
1217 PRD_MultiTruthCollection::const_iterator mc = findTruth(event_data,d,mce);
1218 return mc!=mce;
1219}
1220
1222// Test detector element
1224
1226(const ITk::TrackClusterAssValidation::EventData_t &event_data, int K,const Trk::PrepRawData* d)
1227{
1228 std::multimap<int,const Trk::PrepRawData*>::const_iterator k = event_data.m_kinecluster.find(K);
1229 for(; k!=event_data.m_kinecluster.end(); ++k) {
1230
1231 if((*k).first!= K) return false;
1232 if(d->detectorElement()==(*k).second->detectorElement()) return true;
1233 }
1234 return false;
1235}
1236
1238// Test detector element
1240
1242(const ITk::TrackClusterAssValidation::EventData_t &event_data, int K,const Trk::SpacePoint* sp)
1243{
1244 const Trk::PrepRawData* p1 = sp->clusterList().first;
1245 const Trk::PrepRawData* p2 = sp->clusterList().second;
1246
1247 std::multimap<int,const Trk::SpacePoint*>::const_iterator k = event_data.m_kinespacepoint.find(K);
1248
1249 if(!p2) {
1250
1251 for(; k!=event_data.m_kinespacepoint.end(); ++k) {
1252 if((*k).first!= K) return false;
1253
1254 const Trk::PrepRawData* n1 = (*k).second->clusterList().first ;
1255 const Trk::PrepRawData* n2 = (*k).second->clusterList().second;
1256
1257 if(p1->detectorElement() == n1->detectorElement()) return true;
1258 if(!n2) continue;
1259 if(p1->detectorElement() == n2->detectorElement()) return true;
1260 }
1261 return false;
1262 }
1263
1264 for(; k!=event_data.m_kinespacepoint.end(); ++k) {
1265 if((*k).first!= K) return false;
1266
1267 const Trk::PrepRawData* n1 = (*k).second->clusterList().first ;
1268 const Trk::PrepRawData* n2 = (*k).second->clusterList().second;
1269
1270 if(p1->detectorElement() == n1->detectorElement()) return true;
1271 if(p2->detectorElement() == n1->detectorElement()) return true;
1272 if(!n2) continue;
1273 if(p1->detectorElement() == n2->detectorElement()) return true;
1274 if(p2->detectorElement() == n2->detectorElement()) return true;
1275 }
1276 return false;
1277}
1278
1280// Dump information about no recontructed particles
1282
1284{
1285
1287
1288 auto p = event_data.m_particles[nc].begin(), pe =event_data.m_particles[nc].end();
1289 if(p==pe) continue;
1290
1291 std::list<int>::const_iterator dif = event_data.m_difference[nc].begin();
1292
1293 std::multimap<int,const Trk::PrepRawData*>::const_iterator c,ce = event_data.m_kinecluster.end();
1294
1295 int n = 69-m_tracklocation[nc].key().size();
1296 std::string s1; for(int i=0; i<n; ++i) s1.append(" "); s1.append("|");
1297 std::stringstream out;
1298 out<<"|----------------------------------------------------------------------------------------|\n";
1299 out<<"| "<<m_tracklocation[nc]<<s1<<"\n";
1300 out<<"|----------------------------------------------------------------------------------------|\n";
1301 out<<"| # pdg kine Ncl Ntr Nsp Lose pT(MeV) rapidity radius z |\n";
1302 out<<"|----------------------------------------------------------------------------------------|\n";
1303
1304 n = 0;
1305 for(; p!=pe; ++p) {
1306
1307 const int uniqueID = HepMC::uniqueID(*p);
1308
1309 c = event_data.m_kinecluster.find(uniqueID); if(c==ce) continue;
1310 const Trk::PrepRawData* d = (*c).second;
1311
1312 PRD_MultiTruthCollection::const_iterator mce;
1313 PRD_MultiTruthCollection::const_iterator mc = findTruth(event_data,d,mce);
1314
1315 Identifier ID = d->identify();
1316 bool Q = false;
1317 for(; mc!=mce; ++mc) {
1318 if((*mc).first != ID) break;
1319 if(HepMC::uniqueID((*mc).second)==uniqueID) {Q=true; break;}
1320 }
1321
1322 if(!Q) continue;
1323
1324 const HepMC::ConstGenParticlePtr pa = (*mc).second.cptr();
1325
1326 double px = pa->momentum().px();
1327 double py = pa->momentum().py();
1328 double pz = pa->momentum().pz();
1329 double vx = pa->production_vertex()->position().x();
1330 double vy = pa->production_vertex()->position().y();
1331 double vz = pa->production_vertex()->position().z();
1332 double pt = std::sqrt(px*px+py*py);
1333 double t = std::atan2(pt,pz);
1334 double ra =-std::log(std::tan(.5*t));
1335 double r = std::sqrt(vx*vx+vy*vy);
1336 ++n;
1337 out<<"| "
1338 <<std::setw(4)<<n
1339 <<std::setw(6)<<pa->pdg_id()
1340 <<std::setw(10)<<HepMC::barcode(pa)
1341 <<std::setw(4)<<event_data.m_kinecluster .count(uniqueID)
1342 <<std::setw(4)<<event_data.m_kinespacepoint.count(uniqueID)
1343 <<std::setw(4)<<(*dif)
1344 <<std::setw(12)<<std::setprecision(5)<<pt
1345 <<std::setw(12)<<std::setprecision(5)<<ra
1346 <<std::setw(12)<<std::setprecision(5)<<r
1347 <<std::setw(12)<<std::setprecision(5)<<vz
1348 <<" |\n";
1349 ++dif;
1350
1351 }
1352 out<<"|----------------------------------------------------------------------------------------|\n";
1353 ATH_MSG_INFO("\n"<<out.str());
1354 }
1355 return true;
1356}
1357
1359// Cluster truth information
1361
1362PRD_MultiTruthCollection::const_iterator
1365 const Trk::PrepRawData* d,
1366 PRD_MultiTruthCollection::const_iterator& mce)
1367{
1368 const InDet::SCT_Cluster * si = dynamic_cast<const InDet::SCT_Cluster*> (d);
1369 const InDet::PixelCluster * px = dynamic_cast<const InDet::PixelCluster*> (d);
1370
1371 PRD_MultiTruthCollection::const_iterator mc;
1372
1373 if (px && event_data.m_truthPix) {mc=event_data.m_truthPix->find(d->identify()); mce=event_data.m_truthPix->end();}
1374 else if(si && event_data.m_truthStrip) {mc=event_data.m_truthStrip->find(d->identify()); mce=event_data.m_truthStrip->end();}
1375 else {
1376 const PRD_MultiTruthCollection *truth[] {event_data. m_truthPix,event_data.m_truthStrip};
1377 for (int i=0; i<3; i++) {
1378 if (truth[i]) {
1379 mce=truth[i]->end();
1380 return truth[i]->end();
1381 }
1382 }
1383 throw std::runtime_error("Neither Pixel nor Strip truth.");
1384 }
1385 return mc;
1386}
1387
1389// Cluster truth information
1391
1392int ITk::TrackClusterAssValidation::charge(const ITk::TrackClusterAssValidation::EventData_t &event_data,std::pair<int,const Trk::PrepRawData*> pa,int& rap, double& eta) const
1393{
1394 int uniqueID = pa.first;
1395 const Trk::PrepRawData* d = pa.second;
1396 PRD_MultiTruthCollection::const_iterator mce;
1397 PRD_MultiTruthCollection::const_iterator mc = findTruth(event_data,d,mce);
1398
1399 for(; mc!=mce; ++mc) {
1400 if(HepMC::uniqueID((*mc).second)==uniqueID) {
1401
1402 const HepMC::ConstGenParticlePtr pat = (*mc).second.cptr();
1403
1404 rap = 0;
1405 double px = pat->momentum().px();
1406 double py = pat->momentum().py();
1407 double pz = pat->momentum().pz();
1408 double pt = std::sqrt(px*px+py*py) ;
1409 double t = std::atan2(pt,pz) ;
1410 eta = std::abs(std::log(std::tan(.5*t)));
1411 // Forward
1412 if (eta > 3.0)
1413 rap = 3;
1414 else
1415 // other regions
1416 eta > 1.6 ? rap = 2 : eta > .8 ? rap = 1 : rap = 0;
1417
1418 int pdg = pat->pdg_id();
1419 if (MC::isNucleus(pdg)) continue; // ignore nuclei from hadronic interactions
1420 double ch = MC::charge(pdg);
1421 if(ch > .5) return 1;
1422 if(ch < -.5) return -1;
1423 return 0;
1424 }
1425 }
1426 return 0;
1427}
Scalar eta() const
pseudorapidity method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
double charge(const T &p)
Definition AtlasPID.h:997
std::vector< Identifier > ID
#define AmgVector(rows)
ATLAS-specific HepMC functions.
ReadCards * rp
static Double_t sp
static Double_t sc
const int nmax(200)
Handle class for reading from StoreGate.
bool msgLvl(const MSG::Level lvl) const
An algorithm that can be simultaneously executed in multiple threads.
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
static int kine0(const ITk::TrackClusterAssValidation::EventData_t &event_data, const Trk::PrepRawData *, int *, int)
SG::ReadHandleKey< PRD_MultiTruthCollection > m_truth_locationPixel
int charge(const ITk::TrackClusterAssValidation::EventData_t &event_data, std::pair< int, const Trk::PrepRawData * >, int &, double &) const
StatusCode execute(const EventContext &ctx) const
static PRD_MultiTruthCollection::const_iterator findTruth(const ITk::TrackClusterAssValidation::EventData_t &event_data, const Trk::PrepRawData *, PRD_MultiTruthCollection::const_iterator &)
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_StripDetEleCollKey
bool noReconstructedParticles(const ITk::TrackClusterAssValidation::EventData_t &event_data) const
static MsgStream & dumpevent(MsgStream &out, const ITk::TrackClusterAssValidation::EventData_t &event_data)
void newClustersEvent(const EventContext &ctx, ITk::TrackClusterAssValidation::EventData_t &event_data) const
TrackClusterAssValidation(const std::string &name, ISvcLocator *pSvcLocator)
void tracksComparison(const EventContext &ctx, ITk::TrackClusterAssValidation::EventData_t &event_data) const
MsgStream & dumptools(MsgStream &out, MSG::Level level) const
int qualityTracksSelection(ITk::TrackClusterAssValidation::EventData_t &event_data) const
SG::ReadHandleKey< InDet::SiClusterContainer > m_clustersPixelname
SG::ReadHandleKey< PRD_MultiTruthCollection > m_truth_locationStrip
static bool isTruth(const ITk::TrackClusterAssValidation::EventData_t &, const Trk::PrepRawData *)
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_pixelDetEleCollKey
SG::ReadHandleKey< SpacePointContainer > m_spacepointsStripname
static bool isTheSameDetElement(const ITk::TrackClusterAssValidation::EventData_t &event_data, int, const Trk::PrepRawData *)
SG::ReadHandleKey< SpacePointContainer > m_spacepointsPixelname
SG::ReadHandleKey< SpacePointOverlapCollection > m_spacepointsOverlapname
SG::ReadHandleKey< InDet::SiClusterContainer > m_clustersStripname
void newSpacePointsEvent(const EventContext &ctx, ITk::TrackClusterAssValidation::EventData_t &event_data) const
SG::ReadHandleKeyArray< TrackCollection > m_tracklocation
int kine(const ITk::TrackClusterAssValidation::EventData_t &event_data, const Trk::PrepRawData *, const Trk::PrepRawData *, int *, int) const
unsigned int minclusters(float eta) const
void efficiencyReconstruction(ITk::TrackClusterAssValidation::EventData_t &event_data) const
Class to hold geometrical description of a silicon detector element.
A PRD is mapped onto all contributing particles.
Property holding a SG store/key/clid from which a ReadHandle is made.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
This class is the pure abstract base class for all fittable tracking measurements.
virtual const TrkDetElementBase * detectorElement() const =0
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
virtual const Trk::PrepRawData * prepRawData() const =0
returns the PrepRawData (also known as RIO) object to which this RIO_OnTrack is associated.
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
int ts
Definition globals.cxx:24
int r
Definition globals.cxx:22
int barcode(const T *p)
Definition Barcode.h:16
int uniqueID(const T &p)
const GenParticle * ConstGenParticlePtr
Definition GenParticle.h:38
double charge(const T &p)
bool isNucleus(const T &p)
PDG rule 16 Nuclear codes are given as 10-digit numbers ±10LZZZAAAI.
HandleKeyArray< ReadHandle< T >, ReadHandleKey< T >, Gaudi::DataHandle::Reader > ReadHandleKeyArray
ParametersBase< TrackParametersDim, Charged > TrackParameters
std::multimap< int, const Trk::SpacePoint * > m_kinespacepoint
std::vector< std::list< InDet::PartPropCache > > m_particles
std::vector< SG::ReadHandle< TrackCollection > > m_trackcontainer
std::vector< SG::ReadHandle< SpacePointContainer > > m_spacePointContainer
std::vector< std::multimap< int, int > > m_tracks
std::vector< InDet::TrackCollectionStat_t > m_trackCollectionStat
std::unique_ptr< SG::ReadHandle< SpacePointOverlapCollection > > m_spacepointsOverlap
std::multimap< int, const Trk::PrepRawData * > m_kinecluster
std::vector< std::unique_ptr< SG::VarHandleBase > > m_clusterHandles
MsgStream & msg
Definition testRead.cxx:32