]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG3/vertexingHF/AliRDHFCutsD0toKpi.cxx
Fixed memory leak (Renu)
[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 /////////////////////////////////////////////////////////////
17 //
18 // Class for cuts on AOD reconstructed D0->Kpi
19 //
20 // Author: A.Dainese, andrea.dainese@pd.infn.it
21 /////////////////////////////////////////////////////////////
22
23 #include <TDatabasePDG.h>
24 #include <Riostream.h>
25
26 #include "AliRDHFCutsD0toKpi.h"
27 #include "AliAODRecoDecayHF2Prong.h"
28 #include "AliAODTrack.h"
29 #include "AliESDtrack.h"
30 #include "AliAODPid.h"
31 #include "AliTPCPIDResponse.h"
32 #include "AliAODVertex.h"
33
34 ClassImp(AliRDHFCutsD0toKpi)
35
36 //--------------------------------------------------------------------------
37 AliRDHFCutsD0toKpi::AliRDHFCutsD0toKpi(const char* name) : 
38 AliRDHFCuts(name),
39 fUseSpecialCuts(kFALSE)
40 {
41   //
42   // Default Constructor
43   //
44   Int_t nvars=9;
45   SetNVars(nvars);
46   TString varNames[9]={"inv. mass [GeV]",   
47                        "dca [cm]",
48                        "cosThetaStar", 
49                        "pTK [GeV/c]",
50                        "pTPi [GeV/c]",
51                        "d0K [cm]",
52                        "d0Pi [cm]",
53                        "d0d0 [cm^2]",
54                        "cosThetaPoint"};
55   Bool_t isUpperCut[9]={kTRUE,
56                         kTRUE,
57                         kTRUE,
58                         kFALSE,
59                         kFALSE,
60                         kTRUE,
61                         kTRUE,
62                         kTRUE,
63                         kFALSE};
64   SetVarNames(nvars,varNames,isUpperCut);
65   Bool_t forOpt[9]={kFALSE,
66                     kTRUE,
67                     kTRUE,
68                     kFALSE,
69                     kFALSE,
70                     kFALSE,
71                     kFALSE,
72                     kTRUE,
73                     kTRUE};
74   SetVarsForOpt(4,forOpt);
75   Float_t limits[2]={0,999999999.};
76   SetPtBins(2,limits);
77
78   SetRemoveDaughtersFromPrim(kTRUE);
79 }
80 //--------------------------------------------------------------------------
81 AliRDHFCutsD0toKpi::AliRDHFCutsD0toKpi(const AliRDHFCutsD0toKpi &source) :
82   AliRDHFCuts(source),  
83   fUseSpecialCuts(source.fUseSpecialCuts)
84 {
85   //
86   // Copy constructor
87   //
88
89 }
90 //--------------------------------------------------------------------------
91 AliRDHFCutsD0toKpi &AliRDHFCutsD0toKpi::operator=(const AliRDHFCutsD0toKpi &source)
92 {
93   //
94   // assignment operator
95   //
96   if(&source == this) return *this;
97
98   AliRDHFCuts::operator=(source);
99   fUseSpecialCuts=source.fUseSpecialCuts;
100
101   return *this;
102 }
103
104
105 //---------------------------------------------------------------------------
106 void AliRDHFCutsD0toKpi::GetCutVarsForOpt(AliAODRecoDecayHF *d,Float_t *vars,Int_t nvars,Int_t *pdgdaughters) {
107   // 
108   // Fills in vars the values of the variables 
109   //
110
111   if(nvars!=fnVarsForOpt) {
112     printf("AliRDHFCutsD0toKpi::GetCutsVarsForOpt: wrong number of variables\n");
113     return;
114   }
115
116   AliAODRecoDecayHF2Prong *dd = (AliAODRecoDecayHF2Prong*)d;
117  
118   Int_t iter=-1;
119   if(fVarsForOpt[0]){
120     iter++;
121     if(TMath::Abs(pdgdaughters[0])==211) {
122       vars[iter]=dd->InvMassD0();
123     } else {
124       vars[iter]=dd->InvMassD0bar();
125     }
126   }
127   if(fVarsForOpt[1]){
128     iter++;
129     vars[iter]=dd->GetDCA();
130   }
131   if(fVarsForOpt[2]){
132     iter++;
133     if(TMath::Abs(pdgdaughters[0])==211) {
134       vars[iter] = dd->CosThetaStarD0();
135     } else {
136       vars[iter] = dd->CosThetaStarD0bar();
137     }
138   }
139   if(fVarsForOpt[3]){
140     iter++;
141    if(TMath::Abs(pdgdaughters[0])==321) {
142      vars[iter]=dd->PtProng(0);
143    }
144    else{
145      vars[iter]=dd->PtProng(1);
146    }
147   }
148   if(fVarsForOpt[4]){
149     iter++;
150    if(TMath::Abs(pdgdaughters[0])==211) {
151      vars[iter]=dd->PtProng(0);
152    }
153    else{
154      vars[iter]=dd->PtProng(1);
155    }
156   }
157   if(fVarsForOpt[5]){
158     iter++;
159     if(TMath::Abs(pdgdaughters[0])==321) {
160      vars[iter]=dd->Getd0Prong(0);
161    }
162    else{
163      vars[iter]=dd->Getd0Prong(1);
164    }
165   }
166   if(fVarsForOpt[6]){
167     iter++;
168      if(TMath::Abs(pdgdaughters[0])==211) {
169      vars[iter]=dd->Getd0Prong(0);
170    }
171    else{
172      vars[iter]=dd->Getd0Prong(1);
173    }
174   }
175   if(fVarsForOpt[7]){
176     iter++;
177     vars[iter]= dd->Prodd0d0();
178   }
179   if(fVarsForOpt[8]){
180     iter++;
181     vars[iter]=dd->CosPointingAngle();
182   }
183   
184   return;
185 }
186 //---------------------------------------------------------------------------
187 Int_t AliRDHFCutsD0toKpi::IsSelected(TObject* obj,Int_t selectionLevel,AliAODEvent* aod) {
188   //
189   // Apply selection
190   //
191
192   if(!fCutsRD){
193     cout<<"Cut matrice not inizialized. Exit..."<<endl;
194     return 0;
195   }
196   //PrintAll();
197   AliAODRecoDecayHF2Prong* d=(AliAODRecoDecayHF2Prong*)obj;
198
199   if(!d){
200     cout<<"AliAODRecoDecayHF2Prong null"<<endl;
201     return 0;
202   }
203
204   // selection on daughter tracks 
205   if(selectionLevel==AliRDHFCuts::kAll || 
206      selectionLevel==AliRDHFCuts::kTracks) {
207     if(!AreDaughtersSelected(d)) return 0;
208   }
209
210
211  
212   // returnvalue: 0 not sel, 1 only D0, 2 only D0bar, 3 both
213   Int_t returnvaluePID=3;
214   Int_t returnvalueCuts=3;
215
216   // selection on PID 
217   if(selectionLevel==AliRDHFCuts::kAll || 
218      selectionLevel==AliRDHFCuts::kCandidate ||
219      selectionLevel==AliRDHFCuts::kPID) {
220     returnvaluePID = IsSelectedPID(d);
221   }
222
223
224
225   // selection on candidate
226   if(selectionLevel==AliRDHFCuts::kAll || 
227      selectionLevel==AliRDHFCuts::kCandidate) {
228
229     //recalculate vertex w/o daughters
230     AliAODVertex *origownvtx=0x0;
231     AliAODVertex *recvtx=0x0;
232     if(fRemoveDaughtersFromPrimary) {
233       if(!aod) {
234         AliError("Can not remove daughters from vertex without AOD event");
235         return 0;
236       }
237       if(d->GetOwnPrimaryVtx()) origownvtx=new AliAODVertex(*d->GetOwnPrimaryVtx());
238       recvtx=d->RemoveDaughtersFromPrimaryVtx(aod);
239       if(!recvtx){
240         AliDebug(2,"Removal of daughter tracks failed");
241         //recvtx=d->GetPrimaryVtx();
242         if(origownvtx){
243           delete origownvtx;
244           origownvtx=NULL;
245         }
246         return 0;
247       }
248       //set recalculed primary vertex
249       d->SetOwnPrimaryVtx(recvtx);
250       delete recvtx; recvtx=NULL;
251     }
252
253     
254     Double_t pt=d->Pt();
255    
256     Int_t okD0=0,okD0bar=0;
257  
258     Int_t ptbin=PtBin(pt);
259     if (ptbin==-1) {
260       if(origownvtx){
261         d->SetOwnPrimaryVtx(origownvtx);
262         delete origownvtx;
263         origownvtx=NULL;
264       }
265       else d->UnsetOwnPrimaryVtx();
266       return 0;
267     }
268     Double_t mD0,mD0bar,ctsD0,ctsD0bar;
269     okD0=1; okD0bar=1;
270
271     Double_t mD0PDG = TDatabasePDG::Instance()->GetParticle(421)->Mass();
272
273     if(d->PtProng(1) < fCutsRD[GetGlobalIndex(3,ptbin)] || d->PtProng(0) < fCutsRD[GetGlobalIndex(4,ptbin)]) okD0 = 0;
274     if(d->PtProng(0) < fCutsRD[GetGlobalIndex(3,ptbin)] || d->PtProng(1) < fCutsRD[GetGlobalIndex(4,ptbin)]) okD0bar = 0;
275     if(!okD0 && !okD0bar) returnvalueCuts=0;
276   
277     
278     if(TMath::Abs(d->Getd0Prong(1)) > fCutsRD[GetGlobalIndex(5,ptbin)] || 
279        TMath::Abs(d->Getd0Prong(0)) > fCutsRD[GetGlobalIndex(6,ptbin)]) okD0 = 0;
280     if(TMath::Abs(d->Getd0Prong(0)) > fCutsRD[GetGlobalIndex(6,ptbin)] ||
281        TMath::Abs(d->Getd0Prong(1)) > fCutsRD[GetGlobalIndex(5,ptbin)]) okD0bar = 0;
282     if(!okD0 && !okD0bar)  returnvalueCuts=0;
283     
284     if(d->GetDCA() > fCutsRD[GetGlobalIndex(1,ptbin)])  returnvalueCuts=0;
285     
286     d->InvMassD0(mD0,mD0bar);
287     if(TMath::Abs(mD0-mD0PDG) > fCutsRD[GetGlobalIndex(0,ptbin)]) okD0 = 0;
288     if(TMath::Abs(mD0bar-mD0PDG) > fCutsRD[GetGlobalIndex(0,ptbin)])  okD0bar = 0;
289     if(!okD0 && !okD0bar)  returnvalueCuts=0;
290     
291     d->CosThetaStarD0(ctsD0,ctsD0bar);
292     if(TMath::Abs(ctsD0) > fCutsRD[GetGlobalIndex(2,ptbin)]) okD0 = 0; 
293     if(TMath::Abs(ctsD0bar) > fCutsRD[GetGlobalIndex(2,ptbin)]) okD0bar = 0;
294     if(!okD0 && !okD0bar)   returnvalueCuts=0;
295     
296     if(d->Prodd0d0() > fCutsRD[GetGlobalIndex(7,ptbin)])  returnvalueCuts=0;
297     
298     if(d->CosPointingAngle() < fCutsRD[GetGlobalIndex(8,ptbin)])  returnvalueCuts=0;
299     
300     if (returnvalueCuts!=0) {
301       if (okD0) returnvalueCuts=1; //cuts passed as D0
302       if (okD0bar) returnvalueCuts=2; //cuts passed as D0bar
303       if (okD0 && okD0bar) returnvalueCuts=3; //cuts passed as D0 and D0bar
304     }
305
306     // call special cuts
307     Int_t special=1;
308     if(fUseSpecialCuts) special=IsSelectedSpecialCuts(d);
309     if(!special) returnvalueCuts=0;
310
311     // unset recalculated primary vertex when not needed any more
312     if(origownvtx) {
313       d->SetOwnPrimaryVtx(origownvtx);
314       delete origownvtx;
315       origownvtx=NULL;
316     } else if(fRemoveDaughtersFromPrimary) {
317       d->UnsetOwnPrimaryVtx();
318       AliDebug(3,"delete new vertex\n");
319     }
320
321   }
322
323  
324
325   //  cout<<"Pid = "<<returnvaluePID<<endl;
326   return CombineSelectionLevels(3,returnvalueCuts,returnvaluePID);
327 }
328 //---------------------------------------------------------------------------
329 Bool_t AliRDHFCutsD0toKpi::IsInFiducialAcceptance(Double_t pt, Double_t y) const
330 {
331   //
332   // Checking if D0 is in fiducial acceptance region 
333   //
334
335   if(pt > 5.) {
336     // applying cut for pt > 5 GeV
337     AliDebug(2,Form("pt of D0 = %f (> 5), cutting at |y| < 0.8\n",pt)); 
338     if (TMath::Abs(y) > 0.8){
339       return kFALSE;
340     }
341   } else {
342     // appliying smooth cut for pt < 5 GeV
343     Double_t maxFiducialY = -0.2/15*pt*pt+1.9/15*pt+0.5; 
344     Double_t minFiducialY = 0.2/15*pt*pt-1.9/15*pt-0.5;         
345     AliDebug(2,Form("pt of D0 = %f (< 5), cutting  according to the fiducial zone [%f, %f]\n",pt,minFiducialY,maxFiducialY)); 
346     if (y < minFiducialY || y > maxFiducialY){
347       return kFALSE;
348     }
349   }
350
351   return kTRUE;
352 }
353 //---------------------------------------------------------------------------
354 Int_t AliRDHFCutsD0toKpi::IsSelectedPID(AliAODRecoDecayHF* d) 
355 {
356   // ############################################################
357   //
358   // Apply PID selection
359   //
360   //
361   // temporary selection: PID AS USED FOR D0 by Andrea Rossi (up to 28/06/2010)
362   //
363   // d must be a AliAODRecoDecayHF2Prong object
364   // returns 0 if both D0 and D0bar are rejectecd
365   //         1 if D0 is accepted while D0bar is rejected
366   //         2 if D0bar is accepted while D0 is rejected
367   //         3 if both are accepted
368   // fWhyRejection variable (not returned for the moment, print it if needed)
369   //               keeps some information on why a candidate has been 
370   //               rejected according to the following (unfriendly?) scheme 
371   //             if more rejection cases are considered interesting, just add numbers
372   //
373   //      TO BE CONSIDERED WITH A GRAIN OF SALT (the order in which cut are applied is relevant) 
374   //              from 20 to 30: "detector" selection (PID acceptance)                                             
375   //                                                  26: TPC refit
376   //                                                  27: ITS refit
377   //                                                  28: no (TOF||TPC) pid information (no kTOFpid,kTOFout,kTIME,kTPCpid,...)
378   //
379   //              from 30 to 40: PID selection
380   //                                                  31: no Kaon compatible tracks found between daughters
381   //                                                  32: no Kaon identified tracks found (strong sel. at low momenta)
382   //                                                  33: both mass hypotheses are rejected 
383   //                  
384   // ############################################################
385
386   if(!fUsePID) return 3;
387   fWhyRejection=0;
388   Int_t isD0D0barPID[2]={1,2};
389   Double_t nsigmaTPCpi=-1., nsigmaTPCK=-1.; //used for TPC pid
390   Double_t tofSig,times[5];// used fot TOF pid
391   Int_t hasPID[2]={2,2};// flag to count how many detectors give PID info for the daughters
392   Int_t isKaonPionTOF[2][2],isKaonPionTPC[2][2];
393   Int_t combinedPID[2][2];// CONVENTION: [daught][isK,IsPi]; [0][0]=(prong 1, isK)=value [0][1]=(prong 1, isPi)=value; 
394   //                                                                                                 same for prong 2
395   //                                               values convention -1 = discarded 
396   //                                                                  0 = not identified (but compatible) || No PID (->hasPID flag)
397   //                                                                  1 = identified
398   // PID search:   pion (TPC) or not K (TOF), Kaon hypothesis for both 
399   // Initial hypothesis: unknwon (but compatible) 
400   isKaonPionTOF[0][0]=0;
401   isKaonPionTOF[0][1]=0;
402   isKaonPionTOF[1][0]=0;
403   isKaonPionTOF[1][1]=0;
404   
405   isKaonPionTPC[0][0]=0;
406   isKaonPionTPC[0][1]=0;
407   isKaonPionTPC[1][0]=0;
408   isKaonPionTPC[1][1]=0;
409   
410   combinedPID[0][0]=0;
411   combinedPID[0][1]=0;
412   combinedPID[1][0]=0;
413   combinedPID[1][1]=0;
414   
415   
416  
417   for(Int_t daught=0;daught<2;daught++){
418     //Loop con prongs
419     
420     // ########### Step 0- CHECKING minimal PID "ACCEPTANCE" ####################
421
422     AliAODTrack *aodtrack=(AliAODTrack*)d->GetDaughter(daught); 
423    
424     if(!(aodtrack->GetStatus()&AliESDtrack::kTPCrefit)){
425       fWhyRejection=26;
426       return 0;
427     } 
428     if(!(aodtrack->GetStatus()&AliESDtrack::kITSrefit)){
429       fWhyRejection=27;
430       return 0;
431     } 
432     
433     AliAODPid *pid=aodtrack->GetDetPid();
434     if(!pid) {
435       //delete esdtrack;
436       hasPID[daught]--;
437       continue;
438     }
439   
440     // ########### Step 1- Check of TPC and TOF response ####################
441
442     Double_t ptrack=aodtrack->P();
443     //#################### TPC PID #######################
444      if (!(aodtrack->GetStatus()&AliESDtrack::kTPCpid )){
445        // NO TPC PID INFO FOR THIS TRACK 
446        hasPID[daught]--;
447      }
448      else {
449        static AliTPCPIDResponse theTPCpid;
450        nsigmaTPCpi = theTPCpid.GetNumberOfSigmas((Float_t)aodtrack->P(),(Float_t)pid->GetTPCsignal(),(Int_t)aodtrack->GetTPCClusterMap().CountBits(),AliPID::kPion);
451        nsigmaTPCK =  theTPCpid.GetNumberOfSigmas((Float_t)aodtrack->P(),(Float_t)pid->GetTPCsignal(),(Int_t)aodtrack->GetTPCClusterMap().CountBits(),AliPID::kKaon);
452        if(ptrack<0.6){
453          if(TMath::Abs(nsigmaTPCK)<2.)isKaonPionTPC[daught][0]=1;
454          else if(TMath::Abs(nsigmaTPCK)>3.)isKaonPionTPC[daught][0]=-1;
455          if(TMath::Abs(nsigmaTPCpi)<2.)isKaonPionTPC[daught][1]=1;
456          else if(TMath::Abs(nsigmaTPCpi)>3.)isKaonPionTPC[daught][1]=-1;
457        }
458        else if(ptrack<.8){
459          if(TMath::Abs(nsigmaTPCK)<1.)isKaonPionTPC[daught][0]=1;
460          else if(TMath::Abs(nsigmaTPCK)>3.)isKaonPionTPC[daught][0]=-1;
461          if(TMath::Abs(nsigmaTPCpi)<1.)isKaonPionTPC[daught][1]=1;
462          else if(TMath::Abs(nsigmaTPCpi)>3.)isKaonPionTPC[daught][1]=-1;
463        }     
464        else {
465          //     if(nsigmaTPCK>-2.&&nsigmaTPCK<1.)isKaonPionTPC[daught][0]=1;
466          if(TMath::Abs(nsigmaTPCK)>3.)isKaonPionTPC[daught][0]=-1;
467          //if(nsigmaTPCpi>-1.&&nsigmaTPCpi<2.)isKaonPionTPC[daught][1]=1;
468          if(TMath::Abs(nsigmaTPCpi)>3.)isKaonPionTPC[daught][1]=-1;
469        }
470      }
471     
472     
473     // ##### TOF PID: do not ask nothing for pion/protons ############
474      if(!((aodtrack->GetStatus()&AliESDtrack::kTOFpid)&&(aodtrack->GetStatus()&AliESDtrack::kTOFout)&&(aodtrack->GetStatus()&AliESDtrack::kTIME))){
475        // NO TOF PID INFO FOR THIS TRACK      
476        hasPID[daught]--;
477      }
478      else{
479        tofSig=pid->GetTOFsignal(); 
480        pid->GetIntegratedTimes(times);
481        if(TMath::Abs(tofSig-times[3])>3.*160.){
482          isKaonPionTOF[daught][0]=-1;
483        }
484        else {    
485          if(ptrack<1.5){
486            isKaonPionTOF[daught][0]=1;
487          }
488        }
489      }
490      
491      //######### Step 2: COMBINE TOF and TPC PID ###############
492      // we apply the following convention: if TPC and TOF disagree (discarded Vs identified) -> unknown
493      combinedPID[daught][0]=isKaonPionTOF[daught][0]+isKaonPionTPC[daught][0];
494      combinedPID[daught][1]=isKaonPionTOF[daught][1]+isKaonPionTPC[daught][1];
495      
496      
497      //######### Step 3:   USE PID INFO     
498      
499      if(combinedPID[daught][0]<=-1&&combinedPID[daught][1]<=-1){// if not a K- and not a pi- both D0 and D0bar excluded
500        isD0D0barPID[0]=0;
501        isD0D0barPID[1]=0;
502      }
503      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
504        if(aodtrack->Charge()==-1)isD0D0barPID[1]=0;//if K- D0bar excluded
505        else isD0D0barPID[0]=0;// if K+ D0 excluded
506      }
507      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
508        isD0D0barPID[0]=0;
509        isD0D0barPID[1]=0;
510      }
511      else if(combinedPID[daught][0]>=1||combinedPID[daught][1]<=-1){
512        if(aodtrack->Charge()==-1)isD0D0barPID[1]=0;// not a D0bar if K- or if pi- excluded
513        else isD0D0barPID[0]=0;//  not a D0 if K+ or if pi+ excluded
514      }
515      else if(combinedPID[daught][0]<=-1||combinedPID[daught][1]>=1){
516        if(aodtrack->Charge()==-1)isD0D0barPID[0]=0;// not a D0 if pi- or if K- excluded
517       else isD0D0barPID[1]=0;// not a D0bar if pi+ or if K+ excluded
518      }
519      
520      // ##########  ALSO DIFFERENT TPC PID REQUEST FOR LOW pt D0: request of K identification      ###############################
521      // ########## more tolerant criteria for single particle ID-> more selective criteria for D0   ##############################
522      // ###############                     NOT OPTIMIZED YET                                  ###################################
523      if(d->Pt()<2.){
524        isKaonPionTPC[daught][0]=0;
525        isKaonPionTPC[daught][1]=0;
526        if(ptrack<0.6){
527          if(TMath::Abs(nsigmaTPCK)<3.)isKaonPionTPC[daught][0]=1;
528          else if(TMath::Abs(nsigmaTPCK)>3.)isKaonPionTPC[daught][0]=-1;
529          if(TMath::Abs(nsigmaTPCpi)<3.)isKaonPionTPC[daught][1]=1;
530          else if(TMath::Abs(nsigmaTPCpi)>3.)isKaonPionTPC[daught][1]=-1;
531      }
532        else if(ptrack<.8){
533          if(TMath::Abs(nsigmaTPCK)<2.)isKaonPionTPC[daught][0]=1;
534          else if(TMath::Abs(nsigmaTPCK)>3.)isKaonPionTPC[daught][0]=-1;
535          if(TMath::Abs(nsigmaTPCpi)<3.)isKaonPionTPC[daught][1]=1;
536          else if(TMath::Abs(nsigmaTPCpi)>3.)isKaonPionTPC[daught][1]=-1;
537        }     
538        else {
539          if(TMath::Abs(nsigmaTPCK)>3.)isKaonPionTPC[daught][0]=-1;
540          if(TMath::Abs(nsigmaTPCpi)>3.)isKaonPionTPC[daught][1]=-1;
541        }
542      }
543      
544   }// END OF LOOP ON DAUGHTERS
545   
546   // FURTHER PID REQUEST (both daughter info is needed)
547   if(combinedPID[0][0]<=-1&&combinedPID[1][0]<=-1){
548     fWhyRejection=31;// reject cases in which no kaon-compatible tracks are found
549     return 0;
550   }
551   else if(hasPID[0]==0&&hasPID[1]==0){
552     fWhyRejection=28;// reject cases in which no PID info is available  
553     return 0;
554   }
555   if(d->Pt()<2.){
556     // request of K identification at low D0 pt
557     combinedPID[0][0]=0;
558     combinedPID[0][1]=0;
559     combinedPID[1][0]=0;
560     combinedPID[1][1]=0;
561     
562     combinedPID[0][0]=isKaonPionTOF[0][0]+isKaonPionTPC[0][0];
563     combinedPID[0][1]=isKaonPionTOF[0][1]+isKaonPionTPC[0][1];
564     combinedPID[1][0]=isKaonPionTOF[1][0]+isKaonPionTPC[1][0];
565     combinedPID[1][1]=isKaonPionTOF[1][1]+isKaonPionTPC[1][1];
566     
567     if(combinedPID[0][0]<=0&&combinedPID[1][0]<=0){
568       fWhyRejection=32;// reject cases where the Kaon is not identified
569       return 0;
570     }
571   }
572
573   //  cout<<"Why? "<<fWhyRejection<<endl;  
574   return isD0D0barPID[0]+isD0D0barPID[1];
575 }
576
577 //---------------------------------------------------------------------------
578 Int_t AliRDHFCutsD0toKpi::CombineSelectionLevels(Int_t selectionvalTrack,
579                                                  Int_t selectionvalCand,
580                                                  Int_t selectionvalPID) const
581 {
582   //
583   // This method combines the tracks, PID and cuts selection results
584   //
585   if(selectionvalTrack==0) return 0;
586
587   Int_t returnvalue;
588
589   switch(selectionvalPID) {
590   case 0:
591     returnvalue=0;
592     break;
593   case 1:
594     returnvalue=((selectionvalCand==1 || selectionvalCand==3) ? 1 : 0);
595     break;
596   case 2:
597     returnvalue=((selectionvalCand==2 || selectionvalCand==3) ? 2 : 0);
598     break;
599   case 3:
600     returnvalue=selectionvalCand;
601     break;
602   default:
603     returnvalue=0;
604     break;
605   }
606
607   return returnvalue;
608 }
609 //----------------------------------------------------------------------------
610 Int_t AliRDHFCutsD0toKpi::IsSelectedSpecialCuts(AliAODRecoDecayHF *d) const
611 {
612   //
613   // Note: this method is temporary
614   // Additional cuts on decay lenght and lower cut for d0 norm are applied using vertex without candidate's daughters
615   //
616
617   //apply cuts
618
619   Float_t normDecLengthCut=1.,decLengthCut=TMath::Min(d->P()*0.0066+0.01,0.06/*cm*/), normd0Cut=0.5;
620   // "decay length" expo law with tau' = beta*gamma*ctau= p/m*ctau =p*0.0123/1.864~p*0.0066
621   // decay lenght > ctau' implies to retain (1-1/e) (for signal without considering detector resolution), 
622
623   Int_t returnvalue=3; //cut passed
624   for(Int_t i=0;i<2/*prongs*/;i++){
625     if(TMath::Abs(d->Normalizedd0Prong(i))<normd0Cut) return 0; //normd0Cut not passed
626   }
627   if(d->DecayLength()<decLengthCut)  return 0; //decLengthCut not passed
628   if(d->NormalizedDecayLength()<normDecLengthCut)  return 0; //decLengthCut not passed
629     
630
631   return returnvalue;
632 }