1 /**************************************************************************
\r
2 * Copyright(c) 1998-2010, ALICE Experiment at CERN, All rights reserved. *
\r
4 * Author: The ALICE Off-line Project. *
\r
5 * Contributors are mentioned in the code where appropriate. *
\r
7 * Permission to use, copy, modify and distribute this software and its *
\r
8 * documentation strictly for non-commercial purposes is hereby granted *
\r
9 * without fee, provided that the above copyright notice appears in all *
\r
10 * copies and that both the copyright notice and this permission notice *
\r
11 * appear in the supporting documentation. The authors make no claims *
\r
12 * about the suitability of this software for any purpose. It is *
\r
13 * provided "as is" without express or implied warranty. *
\r
14 **************************************************************************/
\r
16 /////////////////////////////////////////////////////////////
\r
18 // Class for cuts on AOD reconstructed D0->Kpipipi
\r
20 // Author: r.romita@gsi.de, andrea.dainese@pd.infn.it,
21 // fabio.colamaria@ba.infn.it
\r
22 /////////////////////////////////////////////////////////////
\r
24 #include <TDatabasePDG.h>
\r
25 #include <Riostream.h>
\r
27 #include "AliRDHFCutsD0toKpipipi.h"
\r
28 #include "AliAODRecoDecayHF4Prong.h"
\r
29 #include "AliAODTrack.h"
\r
30 #include "AliESDtrack.h"
\r
31 #include "AliAODPidHF.h"
33 ClassImp(AliRDHFCutsD0toKpipipi)
\r
35 //--------------------------------------------------------------------------
\r
36 AliRDHFCutsD0toKpipipi::AliRDHFCutsD0toKpipipi(const char* name) :
\r
40 // Default Constructor
\r
44 TString varNames[9]={"inv. mass [GeV]",
\r
46 "Dist 2-trk Vtx to PrimVtx [cm]",
\r
47 "Dist 3-trk Vtx to PrimVtx [cm]",
\r
48 "Dist 4-trk Vtx to PrimVtx [cm]",
\r
53 Bool_t isUpperCut[9]={kTRUE,
\r
62 SetVarNames(nvars,varNames,isUpperCut);
\r
63 Bool_t forOpt[9]={kFALSE,
\r
72 SetVarsForOpt(5,forOpt);
\r
73 Float_t limits[2]={0,999999999.};
\r
74 SetPtBins(2,limits);
\r
76 //--------------------------------------------------------------------------
\r
77 AliRDHFCutsD0toKpipipi::AliRDHFCutsD0toKpipipi(const AliRDHFCutsD0toKpipipi &source) :
\r
85 //--------------------------------------------------------------------------
\r
86 AliRDHFCutsD0toKpipipi &AliRDHFCutsD0toKpipipi::operator=(const AliRDHFCutsD0toKpipipi &source)
\r
89 // assignment operator
\r
91 if(&source == this) return *this;
\r
93 AliRDHFCuts::operator=(source);
\r
99 //---------------------------------------------------------------------------
\r
100 void AliRDHFCutsD0toKpipipi::GetCutVarsForOpt(AliAODRecoDecayHF *d,Float_t *vars,Int_t nvars,Int_t *pdgdaughters,AliAODEvent* aod) {
\r
102 // Fills in vars the values of the variables
\r
105 if(nvars!=fnVarsForOpt) {
\r
106 printf("AliRDHFCutsD0toKpipipi::GetCutsVarsForOpt: wrong number of variables\n");
\r
110 AliAODRecoDecayHF4Prong *dd = (AliAODRecoDecayHF4Prong*)d;
\r
112 //recalculate vertex w/o daughters
113 Bool_t cleanvtx=kFALSE;
114 AliAODVertex *origownvtx=0x0;
115 if(fRemoveDaughtersFromPrimary) {
116 if(dd->GetOwnPrimaryVtx()) origownvtx=new AliAODVertex(*dd->GetOwnPrimaryVtx());
118 if(!RecalcOwnPrimaryVtx(dd,aod)) {
119 CleanOwnPrimaryVtx(dd,aod,origownvtx);
126 if(fVarsForOpt[0]) {
\r
128 Double_t mD0[2],mD0bar[2];
\r
129 if(TMath::Abs(pdgdaughters[1])==321 || TMath::Abs(pdgdaughters[3])==321) {
\r
130 dd->InvMassD0(mD0);
\r
131 if(TMath::Abs(pdgdaughters[1])==321) {
\r
137 dd->InvMassD0bar(mD0bar);
\r
138 if(TMath::Abs(pdgdaughters[0])==321) {
\r
139 vars[iter]=mD0bar[0];
\r
141 vars[iter]=mD0bar[1];
\r
146 if(fVarsForOpt[1]){
\r
148 vars[iter]=dd->GetDCA();
\r
151 if(fVarsForOpt[2]){
\r
153 vars[iter]=dd->GetDist12toPrim();
\r
155 if(fVarsForOpt[3]){
\r
157 vars[iter]=dd->GetDist3toPrim();
\r
159 if(fVarsForOpt[4]){
\r
161 vars[iter]=dd->GetDist4toPrim();
\r
163 if(fVarsForOpt[5]){
\r
165 vars[iter]=dd->CosPointingAngle();
\r
167 if(fVarsForOpt[6]){
\r
169 vars[iter]=dd->Pt();
\r
171 if(fVarsForOpt[7]){
\r
173 vars[iter]=999999999.;
\r
174 printf("ERROR: optmization for rho mass cut not implemented\n");
\r
176 if(fVarsForOpt[8]){
\r
178 vars[iter]=999999999.;
\r
179 printf("ERROR: optmization for PID cut not implemented\n");
\r
182 if(cleanvtx)CleanOwnPrimaryVtx(dd,aod,origownvtx);
185 //---------------------------------------------------------------------------
\r
186 Int_t AliRDHFCutsD0toKpipipi::IsSelected(TObject* obj,Int_t selectionLevel) {
\r
192 cout<<"Cut matrix not inizialized. Exit..."<<endl;
\r
196 AliAODRecoDecayHF4Prong* d=(AliAODRecoDecayHF4Prong*)obj;
\r
199 cout<<"AliAODRecoDecayHF4Prong null"<<endl;
\r
203 Double_t ptD=d->Pt();
\r
204 if(ptD<fMinPtCand) return 0;
\r
205 if(ptD>fMaxPtCand) return 0;
207 // selection on daughter tracks
\r
208 if(selectionLevel==AliRDHFCuts::kAll ||
\r
209 selectionLevel==AliRDHFCuts::kTracks) {
\r
210 if(!AreDaughtersSelected(d)) return 0;
\r
214 Int_t returnvalue=1;
\r
216 // selection on candidate
\r
217 if(selectionLevel==AliRDHFCuts::kAll ||
\r
218 selectionLevel==AliRDHFCuts::kCandidate) {
\r
220 Int_t ptbin=PtBin(d->Pt());
\r
222 Int_t okD0=1,okD0bar=1;
\r
223 Double_t mD0[2],mD0bar[2];
\r
224 Double_t mD0PDG = TDatabasePDG::Instance()->GetParticle(421)->Mass();
\r
227 if(TMath::Abs(mD0[0]-mD0PDG) > fCutsRD[GetGlobalIndex(0,ptbin)] &&
\r
228 TMath::Abs(mD0[1]-mD0PDG) > fCutsRD[GetGlobalIndex(0,ptbin)]) okD0 = 0;
\r
229 d->InvMassD0bar(mD0bar);
\r
230 if(TMath::Abs(mD0bar[0]-mD0PDG) > fCutsRD[GetGlobalIndex(0,ptbin)] &&
\r
231 TMath::Abs(mD0bar[1]-mD0PDG) > fCutsRD[GetGlobalIndex(0,ptbin)]) okD0bar = 0;
\r
232 if(!okD0 && !okD0bar) return 0;
\r
234 if(d->GetDCA() > fCutsRD[GetGlobalIndex(1,ptbin)]
235 || d->GetDCA(3) > fCutsRD[GetGlobalIndex(1,ptbin)]
236 || d->GetDCA(2) > fCutsRD[GetGlobalIndex(1,ptbin)]
237 || d->GetDCA(5) > fCutsRD[GetGlobalIndex(1,ptbin)]) return 0;
\r
238 if(d->GetDist12toPrim() < fCutsRD[GetGlobalIndex(2,ptbin)]) return 0;
\r
239 if(d->GetDist3toPrim() < fCutsRD[GetGlobalIndex(3,ptbin)]) return 0;
\r
240 if(d->GetDist4toPrim() < fCutsRD[GetGlobalIndex(4,ptbin)]) return 0;
\r
241 if(d->CosPointingAngle() < fCutsRD[GetGlobalIndex(5,ptbin)]) return 0;
\r
242 if(d->Pt() < fCutsRD[GetGlobalIndex(6,ptbin)]) return 0;
\r
243 if(!d->CutRhoMass(mD0,mD0bar,fCutsRD[GetGlobalIndex(0,ptbin)],fCutsRD[GetGlobalIndex(7,ptbin)])) return 0;
\r
245 if (okD0) returnvalue=1; //cuts passed as D0
\r
246 if (okD0bar) returnvalue=2; //cuts passed as D0bar
\r
247 if (okD0 && okD0bar) returnvalue=3; //cuts passed as D0 and D0bar
\r
250 // selection on PID (from AliAODPidHF)
\r
251 if(selectionLevel==AliRDHFCuts::kAll ||
\r
252 selectionLevel==AliRDHFCuts::kPID) {
\r
254 Int_t selD01 = D01Selected(d,AliRDHFCuts::kCandidate);
255 Int_t selD02 = D02Selected(d,AliRDHFCuts::kCandidate);
256 Int_t selD0bar1 = D0bar1Selected(d,AliRDHFCuts::kCandidate);
257 Int_t selD0bar2 = D0bar2Selected(d,AliRDHFCuts::kCandidate);
259 Int_t d01PID = 0, d02PID = 0, d0bar1PID = 0, d0bar2PID = 0;
260 returnvalue = IsSelectedFromPID(d, &d01PID, &d02PID, &d0bar1PID, &d0bar2PID); //This returnvalue is dummy! Now it's modified as it must be!
264 if((selD01 == 1 && d01PID == 1)||(selD02 == 1 && d02PID == 1)||(selD0bar1 == 1 && d0bar1PID == 1)||(selD0bar2 == 1 && d0bar2PID == 1)) returnvalue = 1;
\r
267 return returnvalue;
\r
270 //---------------------------------------------------------------------------
\r
271 Int_t AliRDHFCutsD0toKpipipi::IsSelectedFromPID(AliAODRecoDecayHF4Prong *d, Int_t *hyp1, Int_t *hyp2, Int_t *hyp3, Int_t *hyp4) {
\r
273 // Apply selection (using AliAODPidHF methods)
274 // Mass hypothesis true if each particle is at least compatible with specie of hypothesis
\r
279 Int_t matchK[4], matchPi[4];
280 Double_t ptlimit[2] = {0.6,0.8};
\r
282 trk[0] = (AliAODTrack*)d->GetDaughter(0);
283 trk[1] = (AliAODTrack*)d->GetDaughter(1);
284 trk[2] = (AliAODTrack*)d->GetDaughter(2);
285 trk[3] = (AliAODTrack*)d->GetDaughter(3);
286 // if(!trk[0] || !trk[1] || !trk[2] || !trk[3]) { //REMOVED (needs also AliAODEvent to be passed, here and in IsSelected method)
287 // trk[0]=aodIn->GetTrack(trkIDtoEntry[d->GetProngID(0)]);
288 // trk[1]=aodIn->GetTrack(trkIDtoEntry[d->GetProngID(1)]);
289 // trk[2]=aodIn->GetTrack(trkIDtoEntry[d->GetProngID(2)]);
290 // trk[3]=aodIn->GetTrack(trkIDtoEntry[d->GetProngID(3)]);}
292 AliAODPidHF* PidObj = new AliAODPidHF();
293 PidObj->SetAsym(kTRUE);
294 PidObj->SetPLimit(ptlimit);
295 PidObj->SetSigma(0,2.); //TPC sigma, in three pT ranges
296 PidObj->SetSigma(1,1.);
297 PidObj->SetSigma(2,0.);
298 PidObj->SetSigma(3,2.); //TOF sigma, whole pT range
299 PidObj->SetTPC(kTRUE);
300 PidObj->SetTOF(kTRUE);
302 for(Int_t ii=0; ii<4; ii++) {
303 PidObj->SetSigma(0,2.);
304 matchK[ii] = PidObj->MatchTPCTOF(trk[ii],1,3,kTRUE); //arguments: track, mode, particle#, compatibility allowed
305 PidObj->SetSigma(0,2.);
306 matchPi[ii] = PidObj->MatchTPCTOF(trk[ii],1,2,kTRUE);
309 //Rho invariant mass under various hypotheses (to be matched with PID infos in order to accet the candidate)
310 Int_t d01rho03 = 0, d01rho23 = 0, d02rho01 = 0, d02rho12 = 0, d0bar1rho12 = 0, d0bar1rho23 = 0, d0bar2rho01 = 0, d0bar2rho03 = 0;
311 if(TMath::Abs(0.775 - d->InvMassRho(0,3))<0.1) {d01rho03 = 1; d0bar2rho03 = 1;}
312 if(TMath::Abs(0.775 - d->InvMassRho(2,3))<0.1) {d01rho23 = 1; d0bar1rho23 = 1;}
313 if(TMath::Abs(0.775 - d->InvMassRho(0,1))<0.1) {d02rho01 = 1; d0bar2rho01 = 1;}
314 if(TMath::Abs(0.775 - d->InvMassRho(1,2))<0.1) {d02rho12 = 1; d0bar1rho12 = 1;}
315 Int_t d01rho = 0, d02rho = 0, d0bar1rho = 0, d0bar2rho = 0;
316 if(d01rho03==1||d01rho23==1) d01rho = 1;
317 if(d02rho01==1||d02rho12==1) d02rho = 1;
318 if(d0bar1rho12==1||d0bar1rho23==1) d0bar1rho = 1;
319 if(d0bar2rho01==1||d0bar2rho03==1) d0bar2rho = 1;
321 //This way because there could be multiple hypotheses accepted
\r
322 if(d01rho==1 && (matchK[1]>=0 && matchPi[0]>=0 && matchPi[2]>=0 && matchPi[3]>=0)) {*hyp1 = 1; output = 1;} //d01 hyp
323 if(d02rho==1 && (matchK[3]>=0 && matchPi[0]>=0 && matchPi[1]>=0 && matchPi[2]>=0)) {*hyp2 = 1; output = 1;} //d02 hyp
324 if(d0bar1rho==1 && (matchK[0]>=0 && matchPi[1]>=0 && matchPi[2]>=0 && matchPi[3]>=0)) {*hyp3 = 1; output = 1;} //d0bar1 hyp
325 if(d0bar2rho==1 && (matchK[2]>=0 && matchPi[0]>=0 && matchPi[1]>=0 && matchPi[3]>=0)) {*hyp4 = 1; output = 1;} //d0bar2 hyp
329 //---------------------------------------------------------------------------
\r
330 Int_t AliRDHFCutsD0toKpipipi::D01Selected(TObject* obj,Int_t selectionLevel) {
\r
336 cout<<"Cut matrix not inizialized. Exit..."<<endl;
\r
340 AliAODRecoDecayHF4Prong* d=(AliAODRecoDecayHF4Prong*)obj;
\r
343 cout<<"AliAODRecoDecayHF4Prong null"<<endl;
\r
347 Int_t returnvalue=0;
\r
349 // selection on candidate
\r
350 if(selectionLevel==AliRDHFCuts::kAll ||
\r
351 selectionLevel==AliRDHFCuts::kCandidate) {
\r
353 Int_t ptbin=PtBin(d->Pt());
\r
356 Double_t mD0PDG = TDatabasePDG::Instance()->GetParticle(421)->Mass();
\r
359 if(TMath::Abs(mD0[0]-mD0PDG) < fCutsRD[GetGlobalIndex(0,ptbin)]) returnvalue = 1;
\r
362 return returnvalue;
\r
364 //---------------------------------------------------------------------------
\r
365 Int_t AliRDHFCutsD0toKpipipi::D02Selected(TObject* obj,Int_t selectionLevel) {
\r
371 cout<<"Cut matrix not inizialized. Exit..."<<endl;
\r
375 AliAODRecoDecayHF4Prong* d=(AliAODRecoDecayHF4Prong*)obj;
\r
378 cout<<"AliAODRecoDecayHF4Prong null"<<endl;
\r
382 Int_t returnvalue=0;
\r
384 // selection on candidate
\r
385 if(selectionLevel==AliRDHFCuts::kAll ||
\r
386 selectionLevel==AliRDHFCuts::kCandidate) {
\r
388 Int_t ptbin=PtBin(d->Pt());
\r
391 Double_t mD0PDG = TDatabasePDG::Instance()->GetParticle(421)->Mass();
\r
394 if(TMath::Abs(mD0[1]-mD0PDG) < fCutsRD[GetGlobalIndex(0,ptbin)]) returnvalue = 1;
397 return returnvalue;
\r
398 }
\r//---------------------------------------------------------------------------
\r
399 Int_t AliRDHFCutsD0toKpipipi::D0bar1Selected(TObject* obj,Int_t selectionLevel) {
\r
405 cout<<"Cut matrix not inizialized. Exit..."<<endl;
\r
409 AliAODRecoDecayHF4Prong* d=(AliAODRecoDecayHF4Prong*)obj;
\r
412 cout<<"AliAODRecoDecayHF4Prong null"<<endl;
\r
416 Int_t returnvalue=0;
\r
418 // selection on candidate
\r
419 if(selectionLevel==AliRDHFCuts::kAll ||
\r
420 selectionLevel==AliRDHFCuts::kCandidate) {
\r
422 Int_t ptbin=PtBin(d->Pt());
\r
424 Double_t mD0bar[2];
\r
425 Double_t mD0PDG = TDatabasePDG::Instance()->GetParticle(421)->Mass();
\r
427 d->InvMassD0bar(mD0bar);
\r
428 if(TMath::Abs(mD0bar[0]-mD0PDG) < fCutsRD[GetGlobalIndex(0,ptbin)]) returnvalue = 1;
\r
431 return returnvalue;
\r
433 //---------------------------------------------------------------------------
\r
434 Int_t AliRDHFCutsD0toKpipipi::D0bar2Selected(TObject* obj,Int_t selectionLevel) {
\r
440 cout<<"Cut matrix not inizialized. Exit..."<<endl;
\r
444 AliAODRecoDecayHF4Prong* d=(AliAODRecoDecayHF4Prong*)obj;
\r
447 cout<<"AliAODRecoDecayHF4Prong null"<<endl;
\r
451 Int_t returnvalue=0;
\r
453 // selection on candidate
\r
454 if(selectionLevel==AliRDHFCuts::kAll ||
\r
455 selectionLevel==AliRDHFCuts::kCandidate) {
\r
457 Int_t ptbin=PtBin(d->Pt());
\r
459 Double_t mD0bar[2];
\r
460 Double_t mD0PDG = TDatabasePDG::Instance()->GetParticle(421)->Mass();
\r
462 d->InvMassD0bar(mD0bar);
\r
463 if(TMath::Abs(mD0bar[1]-mD0PDG) < fCutsRD[GetGlobalIndex(0,ptbin)]) returnvalue = 1;
\r
466 return returnvalue;
\r
468 //---------------------------------------------------------------------------
469 Bool_t AliRDHFCutsD0toKpipipi::IsInFiducialAcceptance(Double_t pt, Double_t y) const
472 // Checking if D0 is in fiducial acceptance region
476 // applying cut for pt > 5 GeV
477 AliDebug(4,Form("pt of D0 = %f (> 5), cutting at |y| < 0.8\n",pt));
478 if (TMath::Abs(y) > 0.8){
482 // appliying smooth cut for pt < 5 GeV
483 Double_t maxFiducialY = -0.2/15*pt*pt+1.9/15*pt+0.5;
484 Double_t minFiducialY = 0.2/15*pt*pt-1.9/15*pt-0.5;
485 AliDebug(4,Form("pt of D0 = %f (< 5), cutting according to the fiducial zone [%f, %f]\n",pt,minFiducialY,maxFiducialY));
486 if (y < minFiducialY || y > maxFiducialY){