ROOT logo
//
// Class AliRsnCutPID
//
// General implementation of a single cut strategy, which can be:
// - a value contained in a given interval  [--> IsBetween()   ]
// - a value equal to a given reference     [--> MatchesValue()]
//
// In all cases, the reference value(s) is (are) given as data members
// and each kind of cut requires a given value type (Int, UInt, Double),
// but the cut check procedure is then automatized and chosen thanks to
// an enumeration of the implemented cut types.
// At the end, the user (or any other point which uses this object) has
// to use the method IsSelected() to check if this cut has been passed.
//
// authors: Martin Vala (martin.vala@cern.ch)
//          Alberto Pulvirenti (alberto.pulvirenti@ct.infn.it)
//
#include "TMath.h"

#include "AliExternalTrackParam.h"

#include "AliRsnDaughter.h"
#include "AliRsnCutPID.h"

ClassImp(AliRsnCutPID)

//_________________________________________________________________________________________________
AliRsnCutPID::AliRsnCutPID() :
   AliRsnCut(),
   fPerfect(kFALSE),
   fUseDefault(kTRUE)
{
//
// Default constructor.
// Sets the cut to realistic PID with default weights,
// and defines the 'fMinI' value of the base class as the PID
// to which we want to compare this object.
//

   Int_t i;

   for (i = 0; i < kDetectors; i++) {
      fUseDetector[i] = kFALSE;
      fPtThreshold[i] = 0.0;
      fGoAboveThreshold[i] = kTRUE;
   }

   for (i = 0; i < AliPID::kSPECIES; i++) {
      fWeight[i] = 0.0;
      fPrior[i] = 1.0;
   }

   SetTargetType(AliRsnTarget::kDaughter);
}

//_________________________________________________________________________________________________
AliRsnCutPID::AliRsnCutPID(const char *name, AliPID::EParticleType pid, Double_t probMin, Bool_t perfectPID) :
   AliRsnCut(name, AliRsnCut::kDaughter, (Int_t)pid),
   fPerfect(perfectPID),
   fUseDefault(kTRUE)
{
//
// Default constructor.
// Sets the cut to realistic PID with default weights,
// and defines the 'fMinI' value of the base class as the PID
// to which we want to compare this object.
//

   Int_t i;

   for (i = 0; i < kDetectors; i++) {
      fUseDetector[i] = kFALSE;
      fPtThreshold[i] = 0.0;
      fGoAboveThreshold[i] = kTRUE;
   }

   for (i = 0; i < AliPID::kSPECIES; i++) {
      fWeight[i] = 0.0;
      fPrior[i] = 1.0;
   }

   fMinD = probMin;
   fMaxD = 1.000001;

   SetTargetType(AliRsnTarget::kDaughter);
}

//_____________________________________________________________________________
Bool_t AliRsnCutPID::CheckThreshold(EDetector det, Double_t value) const
{
//
// Checks if the passed value (track pT) stays in the
// interval where the detector should be accepted
//

   if (!CheckBounds(det)) return kFALSE;

   if (fGoAboveThreshold[det]) return (value >= fPtThreshold[det]);
   else return (value <= fPtThreshold[det]);
}

