HighLAND
PIDUtils.cxx
1 #include "PIDUtils.hxx"
2 #include "CutUtils.hxx"
3 #include "VersioningUtils.hxx"
4 
5 const unsigned int NMAXPARTICLESWITHTPC = NMAXPARTICLES;
6 
7 //********************************************************************
9 //********************************************************************
10 
11  // TODO
12  (void)track;
13 
14  /*
15  track.Pullmu = ComputeTPCPull(track,"muon");
16  track.Pullp = ComputeTPCPull(track,"proton");
17  track.Pullele = ComputeTPCPull(track,"electron");
18  track.Pullpi = ComputeTPCPull(track,"pion");
19  track.Pullk = ComputeTPCPull(track,"kaon");
20  */
21 }
22 
23 //********************************************************************
24 void anaUtils::ComputeTPCPull(const AnaTPCParticleB &track, Float_t* pulls) {
25 //********************************************************************
26 
27  pulls[0] = ((track.dEdxMeas - track.dEdxexpMuon) / track.dEdxSigmaMuon);
28  pulls[1] = ((track.dEdxMeas - track.dEdxexpEle) / track.dEdxSigmaEle);
29  pulls[2] = ((track.dEdxMeas - track.dEdxexpProton) / track.dEdxSigmaProton);
30  pulls[3] = ((track.dEdxMeas - track.dEdxexpPion) / track.dEdxSigmaPion);
31 
32 
33 }
34 
35 //********************************************************************
36 Float_t anaUtils::ExpectedTPCdEdx(const AnaTPCParticleB &track, const std::string& particle) {
37 //********************************************************************
38 
39  // for production 5
40  Float_t ExpecteddEP0 = 149.4;
41  Float_t ExpecteddEP1 = 2.765;
42  Float_t ExpecteddEP2 = 0.103;
43  Float_t ExpecteddEP3 = 2.052;
44  Float_t ExpecteddEP4 = 0.5104;
45 
46  if (versionUtils::prod6_corrections){
47  // for production 6
48  ExpecteddEP0 = 53.87;
49  ExpecteddEP1 = 5.551;
50  ExpecteddEP2 = 0.001913;
51  ExpecteddEP3 = 2.283;
52  ExpecteddEP4 = 1.249;
53  }
54 
55  Float_t mass = -1;
56 
57  if (particle == "electron") {
58  mass = 0.511;
59  } else if (particle == "pion") {
60  mass = 139.57;
61  } else if (particle == "muon") {
62  mass = 105.66;
63  } else if (particle == "proton") {
64  mass = 938.27;
65  } else if (particle == "kaon") {
66  mass = 493.67;
67  } else {
68  std::cout << "Tried to compute dEdx for invalid particle hypothesis" << std::endl;
69  return -10000;
70  }
71 
72  Float_t bg = track.Momentum / mass;
73  Float_t beta = bg / sqrt(1. + bg * bg);
74  Float_t func = ExpecteddEP1 - pow(beta, ExpecteddEP3) - log(ExpecteddEP2 + 1. / pow(bg, ExpecteddEP4));
75  func = func * ExpecteddEP0 / pow(beta, ExpecteddEP3);
76 
77  return func;
78 }
79 
80 //********************************************************************
81 void anaUtils::GetPIDLikelihood(const AnaTrackB& track, Float_t* hypo, bool prod5Cut){
82 //********************************************************************
83 
84  UInt_t itrk = track.Index;
85 
86  if( itrk >= NMAXPARTICLESWITHTPC ) return; // Protection against values out of the vector.
87 
88  Double_t prob[4]={1,1,1,1};
89  Double_t tmp_prob[3][4];
90  Double_t total_prob=0;
91  bool found=false;
92 
93  AnaTPCParticleB* segmentsInTPC[3];
94  for(int i = 0; i < 3; ++i){
95  segmentsInTPC[i] = NULL;
96  for (Int_t j=0;j<4;j++){
97  hypo[j]=-1;
98  tmp_prob[i][j] = 1;
99  }
100  }
101  // Get the closest TPC. We should make sure that at least the segment in that TPC has the proper PID info
102  SubDetId::SubDetEnum closesttpc = anaUtils::GetClosestTPC(track);
103 
104  // Loop over TPC segments
105  for (int j = 0; j < track.nTPCSegments; ++j){
106  AnaTPCParticleB* TPCSegment = track.TPCSegments[j];
107  if (!TPCSegment) continue;
108 
109  // Only segments passing the TPC track quality cut will contribute to the likelihood
110  // Was not applied for production 5 BANFF analysis
111  if(!prod5Cut) if (!cutUtils::TPCTrackQualityCut(*TPCSegment)) continue;
112 
113  // Require valid values for all quantities involved
114  if( TPCSegment->dEdxexpMuon==-0xABCDEF || TPCSegment->dEdxexpEle==-0xABCDEF || TPCSegment->dEdxexpPion==-0xABCDEF || TPCSegment->dEdxexpProton==-0xABCDEF) continue;
115  if( TPCSegment->dEdxMeas ==-0xABCDEF ) continue;
116  if( TPCSegment->dEdxexpMuon==-99999 || TPCSegment->dEdxexpEle==-99999 || TPCSegment->dEdxexpPion==-99999 || TPCSegment->dEdxexpProton==-99999) continue;
117  if( TPCSegment->dEdxMeas ==-99999 ) continue;
118 
119  Float_t pulls[4];
120  // Pulls in order: Muon, Electron, Proton, Pion
121  anaUtils::ComputeTPCPull(*TPCSegment,pulls);
122  Float_t pullmu = pulls[0];
123  Float_t pullp = pulls[2];
124  Float_t pullele = pulls[1];
125  Float_t pullpi = pulls[3];
126 
127  if (!TMath::Finite(pullmu) || !TMath::Finite(pullele) || !TMath::Finite(pullp) || !TMath::Finite(pullpi)) continue;
128  if (pullmu != pullmu || pullele != pullele || pullp != pullp || pullpi != pullpi) continue;
129 
131 
132  // To avoid mismatching between FlatTree and oaAnalysis we allow only one segment per TPC to be included in the likelihood, the one with more nodes
133  if (segmentsInTPC[det-2]){
134  if (TPCSegment->NNodes > segmentsInTPC[det-2]->NNodes){
135  segmentsInTPC[det-2] = TPCSegment;
136  tmp_prob[det-2][0] = exp(-(pullmu*pullmu)/2);
137  tmp_prob[det-2][1] = exp(-(pullele*pullele)/2);
138  tmp_prob[det-2][2] = exp(-(pullp*pullp)/2);
139  tmp_prob[det-2][3] = exp(-(pullpi*pullpi)/2);
140  }
141  }
142  else{
143  segmentsInTPC[det-2] = TPCSegment;
144  tmp_prob[det-2][0] = exp(-(pullmu*pullmu)/2);
145  tmp_prob[det-2][1] = exp(-(pullele*pullele)/2);
146  tmp_prob[det-2][2] = exp(-(pullp*pullp)/2);
147  tmp_prob[det-2][3] = exp(-(pullpi*pullpi)/2);
148  }
149  }
150 
151  // Loop over all segments contributing to the likelihood and compute it
152  for (int tpc=0;tpc<3;tpc++){
153  if (segmentsInTPC[tpc]){
154  // The pull should be already corrected by all corrections (CT and CT expected)
155  prob[0] *= tmp_prob[tpc][0];
156  prob[1] *= tmp_prob[tpc][1];
157  prob[2] *= tmp_prob[tpc][2];
158  prob[3] *= tmp_prob[tpc][3];
159 
160  if (SubDetId::GetDetectorUsed(segmentsInTPC[tpc]->Detector, closesttpc)) found = true;
161  }
162  }
163 
164  // If at least the segment in the closest TPC has a valid PID info
165  if (found){
166  for (int h=0;h<4;h++){
167  total_prob += prob[h] ;
168  }
169 
170  if (total_prob>0){
171  for (int h=0;h<4;h++){
172  hypo[h] = prob[h]/total_prob ;
173  }
174  }
175  }
176  return;
177 }
178 
179 //********************************************************************
180 Float_t anaUtils::GetPIDLikelihood(const AnaTrackB& track, Int_t hypo, bool prod5Cut){
181 //********************************************************************
182 
183  if( hypo >= 4 ) return -1.e+6;
184 
185  Float_t Likelihood[4];
186  GetPIDLikelihood(track,Likelihood,prod5Cut);
187  return Likelihood[hypo];
188 }
189 
190 //********************************************************************
192 //********************************************************************
193 
194  Float_t Likelihood[4];
195  GetPIDLikelihood(track,Likelihood);
196 
197  Float_t likemu = Likelihood[0];
198  Float_t likepi = Likelihood[3];
199  Float_t likep = Likelihood[2];
200 
201  return (likemu+likepi)/(1-likep);
202 }
203 
204 //********************************************************************
205 Float_t anaUtils::GetPIDPrior(const AnaTrackB& track, Int_t hypo){
206 //********************************************************************
207 
208  // This function is not used yet
209 
210  Float_t xbins[18] = {0., 100., 200., 300., 400., 500., 600., 700, 800, 1000., 1200., 1400., 1700, 2000., 2500., 3000., 4000., 5000.};
211 
212  Float_t eprior[17] = {800., 250., 100, 40, 30, 25, 10, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0};
213 
214  for (Int_t i=0;i<17;i++){
215  eprior[i] /=400.;
216  }
217 
218  Int_t pbin = 16;
219  for (Int_t i=0;i<17;i++){
220  pbin = i-1;
221  if (track.Momentum>0 && track.Momentum < xbins[i]) break;
222  }
223 
224 
225  if (hypo==1) return eprior[pbin];
226  else return 1.;
227 
228 }
Float_t dEdxexpMuon
Expected dE/dx for a muon, based on the reconstructed momentum.
unsigned long Detector
Float_t dEdxexpProton
Expected dE/dx for a proton, based on the reconstructed momentum.
Int_t NNodes
The number of nodes in the reconstructed object.
SubDetId::SubDetEnum GetClosestTPC(const AnaTrackB &track)
For tracks that start in the FGD, get the closest TPC in the direction of the track.
AnaTPCParticleB * TPCSegments[NMAXTPCS]
The TPC segments that contributed to this global track.
Float_t dEdxSigmaProton
Expected error on the dE/dx measurement, for the proton hypothesis.
static bool GetDetectorUsed(unsigned long BitField, SubDetId::SubDetEnum det)
Method to see if a certain subdetector or subdetector system is used.
Definition: SubDetId.cxx:40
void RecomputeTPCPulls(AnaTPCParticleB &track)
Function to recompute all the pull for a TPC track segment and save them into the segment...
Definition: PIDUtils.cxx:8
Float_t GetPIDPrior(const AnaTrackB &track, Int_t hypo)
A function that is not currently used, and will be documented when it is.
Definition: PIDUtils.cxx:205
Float_t dEdxexpPion
Expected dE/dx for a pion, based on the reconstructed momentum.
Float_t dEdxexpEle
Expected dE/dx for an electron, based on the reconstructed momentum.
Float_t GetPIDLikelihood(const AnaTrackB &track, Int_t hypo, bool prod5Cut=0)
Definition: PIDUtils.cxx:180
Float_t Momentum
The reconstructed momentum of the particle, at the start position.
Int_t Index
The index of this particle track in the vector of particles. TODO: Not sure it is needed (only use in...
int nTPCSegments
How many TPC tracks are associated with this track.
Float_t dEdxSigmaEle
Expected error on the dE/dx measurement, for the electron hypothesis.
SubDetEnum
Enumeration of all detector systems and subdetectors.
Definition: SubDetId.hxx:25
Float_t dEdxMeas
dE/dx as measured by the TPC.
Representation of a global track.
Float_t ComputeTPCPull(const AnaTPCParticleB &track, const std::string &particle)
Function to recompute the pull for a TPC track segment.
static SubDetId::SubDetEnum GetSubdetectorEnum(unsigned long BitField)
Get the single subdetector that this track is from.
Definition: SubDetId.cxx:165
Representation of a TPC segment of a global track.
Float_t ExpectedTPCdEdx(const AnaTPCParticleB &track, const std::string &particle)
Definition: PIDUtils.cxx:36
Float_t dEdxSigmaMuon
Expected error on the dE/dx measurement, for the muon hypothesis.
Float_t dEdxSigmaPion
Expected error on the dE/dx measurement, for the pion hypothesis.
Float_t GetPIDLikelihoodMIP(const AnaTrackB &track)
Get the likelihood for MIP: (like_mu+like_pi)/(1-like_p)
Definition: PIDUtils.cxx:191