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