1 /**************************************************************************
2 * Copyright(c) 1998-2010, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 /////////////////////////////////////////////////////////////
20 // Class for cuts on AOD reconstructed Lc->p+K0s
22 // Modified by Y.S Watanabe - wyosuke@cns.s.u-tokyo.ac.jp
24 /////////////////////////////////////////////////////////////
26 #include <Riostream.h>
28 #include <TDatabasePDG.h>
31 #include "AliAnalysisManager.h"
32 #include "AliInputEventHandler.h"
33 #include "AliPIDResponse.h"
34 #include "AliRDHFCutsLctopK0sfromAODtracks.h"
35 #include "AliAODRecoCascadeHF.h"
36 #include "AliAODTrack.h"
37 #include "AliESDtrack.h"
38 #include "AliESDVertex.h"
39 #include "AliAODVertex.h"
41 #include "AliAODcascade.h"
47 ClassImp(AliRDHFCutsLctopK0sfromAODtracks)
49 //--------------------------------------------------------------------------
50 AliRDHFCutsLctopK0sfromAODtracks::AliRDHFCutsLctopK0sfromAODtracks(const char* name) :
52 fPIDStrategy(kNSigmaCuts),
53 fCombinedPIDThreshold(0.),
54 fUseOnTheFlyV0(kFALSE),
56 fProdTrackEtaRange(0.8),
57 fProdUseAODFilterBit(kTRUE),
58 fProdV0MassTolK0s(0.01),
60 fProdV0CosPointingAngleToPrimVtxMin(0.99),
61 fProdV0DcaDaughtersMax(1.5),
62 fProdV0DaughterEtaRange(0.8),
63 fProdV0DaughterPtMin(0.0),
64 fProdV0DaughterTPCClusterMin(70),
65 fProdRoughMassTol(0.25),
72 // Default Constructor
77 TString varNames[nvars]={"Lc inv. mass [GeV/c2]", // 0
79 "Bachelor pT [GeV/c]", //2
80 "Bachelor d0 [cm]", //3
82 "K0s mass [GeV/c2]", //5
83 "Decay Length XY [cm]" //6
86 Bool_t isUpperCut[nvars]={kTRUE, // 0
94 SetVarNames(nvars,varNames,isUpperCut);
95 Bool_t forOpt[nvars]={kFALSE, // 0
103 SetVarsForOpt(nvars,forOpt);
105 Float_t limits[2]={0,999999999.};
108 //--------------------------------------------------------------------------
109 AliRDHFCutsLctopK0sfromAODtracks::AliRDHFCutsLctopK0sfromAODtracks(const AliRDHFCutsLctopK0sfromAODtracks &source) :
111 fPIDStrategy(source.fPIDStrategy),
112 fCombinedPIDThreshold(source.fCombinedPIDThreshold),
113 fUseOnTheFlyV0(source.fUseOnTheFlyV0),
114 fProdTrackPtMin(source.fProdTrackPtMin),
115 fProdTrackEtaRange(source.fProdTrackEtaRange),
116 fProdUseAODFilterBit(source.fProdUseAODFilterBit),
117 fProdV0MassTolK0s(source.fProdV0MassTolK0s),
118 fProdV0PtMin(source.fProdV0PtMin),
119 fProdV0CosPointingAngleToPrimVtxMin(source.fProdV0CosPointingAngleToPrimVtxMin),
120 fProdV0DcaDaughtersMax(source.fProdV0DcaDaughtersMax),
121 fProdV0DaughterEtaRange(source.fProdV0DaughterEtaRange),
122 fProdV0DaughterPtMin(source.fProdV0DaughterPtMin),
123 fProdV0DaughterTPCClusterMin(source.fProdV0DaughterTPCClusterMin),
124 fProdRoughMassTol(source.fProdRoughMassTol),
125 fProdRoughPtMin(source.fProdRoughPtMin),
126 fnCuts(source.fnCuts),
127 fnTotalCutBins(source.fnTotalCutBins),
133 if(source.fCutsArray) SetCutsArray(source.fnTotalCutBins,source.fCutsArray);
135 //--------------------------------------------------------------------------
136 AliRDHFCutsLctopK0sfromAODtracks &AliRDHFCutsLctopK0sfromAODtracks::operator=(const AliRDHFCutsLctopK0sfromAODtracks &source)
139 // assignment operator
142 if (this != &source) {
143 AliRDHFCuts::operator=(source);
146 fPIDStrategy = source.fPIDStrategy;
147 fCombinedPIDThreshold = source.fCombinedPIDThreshold;
148 fUseOnTheFlyV0 = source.fUseOnTheFlyV0;
149 fProdTrackPtMin = source.fProdTrackPtMin;
150 fProdTrackEtaRange = source.fProdTrackEtaRange;
151 fProdUseAODFilterBit = source.fProdUseAODFilterBit;
152 fProdV0MassTolK0s = source.fProdV0MassTolK0s;
153 fProdV0PtMin = source.fProdV0PtMin;
154 fProdV0CosPointingAngleToPrimVtxMin = source.fProdV0CosPointingAngleToPrimVtxMin;
155 fProdV0DcaDaughtersMax=source.fProdV0DcaDaughtersMax;
156 fProdV0DaughterEtaRange=source.fProdV0DaughterEtaRange;
157 fProdV0DaughterPtMin=source.fProdV0DaughterPtMin;
158 fProdV0DaughterTPCClusterMin=source.fProdV0DaughterTPCClusterMin;
159 fProdRoughMassTol = source.fProdRoughMassTol;
160 fProdRoughPtMin = source.fProdRoughPtMin;
162 if(source.fnCuts) fnCuts = source.fnCuts;
163 if(source.fnTotalCutBins) fnTotalCutBins = source.fnCuts;
164 if(source.fCutsArray) SetCutsArray(source.fnTotalCutBins,source.fCutsArray);
169 //---------------------------------------------------------------------------
170 AliRDHFCutsLctopK0sfromAODtracks::~AliRDHFCutsLctopK0sfromAODtracks() {
172 // Default Destructor
175 if(fCutsArray) delete[] fCutsArray;
178 //---------------------------------------------------------------------------
179 void AliRDHFCutsLctopK0sfromAODtracks::GetCutVarsForOpt(AliAODRecoDecayHF *d,Float_t *vars,Int_t nvars,Int_t *pdgdaughters) {
181 // Fills in vars the values of the variables
184 if (pdgdaughters[0]==-9999) return; // dummy
186 AliAODRecoCascadeHF* dd=(AliAODRecoCascadeHF*)d;
188 AliError("No AliAODRecoCascadeHF object found\n");
192 if (nvars!=fnVarsForOpt) {
193 AliError("Cut object seems to have the wrong number of variables\n");
197 //Double_t ptD=d->Pt();
198 //Int_t ptbin=PtBin(ptD);
203 Double_t mlcPDG = TDatabasePDG::Instance()->GetParticle(4122)->Mass();
204 vars[iter]= TMath::Abs(dd->InvMassLctoK0sP()-mlcPDG) ;
208 vars[iter]= dd->Pt();
212 AliAODTrack *part = dd->GetBachelor();
213 vars[iter]= part->Pt();
217 vars[iter]= dd->Getd0Prong(0);
221 vars[iter]= dd->Getd0Prong(1);
225 AliAODv0 *v0 = dd->Getv0();
226 vars[iter]= v0->MassK0Short();
230 vars[iter]= dd->DecayLengthXY();
236 //---------------------------------------------------------------------------
237 Int_t AliRDHFCutsLctopK0sfromAODtracks::IsSelected(TObject* obj, Int_t selectionLevel) {
243 AliFatal("Cut matrix not inizialized. Exit...");
247 AliAODRecoCascadeHF* d=(AliAODRecoCascadeHF*)obj;
249 AliDebug(2,"AliAODRecoCascadeHF null");
253 Double_t ptD=d->Pt();
254 if(ptD<fMinPtCand) return 0;
255 if(ptD>fMaxPtCand) return 0;
257 if (selectionLevel==AliRDHFCuts::kAll ||
258 selectionLevel==AliRDHFCuts::kTracks) {
259 //Performed in production stage
262 Int_t returnvalueCuts=1;
263 // selection on candidate
264 if (selectionLevel==AliRDHFCuts::kAll ||
265 selectionLevel==AliRDHFCuts::kCandidate) {
268 Int_t ptbin=PtBin(pt);
274 Double_t mlcPDG = TDatabasePDG::Instance()->GetParticle(4122)->Mass();
275 Double_t mk0sPDG = TDatabasePDG::Instance()->GetParticle(310)->Mass();
276 AliAODTrack *part = d->GetBachelor();
277 AliAODv0 *v0 = d->Getv0();
279 if(TMath::Abs(d->InvMassLctoK0sP()-mlcPDG) > fCutsRD[GetGlobalIndex(0,ptbin)])
283 if(d->Pt() < fCutsRD[GetGlobalIndex(1,ptbin)])
287 if(part->Pt() < fCutsRD[GetGlobalIndex(2,ptbin)])
291 if(TMath::Abs(d->Getd0Prong(0)) > fCutsRD[GetGlobalIndex(3,ptbin)])
295 if(TMath::Abs(d->Getd0Prong(1)) > fCutsRD[GetGlobalIndex(4,ptbin)])
299 if(TMath::Abs(v0->MassK0Short()-mk0sPDG) > fCutsRD[GetGlobalIndex(5,ptbin)])
303 if(d->DecayLengthXY() < fCutsRD[GetGlobalIndex(6,ptbin)])
308 if(!okcand) return 0;
312 Int_t returnvaluePID=1;
313 if(selectionLevel==AliRDHFCuts::kAll ||
314 selectionLevel==AliRDHFCuts::kCandidate||
315 selectionLevel==AliRDHFCuts::kPID) {
317 switch(fPIDStrategy){
319 returnvaluePID = IsSelectedPID(d);
322 returnvaluePID = IsSelectedCombinedPID(d);
327 Int_t returnvalue = 0;
328 if(returnvalueCuts==1 && returnvaluePID==1) returnvalue=1;
333 //---------------------------------------------------------------------------
334 Int_t AliRDHFCutsLctopK0sfromAODtracks::IsSelectedPID(AliAODRecoDecayHF* obj)
340 if(!fUsePID || !obj) return 1;
342 AliAODRecoCascadeHF* dd=(AliAODRecoCascadeHF*)obj;
343 AliAODTrack *part = dd->GetBachelor();
347 if(fPidHF->GetPidResponse()==0x0){
348 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
349 AliInputEventHandler *inputHandler=(AliInputEventHandler*)mgr->GetInputEventHandler();
350 AliPIDResponse *pidResp=inputHandler->GetPIDResponse();
351 fPidHF->SetPidResponse(pidResp);
354 Int_t isProton=fPidHF->MakeRawPid(part,4);
355 if(isProton<1) returnvalue = 0;
360 //---------------------------------------------------------------------------
361 Int_t AliRDHFCutsLctopK0sfromAODtracks::IsSelectedCombinedPID(AliAODRecoDecayHF* obj) {
363 // IsSelectedCombinedPID
366 if(!fUsePID || !obj) {return 1;}
368 AliAODRecoCascadeHF* dd=(AliAODRecoCascadeHF*)obj;
369 AliAODTrack *part = dd->GetBachelor();
373 Double_t probProton = GetProtonProbabilityTPCTOF(part);
374 if(probProton<fCombinedPIDThreshold) returnvalue = 0;
379 //________________________________________________________________________
380 Double_t AliRDHFCutsLctopK0sfromAODtracks::GetProtonProbabilityTPCTOF(AliAODTrack* trk)
383 // Get Proton probability
385 fPidHF->GetPidCombined()->SetDetectorMask(AliPIDResponse::kDetTPC+AliPIDResponse::kDetTOF);
386 Double_t prob1[AliPID::kSPECIES];
387 UInt_t detUsed1 = fPidHF->GetPidCombined()->ComputeProbabilities(trk, fPidHF->GetPidResponse(), prob1);
388 if (detUsed1 != (UInt_t)fPidHF->GetPidCombined()->GetDetectorMask() )
390 fPidHF->GetPidCombined()->SetDetectorMask(AliPIDResponse::kDetTPC);
391 detUsed1 = fPidHF->GetPidCombined()->ComputeProbabilities(trk, fPidHF->GetPidResponse(), prob1);
393 return prob1[AliPID::kProton];
396 //________________________________________________________________________
397 Bool_t AliRDHFCutsLctopK0sfromAODtracks::SingleTrkCuts(AliAODTrack *trk)
400 // Single Track Cut to be applied before object creation
403 if(trk->GetStatus()&AliESDtrack::kITSpureSA) return kFALSE;
404 if(!(trk->GetStatus()&AliESDtrack::kITSin)) return kFALSE;
405 if(fProdUseAODFilterBit && !trk->TestFilterMask(BIT(4))) return kFALSE;
406 if(fabs(trk->Eta())>fProdTrackEtaRange) return kFALSE;
407 if(trk->Pt()<fProdTrackPtMin) return kFALSE;
411 if(fPidHF->GetPidResponse()==0x0){
412 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
413 AliInputEventHandler *inputHandler=(AliInputEventHandler*)mgr->GetInputEventHandler();
414 AliPIDResponse *pidResp=inputHandler->GetPIDResponse();
415 fPidHF->SetPidResponse(pidResp);
418 Int_t isProton=fPidHF->MakeRawPid(trk,4);
419 if(isProton<1) return kFALSE;
425 //________________________________________________________________________
426 Bool_t AliRDHFCutsLctopK0sfromAODtracks::SingleV0Cuts(AliAODv0 *v0, AliAODVertex *primVert)
429 // Single V0 Cut to be applied before object creation
432 Bool_t onFlyV0 = v0->GetOnFlyStatus(); // on-the-flight V0s
433 if ( onFlyV0 && !fUseOnTheFlyV0 ) return kFALSE;
435 AliAODTrack *cptrack = (AliAODTrack*)(v0->GetDaughter(0));
436 AliAODTrack *cntrack = (AliAODTrack*)(v0->GetDaughter(1));
437 if(!cptrack || !cntrack) return kFALSE;
438 if ( cptrack->Charge() == cntrack->Charge() ) return kFALSE;
439 if(!(cptrack->GetStatus() & AliESDtrack::kTPCrefit) ||
440 !(cntrack->GetStatus() & AliESDtrack::kTPCrefit)) return kFALSE;
441 AliAODVertex *maybeKinkPos = (AliAODVertex*)cptrack->GetProdVertex();
442 AliAODVertex *maybeKinkNeg = (AliAODVertex*)cntrack->GetProdVertex();
443 if (maybeKinkPos->GetType()==AliAODVertex::kKink || maybeKinkNeg->GetType()==AliAODVertex::kKink)
446 if ( ( ( cptrack->GetTPCClusterInfo(2,1) ) < (Float_t)fProdV0DaughterTPCClusterMin ) ||
447 ( ( cntrack->GetTPCClusterInfo(2,1) ) < (Float_t)fProdV0DaughterTPCClusterMin) ) return kFALSE;
449 Double_t massK0S = v0->MassK0Short();
450 Double_t mk0sPDG = TDatabasePDG::Instance()->GetParticle(310)->Mass();
451 if(fabs(massK0S-mk0sPDG)>fProdV0MassTolK0s) return kFALSE;
454 if(TMath::Abs(v0->DcaV0Daughters())>fProdV0DcaDaughtersMax) return kFALSE;
455 Double_t posVtx[3] = {0.,0.,0.};
456 primVert->GetXYZ(posVtx);
457 Double_t cospav0 = v0->CosPointingAngle(posVtx);
458 if(cospav0<fProdV0CosPointingAngleToPrimVtxMin) return kFALSE;
459 if(v0->Pt()<fProdV0PtMin) return kFALSE;
460 if(fabs(cptrack->Eta())>fProdV0DaughterEtaRange) return kFALSE;
461 if(fabs(cntrack->Eta())>fProdV0DaughterEtaRange) return kFALSE;
462 if(cptrack->Pt()<fProdV0DaughterPtMin) return kFALSE;
463 if(cntrack->Pt()<fProdV0DaughterPtMin) return kFALSE;
468 //________________________________________________________________________
469 Bool_t AliRDHFCutsLctopK0sfromAODtracks::SelectWithRoughCuts(AliAODv0 *v0, AliAODTrack *part)
472 // Mass and pT Cut to be applied before object creation
475 Double_t mprPDG = TDatabasePDG::Instance()->GetParticle(2212)->Mass();
476 Double_t mLcPDG = TDatabasePDG::Instance()->GetParticle(4122)->Mass();
478 Double_t pxpr_init = part->Px();
479 Double_t pypr_init = part->Py();
480 Double_t pzpr_init = part->Pz();
481 Double_t Epr_init = sqrt(pxpr_init*pxpr_init+pypr_init*pypr_init+pzpr_init*pzpr_init+mprPDG*mprPDG);
483 Double_t pxv0_init = v0->Px();
484 Double_t pyv0_init = v0->Py();
485 Double_t pzv0_init = v0->Pz();
486 Double_t massv0_init = v0->MassK0Short();
487 Double_t Ev0_init = sqrt(pxv0_init*pxv0_init+pyv0_init*pyv0_init+pzv0_init*pzv0_init+massv0_init*massv0_init);
489 Double_t pxlc_init = pxpr_init+pxv0_init;
490 Double_t pylc_init = pypr_init+pyv0_init;
491 Double_t pzlc_init = pzpr_init+pzv0_init;
492 Double_t Elc_init = Epr_init+Ev0_init;
493 Double_t lcmass_init = sqrt(Elc_init*Elc_init-pxlc_init*pxlc_init-pylc_init*pylc_init-pzlc_init*pzlc_init);
495 if(lcmass_init<mLcPDG-fProdRoughMassTol || lcmass_init>mLcPDG+fProdRoughMassTol) return kFALSE;
496 if(sqrt(pxlc_init*pxlc_init+pylc_init*pylc_init)<fProdRoughPtMin) return kFALSE;
501 //________________________________________________________________________
502 void AliRDHFCutsLctopK0sfromAODtracks::SetCutsArray(Int_t nCuts, Int_t nVars, Int_t nPtBins, Float_t ***cutsArray)
508 AliError(" wrong number of variables\n");
512 AliError(" wrong number of cuts\n");
515 if (nPtBins!=fnPtBins) {
516 AliError(" wrong number of pT bin\n");
522 fnTotalCutBins = nCuts * nVars * nPtBins;
523 fCutsArray = new Float_t[fnTotalCutBins];
526 for(Int_t icuts=0;icuts<nCuts;icuts++){
527 for(Int_t iv=0;iv<nVars;iv++){
528 for(Int_t ip=0;ip<nPtBins;ip++){
529 Int_t gid = GetCutArrayID(icuts,iv,ip);
530 fCutsArray[gid] = cutsArray[icuts][iv][ip];
537 //________________________________________________________________________
538 void AliRDHFCutsLctopK0sfromAODtracks::SetCutsArray(Int_t nTotBins, Float_t *cutsArray)
544 if (nTotBins!=fnVars*fnPtBins*fnCuts) {
545 AliError(" wrong number of variables\n");
551 fnTotalCutBins = fnCuts * fnVars * fnPtBins;
552 fCutsArray = new Float_t[fnTotalCutBins];
555 for(Int_t i=0;i<nTotBins;i++){
556 fCutsArray[i] = cutsArray[i];
562 //________________________________________________________________________
563 void AliRDHFCutsLctopK0sfromAODtracks::SetCutsFromArray(Int_t iCuts)
566 // Read Cuts from fCutsArray and update fCutsRD
569 cutsarray=new Float_t*[fnVars];
570 for(Int_t ic=0;ic<fnVars;ic++){cutsarray[ic]=new Float_t[fnPtBins];}
572 for(Int_t i=0;i<fnVars;i++){
573 for(Int_t j=0;j<fnPtBins;j++){
574 Int_t gid = GetCutArrayID(iCuts,i,j);
575 cutsarray[i][j] = fCutsArray[gid];
578 SetCuts(fnVars,fnPtBins,cutsarray);
580 for(Int_t ic=0;ic<fnVars;ic++){
581 delete[] cutsarray[ic];
586 //________________________________________________________________________
587 Int_t AliRDHFCutsLctopK0sfromAODtracks::GetCutArrayID(Int_t ic, Int_t iv, Int_t ip)
590 // Global index of fCutsArray
592 return ic*fnVars*fnPtBins+iv*fnPtBins+ip;