]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG3/vertexingHF/AliRDHFCutsD0toKpi.cxx
d1b136a32d0dc472662bd4c07a171db78126d5eb
[u/mrichter/AliRoot.git] / PWG3 / vertexingHF / AliRDHFCutsD0toKpi.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2010, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15
16 /* $Id$ */
17
18 /////////////////////////////////////////////////////////////
19 //
20 // Class for cuts on AOD reconstructed D0->Kpi
21 //
22 // Author: A.Dainese, andrea.dainese@pd.infn.it
23 /////////////////////////////////////////////////////////////
24
25 #include <TDatabasePDG.h>
26 #include <Riostream.h>
27
28 #include "AliRDHFCutsD0toKpi.h"
29 #include "AliAODRecoDecayHF2Prong.h"
30 #include "AliAODTrack.h"
31 #include "AliESDtrack.h"
32 #include "AliAODPid.h"
33 #include "AliTPCPIDResponse.h"
34 #include "AliAODVertex.h"
35 #include "AliKFVertex.h"
36 #include "AliKFParticle.h"
37
38 ClassImp(AliRDHFCutsD0toKpi)
39
40 //--------------------------------------------------------------------------
41 AliRDHFCutsD0toKpi::AliRDHFCutsD0toKpi(const char* name) : 
42 AliRDHFCuts(name),
43 fUseSpecialCuts(kFALSE),
44 fLowPt(kTRUE),
45 fDefaultPID(kFALSE),
46 fUseKF(kFALSE),
47 fPtLowPID(2.)
48 {
49   //
50   // Default Constructor
51   //
52   Int_t nvars=11;
53   SetNVars(nvars);
54   TString varNames[11]={"inv. mass [GeV]",   
55                         "dca [cm]",
56                         "cosThetaStar", 
57                         "pTK [GeV/c]",
58                         "pTPi [GeV/c]",
59                         "d0K [cm]",
60                         "d0Pi [cm]",
61                         "d0d0 [cm^2]",
62                         "cosThetaPoint",
63                         "|cosThetaPointXY|", 
64                         "NormDecayLenghtXY"};
65   Bool_t isUpperCut[11]={kTRUE,
66                          kTRUE,
67                          kTRUE,
68                          kFALSE,
69                          kFALSE,
70                          kTRUE,
71                          kTRUE,
72                          kTRUE,
73                          kFALSE,
74                          kFALSE, 
75                          kFALSE};
76   SetVarNames(nvars,varNames,isUpperCut);
77   Bool_t forOpt[11]={kFALSE,
78                      kTRUE,
79                      kTRUE,
80                      kFALSE,
81                      kFALSE,
82                      kFALSE,
83                      kFALSE,
84                      kTRUE,
85                      kTRUE,
86                      kFALSE,
87                      kFALSE};
88   SetVarsForOpt(4,forOpt);
89   Float_t limits[2]={0,999999999.};
90   SetPtBins(2,limits);
91
92 }
93 //--------------------------------------------------------------------------
94 AliRDHFCutsD0toKpi::AliRDHFCutsD0toKpi(const AliRDHFCutsD0toKpi &source) :
95   AliRDHFCuts(source),   
96   fUseSpecialCuts(source.fUseSpecialCuts),
97   fLowPt(source.fLowPt),
98   fDefaultPID(source.fDefaultPID),
99   fUseKF(source.fUseKF),
100   fPtLowPID(source.fPtLowPID)
101 {
102   //
103   // Copy constructor
104   //
105
106 }
107 //--------------------------------------------------------------------------
108 AliRDHFCutsD0toKpi &AliRDHFCutsD0toKpi::operator=(const AliRDHFCutsD0toKpi &source)
109 {
110   //
111   // assignment operator
112   //
113   if(&source == this) return *this;
114
115   AliRDHFCuts::operator=(source); 
116   fUseSpecialCuts=source.fUseSpecialCuts;
117   fLowPt=source.fLowPt;
118   fDefaultPID=source.fDefaultPID;
119   fPtLowPID=source.fPtLowPID;
120
121   return *this;
122 }
123
124
125 //---------------------------------------------------------------------------
126 void AliRDHFCutsD0toKpi::GetCutVarsForOpt(AliAODRecoDecayHF *d,Float_t *vars,Int_t nvars,Int_t *pdgdaughters,AliAODEvent *aod) {
127   // 
128   // Fills in vars the values of the variables 
129   //
130
131   if(nvars!=fnVarsForOpt) {
132     printf("AliRDHFCutsD0toKpi::GetCutsVarsForOpt: wrong number of variables\n");
133     return;
134   }
135
136   AliAODRecoDecayHF2Prong *dd = (AliAODRecoDecayHF2Prong*)d;
137  
138   //recalculate vertex w/o daughters
139   Bool_t cleanvtx=kFALSE;
140   AliAODVertex *origownvtx=0x0;
141   if(fRemoveDaughtersFromPrimary) {
142     if(dd->GetOwnPrimaryVtx()) origownvtx=new AliAODVertex(*dd->GetOwnPrimaryVtx());
143     cleanvtx=kTRUE;
144     if(!RecalcOwnPrimaryVtx(dd,aod)) {
145       CleanOwnPrimaryVtx(dd,aod,origownvtx);
146       cleanvtx=kFALSE;
147     }
148   }
149
150   Int_t iter=-1;
151   if(fVarsForOpt[0]){
152     iter++;
153     if(TMath::Abs(pdgdaughters[0])==211) {
154       vars[iter]=dd->InvMassD0();
155     } else {
156       vars[iter]=dd->InvMassD0bar();
157     }
158   }
159   if(fVarsForOpt[1]){
160     iter++;
161     vars[iter]=dd->GetDCA();
162   }
163   if(fVarsForOpt[2]){
164     iter++;
165     if(TMath::Abs(pdgdaughters[0])==211) {
166       vars[iter] = dd->CosThetaStarD0();
167     } else {
168       vars[iter] = dd->CosThetaStarD0bar();
169     }
170   }
171   if(fVarsForOpt[3]){
172     iter++;
173    if(TMath::Abs(pdgdaughters[0])==321) {
174      vars[iter]=dd->PtProng(0);
175    }
176    else{
177      vars[iter]=dd->PtProng(1);
178    }
179   }
180   if(fVarsForOpt[4]){
181     iter++;
182    if(TMath::Abs(pdgdaughters[0])==211) {
183      vars[iter]=dd->PtProng(0);
184    }
185    else{
186      vars[iter]=dd->PtProng(1);
187    }
188   }
189   if(fVarsForOpt[5]){
190     iter++;
191     if(TMath::Abs(pdgdaughters[0])==321) {
192      vars[iter]=dd->Getd0Prong(0);
193    }
194    else{
195      vars[iter]=dd->Getd0Prong(1);
196    }
197   }
198   if(fVarsForOpt[6]){
199     iter++;
200      if(TMath::Abs(pdgdaughters[0])==211) {
201      vars[iter]=dd->Getd0Prong(0);
202    }
203    else{
204      vars[iter]=dd->Getd0Prong(1);
205    }
206   }
207   if(fVarsForOpt[7]){
208     iter++;
209     vars[iter]= dd->Prodd0d0();
210   }
211   if(fVarsForOpt[8]){
212     iter++;
213     vars[iter]=dd->CosPointingAngle();
214   }
215   
216   if(fVarsForOpt[9]){
217                 iter++;
218                 vars[iter]=TMath::Abs(dd->CosPointingAngleXY());
219         }
220   
221    if(fVarsForOpt[10]){
222                 iter++;
223            vars[iter]=dd->NormalizedDecayLengthXY();
224         }
225
226    if(cleanvtx)CleanOwnPrimaryVtx(dd,aod,origownvtx);
227
228   return;
229 }
230 //---------------------------------------------------------------------------
231 Int_t AliRDHFCutsD0toKpi::IsSelected(TObject* obj,Int_t selectionLevel,AliAODEvent* aod) {
232   //
233   // Apply selection
234   //
235  
236
237   fIsSelectedCuts=0;
238   fIsSelectedPID=0;
239
240   if(!fCutsRD){
241     cout<<"Cut matrice not inizialized. Exit..."<<endl;
242     return 0;
243   }
244   //PrintAll();
245   AliAODRecoDecayHF2Prong* d=(AliAODRecoDecayHF2Prong*)obj;
246
247   if(!d){
248     cout<<"AliAODRecoDecayHF2Prong null"<<endl;
249     return 0;
250   }
251
252   if(fKeepSignalMC) if(IsSignalMC(d,aod,421)) return 3;
253
254   Double_t ptD=d->Pt();
255   if(ptD<fMinPtCand) return 0;
256   if(ptD>fMaxPtCand) return 0;
257
258   if(d->HasBadDaughters()) return 0;
259
260   // returnvalue: 0 not sel, 1 only D0, 2 only D0bar, 3 both
261   Int_t returnvaluePID=3;
262   Int_t returnvalueCuts=3;
263
264   // selection on candidate
265   if(selectionLevel==AliRDHFCuts::kAll || 
266      selectionLevel==AliRDHFCuts::kCandidate) {
267
268     if(!fUseKF) {
269
270       //recalculate vertex w/o daughters
271       AliAODVertex *origownvtx=0x0;
272       if(fRemoveDaughtersFromPrimary && !fUseMCVertex) {
273         if(d->GetOwnPrimaryVtx()) origownvtx=new AliAODVertex(*d->GetOwnPrimaryVtx());
274         if(!RecalcOwnPrimaryVtx(d,aod)) { 
275           CleanOwnPrimaryVtx(d,aod,origownvtx);
276           return 0;
277         }
278       }
279
280       if(fUseMCVertex) {
281         if(d->GetOwnPrimaryVtx()) origownvtx=new AliAODVertex(*d->GetOwnPrimaryVtx());
282         if(!SetMCPrimaryVtx(d,aod)) {
283           CleanOwnPrimaryVtx(d,aod,origownvtx);
284           return 0;
285         }
286       }
287       
288       Double_t pt=d->Pt();
289       
290       Int_t okD0=0,okD0bar=0;
291       
292       Int_t ptbin=PtBin(pt);
293       if (ptbin==-1) {
294         CleanOwnPrimaryVtx(d,aod,origownvtx);
295         return 0;
296       }
297
298       Double_t mD0,mD0bar,ctsD0,ctsD0bar;
299       okD0=1; okD0bar=1;
300       
301       Double_t mD0PDG = TDatabasePDG::Instance()->GetParticle(421)->Mass();
302
303       d->InvMassD0(mD0,mD0bar);
304       if(TMath::Abs(mD0-mD0PDG) > fCutsRD[GetGlobalIndex(0,ptbin)]) okD0 = 0;
305       if(TMath::Abs(mD0bar-mD0PDG) > fCutsRD[GetGlobalIndex(0,ptbin)])  okD0bar = 0;
306       if(!okD0 && !okD0bar)  {CleanOwnPrimaryVtx(d,aod,origownvtx); return 0;}
307
308       if(d->Prodd0d0() > fCutsRD[GetGlobalIndex(7,ptbin)])  {CleanOwnPrimaryVtx(d,aod,origownvtx); return 0;}
309     
310       
311       if(d->Pt2Prong(1) < fCutsRD[GetGlobalIndex(3,ptbin)]*fCutsRD[GetGlobalIndex(3,ptbin)] || d->Pt2Prong(0) < fCutsRD[GetGlobalIndex(4,ptbin)]*fCutsRD[GetGlobalIndex(4,ptbin)]) okD0 = 0;
312       if(d->Pt2Prong(0) < fCutsRD[GetGlobalIndex(3,ptbin)]*fCutsRD[GetGlobalIndex(3,ptbin)] || d->Pt2Prong(1) < fCutsRD[GetGlobalIndex(4,ptbin)]*fCutsRD[GetGlobalIndex(4,ptbin)]) okD0bar = 0;
313       if(!okD0 && !okD0bar) {CleanOwnPrimaryVtx(d,aod,origownvtx); return 0;}
314       
315       
316       if(TMath::Abs(d->Getd0Prong(1)) > fCutsRD[GetGlobalIndex(5,ptbin)] || 
317          TMath::Abs(d->Getd0Prong(0)) > fCutsRD[GetGlobalIndex(6,ptbin)]) okD0 = 0;
318       if(TMath::Abs(d->Getd0Prong(0)) > fCutsRD[GetGlobalIndex(6,ptbin)] ||
319          TMath::Abs(d->Getd0Prong(1)) > fCutsRD[GetGlobalIndex(5,ptbin)]) okD0bar = 0;
320       if(!okD0 && !okD0bar)  {CleanOwnPrimaryVtx(d,aod,origownvtx); return 0;}
321       
322       if(d->GetDCA() > fCutsRD[GetGlobalIndex(1,ptbin)])  {CleanOwnPrimaryVtx(d,aod,origownvtx); return 0;}
323       
324     
325       d->CosThetaStarD0(ctsD0,ctsD0bar);
326       if(TMath::Abs(ctsD0) > fCutsRD[GetGlobalIndex(2,ptbin)]) okD0 = 0; 
327       if(TMath::Abs(ctsD0bar) > fCutsRD[GetGlobalIndex(2,ptbin)]) okD0bar = 0;
328       if(!okD0 && !okD0bar)   {CleanOwnPrimaryVtx(d,aod,origownvtx); return 0;}
329     
330       if(d->CosPointingAngle() < fCutsRD[GetGlobalIndex(8,ptbin)])  {CleanOwnPrimaryVtx(d,aod,origownvtx); return 0;}
331
332       
333       if(TMath::Abs(d->CosPointingAngleXY()) < fCutsRD[GetGlobalIndex(9,ptbin)])  {CleanOwnPrimaryVtx(d,aod,origownvtx); return 0;}
334         
335       Double_t normalDecayLengXY=d->NormalizedDecayLengthXY();
336       if (normalDecayLengXY < fCutsRD[GetGlobalIndex(10, ptbin)]) {CleanOwnPrimaryVtx(d,aod,origownvtx); return 0;}
337       
338       if (returnvalueCuts!=0) {
339         if (okD0) returnvalueCuts=1; //cuts passed as D0
340         if (okD0bar) returnvalueCuts=2; //cuts passed as D0bar
341         if (okD0 && okD0bar) returnvalueCuts=3; //cuts passed as D0 and D0bar
342       }
343
344       // call special cuts
345       Int_t special=1;
346       if(fUseSpecialCuts) special=IsSelectedSpecialCuts(d);
347       if(!special) {CleanOwnPrimaryVtx(d,aod,origownvtx); return 0;}
348
349       // unset recalculated primary vertex when not needed any more
350       CleanOwnPrimaryVtx(d,aod,origownvtx);
351
352     } else {
353       // go to selection with Kalman vertexing, if requested
354       returnvalueCuts = IsSelectedKF(d,aod);
355     }
356
357     fIsSelectedCuts=returnvalueCuts;
358     if(!returnvalueCuts) return 0;
359   }
360
361
362   // selection on PID 
363   if(selectionLevel==AliRDHFCuts::kAll || 
364      selectionLevel==AliRDHFCuts::kCandidate ||
365      selectionLevel==AliRDHFCuts::kPID) {
366     returnvaluePID = IsSelectedPID(d);
367     fIsSelectedPID=returnvaluePID;
368     if(!returnvaluePID) return 0;
369   }
370
371   Int_t returnvalueComb=CombineSelectionLevels(3,returnvalueCuts,returnvaluePID);
372
373   if(!returnvalueComb) return 0;
374
375   // selection on daughter tracks 
376   if(selectionLevel==AliRDHFCuts::kAll || 
377      selectionLevel==AliRDHFCuts::kTracks) {
378     if(!AreDaughtersSelected(d)) return 0;
379   }
380  
381   //  cout<<"Pid = "<<returnvaluePID<<endl;
382   return returnvalueComb;
383 }
384
385 //------------------------------------------------------------------------------------------
386 Int_t AliRDHFCutsD0toKpi::IsSelectedKF(AliAODRecoDecayHF2Prong *d,
387                                        AliAODEvent* aod) const {
388   //
389   // Apply selection using KF-vertexing
390   //
391         
392   AliAODTrack *track0 = (AliAODTrack*)d->GetDaughter(0);
393   AliAODTrack *track1 = (AliAODTrack*)d->GetDaughter(1); 
394    
395   if(!track0 || !track1) {
396     cout<<"one or two D0 daughters missing!"<<endl;
397     return 0;
398   }
399
400   // returnvalue: 0 not sel, 1 only D0, 2 only D0bar, 3 both
401   Int_t returnvalueCuts=3;
402          
403   // candidate selection with AliKF
404   AliKFParticle::SetField(aod->GetMagneticField()); // set the magnetic field
405   
406   Int_t okD0=0,okD0bar=0;
407   okD0=1; okD0bar=1;
408   
409   // convert tracks into AliKFParticles
410   
411   AliKFParticle negPiKF(*track1,-211); // neg pion kandidate
412   AliKFParticle negKKF(*track1,-321); // neg kaon kandidate
413   AliKFParticle posPiKF(*track0,211); // pos pion kandidate
414   AliKFParticle posKKF(*track0,321); // pos kaon kandidate
415   
416   // build D0 candidates
417   
418   AliKFParticle d0c(negKKF,posPiKF); // D0 candidate
419   AliKFParticle ad0c(posKKF,negPiKF); // D0bar candidate
420   
421   // create kf primary vertices
422   
423   AliAODVertex *vtx1 = aod->GetPrimaryVertex();
424   AliKFVertex primVtx(*vtx1); 
425   AliKFVertex aprimVtx(*vtx1);
426   
427   if(primVtx.GetNContributors()<=0) okD0 = 0;
428   if(aprimVtx.GetNContributors()<=0) okD0bar = 0;
429   if(!okD0 && !okD0bar) returnvalueCuts=0;
430         
431   // calculate mass
432         
433   Double_t d0mass = d0c.GetMass();
434   Double_t ad0mass = ad0c.GetMass();
435         
436   // calculate P of D0 and D0bar
437   Double_t d0P = d0c.GetP();
438   Double_t d0Px = d0c.GetPx();
439   Double_t d0Py = d0c.GetPy();
440   Double_t d0Pz = d0c.GetPz();
441   Double_t ad0P = ad0c.GetP(); 
442   Double_t ad0Px = ad0c.GetPx();
443   Double_t ad0Py = ad0c.GetPy();
444   Double_t ad0Pz = ad0c.GetPz();
445   
446   //calculate Pt of D0 and D0bar
447         
448   Double_t pt=d0c.GetPt(); 
449   Double_t apt=ad0c.GetPt();
450         
451   // remove D0 daughters from primary vertices (if used in vertex fit) and add D0-candidates
452   
453   if(track0->GetUsedForPrimVtxFit()) {
454     primVtx -= posPiKF; 
455     aprimVtx -= posKKF;
456   }
457   
458   if(track1->GetUsedForPrimVtxFit()) { 
459     primVtx -= negKKF; 
460     aprimVtx -= negPiKF;
461   }
462   
463   primVtx += d0c;
464   aprimVtx += ad0c;
465   
466   if(primVtx.GetNContributors()<=0) okD0 = 0;
467   if(aprimVtx.GetNContributors()<=0) okD0bar = 0;
468   if(!okD0 && !okD0bar) returnvalueCuts=0;
469   
470   //calculate cut variables
471   
472   // calculate impact params of daughters w.r.t recalculated vertices
473   
474   Double_t impactPi = posPiKF.GetDistanceFromVertexXY(primVtx);
475   Double_t aimpactPi = negPiKF.GetDistanceFromVertexXY(aprimVtx);
476   Double_t impactKa = negKKF.GetDistanceFromVertexXY(primVtx);
477   Double_t aimpactKa = posKKF.GetDistanceFromVertexXY(aprimVtx);
478         
479   // calculate Product of Impact Params
480         
481   Double_t prodParam = impactPi*impactKa;
482   Double_t aprodParam = aimpactPi*aimpactKa;
483         
484   // calculate cosine of pointing angles
485         
486   TVector3 mom(d0c.GetPx(),d0c.GetPy(),d0c.GetPz());
487   TVector3 fline(d0c.GetX()-primVtx.GetX(),
488                  d0c.GetY()-primVtx.GetY(),
489                  d0c.GetZ()-primVtx.GetZ());
490   Double_t pta = mom.Angle(fline);
491   Double_t cosP = TMath::Cos(pta); // cosine of pta for D0 candidate
492   
493   TVector3 amom(ad0c.GetPx(),ad0c.GetPy(),ad0c.GetPz());
494   TVector3 afline(ad0c.GetX()-aprimVtx.GetX(),
495                   ad0c.GetY()-aprimVtx.GetY(),
496                   ad0c.GetZ()-aprimVtx.GetZ());
497   Double_t apta = amom.Angle(afline);
498   Double_t acosP = TMath::Cos(apta); // cosine of pta for D0bar candidate
499   
500   // calculate P of Pions at Decay Position of D0 and D0bar candidates
501   negKKF.TransportToParticle(d0c);
502   posPiKF.TransportToParticle(d0c);
503   posKKF.TransportToParticle(ad0c);
504   negPiKF.TransportToParticle(ad0c);
505   
506   Double_t pxPi =  posPiKF.GetPx();
507   Double_t pyPi =  posPiKF.GetPy();
508   Double_t pzPi =  posPiKF.GetPz();
509   Double_t ptPi =  posPiKF.GetPt();
510   
511   Double_t apxPi =  negPiKF.GetPx();
512   Double_t apyPi =  negPiKF.GetPy();
513   Double_t apzPi =  negPiKF.GetPz();
514   Double_t aptPi =  negPiKF.GetPt();
515   
516   // calculate Pt of Kaons at Decay Position of D0 and D0bar candidates
517   
518   Double_t ptK =  negKKF.GetPt();
519   Double_t aptK =  posKKF.GetPt();
520         
521   //calculate cos(thetastar)
522   Double_t massvtx = TDatabasePDG::Instance()->GetParticle(421)->Mass();
523   Double_t massp[2];
524   massp[0] = TDatabasePDG::Instance()->GetParticle(321)->Mass();
525   massp[1] = TDatabasePDG::Instance()->GetParticle(211)->Mass();
526   Double_t pStar = TMath::Sqrt(TMath::Power(massvtx*massvtx-massp[0]*massp[0]-massp[1]*massp[1],2.)
527                                -4.*massp[0]*massp[0]*massp[1]*massp[1])/(2.*massvtx);
528   
529   // cos(thetastar) for D0 and Pion
530   
531   Double_t d0E = TMath::Sqrt(massvtx*massvtx + d0P*d0P);
532   Double_t beta = d0P/d0E;
533   Double_t gamma = d0E/massvtx;
534   TVector3 momPi(pxPi,pyPi,pzPi);
535   TVector3 momTot(d0Px,d0Py,d0Pz);
536   Double_t q1 = momPi.Dot(momTot)/momTot.Mag();
537   Double_t cts = (q1/gamma-beta*TMath::Sqrt(pStar*pStar+massp[1]*massp[1]))/pStar;      
538         
539   // cos(thetastar) for D0bar and Pion  
540   
541   Double_t ad0E = TMath::Sqrt(massvtx*massvtx + ad0P*ad0P);
542   Double_t abeta = ad0P/ad0E;
543   Double_t agamma = ad0E/massvtx;
544   TVector3 amomPi(apxPi,apyPi,apzPi);
545   TVector3 amomTot(ad0Px,ad0Py,ad0Pz);
546   Double_t aq1 = amomPi.Dot(amomTot)/amomTot.Mag();
547   Double_t acts = (aq1/agamma-abeta*TMath::Sqrt(pStar*pStar+massp[1]*massp[1]))/pStar;  
548   
549   // calculate reduced Chi2 for the full D0 fit
550   d0c.SetProductionVertex(primVtx);
551   ad0c.SetProductionVertex(aprimVtx);
552   negKKF.SetProductionVertex(d0c);
553   posPiKF.SetProductionVertex(d0c);
554   posKKF.SetProductionVertex(ad0c);
555   negPiKF.SetProductionVertex(ad0c);
556   d0c.TransportToProductionVertex();
557   ad0c.TransportToProductionVertex();
558         
559   // calculate the decay length
560   Double_t decayLengthD0 = d0c.GetDecayLength();
561   Double_t adecayLengthD0 = ad0c.GetDecayLength();
562   
563   Double_t chi2D0 = 50.;
564   if(d0c.GetNDF() > 0 && d0c.GetChi2() >= 0) {
565     chi2D0 = d0c.GetChi2()/d0c.GetNDF();
566   }
567   
568   Double_t achi2D0 = 50.;
569   if(ad0c.GetNDF() > 0 && ad0c.GetChi2() >= 0) {
570     achi2D0 = ad0c.GetChi2()/ad0c.GetNDF();
571   }
572         
573   // Get the Pt-bins
574   Int_t ptbin=PtBin(pt);
575   Int_t aptbin=PtBin(apt);
576
577   if(ptbin < 0) okD0 = 0;
578   if(aptbin < 0) okD0bar = 0;
579   if(!okD0 && !okD0bar) returnvalueCuts=0;
580   
581   if(ptK < fCutsRD[GetGlobalIndex(3,ptbin)] || ptPi < fCutsRD[GetGlobalIndex(4,ptbin)]) okD0 = 0;
582   if(aptK < fCutsRD[GetGlobalIndex(3,aptbin)] || aptPi < fCutsRD[GetGlobalIndex(4,aptbin)]) okD0bar = 0;
583   if(!okD0 && !okD0bar) returnvalueCuts=0;
584   
585   
586   if(TMath::Abs(impactKa) > fCutsRD[GetGlobalIndex(5,ptbin)] || 
587      TMath::Abs(impactPi) > fCutsRD[GetGlobalIndex(6,ptbin)]) okD0 = 0;
588   
589   if(TMath::Abs(aimpactKa) > fCutsRD[GetGlobalIndex(5,aptbin)] ||
590      TMath::Abs(aimpactPi) > fCutsRD[GetGlobalIndex(6,aptbin)]) okD0bar = 0;
591   
592   if(!okD0 && !okD0bar)  returnvalueCuts=0;
593   
594   // for the moment via the standard method due to bug in AliKF
595   if(d->GetDCA() > fCutsRD[GetGlobalIndex(1,ptbin)]) okD0 = 0;
596   if(d->GetDCA() > fCutsRD[GetGlobalIndex(1,aptbin)]) okD0bar = 0;
597   if(!okD0 && !okD0bar) returnvalueCuts=0;
598     
599     
600   if(TMath::Abs(d0mass-massvtx) > fCutsRD[GetGlobalIndex(0,ptbin)]) okD0 = 0;
601   if(TMath::Abs(ad0mass-massvtx) > fCutsRD[GetGlobalIndex(0,aptbin)])  okD0bar = 0;
602   if(!okD0 && !okD0bar)  returnvalueCuts=0;
603   
604   
605   if(TMath::Abs(cts) > fCutsRD[GetGlobalIndex(2,ptbin)]) okD0 = 0; 
606   if(TMath::Abs(acts) > fCutsRD[GetGlobalIndex(2,aptbin)]) okD0bar = 0;
607   if(!okD0 && !okD0bar)   returnvalueCuts=0;
608   
609   if(prodParam  > fCutsRD[GetGlobalIndex(7,ptbin)]) okD0 = 0;
610   if(aprodParam > fCutsRD[GetGlobalIndex(7,aptbin)]) okD0bar = 0;
611   if(!okD0 && !okD0bar)  returnvalueCuts=0;
612     
613   if(cosP  < fCutsRD[GetGlobalIndex(8,ptbin)]) okD0 = 0; 
614   if(acosP < fCutsRD[GetGlobalIndex(8,aptbin)]) okD0bar = 0;
615   if(!okD0 && !okD0bar)  returnvalueCuts=0;
616         
617   if(chi2D0  > fCutsRD[GetGlobalIndex(10,ptbin)]) okD0 = 0; 
618   if(achi2D0 > fCutsRD[GetGlobalIndex(10,aptbin)]) okD0bar = 0;
619   if(!okD0 && !okD0bar)  returnvalueCuts=0;
620         
621   if(decayLengthD0  < fCutsRD[GetGlobalIndex(9,ptbin)]) okD0 = 0; 
622   if(adecayLengthD0 < fCutsRD[GetGlobalIndex(9,aptbin)]) okD0bar = 0;
623   if(!okD0 && !okD0bar)  returnvalueCuts=0;
624     
625   if(returnvalueCuts!=0) {
626     if(okD0) returnvalueCuts=1; //cuts passed as D0
627     if(okD0bar) returnvalueCuts=2; //cuts passed as D0bar
628     if(okD0 && okD0bar) returnvalueCuts=3; //cuts passed as D0 and D0bar
629   }
630
631   return returnvalueCuts;  
632 }
633
634 //---------------------------------------------------------------------------
635
636 Bool_t AliRDHFCutsD0toKpi::IsInFiducialAcceptance(Double_t pt, Double_t y) const
637 {
638   //
639   // Checking if D0 is in fiducial acceptance region 
640   //
641
642   if(pt > 5.) {
643     // applying cut for pt > 5 GeV
644     AliDebug(2,Form("pt of D0 = %f (> 5), cutting at |y| < 0.8\n",pt)); 
645     if (TMath::Abs(y) > 0.8){
646       return kFALSE;
647     }
648   } else {
649     // appliying smooth cut for pt < 5 GeV
650     Double_t maxFiducialY = -0.2/15*pt*pt+1.9/15*pt+0.5; 
651     Double_t minFiducialY = 0.2/15*pt*pt-1.9/15*pt-0.5;         
652     AliDebug(2,Form("pt of D0 = %f (< 5), cutting  according to the fiducial zone [%f, %f]\n",pt,minFiducialY,maxFiducialY)); 
653     if (y < minFiducialY || y > maxFiducialY){
654       return kFALSE;
655     }
656   }
657
658   return kTRUE;
659 }
660 //---------------------------------------------------------------------------
661 Int_t AliRDHFCutsD0toKpi::IsSelectedPID(AliAODRecoDecayHF* d) 
662 {
663   // ############################################################
664   //
665   // Apply PID selection
666   //
667   //
668   // ############################################################
669
670   if(!fUsePID) return 3;
671   if(fDefaultPID) return IsSelectedPIDdefault(d);
672   fWhyRejection=0;
673   Int_t isD0D0barPID[2]={1,2};
674   Int_t combinedPID[2][2];// CONVENTION: [daught][isK,IsPi]; [0][0]=(prong 1, isK)=value [0][1]=(prong 1, isPi)=value; 
675   //                                                                                                 same for prong 2
676   //                                               values convention -1 = discarded 
677   //                                                                  0 = not identified (but compatible) || No PID (->hasPID flag)
678   //                                                                  1 = identified
679   // PID search:   pion (TPC) or not K (TOF), Kaon hypothesis for both 
680   // Initial hypothesis: unknwon (but compatible) 
681   combinedPID[0][0]=0;  // prima figlia, Kaon
682   combinedPID[0][1]=0;  // prima figlia, pione
683   combinedPID[1][0]=0;  // seconda figlia, Kaon
684   combinedPID[1][1]=0;  // seconda figlia, pion
685   
686   Bool_t checkPIDInfo[2]={kTRUE,kTRUE};
687   Double_t sigma_tmp[3]={fPidHF->GetSigma(0),fPidHF->GetSigma(1),fPidHF->GetSigma(2)};
688   for(Int_t daught=0;daught<2;daught++){
689     //Loop con prongs
690     AliAODTrack *aodtrack=(AliAODTrack*)d->GetDaughter(daught);
691     if(fPidHF->IsTOFPiKexcluded(aodtrack,5.)) return 0; 
692     
693     if(!(fPidHF->CheckStatus(aodtrack,"TPC")) && !(fPidHF->CheckStatus(aodtrack,"TOF"))) {
694       checkPIDInfo[daught]=kFALSE; 
695       continue;
696     }
697
698     // identify kaon
699     combinedPID[daught][0]=fPidHF->MakeRawPid(aodtrack,3);
700
701     // identify pion
702
703     if(!(fPidHF->CheckStatus(aodtrack,"TPC"))) {
704      combinedPID[daught][1]=0;
705     }else{
706       fPidHF->SetTOF(kFALSE);
707       combinedPID[daught][1]=fPidHF->MakeRawPid(aodtrack,2);
708       fPidHF->SetTOF(kTRUE);
709       fPidHF->SetCompat(kTRUE);
710      }
711
712
713     if(combinedPID[daught][0]<=-1&&combinedPID[daught][1]<=-1){ // if not a K- and not a pi- both D0 and D0bar excluded
714       isD0D0barPID[0]=0;
715       isD0D0barPID[1]=0;
716     }
717     else if(combinedPID[daught][0]==2&&combinedPID[daught][1]>=1){
718       if(aodtrack->Charge()==-1)isD0D0barPID[1]=0;//if K- D0bar excluded
719       else isD0D0barPID[0]=0;// if K+ D0 excluded
720     }
721     /*    else if(combinedPID[daught][0]==1&&combinedPID[daught][1]>=1){
722           isD0D0barPID[0]=0;
723           isD0D0barPID[1]=0;
724           }
725     */
726     else if(combinedPID[daught][0]>=1||combinedPID[daught][1]<=-1){ 
727       if(aodtrack->Charge()==-1)isD0D0barPID[1]=0;// not a D0bar if K- or if pi- excluded
728       else isD0D0barPID[0]=0;//  not a D0 if K+ or if pi+ excluded
729     }
730     else if(combinedPID[daught][0]<=-1||combinedPID[daught][1]>=1){
731       if(aodtrack->Charge()==-1)isD0D0barPID[0]=0;// not a D0 if pi- or if K- excluded
732       else isD0D0barPID[1]=0;// not a D0bar if pi+ or if K+ excluded
733     }
734
735     if(fLowPt && d->Pt()<fPtLowPID){
736      Double_t sigmaTPC[3]={3.,2.,0.};
737      fPidHF->SetSigmaForTPC(sigmaTPC);
738     // identify kaon
739     combinedPID[daught][0]=fPidHF->MakeRawPid(aodtrack,3);
740
741     Double_t ptProng=aodtrack->P();
742
743     if(ptProng<0.6){
744      fPidHF->SetCompat(kFALSE);
745      combinedPID[daught][0]=fPidHF->MakeRawPid(aodtrack,3);
746      fPidHF->SetCompat(kTRUE);
747     }
748
749     if(!(fPidHF->CheckStatus(aodtrack,"TPC"))) {
750      combinedPID[daught][1]=0;
751     }else{
752       fPidHF->SetTOF(kFALSE);
753       Double_t sigmaTPCpi[3]={3.,3.,0.};
754       fPidHF->SetSigmaForTPC(sigmaTPCpi);
755       combinedPID[daught][1]=fPidHF->MakeRawPid(aodtrack,2);
756       fPidHF->SetTOF(kTRUE);
757        if(ptProng<0.8){
758         Bool_t isTPCpion=fPidHF->IsPionRaw(aodtrack,"TPC");
759         if(isTPCpion){
760          combinedPID[daught][1]=1;
761         }else{
762          combinedPID[daught][1]=-1;
763         }
764       }
765     }
766
767    }
768    fPidHF->SetSigmaForTPC(sigma_tmp);
769   }// END OF LOOP ON DAUGHTERS
770
771    if(!checkPIDInfo[0] && !checkPIDInfo[1]) {
772     if(fLowPt) fPidHF->SetSigmaForTPC(sigma_tmp);
773     return 0;
774    }
775
776
777   // FURTHER PID REQUEST (both daughter info is needed)
778   if(combinedPID[0][0]<=-1&&combinedPID[1][0]<=-1){
779     fWhyRejection=31;// reject cases in which no kaon-compatible tracks are found
780     if(fLowPt) fPidHF->SetSigmaForTPC(sigma_tmp);
781     return 0;
782   }
783
784   if(fLowPt && d->Pt()<fPtLowPID){    
785     if(combinedPID[0][0]<=0&&combinedPID[1][0]<=0){
786       fWhyRejection=32;// reject cases where the Kaon is not identified
787       fPidHF->SetSigmaForTPC(sigma_tmp);
788       return 0;
789     }
790   }
791     if(fLowPt) fPidHF->SetSigmaForTPC(sigma_tmp);
792
793   //  cout<<"Why? "<<fWhyRejection<<endl;  
794   return isD0D0barPID[0]+isD0D0barPID[1];
795 }
796 //---------------------------------------------------------------------------
797 Int_t AliRDHFCutsD0toKpi::IsSelectedPIDdefault(AliAODRecoDecayHF* d) 
798 {
799   // ############################################################
800   //
801   // Apply PID selection
802   //
803   //
804   // temporary selection: PID AS USED FOR D0 by Andrea Rossi (up to 28/06/2010)
805   //
806   // d must be a AliAODRecoDecayHF2Prong object
807   // returns 0 if both D0 and D0bar are rejectecd
808   //         1 if D0 is accepted while D0bar is rejected
809   //         2 if D0bar is accepted while D0 is rejected
810   //         3 if both are accepted
811   // fWhyRejection variable (not returned for the moment, print it if needed)
812   //               keeps some information on why a candidate has been 
813   //               rejected according to the following (unfriendly?) scheme 
814   //             if more rejection cases are considered interesting, just add numbers
815   //
816   //      TO BE CONSIDERED WITH A GRAIN OF SALT (the order in which cut are applied is relevant) 
817   //              from 20 to 30: "detector" selection (PID acceptance)                                             
818   //                                                  26: TPC refit
819   //                                                  27: ITS refit
820   //                                                  28: no (TOF||TPC) pid information (no kTOFpid,kTOFout,kTIME,kTPCpid,...)
821   //
822   //              from 30 to 40: PID selection
823   //                                                  31: no Kaon compatible tracks found between daughters
824   //                                                  32: no Kaon identified tracks found (strong sel. at low momenta)
825   //                                                  33: both mass hypotheses are rejected 
826   //                  
827   // ############################################################
828
829   if(!fUsePID) return 3;
830   fWhyRejection=0;
831   Int_t isD0D0barPID[2]={1,2};
832   Double_t nsigmaTPCpi=-1., nsigmaTPCK=-1.; //used for TPC pid
833   Double_t tofSig,times[5];// used fot TOF pid
834   Int_t hasPID[2]={2,2};// flag to count how many detectors give PID info for the daughters
835   Int_t isKaonPionTOF[2][2],isKaonPionTPC[2][2];
836   Int_t combinedPID[2][2];// CONVENTION: [daught][isK,IsPi]; [0][0]=(prong 1, isK)=value [0][1]=(prong 1, isPi)=value; 
837   //                                                                                                 same for prong 2
838   //                                               values convention -1 = discarded 
839   //                                                                  0 = not identified (but compatible) || No PID (->hasPID flag)
840   //                                                                  1 = identified
841   // PID search:   pion (TPC) or not K (TOF), Kaon hypothesis for both 
842   // Initial hypothesis: unknwon (but compatible) 
843   isKaonPionTOF[0][0]=0;
844   isKaonPionTOF[0][1]=0;
845   isKaonPionTOF[1][0]=0;
846   isKaonPionTOF[1][1]=0;
847   
848   isKaonPionTPC[0][0]=0;
849   isKaonPionTPC[0][1]=0;
850   isKaonPionTPC[1][0]=0;
851   isKaonPionTPC[1][1]=0;
852   
853   combinedPID[0][0]=0;
854   combinedPID[0][1]=0;
855   combinedPID[1][0]=0;
856   combinedPID[1][1]=0;
857   
858   
859  
860   for(Int_t daught=0;daught<2;daught++){
861     //Loop con prongs
862     
863     // ########### Step 0- CHECKING minimal PID "ACCEPTANCE" ####################
864
865     AliAODTrack *aodtrack=(AliAODTrack*)d->GetDaughter(daught); 
866    
867     if(!(aodtrack->GetStatus()&AliESDtrack::kTPCrefit)){
868       fWhyRejection=26;
869       return 0;
870     } 
871     if(!(aodtrack->GetStatus()&AliESDtrack::kITSrefit)){
872       fWhyRejection=27;
873       return 0;
874     } 
875     
876     AliAODPid *pid=aodtrack->GetDetPid();
877     if(!pid) {
878       //delete esdtrack;
879       hasPID[daught]--;
880       continue;
881     }
882   
883     // ########### Step 1- Check of TPC and TOF response ####################
884
885     Double_t ptrack=aodtrack->P();
886     //#################### TPC PID #######################
887      if (!(aodtrack->GetStatus()&AliESDtrack::kTPCpid )){
888        // NO TPC PID INFO FOR THIS TRACK 
889        hasPID[daught]--;
890      }
891      else {
892        static AliTPCPIDResponse theTPCpid;
893        AliAODPid *pidObj = aodtrack->GetDetPid();
894        Double_t ptProng=pidObj->GetTPCmomentum();
895        nsigmaTPCpi = theTPCpid.GetNumberOfSigmas(ptProng,(Float_t)pid->GetTPCsignal(),(Int_t)aodtrack->GetTPCClusterMap().CountBits(),AliPID::kPion);
896        nsigmaTPCK =  theTPCpid.GetNumberOfSigmas(ptProng,(Float_t)pid->GetTPCsignal(),(Int_t)aodtrack->GetTPCClusterMap().CountBits(),AliPID::kKaon);
897        //if(ptrack<0.6){
898        if(ptProng<0.6){
899          if(TMath::Abs(nsigmaTPCK)<2.)isKaonPionTPC[daught][0]=1;
900          else if(TMath::Abs(nsigmaTPCK)>3.)isKaonPionTPC[daught][0]=-1;
901          if(TMath::Abs(nsigmaTPCpi)<2.)isKaonPionTPC[daught][1]=1;
902          else if(TMath::Abs(nsigmaTPCpi)>3.)isKaonPionTPC[daught][1]=-1;
903        }
904        //else if(ptrack<.8){
905        else if(ptProng<.8){
906          if(TMath::Abs(nsigmaTPCK)<1.)isKaonPionTPC[daught][0]=1;
907          else if(TMath::Abs(nsigmaTPCK)>3.)isKaonPionTPC[daught][0]=-1;
908          if(TMath::Abs(nsigmaTPCpi)<1.)isKaonPionTPC[daught][1]=1;
909          else if(TMath::Abs(nsigmaTPCpi)>3.)isKaonPionTPC[daught][1]=-1;
910        }     
911        else {
912          //     if(nsigmaTPCK>-2.&&nsigmaTPCK<1.)isKaonPionTPC[daught][0]=1;
913          if(TMath::Abs(nsigmaTPCK)>3.)isKaonPionTPC[daught][0]=-1;
914          //if(nsigmaTPCpi>-1.&&nsigmaTPCpi<2.)isKaonPionTPC[daught][1]=1;
915          if(TMath::Abs(nsigmaTPCpi)>3.)isKaonPionTPC[daught][1]=-1;
916        }
917      }
918     
919     
920     // ##### TOF PID: do not ask nothing for pion/protons ############
921      if(!((aodtrack->GetStatus()&AliESDtrack::kTOFpid)&&(aodtrack->GetStatus()&AliESDtrack::kTOFout)&&(aodtrack->GetStatus()&AliESDtrack::kTIME))){
922        // NO TOF PID INFO FOR THIS TRACK      
923        hasPID[daught]--;
924      }
925      else{
926        tofSig=pid->GetTOFsignal(); 
927        pid->GetIntegratedTimes(times);
928        if((tofSig-times[3])>5.*160.)return 0;// PROTON REJECTION
929        if(TMath::Abs(tofSig-times[3])>3.*160.){
930          isKaonPionTOF[daught][0]=-1;
931        }
932        else {    
933          if(ptrack<1.5){
934            isKaonPionTOF[daught][0]=1;
935          }
936        }
937      }
938      
939      //######### Step 2: COMBINE TOF and TPC PID ###############
940      // we apply the following convention: if TPC and TOF disagree (discarded Vs identified) -> unknown
941      combinedPID[daught][0]=isKaonPionTOF[daught][0]+isKaonPionTPC[daught][0];
942      combinedPID[daught][1]=isKaonPionTOF[daught][1]+isKaonPionTPC[daught][1];
943      
944      
945      //######### Step 3:   USE PID INFO     
946      
947      if(combinedPID[daught][0]<=-1&&combinedPID[daught][1]<=-1){// if not a K- and not a pi- both D0 and D0bar excluded
948        isD0D0barPID[0]=0;
949        isD0D0barPID[1]=0;
950      }
951      else if(combinedPID[daught][0]==2&&combinedPID[daught][1]>=1){// if in conflict (both pi- and K-), if k for both TPC and TOF -> is K
952        if(aodtrack->Charge()==-1)isD0D0barPID[1]=0;//if K- D0bar excluded
953        else isD0D0barPID[0]=0;// if K+ D0 excluded
954      }
955      else if(combinedPID[daught][0]==1&&combinedPID[daught][1]>=1){// if in conflict (both pi- and K-) and k- only for TPC or TOF -> reject
956        isD0D0barPID[0]=0;
957        isD0D0barPID[1]=0;
958      }
959      else if(combinedPID[daught][0]>=1||combinedPID[daught][1]<=-1){
960        if(aodtrack->Charge()==-1)isD0D0barPID[1]=0;// not a D0bar if K- or if pi- excluded
961        else isD0D0barPID[0]=0;//  not a D0 if K+ or if pi+ excluded
962      }
963      else if(combinedPID[daught][0]<=-1||combinedPID[daught][1]>=1){
964        if(aodtrack->Charge()==-1)isD0D0barPID[0]=0;// not a D0 if pi- or if K- excluded
965       else isD0D0barPID[1]=0;// not a D0bar if pi+ or if K+ excluded
966      }
967      
968      // ##########  ALSO DIFFERENT TPC PID REQUEST FOR LOW pt D0: request of K identification      ###############################
969      // ########## more tolerant criteria for single particle ID-> more selective criteria for D0   ##############################
970      // ###############                     NOT OPTIMIZED YET                                  ###################################
971      if(d->Pt()<2.){
972        isKaonPionTPC[daught][0]=0;
973        isKaonPionTPC[daught][1]=0;
974        AliAODPid *pidObj = aodtrack->GetDetPid();
975        Double_t ptProng=pidObj->GetTPCmomentum();
976        //if(ptrack<0.6){
977        if(ptProng<0.6){
978          if(TMath::Abs(nsigmaTPCK)<3.)isKaonPionTPC[daught][0]=1;
979          else if(TMath::Abs(nsigmaTPCK)>3.)isKaonPionTPC[daught][0]=-1;
980          if(TMath::Abs(nsigmaTPCpi)<3.)isKaonPionTPC[daught][1]=1;
981          else if(TMath::Abs(nsigmaTPCpi)>3.)isKaonPionTPC[daught][1]=-1;
982      }
983        //else if(ptrack<.8){
984        else if(ptProng<.8){
985          if(TMath::Abs(nsigmaTPCK)<2.)isKaonPionTPC[daught][0]=1;
986          else if(TMath::Abs(nsigmaTPCK)>3.)isKaonPionTPC[daught][0]=-1;
987          if(TMath::Abs(nsigmaTPCpi)<3.)isKaonPionTPC[daught][1]=1;
988          else if(TMath::Abs(nsigmaTPCpi)>3.)isKaonPionTPC[daught][1]=-1;
989        }     
990        else {
991          if(TMath::Abs(nsigmaTPCK)>3.)isKaonPionTPC[daught][0]=-1;
992          if(TMath::Abs(nsigmaTPCpi)>3.)isKaonPionTPC[daught][1]=-1;
993        }
994      }
995      
996   }// END OF LOOP ON DAUGHTERS
997   
998   // FURTHER PID REQUEST (both daughter info is needed)
999   if(combinedPID[0][0]<=-1&&combinedPID[1][0]<=-1){
1000     fWhyRejection=31;// reject cases in which no kaon-compatible tracks are found
1001     return 0;
1002   }
1003   else if(hasPID[0]==0&&hasPID[1]==0){
1004     fWhyRejection=28;// reject cases in which no PID info is available  
1005     return 0;
1006   }
1007   if(d->Pt()<2.){
1008     // request of K identification at low D0 pt
1009     combinedPID[0][0]=0;
1010     combinedPID[0][1]=0;
1011     combinedPID[1][0]=0;
1012     combinedPID[1][1]=0;
1013     
1014     combinedPID[0][0]=isKaonPionTOF[0][0]+isKaonPionTPC[0][0];
1015     combinedPID[0][1]=isKaonPionTOF[0][1]+isKaonPionTPC[0][1];
1016     combinedPID[1][0]=isKaonPionTOF[1][0]+isKaonPionTPC[1][0];
1017     combinedPID[1][1]=isKaonPionTOF[1][1]+isKaonPionTPC[1][1];
1018     
1019     if(combinedPID[0][0]<=0&&combinedPID[1][0]<=0){
1020       fWhyRejection=32;// reject cases where the Kaon is not identified
1021       return 0;
1022     }
1023   }
1024
1025   //  cout<<"Why? "<<fWhyRejection<<endl;  
1026   return isD0D0barPID[0]+isD0D0barPID[1];
1027 }
1028
1029
1030
1031 //---------------------------------------------------------------------------
1032 Int_t AliRDHFCutsD0toKpi::CombineSelectionLevels(Int_t selectionvalTrack,
1033                                                  Int_t selectionvalCand,
1034                                                  Int_t selectionvalPID) const
1035 {
1036   //
1037   // This method combines the tracks, PID and cuts selection results
1038   //
1039   if(selectionvalTrack==0) return 0;
1040
1041   Int_t returnvalue;
1042
1043   switch(selectionvalPID) {
1044   case 0:
1045     returnvalue=0;
1046     break;
1047   case 1:
1048     returnvalue=((selectionvalCand==1 || selectionvalCand==3) ? 1 : 0);
1049     break;
1050   case 2:
1051     returnvalue=((selectionvalCand==2 || selectionvalCand==3) ? 2 : 0);
1052     break;
1053   case 3:
1054     returnvalue=selectionvalCand;
1055     break;
1056   default:
1057     returnvalue=0;
1058     break;
1059   }
1060
1061   return returnvalue;
1062 }
1063 //----------------------------------------------------------------------------
1064 Int_t AliRDHFCutsD0toKpi::IsSelectedSpecialCuts(AliAODRecoDecayHF *d) const
1065 {
1066   //
1067   // Note: this method is temporary
1068   // Additional cuts on decay lenght and lower cut for d0 norm are applied using vertex without candidate's daughters
1069   //
1070
1071   //apply cuts
1072
1073   Float_t normDecLengthCut=1.,decLengthCut=TMath::Min(d->P()*0.0066+0.01,0.06/*cm*/), normd0Cut=0.5;
1074   // "decay length" expo law with tau' = beta*gamma*ctau= p/m*ctau =p*0.0123/1.864~p*0.0066
1075   // decay lenght > ctau' implies to retain (1-1/e) (for signal without considering detector resolution), 
1076
1077   Int_t returnvalue=3; //cut passed
1078   for(Int_t i=0;i<2/*prongs*/;i++){
1079     if(TMath::Abs(d->Normalizedd0Prong(i))<normd0Cut) return 0; //normd0Cut not passed
1080   }
1081   if(d->DecayLength2()<decLengthCut*decLengthCut)  return 0; //decLengthCut not passed
1082   if(d->NormalizedDecayLength2()<normDecLengthCut*normDecLengthCut)  return 0; //decLengthCut not passed
1083         
1084   return returnvalue;
1085 }
1086
1087 //----------------------------------------------
1088 void AliRDHFCutsD0toKpi::SetUseKF(Bool_t useKF)
1089 {
1090   //switch on candidate selection via AliKFparticle
1091   if(!useKF) return;
1092   if(useKF){
1093     fUseKF=useKF;
1094     Int_t nvarsKF=11;
1095     SetNVars(nvarsKF);
1096     TString varNamesKF[11]={"inv. mass [GeV]",   
1097                             "dca [cm]",
1098                             "cosThetaStar", 
1099                             "pTK [GeV/c]",
1100                             "pTPi [GeV/c]",
1101                             "d0K [cm]",
1102                             "d0Pi [cm]",
1103                             "d0d0 [cm^2]",
1104                             "cosThetaPoint"
1105                             "DecayLength[cm]",
1106                             "RedChi2"};
1107     Bool_t isUpperCutKF[11]={kTRUE,
1108                              kTRUE,
1109                              kTRUE,
1110                              kFALSE,
1111                              kFALSE,
1112                              kTRUE,
1113                              kTRUE,
1114                              kTRUE,
1115                              kFALSE,
1116                              kFALSE,
1117                              kTRUE};
1118     SetVarNames(nvarsKF,varNamesKF,isUpperCutKF);
1119     SetGlobalIndex();
1120     Bool_t forOpt[11]={kFALSE,
1121                     kTRUE,
1122                     kTRUE,
1123                     kFALSE,
1124                     kFALSE,
1125                     kFALSE,
1126                     kFALSE,
1127                     kTRUE,
1128                     kTRUE,
1129                     kFALSE,
1130                     kFALSE};
1131     SetVarsForOpt(4,forOpt);
1132   }
1133   return;
1134 }
1135
1136
1137 void AliRDHFCutsD0toKpi::SetStandardCutsPP2010() {
1138   //
1139   //STANDARD CUTS USED FOR 2010 pp analysis 
1140   //dca cut will be enlarged soon to 400 micron
1141   //
1142   
1143   SetName("D0toKpiCutsStandard");
1144   SetTitle("Standard Cuts for D0 analysis");
1145   
1146   // PILE UP REJECTION
1147   SetOptPileup(AliRDHFCuts::kRejectPileupEvent);
1148
1149   // EVENT CUTS
1150   SetMinVtxContr(1);
1151
1152   
1153   // TRACKS ON SINGLE TRACKS
1154   AliESDtrackCuts *esdTrackCuts = new AliESDtrackCuts("AliESDtrackCuts","default");
1155   esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
1156   esdTrackCuts->SetRequireTPCRefit(kTRUE);
1157   esdTrackCuts->SetRequireITSRefit(kTRUE);
1158   //  esdTrackCuts->SetMinNClustersITS(4);
1159   esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
1160   esdTrackCuts->SetMinDCAToVertexXY(0.);
1161   esdTrackCuts->SetEtaRange(-0.8,0.8);
1162   esdTrackCuts->SetPtRange(0.3,1.e10);
1163   
1164   AddTrackCuts(esdTrackCuts);
1165   
1166   const Int_t nptbins =14;
1167   const Double_t ptmax = 9999.;
1168   const Int_t nvars=11;
1169   Float_t ptbins[nptbins+1];
1170   ptbins[0]=0.;
1171   ptbins[1]=0.5;        
1172   ptbins[2]=1.;
1173   ptbins[3]=2.;
1174   ptbins[4]=3.;
1175   ptbins[5]=4.;
1176   ptbins[6]=5.;
1177   ptbins[7]=6.;
1178   ptbins[8]=7.;
1179   ptbins[9]=8.;
1180   ptbins[10]=12.;
1181   ptbins[11]=16.;
1182   ptbins[12]=20.;
1183   ptbins[13]=24.;
1184   ptbins[14]=ptmax;
1185
1186   SetGlobalIndex(nvars,nptbins);
1187   SetPtBins(nptbins+1,ptbins);
1188   
1189   Float_t cutsMatrixD0toKpiStand[nptbins][nvars]={{0.400,350.*1E-4,0.8,0.5,0.5,1000.*1E-4,1000.*1E-4,-5000.*1E-8,0.80,0.,0.},/* pt<0.5*/
1190                                                   {0.400,350.*1E-4,0.8,0.5,0.5,1000.*1E-4,1000.*1E-4,-5000.*1E-8,0.80,0.,0.},/* 0.5<pt<1*/
1191                                                   {0.400,300.*1E-4,0.8,0.4,0.4,1000.*1E-4,1000.*1E-4,-25000.*1E-8,0.80,0.,0.},/* 1<pt<2 */
1192                                                   {0.400,300.*1E-4,0.8,0.7,0.7,1000.*1E-4,1000.*1E-4,-15000.*1E-8,0.85,0.,0.},/* 2<pt<3 */
1193                                                   {0.400,300.*1E-4,0.8,0.7,0.7,1000.*1E-4,1000.*1E-4,-8000.*1E-8,0.85,0.,0.},/* 3<pt<4 */
1194                                                   {0.400,300.*1E-4,0.8,0.7,0.7,1000.*1E-4,1000.*1E-4,-8000.*1E-8,0.85,0.,0.},/* 4<pt<5 */
1195                                                   {0.400,300.*1E-4,0.8,0.7,0.7,1000.*1E-4,1000.*1E-4,-8000.*1E-8,0.85,0.,0.},/* 5<pt<6 */
1196                                                   {0.400,300.*1E-4,0.8,0.7,0.7,1000.*1E-4,1000.*1E-4,-8000.*1E-8,0.85,0.,0.},/* 6<pt<7 */
1197                                                   {0.400,300.*1E-4,0.8,0.7,0.7,1000.*1E-4,1000.*1E-4,-7000.*1E-8,0.85,0.,0.},/* 7<pt<8 */
1198                                                   {0.400,300.*1E-4,0.9,0.7,0.7,1000.*1E-4,1000.*1E-4,-5000.*1E-8,0.85,0.,0.},/* 8<pt<12 */
1199                                                   {0.400,300.*1E-4,1.0,0.7,0.7,1000.*1E-4,1000.*1E-4,10000.*1E-8,0.85,0.,0.},/* 12<pt<16 */
1200                                                   {0.400,300.*1E-4,1.0,0.7,0.7,1000.*1E-4,1000.*1E-4,999999.*1E-8,0.85,0.,0.},/* 16<pt<20 */
1201                                                   {0.400,300.*1E-4,1.0,0.7,0.7,1000.*1E-4,1000.*1E-4,999999.*1E-8,0.85,0.,0.},/* 20<pt<24 */
1202                                                   {0.400,300.*1E-4,1.0,0.7,0.7,1000.*1E-4,1000.*1E-4,999999.*1E-8,0.85,0.,0.}};/* pt>24 */
1203   
1204   
1205   //CREATE TRANSPOSE MATRIX...REVERSE INDICES as required by AliRDHFCuts
1206   Float_t **cutsMatrixTransposeStand=new Float_t*[nvars];
1207   for(Int_t iv=0;iv<nvars;iv++)cutsMatrixTransposeStand[iv]=new Float_t[nptbins];
1208   
1209   for (Int_t ibin=0;ibin<nptbins;ibin++){
1210     for (Int_t ivar = 0; ivar<nvars; ivar++){
1211       cutsMatrixTransposeStand[ivar][ibin]=cutsMatrixD0toKpiStand[ibin][ivar];      
1212     }
1213   }
1214   
1215   SetCuts(nvars,nptbins,cutsMatrixTransposeStand);
1216   SetUseSpecialCuts(kTRUE);
1217   SetRemoveDaughtersFromPrim(kTRUE);
1218   
1219   for(Int_t iv=0;iv<nvars;iv++) delete [] cutsMatrixTransposeStand[iv];
1220   delete [] cutsMatrixTransposeStand;
1221   cutsMatrixTransposeStand=NULL;
1222
1223   // PID SETTINGS
1224   AliAODPidHF* pidObj=new AliAODPidHF();
1225   //pidObj->SetName("pid4D0");
1226   Int_t mode=1;
1227   const Int_t nlims=2;
1228   Double_t plims[nlims]={0.6,0.8}; //TPC limits in momentum [GeV/c]
1229   Bool_t compat=kTRUE; //effective only for this mode
1230   Bool_t asym=kTRUE;
1231   Double_t sigmas[5]={2.,1.,0.,3.,0.}; //to be checked and to be modified with new implementation of setters by Rossella
1232   pidObj->SetAsym(asym);// if you want to use the asymmetric bands in TPC
1233   pidObj->SetMatch(mode);
1234   pidObj->SetPLimit(plims,nlims);
1235   pidObj->SetSigma(sigmas);
1236   pidObj->SetCompat(compat);
1237   pidObj->SetTPC(kTRUE);
1238   pidObj->SetTOF(kTRUE);
1239   pidObj->SetPCompatTOF(1.5);
1240   pidObj->SetSigmaForTPCCompat(3.);
1241   pidObj->SetSigmaForTOFCompat(3.);
1242
1243   SetPidHF(pidObj);
1244   SetUsePID(kTRUE);
1245   SetUseDefaultPID(kFALSE);
1246
1247
1248   PrintAll();
1249
1250   delete pidObj;
1251   pidObj=NULL;
1252
1253   return;
1254
1255 }
1256
1257
1258 void AliRDHFCutsD0toKpi::SetStandardCutsPbPb2010() {
1259   //
1260   //PRELIMINARY CUTS USED FOR 2010 PbPb analysis
1261   //... EVOLVING SOON 
1262   // 
1263   
1264   SetName("D0toKpiCutsStandard");
1265   SetTitle("Standard Cuts for D0 analysis in PbPb2010 run");
1266   
1267   // PILE UP REJECTION
1268   //SetOptPileup(AliRDHFCuts::kRejectPileupEvent);
1269   // CENTRALITY SELECTION
1270   SetMinCentrality(0.);
1271   SetMaxCentrality(80.);
1272   SetUseCentrality(AliRDHFCuts::kCentV0M);
1273
1274
1275   // EVENT CUTS
1276   SetMinVtxContr(1);
1277   // MAX Z-VERTEX CUT
1278   SetMaxVtxZ(10.);
1279   
1280   // TRACKS ON SINGLE TRACKS
1281   AliESDtrackCuts *esdTrackCuts = new AliESDtrackCuts("AliESDtrackCuts","default");
1282   esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
1283   esdTrackCuts->SetRequireTPCRefit(kTRUE);
1284   esdTrackCuts->SetRequireITSRefit(kTRUE);
1285   //  esdTrackCuts->SetMinNClustersITS(4);
1286   esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
1287   esdTrackCuts->SetMinDCAToVertexXY(0.);
1288   esdTrackCuts->SetEtaRange(-0.8,0.8);
1289   esdTrackCuts->SetPtRange(0.7,1.e10);
1290
1291   esdTrackCuts->SetMaxDCAToVertexXY(1.);  
1292   esdTrackCuts->SetMaxDCAToVertexZ(1.);
1293   esdTrackCuts->SetMinDCAToVertexXYPtDep("0.0075*TMath::Max(0.,(1-TMath::Floor(TMath::Abs(pt)/2.)))");  
1294
1295
1296   AddTrackCuts(esdTrackCuts);
1297
1298   // CANDIDATE CUTS  
1299   const Int_t nptbins =13;
1300   const Double_t ptmax = 9999.;
1301   const Int_t nvars=11;
1302   Float_t ptbins[nptbins+1];
1303   ptbins[0]=0.;
1304   ptbins[1]=0.5;        
1305   ptbins[2]=1.;
1306   ptbins[3]=2.;
1307   ptbins[4]=3.;
1308   ptbins[5]=4.;
1309   ptbins[6]=5.;
1310   ptbins[7]=6.;
1311   ptbins[8]=8.;
1312   ptbins[9]=12.;
1313   ptbins[10]=16.;
1314   ptbins[11]=20.;
1315   ptbins[12]=24.;
1316   ptbins[13]=ptmax;
1317
1318   SetGlobalIndex(nvars,nptbins);
1319   SetPtBins(nptbins+1,ptbins);
1320   SetMinPtCandidate(2.);
1321
1322   Float_t cutsMatrixD0toKpiStand[nptbins][nvars]={{0.400,400.*1E-4,0.8,0.3,0.3,1000.*1E-4,1000.*1E-4,-10000.*1E-8,0.85,0.,5.},/* pt<0.5*/
1323                                                   {0.400,400.*1E-4,0.8,0.3,0.3,1000.*1E-4,1000.*1E-4,-35000.*1E-8,0.9,0.,5.},/* 0.5<pt<1*/
1324                                                   {0.400,400.*1E-4,0.8,0.4,0.4,1000.*1E-4,1000.*1E-4,-43000.*1E-8,0.85,0.,5.},/* 1<pt<2 */
1325                                                   {0.400,250.*1E-4,0.8,0.7,0.7,1000.*1E-4,1000.*1E-4,-40000.*1E-8,0.95,0.998,5.},/* 2<pt<3 */
1326                                                   {0.400,250.*1E-4,0.8,0.7,0.7,1000.*1E-4,1000.*1E-4,-36000.*1E-8,0.95,0.998,5.},/* 3<pt<4 */
1327                                                   {0.400,250.*1E-4,0.8,0.7,0.7,1000.*1E-4,1000.*1E-4,-27000.*1E-8,0.95,0.998,5.},/* 4<pt<5 */
1328                                                   {0.400,250.*1E-4,0.8,0.7,0.7,1000.*1E-4,1000.*1E-4,-21000.*1E-8,0.92,0.998,5.},/* 5<pt<6 */
1329                                                   {0.400,270.*1E-4,0.8,0.7,0.7,1000.*1E-4,1000.*1E-4,-14000.*1E-8,0.88,0.998,5.},/* 6<pt<8 */
1330                                                   {0.400,300.*1E-4,0.8,0.7,0.7,1000.*1E-4,1000.*1E-4,-5000.*1E-8,0.85,0.998,5.},/* 8<pt<12 */
1331                                                   {0.400,350.*1E-4,1.0,0.7,0.7,1000.*1E-4,1000.*1E-4,-1000.*1E-8,0.83,0.998,5.},/* 12<pt<16 */
1332                                                   {0.400,400.*1E-4,1.0,0.7,0.7,1000.*1E-4,1000.*1E-4,-1000.*1E-8,0.82,0.998,5.},/* 16<pt<20 */
1333                                                   {0.400,400.*1E-4,1.0,0.7,0.7,1000.*1E-4,1000.*1E-4,-1000.*1E-8,0.81,0.998,5.},/* 20<pt<24 */
1334                                                   {0.400,400.*1E-4,1.0,0.7,0.7,1000.*1E-4,1000.*1E-4,-1000.*1E-8,0.8,0.998,5.}};/* pt>24 */
1335   
1336   
1337   //CREATE TRANSPOSE MATRIX...REVERSE INDICES as required by AliRDHFCuts
1338   Float_t **cutsMatrixTransposeStand=new Float_t*[nvars];
1339   for(Int_t iv=0;iv<nvars;iv++)cutsMatrixTransposeStand[iv]=new Float_t[nptbins];
1340   
1341   for (Int_t ibin=0;ibin<nptbins;ibin++){
1342     for (Int_t ivar = 0; ivar<nvars; ivar++){
1343       cutsMatrixTransposeStand[ivar][ibin]=cutsMatrixD0toKpiStand[ibin][ivar];      
1344     }
1345   }
1346   
1347   SetCuts(nvars,nptbins,cutsMatrixTransposeStand);
1348   SetUseSpecialCuts(kTRUE);
1349   SetRemoveDaughtersFromPrim(kFALSE);// THIS IS VERY IMPORTANT! TOO SLOW IN PbPb
1350   for(Int_t iv=0;iv<nvars;iv++) delete [] cutsMatrixTransposeStand[iv];
1351   delete [] cutsMatrixTransposeStand;
1352   cutsMatrixTransposeStand=NULL;
1353   
1354   // PID SETTINGS
1355   AliAODPidHF* pidObj=new AliAODPidHF();
1356   //pidObj->SetName("pid4D0");
1357   Int_t mode=1;
1358   const Int_t nlims=2;
1359   Double_t plims[nlims]={0.6,0.8}; //TPC limits in momentum [GeV/c]
1360   Bool_t compat=kTRUE; //effective only for this mode
1361   Bool_t asym=kTRUE;
1362   Double_t sigmas[5]={2.,1.,0.,3.,0.}; //to be checked and to be modified with new implementation of setters by Rossella
1363   pidObj->SetAsym(asym);// if you want to use the asymmetric bands in TPC
1364   pidObj->SetMatch(mode);
1365   pidObj->SetPLimit(plims,nlims);
1366   pidObj->SetSigma(sigmas);
1367   pidObj->SetCompat(compat);
1368   pidObj->SetTPC(kTRUE);
1369   pidObj->SetTOF(kTRUE);
1370   pidObj->SetPCompatTOF(2.);
1371   pidObj->SetSigmaForTPCCompat(3.);
1372   pidObj->SetSigmaForTOFCompat(3.);  
1373
1374
1375   SetPidHF(pidObj);
1376   SetUsePID(kTRUE);
1377   SetUseDefaultPID(kFALSE);
1378
1379
1380   PrintAll();
1381
1382
1383   delete pidObj;
1384   pidObj=NULL;
1385
1386   return;
1387
1388 }