//_________________________________________________________________________________________________
Bool_t AliRsnCutPID::ComputeWeights(AliRsnDaughter *daughter)
{
//
// Compute the PID weights using the class settings.
// If the argument is an ESD track, customized weights can be computed
// It the argument is a track (ESD or AOD), at least default weights
// can be computed, otherwise, no weights can be defined.
// The return value tells if the operation was successful.
//

   Int_t  i, j;
   Bool_t useDefault = fUseDefault;
   Bool_t perfectPID = fPerfect;
   if (perfectPID && !daughter->GetRefMC()) return kFALSE;
   if (!daughter->Ref2ESDtrack()) useDefault = kTRUE;
   if (!daughter->Ref2ESDtrack() && !daughter->Ref2AODtrack()) return kFALSE;

   // if perfect PID ise required,
   // compare the PDG code of the type stored in 'fMinI' of the cut
   // and that of the particle which is checked, looking at its MC
   if (perfectPID) {
      i = TMath::Abs(AliPID::ParticleCode(fMinI));
      j = daughter->GetPDG();
      return (i == j);
   }

   // if default weights are (or need to be) used,
   // they are taken directly and function exits
   if (useDefault) {
      if (daughter->Ref2ESDtrack())
         daughter->Ref2ESDtrack()->GetESDpid(fWeight);
      else {
         for (i = 0; i < AliPID::kSPECIES; i++)
            fWeight[i] = daughter->Ref2AODtrack()->PID()[i];
      }
      return kTRUE;
   }

   // if we arrive here, this means that we have an ESD track
   // and we want to customize the PID
   AliESDtrack *track = daughter->Ref2ESDtrack();
   Double_t     w[kDetectors][AliPID::kSPECIES];
   track->GetITSpid(w[kITS]);
   track->GetTPCpid(w[kTPC]);
   track->GetTRDpid(w[kTRD]);
   track->GetTOFpid(w[kTOF]);
   track->GetHMPIDpid(w[kHMPID]);

   // if a detector is excluded or the track has not the right pT
   // all related weights are set to 1 in order not to contribute
   // to final multiplication
   for (i = 0; i < kDetectors; i++) {
      if (!fUseDetector[i] || !CheckThreshold((EDetector)i, track->Pt())) {
         for (j = 0; j < AliPID::kSPECIES; j++) {
            w[i][j] = 1.0;
         }
      }
   }

   // multiplicate all weights to compute final one
   for (i = 0; i < AliPID::kSPECIES; i++) {
      fWeight[i] = w[kITS][i] * w[kTPC][i] * w[kTRD][i] * w[kTOF][i] * w[kHMPID][i];
   }

   return kTRUE;
}

//_________________________________________________________________________________________________
Int_t AliRsnCutPID::RealisticPID(AliRsnDaughter *const daughter, Double_t &prob)
{
//
// Combines the weights collected from chosen detectors with the priors
// and gives the corresponding particle with the largest probability,
// in terms of the AliPID particle type enumeration.
// The argument, passed by reference, gives the corresponding probability,
// since the cut could require that it is larger than a threshold.
//

   // try to compute the weights
   if (!ComputeWeights(daughter)) {
      prob = -1.0;
      return AliPID::kUnknown;
   }

   // combine with priors and normalize
   Int_t    i;
   Double_t sum = 0.0, w[AliPID::kSPECIES];
   for (i = 0; i < AliPID::kSPECIES; i++) {
      w[i] = fWeight[i] * fPrior[i];
      sum += w[i];
   }
   if (sum <= 0.0) {
      AliError("Sum = 0");
      prob = -1.0;
      return AliPID::kUnknown;
   }
   for (i = 0; i < AliPID::kSPECIES; i++) w[i] /= sum;

   // find the largest probability and related PID
   Int_t ibest = 0;
   prob = w[0];
   for (i = 1; i < AliPID::kSPECIES; i++) {
      if (w[i] > prob) {
         prob = w[i];
         ibest = i;
      }
   }

   // return the value, while the probability
   // will be consequentially set
   return ibest;
}

//_________________________________________________________________________________________________
Int_t AliRsnCutPID::PerfectPID(AliRsnDaughter *const daughter)
{
//
// If MC is present, retrieve the particle corresponding to the used track
// (using the fRefMC data member) and then return the true particle type
// taken from the PDG code of the reference particle itself, converted
// into the enumeration from AliPID object.
//

   // works only if the MC is present
   if (!daughter->GetRefMC()) return AliPID::kUnknown;

   // get the PDG code of the particle
   Int_t pdg = daughter->GetPDG();

   // loop over all species listed in AliPID to find the match
   Int_t i;
   for (i = 0; i < AliPID::kSPECIES; i++) {
      if (AliPID::ParticleCode(i) == TMath::Abs(pdg)) return i;
   }

   return AliPID::kUnknown;
}

//_________________________________________________________________________________________________
Bool_t AliRsnCutPID::IsSelected(TObject *object)
{
//
// Cut checker.
//

   // convert the object into the unique correct type

   if (!TargetOK(object)) {
      AliError(Form("[%s]: this cut works only with AliRsnDaughter objects", GetName()));
      return kTRUE;
   }

   // if target is OK, do a dynamic cast
   AliRsnDaughter *daughter = fDaughter;

   // depending on the PID type, recalls the appropriate method:
   // in case of perfect PID, checks only if the PID type is
   // corresponding to the request in the cut (fMinI)
   // while in case of realistic PID checks also the probability
   // to be within the required interval
   if (fPerfect && daughter) {
      fCutValueI = PerfectPID(daughter);
      return OkValueI();
   } else if (daughter) {
      fCutValueI = RealisticPID(daughter, fCutValueD);
      return OkValueI() && OkRangeD();
   } else
      return kFALSE;
}

