TrdMCClusterR Fit Classifier
AMSMCEventClassifier.h
Go to the documentation of this file.
1 
12 #include <root.h>
13 #include "amschain.h"
14 
15 #include <TFile.h>
16 #include <TH1F.h>
17 #include <TH2.h>
18 
19 #include <map>
20 #include <vector>
21 #include <iostream>
22 #include <unordered_map>
23 
24 #include "Point.h"
25 #include "TRDConstants.h"
26 #include "Utilities.h"
27 #include "AMSTrdMCTrack.h"
28 #include "Intersection3D.h"
29 #include "ClusterFitter.h"
30 #include "LinearAlgebra.h"
31 #include "AMSTracker.h"
32 
33 
34 
36 std::pair<int, double> GetTRDVertexClassifierOutput(AMSEventR * pev, TH2D * h_TrackerL1_XY, bool debugMode = false)
37 {
40  int NLENGTH = 80;
41 
57  int TRDVertexStatus = -99;
58 
59 
66  double PrimaryParticleL1HitDistance = -9;
67 
69  int nFittedPrimaryMCTRDtrkInEvent = 0;
70  int nPrimaryParticleL1Hit = 0;
71 
72 
73 
74  if (pev == NULL)
75  return {-999, -90};
76 
77 
78 
80  MCEventgR * mc0 = pev->GetPrimaryMC();
81  const int mc0_PID = mc0->Particle; // primary particle type
82  int mc0_trkID = mc0->trkID;
83  double mc0_mom = mc0->Momentum;
84  int mc0_Nskip = mc0->Nskip;
85  double mc0_x = mc0->Coo[0];
86  double mc0_y = mc0->Coo[1];
87  double mc0_z = mc0->Coo[2];
88  // delete mc0;
89 
90  if (debugMode)
91  {
92  std::cerr<<std::string(NLENGTH, '_')<<std::endl;
93  printf("\n\n\nFor primary MC particle in this AMS event:\n");
94  printf("g3 PID = %10d, trkID = %10d, Momentum = %7.2f, Nskip = %12d, (MCCooX, MCCooY, MCCooZ) = %8.2f %8.2f %8.2f\n",
95  mc0_PID, mc0_trkID, mc0_mom, mc0_Nskip, mc0_x, mc0_y, mc0_z);
96  }
97 
98 
104 
105  int nmceventg = pev->nMCEventg();
106  std::vector<int> vMCtrkIDs = {};
107  std::vector<Point::Point2DwID> vMCEventgClustersXY = {};
108 
109 
110  if (debugMode)
111  printf("\nFound %d MCEventgR's in this AMS event.\n", nmceventg);
112 
113  for(int imc = 0; imc < nmceventg; imc++)
114  {
115  MCEventgR mc = pev->MCEventg(imc);
116  vMCtrkIDs.push_back(mc.trkID);
117 
120  if ((mc.Coo[2] >= TrkL1_ZPos - TrkL1_ZPosCutoff) && (mc.Coo[2] <= TrkL1_ZPos + TrkL1_ZPosCutoff) &&
121  TrackerL1::HasL1XYHit(h_TrackerL1_XY, mc.Coo[0], mc.Coo[1]))
122  {
124  vMCEventgClustersXY.emplace_back(mc.Coo[0], mc.Coo[1], mc.trkID, mc.Particle, -1);
125  }
126 
127  if (debugMode)
128  {
129  printf("g3 PID = %10d, trkID = %10d, Momentum = %7.2f, Nskip = %12d, (MCCooX, MCCooY, MCCooZ) = %8.2f %8.2f %8.2f\n",
130  mc.Particle, mc.trkID, mc.Momentum, mc.Nskip, mc.Coo[0], mc.Coo[1], mc.Coo[2]);
131  }
132  }
133 
134  auto MCEventgResultMap = VectorUtilities::GetUniqueElementsAndFrequency(vMCtrkIDs);
135 
137  if (debugMode)
138  {
139  printf("Unique trkIDs found: %zu.\nDetails of trkIDs with nClusters > 1:\n", MCEventgResultMap.size());
140  for(const auto& pair : MCEventgResultMap)
141  {
142  if (pair.second > 1)
143  printf("trkID = %10d, nClusters = %10d\n", pair.first, pair.second);
144  }
145  }
146 
147 
148 
149 
151 
158  if (debugMode)
159  {
160  std::cerr<<std::string(NLENGTH, '_')<<std::endl;
161  printf("\n\nNow analyzing MC TRD track clusters in this event...");
162  }
163 
164  int ntrdmccluster = pev->nTrdMCCluster();
165  std::vector<int> vTRDMCtrkIDs = {};
166 
167  if (debugMode)
168  printf("\nFound %d TrdMCClusterR's in this AMS event.\n", ntrdmccluster);
169 
170  if (ntrdmccluster == 0)
171  {
172  TRDVertexStatus = -29;
173  return std::make_pair(TRDVertexStatus, PrimaryParticleL1HitDistance);
174  }
175 
176  for(int iTRDMCCluster = 0; iTRDMCCluster < ntrdmccluster; iTRDMCCluster++)
177  {
178  TrdMCClusterR trdCltr = pev->TrdMCCluster(iTRDMCCluster);
179  vTRDMCtrkIDs.push_back(trdCltr.GtrkID);
180 
181  if (debugMode)
182  {
183  printf("g3 PID = %10d, GtrkID = %10d, Ekin = %7.2f, ProcID = %12d, MCCooX = %8.2f, MCCooY = %8.2f, MCCooZ = %8.2f\n",
184  trdCltr.ParticleNo,trdCltr.GtrkID, trdCltr.Ekin,trdCltr.ProcID, trdCltr.Xgl[0], trdCltr.Xgl[1], trdCltr.Xgl[2]);
185  }
186  }
187 
188  std::map<int, int> TRDMCresultMap = VectorUtilities::GetUniqueElementsAndFrequency(vTRDMCtrkIDs);
189  if (debugMode)
190  printf("\n\nUnique TRD trkIDs found: %zu.", TRDMCresultMap.size());
191 
195  unsigned int size_TRDMCresultMap = TRDMCresultMap.size();
196 
198  if (debugMode)
199  {
200  printf("\nGood TRD trkIDs found : %zu.\nDetails of good TRD trkIDs with nClusters > 1:\n", TRDMCresultMap.size());
201  for(const auto& pair : TRDMCresultMap)
202  {
203  if (pair.second < nMIN_CLUSTERS_FOR_FIT)
204  continue;
205 
206  printf("TRD trkID = %10d, nClusters = %10d\n", pair.first, pair.second);
207  }
208  }
209 
210 
211 
212 
214 
218  if (debugMode)
219  {
220  std::cerr<<std::string(NLENGTH, '_')<<std::endl;
221  printf("\n\nNow grouping clusters under separate AMSTrdMCTrack::Tracks...");
222  }
223 
224  std::vector<AMSTrdMCTrack::Track> vMCTracksInEvent = {};
225 
226  for(const auto& pair : TRDMCresultMap)
227  {
228  if (pair.second < nMIN_CLUSTERS_FOR_FIT)
229  continue;
230 
231  AMSTrdMCTrack::Track track;
232  track.trkID = pair.first;
233 
234  std::vector<int> vClusterG3PID;
235 
236  for(int iTRDMCCluster = 0; iTRDMCCluster < ntrdmccluster; iTRDMCCluster++)
237  {
238  TrdMCClusterR trdCltr = pev->TrdMCCluster(iTRDMCCluster);
239 
240  if (pair.first != trdCltr.GtrkID)
241  continue;
242 
243  vClusterG3PID.push_back(trdCltr.ParticleNo);
244 
245  AMSTrdMCTrack::Cluster cluster;
246  cluster.x = trdCltr.Xgl[0];
247  cluster.y = trdCltr.Xgl[1];
248  cluster.z = trdCltr.Xgl[2];
249  track.clusters.push_back(cluster);
250  }
251 
252 
254  if (VectorUtilities::areAllElementsEqual(vClusterG3PID) == true)
255  {
256  track.g3PID = vClusterG3PID[0];
257  vMCTracksInEvent.push_back(track);
258  }
259  else if (VectorUtilities::countDifferentFromMajority(vClusterG3PID) == 1)
260  {
261  if (debugMode)
262  printf("\n\nWARNING: In TRD trkID = %10d, nClusters = %10d, one vClusterG3PID element is different from the rest. Ignoring this element and moving on...\n", pair.first, pair.second);
263  track.g3PID = VectorUtilities::getMajorityElement(vClusterG3PID);
264  vMCTracksInEvent.push_back(track);
265  }
266  else
267  {
269  --size_TRDMCresultMap;
270  if (debugMode)
271  {
272  printf("\n\n\n\nERROR! Track clusters do not have the same g3 PID!\n");
273  printf("vClusterG3PID.size() = %zu\n", vClusterG3PID.size());
274  printf("vClusterG3PID elements:\n");
275  VectorUtilities::printVector(vClusterG3PID);
276  printf("These clusters won't be used!\n\n\n\n");
277  }
278  }
279 
280  vClusterG3PID.clear(); vClusterG3PID.resize(0);
281  }
282 
284  if (vMCTracksInEvent.size() != size_TRDMCresultMap)
285  printf("\n\n\n\nERROR! Number of tracks saved does not equal unique tracks found!\n\nPlease confirm logic!\n\n\n\n");
286 
288  if (debugMode)
289  printf("\n\nSaved %zu tracks in this AMS event for fitting:", vMCTracksInEvent.size());
290 
291  if (vMCTracksInEvent.size() == 0)
292  {
293  TRDVertexStatus = -29;
294  return std::make_pair(TRDVertexStatus, PrimaryParticleL1HitDistance);
295  }
296 
297 
298 
299 
302  if (debugMode)
303  {
304  std::cerr<<std::string(NLENGTH, '_')<<std::endl;
305  printf("\n\nNow performing track fits...");
306  }
307 
308  std::vector<std::vector<Line::FitLine2D>> vvFittedTracks = {};
309  for (const AMSTrdMCTrack::Track& track : vMCTracksInEvent)
310  {
311  if (debugMode)
312  printf("\n\ntrkID = %d, G3PID = %d, nClusters = %zu\n", track.trkID, track.g3PID, track.clusters.size());
313 
314  for (const AMSTrdMCTrack::Cluster& cluster : track.clusters)
315  {
316  if (debugMode)
317  printf("---> Cluster: %9.3f %9.3f %9.3f\n", cluster.x, cluster.y, cluster.z);
318  }
319 
320  std::vector<Line::FitLine2D> vFitted_Lines2D = ClusterFitter::GetClusterProjectionLinearFits(
324  track.trkID,
325  track.g3PID,
326  debugMode,
328 
329  if (vFitted_Lines2D.size() == 3)
330  vvFittedTracks.push_back(vFitted_Lines2D);
331 
332  // vFitted_Lines2D.clear(); vFitted_Lines2D.resize(0); /// Not required as it is not a vector of pointers.
333  }
334 
336  unsigned int nFittedTracks = vvFittedTracks.size();
337  if (nFittedTracks == 0)
338  {
339  TRDVertexStatus = -29;
340  return std::make_pair(TRDVertexStatus, PrimaryParticleL1HitDistance);
341  }
342 
343 
345  if (debugMode)
346  printf("\n\n%d fitted AMSTrdMCTrack::Track found in event.\nVerifying track fit prameters:\n", nFittedTracks);
347 
348  for (unsigned int iFittedTrack = 0; iFittedTrack < nFittedTracks; iFittedTrack++)
349  {
350  if (debugMode)
351  {
352  for (unsigned int iPlane = 0; iPlane < 3; iPlane++)
353  {
354  printf("Track#: %3d (%5d, %5d) = Fit plane: %s, M = %14.7f, C = %14.7f\n",
355  iFittedTrack, vvFittedTracks[iFittedTrack][iPlane].trkID, vvFittedTracks[iFittedTrack][iPlane].g3PID,
356  vFitPlanes[iPlane].c_str(), vvFittedTracks[iFittedTrack][iPlane].m, vvFittedTracks[iFittedTrack][iPlane].c);
357  }
358  }
359 
362  if (vvFittedTracks[iFittedTrack][0].trkID == 1 && vvFittedTracks[iFittedTrack][0].g3PID == mc0_PID)
363  ++nFittedPrimaryMCTRDtrkInEvent;
364  }
365  if (nFittedPrimaryMCTRDtrkInEvent < 1)
366  {
369  TRDVertexStatus = -9;
370  return std::make_pair(TRDVertexStatus, PrimaryParticleL1HitDistance);
371  }
372 
373 
374 
375 
378 
386  if (debugMode)
387  {
388  std::cerr<<std::string(NLENGTH, '_')<<std::endl;
389  printf("\n\nNow finding 3D line from fitted plane projections...");
390  }
391 
392 
393  for (unsigned int iFittedTrack = 0; iFittedTrack < nFittedTracks; iFittedTrack++)
394  {
395  const double m1 = vvFittedTracks[iFittedTrack][0].m; const double b1 = vvFittedTracks[iFittedTrack][0].c;
396  const double m2 = vvFittedTracks[iFittedTrack][1].m; const double b2 = vvFittedTracks[iFittedTrack][1].c;
397  const double m3 = vvFittedTracks[iFittedTrack][2].m; const double b3 = vvFittedTracks[iFittedTrack][2].c;
398  const int fit_trkID = vvFittedTracks[iFittedTrack][0].trkID;
399  const int fit_g3PID = vvFittedTracks[iFittedTrack][0].g3PID;
400 
401  if (debugMode)
402  {
403  printf("\n\n----> For fitted track# %d, (trkID = %d, g3PID = %d), the 2D projections provided are:\n", iFittedTrack, fit_trkID, fit_g3PID);
404  printf("XZ: m1, b1 = (%9.4f, %9.4f)\n", m1, b1);
405  printf("YZ: m2, b2 = (%9.4f, %9.4f)\n", m2, b2);
406  printf("XY: m3, b3 = (%9.4f, %9.4f)\n", m3, b3);
407  }
408 
410  Line::Line3DParametricForm line3D = Line::Getline3DParametricForm(m1, b1, m2, b2, m3, b3, fit_trkID, fit_g3PID, debugMode);
411 
413  if (!line3D.point.empty() && !line3D.direction.empty())
414  {
416  if (debugMode)
417  {
418  // std::cout<<"The point on the line is: (" << line3D.point[0] << ", " << line3D.point[1] << ", " << line3D.point[2] <<")\n";
419  // std::cout<<"The direction ratios of the line are: (" << line3D.direction[0] << ", " << line3D.direction[1] << ", " << line3D.direction[2] <<")\n";
420  }
421  }
422 
423  else
424  {
426  if (debugMode)
427  std::cout<<"\nInvalid input or no solution exists for the given projections.\n";
428 
430  continue;
431  }
432 
433 
436  auto closestPoint = TrackerL1::FindClosestTrkL1ClusterFrom3DLine(h_TrackerL1_XY, line3D, vMCEventgClustersXY);
437 
439  if (closestPoint.second == false)
440  {
441  if (debugMode)
442  std::cout<<"\nNo L1 hit found for this fitted track.\n\n";
443  }
444 
445  else
446  {
447  if (debugMode)
448  std::cout<<"\nFitted track potentially intersects with L1. Matching with MCEventgCluster hits...";
449 
451  if (closestPoint.first.trkID == fit_trkID && closestPoint.first.PID == fit_g3PID)
452  {
453  if (debugMode)
454  std::cout<<"\nThe closest L1 hit found: ("<<closestPoint.first.x<< ", "<<closestPoint.first.y<<") at "<<closestPoint.first.closedis<<" cm.\n";
455 
457  if (fit_trkID == mc0_trkID && fit_g3PID == mc0_PID)
458  {
459  ++nPrimaryParticleL1Hit;
460  PrimaryParticleL1HitDistance = closestPoint.first.closedis;
461  }
462  }
463 
464  else
465  {
466  if (debugMode)
467  std::cout<<"\nBut no matched L1 MCEventgCluster hit found for this fitted track.\n\n";
468  }
469  }
470  }
471 
472  if (nPrimaryParticleL1Hit != 1)
473  PrimaryParticleL1HitDistance = -5;
474 
475 
476 
477 
478 
479 
480 
481 
482 
485 
505  int nMAX_POSSIBLE_PAIRS = Utilities::CalculatePairs(nFittedTracks);
506  int nNEXTTOMAX_POSSIBLE_PAIRS = Utilities::CalculatePairs(nFittedTracks - 1);
507 
508  if (debugMode)
509  {
510  std::cerr<<std::string(NLENGTH, '_')<<std::endl;
511  printf("\n\nFinding vertices in fitted intersecting tracks...");
512  printf("\n\nFor %d fitted tracks in this event.\n", nFittedTracks);
513  printf("nMAX_POSSIBLE_PAIRS = %d\n", nMAX_POSSIBLE_PAIRS);
514  printf("nNEXTTOMAX_POSSIBLE_PAIRS = %d\n", nNEXTTOMAX_POSSIBLE_PAIRS);
515  }
516 
517 
521 
522  int nIntersecting_3Dlines = Intersection3D::GetNIntersectingLinePairs(vvFittedTracks, debugMode);
523  if (debugMode)
524  printf("\nnIntersecting 3D lines found = %d\n", nIntersecting_3Dlines);
525 
526 
529 
530  if (nIntersecting_3Dlines == 0)
531  {
532  if (nFittedTracks == 1)
533  TRDVertexStatus = 1;
534  else
535  TRDVertexStatus = 2;
536  }
537 
538  else if (nIntersecting_3Dlines == nMAX_POSSIBLE_PAIRS && nFittedTracks > 1)
539  {
542  if ((nFittedTracks == 2) &&
543  (vvFittedTracks[0][0].g3PID == -3 || vvFittedTracks[1][0].g3PID == -3) &&
544  (vvFittedTracks[0][0].g3PID * vvFittedTracks[1][0].g3PID < 0))
545  {
546  TRDVertexStatus = 3;
547  }
548 
551  else
552  TRDVertexStatus = -19;
553  }
554 
555  else if (nIntersecting_3Dlines == nNEXTTOMAX_POSSIBLE_PAIRS && nFittedTracks > 2)
556  {
564 
565  TRDVertexStatus = 0;
566  }
567 
568  else if (nIntersecting_3Dlines > nNEXTTOMAX_POSSIBLE_PAIRS && nIntersecting_3Dlines < nMAX_POSSIBLE_PAIRS)
569  {
573  TRDVertexStatus = -2;
574  }
575 
576  else if (nIntersecting_3Dlines > 0 && nIntersecting_3Dlines < nNEXTTOMAX_POSSIBLE_PAIRS && nFittedTracks > 3)
577  {
582  TRDVertexStatus = -1;
583  }
584 
585  else
586  {
587  TRDVertexStatus = -39;
588  if (debugMode)
589  printf("\n\n\n\nWARNING: Unknown logic: unable to assign the TRDVertexStatus!\n\n\n\n");
590  }
591 
592 
593  if (debugMode)
594  printf("\nEvent has been classified as TRDVertexStatus = %d\n", TRDVertexStatus);
595 
596 
597 
598 
601  vMCtrkIDs.clear(); vMCtrkIDs.resize(0);
602  vMCEventgClustersXY.clear(); vMCEventgClustersXY.resize(0);
603  vTRDMCtrkIDs.clear(); vTRDMCtrkIDs.resize(0);
604  vMCTracksInEvent.clear(); vMCTracksInEvent.resize(0); //std::vector<AMSTrdMCTrack::Track>().swap(vMCTracksInEvent);
605  vvFittedTracks.clear(); vvFittedTracks.resize(0);
606 
607  return std::make_pair(TRDVertexStatus, PrimaryParticleL1HitDistance);
608 }
std::pair< int, double > GetTRDVertexClassifierOutput(AMSEventR *pev, TH2D *h_TrackerL1_XY, bool debugMode=false)
Definition: AMSMCEventClassifier.h:36
const double TrkL1_ZPos
Definition: AMSTracker.h:12
const double TrkL1_ZPosCutoff
cm
Definition: AMSTracker.h:13
const std::vector< std::string > vFitPlanes
Strings for fit planes and components.
Definition: TRDConstants.h:23
const int nMIN_CLUSTERS_FOR_FIT
cm
Definition: TRDConstants.h:19
const double fitChi2perNDF_threshold
fit threshold for ClusterFitter::GetClusterProjectionLinearFits()
Definition: TRDConstants.h:38
@ Z
Definition: AMSTrdMCTrack.h:21
@ X
Definition: AMSTrdMCTrack.h:19
@ Y
Definition: AMSTrdMCTrack.h:20
std::vector< double > GetTrkPosValues(const Track &track, Coordinate coord)
Definition: AMSTrdMCTrack.h:211
std::vector< Line::FitLine2D > GetClusterProjectionLinearFits(const std::vector< double > &TrkClusters_x, const std::vector< double > &TrkClusters_y, const std::vector< double > &TrkClusters_z, const int &trkID, const int &g3PID, const bool &debug=false, const double threshold=1000)
Definition: ClusterFitter.h:19
int GetNIntersectingLinePairs(const std::vector< std::vector< Line::FitLine2D >> &vvFittedTracks, const bool &debugMode=false)
Definition: Intersection3D.h:171
Line3DParametricForm Getline3DParametricForm(const double &m1, const double &b1, const double &m2, const double &b2, const double &m3, const double &b3, const int &trkID, const int &g3PID, bool debugMode)
Definition: Line.h:76
bool HasL1XYHit(const TH2D *hTrackerL1_XY, const double &x, const double &y, const bool &debug=false)
Definition: AMSTracker.h:20
std::pair< Point::Point2DwID, bool > FindClosestTrkL1ClusterFrom3DLine(const TH2D *hTrackerL1_XY, const Line::Line3DParametricForm &line, const std::vector< Point::Point2DwID > &gMCClustersXY, const bool &debug=false)
Definition: AMSTracker.h:34
int CalculatePairs(int n)
Definition: Utilities.h:30
bool areAllElementsEqual(const std::vector< T > &vec)
Definition: Utilities.h:113
void filterAndShrinkMap(std::map< int, int > &frequencyMap, int threshold=2)
Definition: Utilities.h:97
int getMajorityElement(const std::vector< int > &vec)
Definition: Utilities.h:122
std::map< int, int > GetUniqueElementsAndFrequency(const std::vector< int > &vec)
Definition: Utilities.h:83
void printVector(const std::vector< T > &v)
Definition: Utilities.h:58
int countDifferentFromMajority(const std::vector< int > &vec)
Definition: Utilities.h:146
Definition: AMSTrdMCTrack.h:27
double y
Definition: AMSTrdMCTrack.h:29
double z
Definition: AMSTrdMCTrack.h:30
double x
Definition: AMSTrdMCTrack.h:28
Definition: AMSTrdMCTrack.h:49
int trkID
Definition: AMSTrdMCTrack.h:50
std::vector< Cluster > clusters
Definition: AMSTrdMCTrack.h:52
int g3PID
Definition: AMSTrdMCTrack.h:51
Definition: Line.h:60
std::vector< double > point
Definition: Line.h:63
std::vector< double > direction
Vector containing the point on the line (x0, y0, z0)
Definition: Line.h:64