4 // General implementation of a single cut strategy, which can be:
5 // - a value contained in a given interval [--> IsBetween() ]
6 // - a value equal to a given reference [--> MatchesValue()]
8 // In all cases, the reference value(s) is (are) given as data members
9 // and each kind of cut requires a given value type (Int, UInt, Double),
10 // but the cut check procedure is then automatized and chosen thanks to
11 // an enumeration of the implemented cut types.
12 // At the end, the user (or any other point which uses this object) has
13 // to use the method IsSelected() to check if this cut has been passed.
15 // authors: Martin Vala (martin.vala@cern.ch)
16 // Alberto Pulvirenti (alberto.pulvirenti@ct.infn.it)
20 #include "AliExternalTrackParam.h"
22 #include "AliRsnDaughter.h"
23 #include "AliRsnCutPID.h"
25 ClassImp(AliRsnCutPID)
27 //_________________________________________________________________________________________________
28 AliRsnCutPID::AliRsnCutPID() :
29 AliRsnCut(AliRsnCut::kDaughter),
34 // Default constructor.
35 // Sets the cut to realistic PID with default weights,
36 // and defines the 'fMinI' value of the base class as the PID
37 // to which we want to compare this object.
42 for (i = 0; i < kDetectors; i++)
44 fUseDetector[i] = kFALSE;
45 fPtThreshold[i] = 0.0;
46 fGoAboveThreshold[i] = kTRUE;
49 for (i = 0; i < AliPID::kSPECIES; i++)
56 //_________________________________________________________________________________________________
57 AliRsnCutPID::AliRsnCutPID(const char *name, AliPID::EParticleType pid, Double_t probMin, Bool_t perfectPID) :
58 AliRsnCut(name, AliRsnCut::kDaughter, (Int_t)pid),
63 // Default constructor.
64 // Sets the cut to realistic PID with default weights,
65 // and defines the 'fMinI' value of the base class as the PID
66 // to which we want to compare this object.
71 for (i = 0; i < kDetectors; i++)
73 fUseDetector[i] = kFALSE;
74 fPtThreshold[i] = 0.0;
75 fGoAboveThreshold[i] = kTRUE;
78 for (i = 0; i < AliPID::kSPECIES; i++)
88 //_____________________________________________________________________________
89 Bool_t AliRsnCutPID::CheckThreshold(EDetector det, Double_t value)
92 // Checks if the passed value (track pT) stays in the
93 // interval where the detector should be accepted
96 if (!CheckBounds(det)) return kFALSE;
98 if (fGoAboveThreshold[det]) return (value >= fPtThreshold[det]);
99 else return (value <= fPtThreshold[det]);
102 //_________________________________________________________________________________________________
103 Bool_t AliRsnCutPID::ComputeWeights(AliRsnDaughter *daughter)
106 // Compute the PID weights using the class settings.
107 // If the argument is an ESD track, customized weights can be computed
108 // It the argument is a track (ESD or AOD), at least default weights
109 // can be computed, otherwise, no weights can be defined.
110 // The return value tells if the operation was successful.
114 Bool_t useDefault = fUseDefault;
115 Bool_t perfectPID = fPerfect;
116 if (perfectPID && !daughter->GetRefMC()) perfectPID = kFALSE;
117 if (!daughter->GetRefESDtrack()) useDefault = kTRUE;
118 if (!daughter->GetRefESDtrack() && !daughter->GetRefAODtrack()) return kFALSE;
120 // if perfect PID ise required, this overcomes all
121 // in this case the weight of the correct species is set to 1
122 // and the others to 0
123 // of course this happens only if there is a reference MC
126 j = TMath::Abs(daughter->GetRefMC()->Particle()->GetPdgCode());
127 for (i = 0; i < AliPID::kSPECIES; i++)
129 if (AliPID::ParticleCode((AliPID::EParticleType)i) == j) fWeight[i] = 1.0;
130 else fWeight[i] = 0.0;
135 // if default weights are (or need to be) used,
136 // they are taken directly and function exits
139 if (daughter->GetRefESDtrack())
140 daughter->GetRefESDtrack()->GetESDpid(fWeight);
143 for (i = 0; i < AliPID::kSPECIES; i++)
144 fWeight[i] = daughter->GetRefAODtrack()->PID()[i];
149 // if we arrive here, this means that we have an ESD track
150 // and we want to customize the PID
151 AliESDtrack *track = daughter->GetRefESDtrack();
152 Double_t w[kDetectors][AliPID::kSPECIES];
153 track->GetITSpid(w[kITS]);
154 track->GetTPCpid(w[kTPC]);
155 track->GetTRDpid(w[kTRD]);
156 track->GetTOFpid(w[kTOF]);
157 track->GetHMPIDpid(w[kHMPID]);
159 // if a detector is excluded or the track has not the right pT
160 // all related weights are set to 1 in order not to contribute
161 // to final multiplication
162 for (i = 0; i < kDetectors; i++)
164 if (!fUseDetector[i] || !CheckThreshold((EDetector)i, track->Pt()))
166 for (j = 0; j < AliPID::kSPECIES; j++) {
172 // multiplicate all weights to compute final one
173 for (i = 0; i < AliPID::kSPECIES; i++)
175 fWeight[i] = w[kITS][i] * w[kTPC][i] * w[kTRD][i] * w[kTOF][i] * w[kHMPID][i];
181 //_________________________________________________________________________________________________
182 Bool_t AliRsnCutPID::IsSelected(TObject *obj1, TObject* /*obj2*/)
189 if (!AliRsnCut::TargetOK(obj1))
191 AliError(Form("Wrong target. Skipping cut", GetName()));
195 // convert the object into the unique correct type
196 AliRsnDaughter *daughter = dynamic_cast<AliRsnDaughter*>(obj1);
198 // try to compute the weights
199 if (!ComputeWeights(daughter)) return kFALSE;
201 // combine with priors and get the majority
203 Double_t sum = 0.0, w[AliPID::kSPECIES];
204 for (i = 0; i < AliPID::kSPECIES; i++)
206 w[i] = fWeight[i] * fPrior[i];
214 for (i = 0; i < AliPID::kSPECIES; i++) w[i] /= sum;
216 // find the largest probability and related PID
217 // and assign them to the mother class members which
218 // are checked for the cut
221 for (i = 1; i < AliPID::kSPECIES; i++)
223 if (w[i] > fCutValueD)
230 // if the best probability is too small, the cut is failed anyway
231 if (!OkRangeD()) return kFALSE;
233 // if the best probability is OK, the cut is passed
234 // if it correspond to the right particle
238 void AliRsnCutPID::IncludeDetector(EDetector det, Double_t threshold, Bool_t goAbove)
241 // Include a detector for a customized weight computing
242 // and specify also its eventual threshold and if the detector
243 // must be used above or below the threshold.
244 // By default the threshold is zero and detector is always used.
247 if (!CheckBounds(det)) return;
249 fUseDetector[det] = kTRUE;
250 fPtThreshold[det] = threshold;
251 fGoAboveThreshold[det] = goAbove;