EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MuonPIDModule.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file MuonPIDModule.cc
1 #include "MuonPIDModule.h"
2 
3 #include "TClonesArray.h"
4 #include "TRandom3.h"
5 #include "Math/PdfFuncMathCore.h"
6 
7 #include "AnalysisFunctions.cc"
8 
9 #include <iostream>
10 
12  : Module(data)
13 {
14 
15 }
16 
18 {
19 
20 }
21 
22 
23 
24 bool MuonPIDModule::execute(std::map<std::string, std::any>* DataStore)
25 {
26  auto data = getData();
27 
28  // If event contains at least 1 jet
29  // std::vector<Jet*> all_jets;
30  // for (int ijet = 0; ijet < getJets()->GetEntries(); ijet++)
31  // {
32  // // Take first jet
33  // Jet *jet = (Jet*) getJets()->At(ijet);
34  // all_jets.push_back(jet);
35  // }
36 
37  // std::vector<Jet*> fiducial_jets = SelectorFcn<Jet>(all_jets, [](Jet* j){ return (TMath::Abs(j->Eta) < 3.0 && j->PT > 5.0); });
38  // std::vector<Jet*> charmJets = SelectorFcn<Jet>(fiducial_jets, [](Jet* j){ return (j->Flavor == 4); });
39 
40  std::vector<Track*> all_muons;
41 
42  // If the DataStore contains already a list of tracks to be used for PID assignment,
43  // use that. If not, use the getEFlowTracks() method to get the general list of all tracks.
44  // TracksForPID is special - it contains tracks NOT already used by another PID algorithm,
45  // to avoid using the same track (pion) twice in two categories.
46 
47  float mu_efficiency = 0.95;
48  float mupi_separation = 2.0; //sigma
49  // float mu_efficiency = 1.0;
50  // float mupi_separation = 100.0; //sigma
51 
52 
53  if (DataStore->find("TracksForPID") != DataStore->end()) {
54  for (auto track : std::any_cast<std::vector<Track*>>((*DataStore)["TracksForPID"])) {
55  if (MuonPID(track, mu_efficiency, mupi_separation))
56  all_muons.push_back(track);
57  }
58 
59 
60  } else {
61  for (int itrk = 0; itrk < getEFlowTracks()->GetEntries(); itrk++)
62  {
63  Track* track = (Track*) getEFlowTracks()->At(itrk);
64  if (MuonPID(track, mu_efficiency, mupi_separation))
65  all_muons.push_back(track);
66  }
67 
68  std::vector<Track*> tracks_for_PID;
69  for (int itrk = 0; itrk < getEFlowTracks()->GetEntries(); itrk++)
70  {
71  Track* track = (Track*) getEFlowTracks()->At(itrk);
72  tracks_for_PID.push_back(track);
73  }
74  (*DataStore)["TracksForPID"] = tracks_for_PID;
75  }
76 
77  //auto reconstructed_muons = all_muons;
78  std::vector<Track*> reconstructed_muons = SelectorFcn<Track>(all_muons, [](Track* t){ return (t->PT >= 0.1); });
79 
80  std::vector<Track*> tracks_for_PID = std::any_cast<std::vector<Track*>>((*DataStore)["TracksForPID"]);
81  for (auto muon : reconstructed_muons) {
82  tracks_for_PID.erase(std::find(tracks_for_PID.begin(), tracks_for_PID.end(), muon));
83  }
84  (*DataStore)["TracksForPID"] = tracks_for_PID;
85 
86  (*DataStore)["Muons"] = reconstructed_muons;
87 
88 
89  return true;
90 }
91 
92 
93 bool MuonPIDModule::MuonPID(Track* track, float muIDprob, float separation)
94 {
95  bool TrackIsMuon = false;
96 
97 
98  // Apply a basic parameterized muon PID to tracks. If the track is really a
99  // muon from truth information, apply a flat ID probability. If it's a pion,
100  // use the separation (in Gaussian sigma) to determine if it's mis-identified.
101 
102  if (track->PT < 0.1)
103  return TrackIsMuon;
104 
105  int track_truth = track->PID;
106 
107  if (TMath::Abs(track_truth) == 13) {
108  // true charged muon
109  if (gRandom->Uniform(0, 1) <= muIDprob) {
110  TrackIsMuon = true;
111  } else {
112  TrackIsMuon = false;
113  }
114 
115 
116 
117  } else if (TMath::Abs(track_truth) == 211) {
118  // true charged pion
119  if (gRandom->Uniform(0,1) <= ROOT::Math::gaussian_pdf(separation)) {
120  TrackIsMuon = true;
121  } else {
122  TrackIsMuon = false;
123  }
124 
125  } else {
126  // ignore ALL other species for now
127  TrackIsMuon = false;
128  }
129 
130 
131  return TrackIsMuon;
132 }
133 
134 
135 
136