1 /*************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////
18 // Analysis task for computing single particle efficiencies //
20 ///////////////////////////////////////////////////////////////////////////
25 #include <THashList.h>
29 #include <AliCFContainer.h>
30 #include <AliInputEventHandler.h>
31 #include <AliESDInputHandler.h>
32 #include <AliAODInputHandler.h>
33 #include <AliAnalysisManager.h>
34 #include <AliVEvent.h>
35 #include <AliESDEvent.h>
37 #include <AliESDv0Cuts.h>
38 #include <AliESDv0KineCuts.h>
39 #include <AliKFVertex.h>
40 #include <AliESDfriendTrack.h>
41 #include <AliESDfriend.h>
42 #include <AliTRDseedV1.h>
43 #include <AliTRDcluster.h>
44 #include <AliTRDtrackV1.h>
46 #include "AliDielectron.h"
47 #include "AliDielectronHistos.h"
48 #include "AliDielectronPair.h"
49 #include "AliDielectronCF.h"
50 #include "AliDielectronMC.h"
51 #include "AliDielectronHistos.h"
52 #include "AliAnalysisTaskSingleParticle.h"
57 ClassImp(AliAnalysisTaskSingleParticle)
59 //_________________________________________________________________________________
60 AliAnalysisTaskSingleParticle::AliAnalysisTaskSingleParticle() :
65 fSelectPhysics(kTRUE),
66 fTriggerMask(AliVEvent::kMB),
67 fRejectPileup(kFALSE),
68 fFillTRDfriendPH(kFALSE),
82 for(Int_t i=0; i<kNMaxDimensions; ++i) {
83 fCFVarsEnabled[i] = -1; fCFVarsNbins[i] = 0;
84 fCFVarRanges[i][0] = 0.0; fCFVarRanges[i][1] = -1.0;
89 //_________________________________________________________________________________
90 AliAnalysisTaskSingleParticle::AliAnalysisTaskSingleParticle(const char *name) :
91 AliAnalysisTaskSE(name),
95 fSelectPhysics(kTRUE),
96 fTriggerMask(AliVEvent::kMB),
97 fRejectPileup(kFALSE),
98 fFillTRDfriendPH(kFALSE),
112 for(Int_t i=0; i<kNMaxDimensions; ++i) {
113 fCFVarsEnabled[i] = -1; fCFVarsNbins[i] = 0;
114 fCFVarRanges[i][0] = 0.0; fCFVarRanges[i][1] = -1.0;
117 fHistogramList.SetName("QAhistos");
118 fHistogramList.SetOwner();
119 DefineInput(0, TChain::Class());
120 DefineOutput(1, AliCFContainer::Class());
121 DefineOutput(2, TList::Class());
122 DefineOutput(3, TH1D::Class());
126 //____________________________________________________________________
127 AliAnalysisTaskSingleParticle::~AliAnalysisTaskSingleParticle()
132 fHistogramList.SetOwner(kFALSE);
133 if(fHistos) delete fHistos;
138 //____________________________________________________________________
139 void AliAnalysisTaskSingleParticle::AddCFVar(Int_t var, Int_t nbins, Double_t lowLim, Double_t highLim) {
141 // Configure variables for the CF container
143 if(fCFNVars>=kNMaxDimensions) return;
144 fCFVarsEnabled[fCFNVars] = var;
145 fCFVarsNbins[fCFNVars] = nbins;
146 fCFVarRanges[fCFNVars][0] = lowLim;
147 fCFVarRanges[fCFNVars][1] = highLim;
152 //____________________________________________________________________
153 void AliAnalysisTaskSingleParticle::AddCFVar(Int_t var, const Char_t* bins) {
155 // Configure variables for the CF container
157 if(fCFNVars>=kNMaxDimensions) return;
158 fCFVarsEnabled[fCFNVars] = var;
159 fCFVarBins[fCFNVars] = bins;
164 //_________________________________________________________________________________
165 void AliAnalysisTaskSingleParticle::UserCreateOutputObjects()
168 // Initialize CF container
170 if(fCfContainer) return;
171 if(!fHistogramList.IsEmpty()) return;
174 fEventStat=new TH1D("hEventStat","Event statistics",4,-0.5,3.5);
175 fEventStat->GetXaxis()->SetBinLabel(1,"Before Phys. Sel.");
176 fEventStat->GetXaxis()->SetBinLabel(2,"After Phys. Sel.");
177 fEventStat->GetXaxis()->SetBinLabel(3,"After event filter");
178 fEventStat->GetXaxis()->SetBinLabel(4,"After pileup rejection");
181 //Bool_t hasMC = AliDielectronMC::Instance()->HasMC();
184 for(Int_t ivar=0; ivar<fCFNVars; ++ivar) {
185 if(fCFVarBins[ivar][0]!='\0') {
186 TObjArray* arr = fCFVarBins[ivar].Tokenize(",");
187 fCFVarsNbins[ivar] = arr->GetEntries()-1;
190 fCFVarsNbins[fCFNVars] = AliPID::kSPECIES;
192 // If fFillTRDfriendPH is toggled then add some predefined variables to the CF
193 // Hardcoded variables and binning !! TODO: Implement them in the VarManager ??
194 // This container is filled for every TRD time bin, and every tracklet from a track
195 Double_t phLimits[2] = {0.0, 2000.}; Int_t phBins = 200;
196 Double_t detLimits[2] = {-0.5, 539.5}; Int_t detBins = 540;
197 const Int_t kNTrdMomBins = 17;
198 Double_t trdMomLimits[kNTrdMomBins+1] = {0.0, 0.5, 0.7, 0.9, 1.1, 1.3, 1.5, 1.7, 1.9, 2.1, 2.5, 3.0, 3.5, 4.0, 5.0, 6.0, 8.0, 10.0};
199 Int_t trdNtb = 30; Double_t trdTbLims[2] = {0.5, 30.5};
200 Int_t trdQtotNbins = 200; Double_t trdQtotLims[2] = {0.0, 10000.};
201 fCFVarsNbins[fCFNVars+1] = kNTrdMomBins;
202 fCFVarsNbins[fCFNVars+2] = detBins;
203 fCFVarsNbins[fCFNVars+3] = trdNtb;
204 fCFVarsNbins[fCFNVars+4] = phBins;
205 fCFVarsNbins[fCFNVars+5] = trdQtotNbins;
207 if(fCFNVars>0 || fFillTRDfriendPH) {
208 fCfContainer = new AliCFContainer("SingleParticle", "Single Particle CF", 1, (fFillTRDfriendPH ? fCFNVars+6 : fCFNVars+1), fCFVarsNbins);
209 for(Int_t ivar=0; ivar<fCFNVars; ++ivar) {
210 if(fCFVarBins[ivar][0]=='\0')
211 fCfContainer->SetBinLimits(ivar, fCFVarRanges[ivar][0], fCFVarRanges[ivar][1]);
213 TObjArray* arr = fCFVarBins[ivar].Tokenize(",");
214 if(arr->GetEntries()-1>0) {
215 Double_t* binLims = new Double_t[arr->GetEntries()];
216 for(Int_t ib=0;ib<arr->GetEntries();++ib) {
217 TString binStr = arr->At(ib)->GetName();
218 binLims[ib] = binStr.Atof();
220 fCfContainer->SetBinLimits(ivar, binLims);
223 fCfContainer->SetVarTitle(ivar, AliDielectronVarManager::GetValueName(fCFVarsEnabled[ivar]));
225 fCfContainer->SetBinLimits(fCFNVars, -0.5+AliPID::kElectron, 0.5+AliPID::kProton);
226 fCfContainer->SetVarTitle(fCFNVars, "specie");
227 if(fFillTRDfriendPH) {
228 fCfContainer->SetBinLimits(fCFNVars+1, trdMomLimits);
229 fCfContainer->SetVarTitle(fCFNVars+1, "TRD_trackletMom");
230 fCfContainer->SetBinLimits(fCFNVars+2, detLimits[0], detLimits[1]);
231 fCfContainer->SetVarTitle(fCFNVars+2, "TRD_detector");
232 fCfContainer->SetBinLimits(fCFNVars+3, trdTbLims[0], trdTbLims[1]);
233 fCfContainer->SetVarTitle(fCFNVars+3, "TRD_tb");
234 fCfContainer->SetBinLimits(fCFNVars+4, phLimits[0], phLimits[1]);
235 fCfContainer->SetVarTitle(fCFNVars+4, "TRD_PH");
236 fCfContainer->SetBinLimits(fCFNVars+5, trdQtotLims[0], trdQtotLims[1]);
237 fCfContainer->SetVarTitle(fCFNVars+5, "TRD_Qtot");
239 fCfContainer->SetStepTitle(0, "Tracking");
244 fHistogramList.Add(const_cast<THashList*>(fHistos->GetHistogramList()));
247 if(fCfContainer) PostData(1, fCfContainer);
248 if(fHistos) PostData(2, &fHistogramList);
249 PostData(3, fEventStat);
252 //_________________________________________________________________________________
253 void AliAnalysisTaskSingleParticle::UserExec(Option_t *)
256 // Main loop. Called for every event
259 AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
260 //Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
261 //Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
263 AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
264 if (!inputHandler) return;
266 if ( inputHandler->GetPIDResponse() ){
267 AliDielectronVarManager::SetPIDResponse( inputHandler->GetPIDResponse() );
269 AliFatal("This task needs the PID response attached to the input event handler!");
271 // Was event selected ?
272 UInt_t isSelected = AliVEvent::kAny;
273 if( fSelectPhysics && inputHandler && inputHandler->GetEventSelection() ) {
274 isSelected = inputHandler->IsEventSelected();
275 isSelected&=fTriggerMask;
278 //Before physics selection
281 PostData(3,fEventStat);
284 //after physics selection
289 if (!fEventFilter->IsSelected(InputEvent())) {PostData(3, fEventStat); return;}
295 if (InputEvent()->IsPileupFromSPD(3,0.8,3.,2.,5.)) {PostData(3, fEventStat); return;}
299 if(!fCfContainer) {PostData(3, fEventStat); return;}
301 Double_t bz = InputEvent()->GetMagneticField();
302 AliKFParticle::SetField( bz );
304 AliDielectronPID::SetCorrVal((Double_t)InputEvent()->GetRunNumber());
306 AliESDEvent* esd = (AliESDEvent*)InputEvent();
307 AliDielectronVarManager::SetEvent(esd);
309 Double_t valuesPos[AliDielectronVarManager::kNMaxValues];
310 Double_t valuesNeg[AliDielectronVarManager::kNMaxValues];
311 Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
312 AliDielectronVarManager::Fill(esd, valuesPos);
313 AliDielectronVarManager::Fill(esd, valuesNeg);
314 AliDielectronVarManager::Fill(esd, valuesPair);
316 if(fHistos && fHistos->GetHistogramList()->FindObject("Event"))
317 fHistos->FillClass("Event", AliDielectronVarManager::kNMaxValues, valuesPos);
319 const AliESDVertex *primaryVertex = esd->GetPrimaryVertex();
320 AliKFVertex primaryVertexKF(*primaryVertex);
322 fV0KineCuts->SetEvent(esd);
323 fV0KineCuts->SetPrimaryVertex(&primaryVertexKF);
325 Int_t pdgV0=0; Int_t pdgP=0; Int_t pdgN=0;
326 for(Int_t iV0=0; iV0<InputEvent()->GetNumberOfV0s(); ++iV0) { // loop over V0s
327 //cout << "iV0 = " << iV0 << endl;
328 AliESDv0 *v0 = esd->GetV0(iV0);
330 AliESDtrack* legPos = esd->GetTrack(v0->GetPindex());
331 AliESDtrack* legNeg = esd->GetTrack(v0->GetNindex());
333 if(legPos->GetSign() == legNeg->GetSign()) {
334 //cout << "V0 rejected: same sign legs" << endl;
338 //To avoid ghosts test of trunk for the refit
339 if(!(legPos->GetStatus() & AliESDtrack::kTPCrefit)) {
340 //cout << "pos leg rejected: no TPCrefit" << endl;
343 if(!(legNeg->GetStatus() & AliESDtrack::kTPCrefit)) {
344 //cout << "neg leg rejected: no TPCrefit" << endl;
348 Bool_t v0ChargesAreCorrect = (legPos->GetSign()==+1 ? kTRUE : kFALSE);
349 legPos = (!v0ChargesAreCorrect ? esd->GetTrack(v0->GetNindex()) : legPos);
350 legNeg = (!v0ChargesAreCorrect ? esd->GetTrack(v0->GetPindex()) : legNeg);
352 Bool_t good = fV0KineCuts->ProcessV0(v0, pdgV0, pdgP, pdgN);
354 //cout << "V0KineCuts rejected V0" << endl;
358 if(!fFillTRDfriendPH) {
359 //cout << "No TRD friend filling" << endl;
360 if(pdgV0!=22) continue;
361 if(TMath::Abs(pdgN)!=11) continue;
362 if(TMath::Abs(pdgP)!=11) continue;
369 v0List.Add(legPos); v0List.Add(legNeg);
370 v0List.Add(const_cast<AliESDVertex*>(primaryVertex));
371 if(!fV0Cuts->IsSelected(&v0List)) continue;
374 // additional track filtering
375 if(fTrackFilter && !fTrackFilter->IsSelected(legPos)) {
376 //cout << "pos leg rejected: track filter" << endl;
379 if(fTrackFilter && !fTrackFilter->IsSelected(legNeg)) {
380 //cout << "neg leg rejected: track filter" << endl;
384 AliKFParticle* posKF = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamP()),pdgP) : new AliKFParticle(*(v0->GetParamN()),pdgN));
385 AliKFParticle* negKF = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamN()),pdgN) : new AliKFParticle(*(v0->GetParamP()),pdgP));
386 AliDielectronPair pair;
387 pair.SetTracks(posKF, negKF, legPos, legNeg);
389 if(fPairFilter && !fPairFilter->IsSelected(&pair)) {
390 //cout << "diele pair rejected: pair filter" << endl;
394 // additional filtering on the KF pair (mass, chi2, etc.)
395 // Gamma conversion inclusion cuts
397 AliKFParticle* posKFGammaEle = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamP()),-11) : new AliKFParticle(*(v0->GetParamN()),-11));
398 AliKFParticle* negKFGammaEle = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamN()),+11) : new AliKFParticle(*(v0->GetParamP()),+11));
399 AliDielectronPair gammaPair;
400 gammaPair.SetTracks(posKFGammaEle, negKFGammaEle, legPos, legNeg);
401 gammaPair.SetType(1);
402 if(fPairFilter && !fPairFilter->IsSelected(&gammaPair)) continue;
405 // Lambda exclusion cuts
406 AliKFParticle* posKFLambdaPro = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamP()),2212) : new AliKFParticle(*(v0->GetParamN()),2212));
407 AliKFParticle* negKFLambdaPio = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamN()),-211) : new AliKFParticle(*(v0->GetParamP()),-211));
408 AliDielectronPair lambdaPair;
409 lambdaPair.SetTracks(posKFLambdaPro, negKFLambdaPio, legPos, legNeg);
410 lambdaPair.SetType(1);
411 if(fLambdaFilter && fLambdaFilter->IsSelected(&lambdaPair)) continue;
412 // Anti-Lambda exclusion cuts
413 AliKFParticle* posKFALambdaPio = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamP()),211) : new AliKFParticle(*(v0->GetParamN()),211));
414 AliKFParticle* negKFALambdaPro = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamN()),-2212) : new AliKFParticle(*(v0->GetParamP()),-2212));
415 AliDielectronPair alambdaPair;
416 alambdaPair.SetTracks(posKFALambdaPio, negKFALambdaPro, legPos, legNeg);
417 alambdaPair.SetType(1);
418 if(fLambdaFilter && fLambdaFilter->IsSelected(&alambdaPair)) continue;
419 // K0s exclusion cuts
420 AliKFParticle* posKFK0sPio = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamP()),211) : new AliKFParticle(*(v0->GetParamN()),211));
421 AliKFParticle* negKFK0sPio = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamN()),-211) : new AliKFParticle(*(v0->GetParamP()),-211));
422 AliDielectronPair k0sPair;
423 k0sPair.SetTracks(posKFK0sPio, negKFK0sPio, legPos, legNeg);
425 if(fK0sFilter && fK0sFilter->IsSelected(&k0sPair)) continue;
428 // Fill histograms and the CF container
429 AliDielectronVarManager::Fill(legPos, valuesPos);
430 AliDielectronVarManager::Fill(legNeg, valuesNeg);
432 if(fHistos && fHistos->GetHistogramList()->FindObject("Track_Pos"))
433 fHistos->FillClass("Track_Pos", AliDielectronVarManager::kNMaxValues, valuesPos);
434 if(fHistos && fHistos->GetHistogramList()->FindObject("Track_Neg"))
435 fHistos->FillClass("Track_Neg", AliDielectronVarManager::kNMaxValues, valuesNeg);
437 AliDielectronVarManager::Fill(&pair, valuesPair);
438 if(fHistos && fHistos->GetHistogramList()->FindObject(Form("Pair_%s",AliDielectron::PairClassName(1))))
439 fHistos->FillClass(Form("Pair_%s",AliDielectron::PairClassName(1)), AliDielectronVarManager::kNMaxValues, valuesPair);
441 if(valuesPos[AliDielectronVarManager::kPOut]>=0.5)
442 FillContainer(0, valuesPos, (v0ChargesAreCorrect ? v0->GetPindex() : v0->GetNindex()), (v0ChargesAreCorrect ? pdgP : pdgN));
443 if(valuesNeg[AliDielectronVarManager::kPOut]>=0.5)
444 FillContainer(0, valuesNeg, (v0ChargesAreCorrect ? v0->GetNindex() : v0->GetPindex()), (v0ChargesAreCorrect ? pdgN : pdgP));
445 } // end loop over online V0s
449 PostData(1, fCfContainer);
450 PostData(2, &fHistogramList);
451 PostData(3, fEventStat);
454 //_________________________________________________________________________________
455 void AliAnalysisTaskSingleParticle::FinishTaskOutput()
463 //_________________________________________________________________________________
464 void AliAnalysisTaskSingleParticle::FillContainer(Int_t step, const Double_t* values, Int_t trackId, Int_t pdg) {
466 // Fill the CF container
468 Double_t valuesCF[kNMaxDimensions];
469 for(Int_t i=0; i<fCFNVars; ++i) valuesCF[i] = values[fCFVarsEnabled[i]];
472 if(TMath::Abs(pdg)==11) pid = AliPID::kElectron;
473 if(TMath::Abs(pdg)==13) pid = AliPID::kMuon;
474 if(TMath::Abs(pdg)==211) pid = AliPID::kPion;
475 if(TMath::Abs(pdg)==321) pid = AliPID::kKaon;
476 if(TMath::Abs(pdg)==2212) pid = AliPID::kProton;
477 valuesCF[fCFNVars] = pid;
479 if(fFillTRDfriendPH) {
480 AliESDfriendTrack* friendTrk = fESDfriend->GetTrack(trackId);
481 if(!friendTrk) return;
482 if(values[AliDielectronVarManager::kTRDntracklets]>0.001) {
483 TObject* o=0x0; Int_t ical = 0;
484 AliTRDtrackV1* trdTrack=0x0;
486 o = friendTrk->GetCalibObject(ical++);
488 TString objName = o->IsA()->GetName();
489 if(!objName.Contains("AliTRDtrackV1")) continue;
490 trdTrack = dynamic_cast<AliTRDtrackV1*>(o);
493 if(!trdTrack) return;
495 Double_t charge = 0.0;
496 for(Int_t ipl = 0; ipl < 6; ipl++) { // loop over TRD layers
497 AliTRDseedV1 *tracklet = trdTrack->GetTracklet(ipl);
498 if(!tracklet) continue;
499 if(!tracklet->IsOK()) continue;
500 valuesCF[fCFNVars+1] = tracklet->GetMomentum();
501 valuesCF[fCFNVars+2] = tracklet->GetDetector();
503 for(Int_t itb = 0; itb < AliTRDseedV1::kNtb; itb++){
504 AliTRDcluster *c = tracklet->GetClusters(itb);
505 AliTRDcluster *c1 = tracklet->GetClusters(itb + AliTRDseedV1::kNtb); // second pad row
506 if(c) charge += TMath::Abs(c->GetQ()); //
507 if(c1) charge += TMath::Abs(c1->GetQ());
509 valuesCF[fCFNVars+5] = charge;
511 for(Int_t itb = 0; itb < AliTRDseedV1::kNtb; itb++){
512 AliTRDcluster *c = tracklet->GetClusters(itb);
513 AliTRDcluster *c1 = tracklet->GetClusters(itb + AliTRDseedV1::kNtb); // second pad row
514 if(!(c || c1)) continue;
515 AliTRDcluster *cptr = (c ? c : c1);
516 Int_t tcal = cptr->GetLocalTimeBin();
518 if(c) sig += TMath::Abs(c->GetQ()); //
519 if(c1) sig += TMath::Abs(c1->GetQ());
520 valuesCF[fCFNVars+3] = tcal;
521 valuesCF[fCFNVars+4] = sig;
523 fCfContainer->Fill(valuesCF, step);
524 } // end loop over time bins
525 } // end loop over tracklets
526 } // end if track has TRD tracklets
527 } // end if fill TRD friend PH
528 if(!fFillTRDfriendPH)
529 fCfContainer->Fill(valuesCF, step);