9eb63e2ec0afb1b3f263f4abfb5611a5dac87bca
[u/mrichter/AliRoot.git] / PWGLF / RESONANCES / AliRsnCutPIDNSigma.cxx
1 //
2 // Class AliRsnCutPIDNSigma
3 //
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()]
7 //
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.
14 //
15 // authors: Martin Vala (martin.vala@cern.ch)
16 //          Alberto Pulvirenti (alberto.pulvirenti@ct.infn.it)
17 //
18
19 #include "AliPIDResponse.h"
20 #include "AliESDpid.h"
21 #include "AliAODpidUtil.h"
22
23 #include "AliRsnCutPIDNSigma.h"
24
25 ClassImp(AliRsnCutPIDNSigma::AliRsnPIDRange)
26 ClassImp(AliRsnCutPIDNSigma)
27
28 //_________________________________________________________________________________________________
29 AliRsnCutPIDNSigma::AliRsnCutPIDNSigma() :
30    AliRsnCut("cut", AliRsnTarget::kDaughter),
31    fSpecies(AliPID::kUnknown),
32    fDetector(kDetectors),
33    fRejectUnmatched(kFALSE),
34    fTrackNSigma(0.0),
35    fTrackMom(0.0),
36    fMyPID(0x0),
37    fRanges("AliRsnCutPIDNSigma::AliRsnPIDRange", 0)
38 {
39 //
40 // Main constructor.
41 //
42 }
43
44 //_________________________________________________________________________________________________
45 AliRsnCutPIDNSigma::AliRsnCutPIDNSigma
46 (const char *name, AliPID::EParticleType species, EDetector det) :
47    AliRsnCut(name, AliRsnTarget::kDaughter),
48    fSpecies(species),
49    fDetector(det),
50    fRejectUnmatched(kFALSE),
51    fTrackNSigma(0.0),
52    fTrackMom(0.0),
53    fMyPID(0x0),
54    fRanges("AliRsnCutPIDNSigma::AliRsnPIDRange", 0)
55 {
56 //
57 // Main constructor.
58 //
59 }
60
61 //_________________________________________________________________________________________________
62 AliRsnCutPIDNSigma::AliRsnCutPIDNSigma
63 (const AliRsnCutPIDNSigma &copy) :
64    AliRsnCut(copy),
65    fSpecies(copy.fSpecies),
66    fDetector(copy.fDetector),
67    fRejectUnmatched(copy.fRejectUnmatched),
68    fTrackNSigma(0.0),
69    fTrackMom(0.0),
70    fMyPID(copy.fMyPID),
71    fRanges(copy.fRanges)
72 {
73 //
74 // Copy constructor.
75 //
76 }
77
78 //_________________________________________________________________________________________________
79 AliRsnCutPIDNSigma &AliRsnCutPIDNSigma::operator=(const AliRsnCutPIDNSigma &copy)
80 {
81 //
82 // Assignment operator
83 //
84
85    AliRsnCut::operator=(copy);
86    if (this == &copy)
87       return *this;
88    fSpecies = copy.fSpecies;
89    fDetector = copy.fDetector;
90    fRejectUnmatched = copy.fRejectUnmatched;
91    fMyPID = copy.fMyPID;
92    fRanges = copy.fRanges;
93
94    return (*this);
95 }
96
97 //__________________________________________________________________________________________________
98 void AliRsnCutPIDNSigma::InitMyPID(Bool_t isMC, Bool_t isESD)
99 {
100 //
101 // Initialize manual PID object
102 //
103
104    if (isESD)
105       fMyPID = new AliESDpid(isMC);
106    else
107       fMyPID = new AliAODpidUtil(isMC);
108 }
109
110 //_________________________________________________________________________________________________
111 Bool_t AliRsnCutPIDNSigma::IsSelected(TObject *object)
112 {
113 //
114 // Cut checker.
115 // As usual, there are 'kFALSE' exit points whenever one of the conditions is not passed,
116 // and at the end, it returns kTRUE since it bypassed all possible exit points.
117 //
118
119    // coherence check
120    if (!TargetOK(object)) return kFALSE;
121
122    // check initialization of PID object
123    // if manual PID is used, use that, otherwise get from source event
124    AliPIDResponse *pid = 0x0;
125    if (fMyPID)
126       pid = fMyPID;
127    else
128       pid = fEvent->GetPIDResponse();
129    if (!pid) {
130       AliFatal("NULL PID response");
131       return kFALSE;
132    }
133
134    // convert input object into AliVTrack
135    // if this fails, the cut cannot be checked
136    AliVTrack *vtrack = fDaughter->Ref2Vtrack();
137    if (!vtrack) {
138       AliDebugClass(2, "Referenced daughter is not a track");
139       return kFALSE;
140    }
141
142    // check matching, if required
143    // a) if detector is not matched and matching is required, reject the track
144    // b) if detector is not matched and matching is not required, accept blindly the track
145    //    since missing the matching causes one not to be able to rely that detector
146    if (!MatchDetector(vtrack)) {
147       AliDebugClass(2, Form("Detector not matched. fRejectUnmatched = %s --> track is %s", (fRejectUnmatched ? "true" : "false"), (fRejectUnmatched ? "rejected" : "accepted")));
148       return (!fRejectUnmatched);
149    }
150
151    // get reference momentum
152    fTrackMom = (fDetector == kTPC) ? vtrack->GetTPCmomentum() : vtrack->P();
153
154    // get number of sigmas
155    switch (fDetector) {
156       case kITS:
157          fTrackNSigma = TMath::Abs(pid->NumberOfSigmasITS(vtrack, fSpecies));
158          break;
159       case kTPC:
160          fTrackNSigma = TMath::Abs(pid->NumberOfSigmasTPC(vtrack, fSpecies));
161          break;
162       case kTOF:
163          fTrackNSigma = TMath::Abs(pid->NumberOfSigmasTOF(vtrack, fSpecies));
164          break;
165       default:
166          AliError("Bad detector chosen. Rejecting track");
167          return kFALSE;
168    }
169
170    // loop on all ranges, and use the one which contains this momentum
171    // if none is found, the cut is not passed
172    Bool_t accept = kFALSE;
173    Int_t  i, goodRange = -1, nRanges = fRanges.GetEntriesFast();
174    for (i = 0; i < nRanges; i++) {
175       AliRsnPIDRange *range = (AliRsnPIDRange *)fRanges[i];
176       if (!range) continue;
177       if (!range->IsInRange(fTrackMom)) continue;
178       else {
179          goodRange = i;
180          accept = range->CutPass(fTrackNSigma);
181          AliDebugClass(2, Form("[%s] NSigma = %.3f, max = %.3f, track %s", GetName(), fTrackNSigma, range->NSigmaCut(), (accept ? "accepted" : "rejected")));
182          break;
183       }
184    }
185    if (goodRange < 0) {
186       AliDebugClass(2, Form("[%s] No good range found. Rejecting track", GetName()));
187       return kFALSE;
188    } else {
189       AliDebugClass(2, Form("[%s] Mom = %.3f, good range found (#%d), track was %s", GetName(), fTrackMom, goodRange, (accept ? "accepted" : "rejected")));
190       return accept;
191    }
192 }
193
194 //_________________________________________________________________________________________________
195 void AliRsnCutPIDNSigma::Print(const Option_t *) const
196 {
197 //
198 // Print information on this cut
199 //
200
201    Char_t mom[200], det[100], match[200];
202
203    if (fRejectUnmatched)
204       snprintf(match, 200, "Unmatched tracks are rejected");
205    else
206       snprintf(match, 200, "No check on track matching");
207
208    switch (fDetector) {
209       case kITS: snprintf(det, 3, "ITS"); break;
210       case kTPC: snprintf(det, 3, "TPC"); break;
211       case kTOF: snprintf(det, 3, "TOF"); break;
212       default  : snprintf(det, 3, "undefined");
213    }
214
215    AliInfo(Form("Cut name          : %s", GetName()));
216    AliInfo(Form("--> PID detector  : %s", det));
217    AliInfo(Form("--> match criteria: %s", match));
218    AliInfo(Form("--> momentum range: %s", mom));
219 }