//__________________________________________________________________________________________________
void AliRsnCutPID::IncludeDetector(EDetector det, Double_t threshold, Bool_t goAbove)
{
//
// Include a detector for a customized weight computing
// and specify also its eventual threshold and if the detector
// must be used above or below the threshold.
// By default the threshold is zero and detector is always used.
//

   if (!CheckBounds(det)) return;

   fUseDetector[det] = kTRUE;
   fPtThreshold[det] = threshold;
   fGoAboveThreshold[det] = goAbove;
}
 AliRsnCutPID.cxx:1
 AliRsnCutPID.cxx:2
 AliRsnCutPID.cxx:3
 AliRsnCutPID.cxx:4
 AliRsnCutPID.cxx:5
 AliRsnCutPID.cxx:6
 AliRsnCutPID.cxx:7
 AliRsnCutPID.cxx:8
 AliRsnCutPID.cxx:9
 AliRsnCutPID.cxx:10
 AliRsnCutPID.cxx:11
 AliRsnCutPID.cxx:12
 AliRsnCutPID.cxx:13
 AliRsnCutPID.cxx:14
 AliRsnCutPID.cxx:15
 AliRsnCutPID.cxx:16
 AliRsnCutPID.cxx:17
 AliRsnCutPID.cxx:18
 AliRsnCutPID.cxx:19
 AliRsnCutPID.cxx:20
 AliRsnCutPID.cxx:21
 AliRsnCutPID.cxx:22
 AliRsnCutPID.cxx:23
 AliRsnCutPID.cxx:24
 AliRsnCutPID.cxx:25
 AliRsnCutPID.cxx:26
 AliRsnCutPID.cxx:27
 AliRsnCutPID.cxx:28
 AliRsnCutPID.cxx:29
 AliRsnCutPID.cxx:30
 AliRsnCutPID.cxx:31
 AliRsnCutPID.cxx:32
 AliRsnCutPID.cxx:33
 AliRsnCutPID.cxx:34
 AliRsnCutPID.cxx:35
 AliRsnCutPID.cxx:36
 AliRsnCutPID.cxx:37
 AliRsnCutPID.cxx:38
 AliRsnCutPID.cxx:39
 AliRsnCutPID.cxx:40
 AliRsnCutPID.cxx:41
 AliRsnCutPID.cxx:42
 AliRsnCutPID.cxx:43
 AliRsnCutPID.cxx:44
 AliRsnCutPID.cxx:45
 AliRsnCutPID.cxx:46
 AliRsnCutPID.cxx:47
 AliRsnCutPID.cxx:48
 AliRsnCutPID.cxx:49
 AliRsnCutPID.cxx:50
 AliRsnCutPID.cxx:51
 AliRsnCutPID.cxx:52
 AliRsnCutPID.cxx:53
 AliRsnCutPID.cxx:54
 AliRsnCutPID.cxx:55
 AliRsnCutPID.cxx:56
 AliRsnCutPID.cxx:57
 AliRsnCutPID.cxx:58
 AliRsnCutPID.cxx:59
 AliRsnCutPID.cxx:60
 AliRsnCutPID.cxx:61
 AliRsnCutPID.cxx:62
 AliRsnCutPID.cxx:63
 AliRsnCutPID.cxx:64
 AliRsnCutPID.cxx:65
 AliRsnCutPID.cxx:66
 AliRsnCutPID.cxx:67
 AliRsnCutPID.cxx:68
 AliRsnCutPID.cxx:69
 AliRsnCutPID.cxx:70
 AliRsnCutPID.cxx:71
 AliRsnCutPID.cxx:72
 AliRsnCutPID.cxx:73
 AliRsnCutPID.cxx:74
 AliRsnCutPID.cxx:75
 AliRsnCutPID.cxx:76
 AliRsnCutPID.cxx:77
 AliRsnCutPID.cxx:78
 AliRsnCutPID.cxx:79
 AliRsnCutPID.cxx:80
 AliRsnCutPID.cxx:81
 AliRsnCutPID.cxx:82
 AliRsnCutPID.cxx:83
 AliRsnCutPID.cxx:84
 AliRsnCutPID.cxx:85
 AliRsnCutPID.cxx:86
 AliRsnCutPID.cxx:87
 AliRsnCutPID.cxx:88
 AliRsnCutPID.cxx:89
 AliRsnCutPID.cxx:90
 AliRsnCutPID.cxx:91
 AliRsnCutPID.cxx:92
 AliRsnCutPID.cxx:93
 AliRsnCutPID.cxx:94
 AliRsnCutPID.cxx:95
 AliRsnCutPID.cxx:96
 AliRsnCutPID.cxx:97
 AliRsnCutPID.cxx:98
 AliRsnCutPID.cxx:99
 AliRsnCutPID.cxx:100
 AliRsnCutPID.cxx:101
 AliRsnCutPID.cxx:102
 AliRsnCutPID.cxx:103
 AliRsnCutPID.cxx:104
 AliRsnCutPID.cxx:105
 AliRsnCutPID.cxx:106
 AliRsnCutPID.cxx:107
 AliRsnCutPID.cxx:108
 AliRsnCutPID.cxx:109
 AliRsnCutPID.cxx:110
 AliRsnCutPID.cxx:111
 AliRsnCutPID.cxx:112
 AliRsnCutPID.cxx:113
 AliRsnCutPID.cxx:114
 AliRsnCutPID.cxx:115
 AliRsnCutPID.cxx:116
 AliRsnCutPID.cxx:117
 AliRsnCutPID.cxx:118
 AliRsnCutPID.cxx:119
 AliRsnCutPID.cxx:120
 AliRsnCutPID.cxx:121
 AliRsnCutPID.cxx:122
 AliRsnCutPID.cxx:123
 AliRsnCutPID.cxx:124
 AliRsnCutPID.cxx:125
 AliRsnCutPID.cxx:126
 AliRsnCutPID.cxx:127
 AliRsnCutPID.cxx:128
 AliRsnCutPID.cxx:129
 AliRsnCutPID.cxx:130
 AliRsnCutPID.cxx:131
 AliRsnCutPID.cxx:132
 AliRsnCutPID.cxx:133
 AliRsnCutPID.cxx:134
 AliRsnCutPID.cxx:135
 AliRsnCutPID.cxx:136
 AliRsnCutPID.cxx:137
 AliRsnCutPID.cxx:138
 AliRsnCutPID.cxx:139
 AliRsnCutPID.cxx:140
 AliRsnCutPID.cxx:141
 AliRsnCutPID.cxx:142
 AliRsnCutPID.cxx:143
 AliRsnCutPID.cxx:144
 AliRsnCutPID.cxx:145
 AliRsnCutPID.cxx:146
 AliRsnCutPID.cxx:147
 AliRsnCutPID.cxx:148
 AliRsnCutPID.cxx:149
 AliRsnCutPID.cxx:150
 AliRsnCutPID.cxx:151
 AliRsnCutPID.cxx:152
 AliRsnCutPID.cxx:153
 AliRsnCutPID.cxx:154
 AliRsnCutPID.cxx:155
 AliRsnCutPID.cxx:156
 AliRsnCutPID.cxx:157
 AliRsnCutPID.cxx:158
 AliRsnCutPID.cxx:159
 AliRsnCutPID.cxx:160
 AliRsnCutPID.cxx:161
 AliRsnCutPID.cxx:162
 AliRsnCutPID.cxx:163
 AliRsnCutPID.cxx:164
 AliRsnCutPID.cxx:165
 AliRsnCutPID.cxx:166
 AliRsnCutPID.cxx:167
 AliRsnCutPID.cxx:168
 AliRsnCutPID.cxx:169
 AliRsnCutPID.cxx:170
 AliRsnCutPID.cxx:171
 AliRsnCutPID.cxx:172
 AliRsnCutPID.cxx:173
 AliRsnCutPID.cxx:174
 AliRsnCutPID.cxx:175
 AliRsnCutPID.cxx:176
 AliRsnCutPID.cxx:177
 AliRsnCutPID.cxx:178
 AliRsnCutPID.cxx:179
 AliRsnCutPID.cxx:180
 AliRsnCutPID.cxx:181
 AliRsnCutPID.cxx:182
 AliRsnCutPID.cxx:183
 AliRsnCutPID.cxx:184
 AliRsnCutPID.cxx:185
 AliRsnCutPID.cxx:186
 AliRsnCutPID.cxx:187
 AliRsnCutPID.cxx:188
 AliRsnCutPID.cxx:189
 AliRsnCutPID.cxx:190
 AliRsnCutPID.cxx:191
 AliRsnCutPID.cxx:192
 AliRsnCutPID.cxx:193
 AliRsnCutPID.cxx:194
 AliRsnCutPID.cxx:195
 AliRsnCutPID.cxx:196
 AliRsnCutPID.cxx:197
 AliRsnCutPID.cxx:198
 AliRsnCutPID.cxx:199
 AliRsnCutPID.cxx:200
 AliRsnCutPID.cxx:201
 AliRsnCutPID.cxx:202
 AliRsnCutPID.cxx:203
 AliRsnCutPID.cxx:204
 AliRsnCutPID.cxx:205
 AliRsnCutPID.cxx:206
 AliRsnCutPID.cxx:207
 AliRsnCutPID.cxx:208
 AliRsnCutPID.cxx:209
 AliRsnCutPID.cxx:210
 AliRsnCutPID.cxx:211
 AliRsnCutPID.cxx:212
 AliRsnCutPID.cxx:213
 AliRsnCutPID.cxx:214
 AliRsnCutPID.cxx:215
 AliRsnCutPID.cxx:216
 AliRsnCutPID.cxx:217
 AliRsnCutPID.cxx:218
 AliRsnCutPID.cxx:219
 AliRsnCutPID.cxx:220
 AliRsnCutPID.cxx:221
 AliRsnCutPID.cxx:222
 AliRsnCutPID.cxx:223
 AliRsnCutPID.cxx:224
 AliRsnCutPID.cxx:225
 AliRsnCutPID.cxx:226
 AliRsnCutPID.cxx:227
 AliRsnCutPID.cxx:228
 AliRsnCutPID.cxx:229
 AliRsnCutPID.cxx:230
 AliRsnCutPID.cxx:231
 AliRsnCutPID.cxx:232
 AliRsnCutPID.cxx:233
 AliRsnCutPID.cxx:234
 AliRsnCutPID.cxx:235
 AliRsnCutPID.cxx:236
 AliRsnCutPID.cxx:237
 AliRsnCutPID.cxx:238
 AliRsnCutPID.cxx:239
 AliRsnCutPID.cxx:240
 AliRsnCutPID.cxx:241
 AliRsnCutPID.cxx:242
 AliRsnCutPID.cxx:243
 AliRsnCutPID.cxx:244
 AliRsnCutPID.cxx:245
 AliRsnCutPID.cxx:246
 AliRsnCutPID.cxx:247
 AliRsnCutPID.cxx:248
 AliRsnCutPID.cxx:249
 AliRsnCutPID.cxx:250
 AliRsnCutPID.cxx:251
 AliRsnCutPID.cxx:252
 AliRsnCutPID.cxx:253
 AliRsnCutPID.cxx:254
 AliRsnCutPID.cxx:255
 AliRsnCutPID.cxx:256
 AliRsnCutPID.cxx:257
 AliRsnCutPID.cxx:258
 AliRsnCutPID.cxx:259
 AliRsnCutPID.cxx:260
 AliRsnCutPID.cxx:261
 AliRsnCutPID.cxx:262
 AliRsnCutPID.cxx:263
 AliRsnCutPID.cxx:264
 AliRsnCutPID.cxx:265
 AliRsnCutPID.cxx:266
 AliRsnCutPID.cxx:267
 AliRsnCutPID.cxx:268
 AliRsnCutPID.cxx:269
 AliRsnCutPID.cxx:270
 AliRsnCutPID.cxx:271
 AliRsnCutPID.cxx:272
 AliRsnCutPID.cxx:273
 AliRsnCutPID.cxx:274
 AliRsnCutPID.cxx:275
 AliRsnCutPID.cxx:276
 AliRsnCutPID.cxx:277
 AliRsnCutPID.cxx:278
 AliRsnCutPID.cxx:279
 AliRsnCutPID.cxx:280
 AliRsnCutPID.cxx:281
 AliRsnCutPID.cxx:282
 AliRsnCutPID.cxx:283
 AliRsnCutPID.cxx:284
 AliRsnCutPID.cxx:285
 AliRsnCutPID.cxx:286
 AliRsnCutPID.cxx:287
 AliRsnCutPID.cxx:288