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 // Basic Analysis Task //
20 ///////////////////////////////////////////////////////////////////////////
25 #include <AliAODHandler.h>
26 #include <AliAODInputHandler.h>
27 #include <AliAnalysisManager.h>
28 #include <AliVEvent.h>
29 #include <AliTriggerAnalysis.h>
30 #include <AliInputEventHandler.h>
31 #include <AliAODInputHandler.h>
32 #include <AliESDInputHandler.h>
34 #include "AliDielectron.h"
35 #include "AliDielectronMC.h"
36 #include "AliDielectronHistos.h"
37 #include "AliDielectronVarManager.h"
38 #include "AliAnalysisTaskDielectronFilter.h"
39 #include "AliAODCaloCluster.h"
41 ClassImp(AliAnalysisTaskDielectronFilter)
43 //_________________________________________________________________________________
44 AliAnalysisTaskDielectronFilter::AliAnalysisTaskDielectronFilter() :
47 fSelectPhysics(kTRUE),
48 fTriggerMask(AliVEvent::kMB),
49 fExcludeTriggerMask(0),
50 fTriggerOnV0AND(kFALSE),
51 fRejectPileup(kFALSE),
54 fTriggerAnalysis(0x0),
55 fStoreLikeSign(kFALSE),
56 fStoreRotatedPairs(kFALSE),
57 fStoreEventsWithSingleTracks(kFALSE),
58 fCreateNanoAOD(kFALSE),
67 //_________________________________________________________________________________
68 AliAnalysisTaskDielectronFilter::AliAnalysisTaskDielectronFilter(const char *name) :
69 AliAnalysisTaskSE(name),
71 fSelectPhysics(kTRUE),
72 fTriggerMask(AliVEvent::kMB),
73 fExcludeTriggerMask(0),
74 fTriggerOnV0AND(kFALSE),
75 fRejectPileup(kFALSE),
78 fTriggerAnalysis(0x0),
79 fStoreLikeSign(kFALSE),
80 fStoreRotatedPairs(kFALSE),
81 fStoreEventsWithSingleTracks(kFALSE),
82 fCreateNanoAOD(kFALSE),
89 DefineInput(0,TChain::Class());
90 DefineOutput(1, THashList::Class());
91 DefineOutput(2, TH1D::Class());
94 //_________________________________________________________________________________
95 void AliAnalysisTaskDielectronFilter::Init()
98 if (fDebug > 1) AliInfo("Init() \n");
100 // require AOD handler
101 AliAODHandler *aodH = (AliAODHandler*)((AliAnalysisManager::GetAnalysisManager())->GetOutputEventHandler());
102 if (!aodH) AliFatal("No AOD handler. Halting.");
104 aodH->AddFilteredAOD("AliAOD.Dielectron.root", "DielectronEvents");
105 // AddAODBranch("AliDielectronCandidates",fDielectron->GetPairArraysPointer(),"deltaAOD.Dielectron.root");
108 //_________________________________________________________________________________
109 void AliAnalysisTaskDielectronFilter::UserCreateOutputObjects()
112 // Initilise histograms
115 //require dielectron framework
117 AliFatal("Dielectron framework class required. Please create and instance with proper cuts and set it via 'SetDielectron' before executing this task!!!");
120 if(fStoreRotatedPairs) fDielectron->SetStoreRotatedPairs(kTRUE);
121 fDielectron->SetDontClearArrays();
124 Int_t nbins=kNbinsEvent+2;
126 fEventStat=new TH1D("hEventStat","Event statistics",nbins,0,nbins);
127 fEventStat->GetXaxis()->SetBinLabel(1,"Before Phys. Sel.");
128 fEventStat->GetXaxis()->SetBinLabel(2,"After Phys. Sel.");
131 fEventStat->GetXaxis()->SetBinLabel(3,"Bin3 not used");
132 fEventStat->GetXaxis()->SetBinLabel(4,"Bin4 not used");
133 fEventStat->GetXaxis()->SetBinLabel(5,"Bin5 not used");
135 if(fTriggerOnV0AND) fEventStat->GetXaxis()->SetBinLabel(3,"V0and triggers");
136 if (fEventFilter) fEventStat->GetXaxis()->SetBinLabel(4,"After Event Filter");
137 if (fRejectPileup) fEventStat->GetXaxis()->SetBinLabel(5,"After Pileup rejection");
139 fEventStat->GetXaxis()->SetBinLabel((kNbinsEvent+1),Form("#splitline{1 candidate}{%s}",fDielectron->GetName()));
140 fEventStat->GetXaxis()->SetBinLabel((kNbinsEvent+2),Form("#splitline{With >1 candidate}{%s}",fDielectron->GetName()));
143 Bool_t isAOD=AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
144 if(fCreateNanoAOD && isAOD){
145 AliAODHandler *aodH = (AliAODHandler*)((AliAnalysisManager::GetAnalysisManager())->GetOutputEventHandler());
146 AliAODExtension *extDielectron = aodH->GetFilteredAOD("AliAOD.Dielectron.root");
147 TClonesArray *nanoAODTracks = new TClonesArray("AliAODTrack",500);
148 nanoAODTracks->SetName("tracks");
149 extDielectron->AddBranch("TClonesArray", &nanoAODTracks);
150 TClonesArray *nanoAODVertices = new TClonesArray("AliAODVertex",500);
151 nanoAODVertices->SetName("vertices");
152 extDielectron->AddBranch("TClonesArray", &nanoAODVertices);
153 TClonesArray *nanoAODCaloCluster = new TClonesArray("AliAODCaloCluster",500);
154 nanoAODCaloCluster->SetName("caloClusters");
155 extDielectron->AddBranch("TClonesArray", &nanoAODCaloCluster);
156 extDielectron->GetAOD()->GetStdContent();
157 }else if(fCreateNanoAOD && !isAOD){AliWarning("Filtered-Nano AODs creation works only on AODs "); }
159 PostData(1, const_cast<THashList*>(fDielectron->GetHistogramList()));
160 PostData(2,fEventStat);
163 //_________________________________________________________________________________
164 void AliAnalysisTaskDielectronFilter::UserExec(Option_t *)
167 // Main loop. Called for every event
170 if (!fDielectron) return;
172 AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
173 Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
174 Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
177 AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
178 if (!inputHandler) return;
180 if ( inputHandler->GetPIDResponse() ){
181 AliDielectronVarManager::SetPIDResponse( inputHandler->GetPIDResponse() );
183 AliFatal("This task needs the PID response attached to the input event handler!");
186 // Was event selected ?
187 ULong64_t isSelected = AliVEvent::kAny;
188 Bool_t isRejected = kFALSE;
189 if( fSelectPhysics && inputHandler){
190 if((isESD && inputHandler->GetEventSelection()) || isAOD){
191 isSelected = inputHandler->IsEventSelected();
192 if (fExcludeTriggerMask && (isSelected&fExcludeTriggerMask)) isRejected=kTRUE;
193 if (fTriggerLogic==kAny) isSelected&=fTriggerMask;
194 else if (fTriggerLogic==kExact) isSelected=((isSelected&fTriggerMask)==fTriggerMask);
198 //before physics selection
199 fEventStat->Fill(kAllEvents);
200 if (isSelected==0||isRejected) {
201 PostData(2,fEventStat);
204 //after physics selection
205 fEventStat->Fill(kSelectedEvents);
209 if(isESD){if (!fTriggerAnalysis->IsOfflineTriggerFired(static_cast<AliESDEvent*>(InputEvent()), AliTriggerAnalysis::kV0AND))
211 if(isAOD){if(!((static_cast<AliAODEvent*>(InputEvent()))->GetVZEROData()->GetV0ADecision() == AliVVZERO::kV0BB &&
212 (static_cast<AliAODEvent*>(InputEvent()))->GetVZEROData()->GetV0CDecision() == AliVVZERO::kV0BB) )
216 fEventStat->Fill(kV0andEvents);
218 //Fill Event histograms before the event filter
219 Double_t values[AliDielectronVarManager::kNMaxValues]={0};
220 Double_t valuesMC[AliDielectronVarManager::kNMaxValues]={0};
221 AliDielectronVarManager::SetEvent(InputEvent());
222 AliDielectronVarManager::Fill(InputEvent(),values);
223 AliDielectronVarManager::Fill(InputEvent(),valuesMC);
225 Bool_t hasMC=AliDielectronMC::Instance()->HasMC();
227 if (AliDielectronMC::Instance()->ConnectMCEvent())
228 AliDielectronVarManager::Fill(AliDielectronMC::Instance()->GetMCEvent(),valuesMC);
231 AliDielectronHistos *h=fDielectron->GetHistoManager();
233 if (h->GetHistogramList()->FindObject("Event_noCuts"))
234 h->FillClass("Event_noCuts",AliDielectronVarManager::kNMaxValues,values);
235 if (hasMC && h->GetHistogramList()->FindObject("MCEvent_noCuts"))
236 h->FillClass("Event_noCuts",AliDielectronVarManager::kNMaxValues,valuesMC);
241 if (!fEventFilter->IsSelected(InputEvent())) return;
243 fEventStat->Fill(kFilteredEvents);
247 if (InputEvent()->IsPileupFromSPD(3,0.8,3.,2.,5.)) return;
249 fEventStat->Fill(kPileupEvents);
252 Double_t bz = InputEvent()->GetMagneticField();
253 AliKFParticle::SetField( bz );
255 AliDielectronPID::SetCorrVal((Double_t)InputEvent()->GetRunNumber());
257 fDielectron->Process(InputEvent());
259 Bool_t hasCand = kFALSE;
260 if(fStoreLikeSign) hasCand = (fDielectron->HasCandidates() || fDielectron->HasCandidatesLikeSign());
261 else hasCand = (fDielectron->HasCandidates());
263 if(fStoreRotatedPairs) hasCand = (hasCand || fDielectron->HasCandidatesTR());
265 if(fStoreEventsWithSingleTracks) hasCand = (hasCand || fDielectron->GetTrackArray(0) || fDielectron->GetTrackArray(1));
268 AliAODHandler *aodH=(AliAODHandler*)((AliAnalysisManager::GetAnalysisManager())->GetOutputEventHandler());
269 AliAODExtension *extDielectron = aodH->GetFilteredAOD("AliAOD.Dielectron.root");
271 AliAODEvent *aod = aodH->GetAOD();
273 // reset bit for all tracks
275 for(Int_t it=0;it<aod->GetNumberOfTracks();it++){
276 aod->GetTrack(it)->ResetBit(kIsReferenced); aod->GetTrack(it)->SetUniqueID(0);
280 //replace the references of the legs with the AOD references
281 TObjArray *obj = 0x0;
282 for(Int_t i=0; i < 11; i++ ){
283 obj = (TObjArray*)((*(fDielectron->GetPairArraysPointer()))->UncheckedAt(i));
285 for(int j=0;j<obj->GetEntriesFast();j++){
286 AliDielectronPair *pairObj = (AliDielectronPair*)obj->UncheckedAt(j);
287 Int_t id1 = ((AliVTrack*)pairObj->GetFirstDaughter())->GetID();
288 Int_t id2 = ((AliVTrack*)pairObj->GetSecondDaughter())->GetID();
290 for(Int_t it=0;it<aod->GetNumberOfTracks();it++){
291 if(aod->GetTrack(it)->GetID() == id1) pairObj->SetRefFirstDaughter(aod->GetTrack(it));
292 if(aod->GetTrack(it)->GetID() == id2) pairObj->SetRefSecondDaughter(aod->GetTrack(it));
297 extDielectron->SelectEvent();
298 Int_t ncandidates=fDielectron->GetPairArray(1)->GetEntriesFast();
299 if (ncandidates==1) fEventStat->Fill((kNbinsEvent));
300 else if (ncandidates>1) fEventStat->Fill((kNbinsEvent+1));
302 //see if dielectron candidate branch exists, if not create is
303 TTree *t=extDielectron->GetTree();
305 if(!t->GetListOfBranches()->GetEntries() && isAOD)
306 t->Branch(aod->GetList());
308 if (!t->GetBranch("dielectrons"))
309 t->Bronch("dielectrons","TObjArray",fDielectron->GetPairArraysPointer());
311 // store positive and negative tracks
312 if(fCreateNanoAOD && isAOD){
313 Int_t nTracks = (fDielectron->GetTrackArray(0))->GetEntries() + (fDielectron->GetTrackArray(1))->GetEntries();
314 AliAODEvent *nanoEv = extDielectron->GetAOD();
315 nanoEv->GetTracks()->Clear();
316 nanoEv->GetVertices()->Clear();
317 nanoEv->GetCaloClusters()->Clear();
319 AliAODVertex* tmp = ((static_cast<AliAODEvent*>(InputEvent()))->GetPrimaryVertex())->CloneWithoutRefs();
320 nanoEv->AddVertex(tmp);
321 AliAODVertex* tmpSpd = ((static_cast<AliAODEvent*>(InputEvent()))->GetPrimaryVertexSPD())->CloneWithoutRefs();
322 nanoEv->AddVertex(tmpSpd);
323 nanoEv->GetVertex(0)->SetNContributors((static_cast<AliAODEvent*>(InputEvent()))->GetPrimaryVertex()->GetNContributors());
324 nanoEv->GetVertex(1)->SetNContributors((static_cast<AliAODEvent*>(InputEvent()))->GetPrimaryVertexSPD()->GetNContributors());
326 nanoEv->GetHeader()->SetEventplane((static_cast<AliAODEvent*>(InputEvent()))->GetHeader()->GetEventplaneP());
327 nanoEv->GetHeader()->ResetEventplanePointer();
329 nanoEv->GetHeader()->SetRefMultiplicity((Int_t)values[AliDielectronVarManager::kNTrk]);
330 nanoEv->GetHeader()->SetRefMultiplicityPos((Int_t)values[AliDielectronVarManager::kNacc]);
331 //nanoEv->GetHeader()->SetRefMultiplicityNeg(values[AliDielectronVarManager::kMatchEffITSTPC]);
333 for(int kj=0; kj<(fDielectron->GetTrackArray(0))->GetEntries(); kj++){
334 Int_t posit = nanoEv->AddTrack((AliAODTrack*)fDielectron->GetTrackArray(0)->At(kj));
335 Int_t posVtx = nanoEv->AddVertex(((AliAODTrack*)fDielectron->GetTrackArray(0)->At(kj))->GetProdVertex());
336 nanoEv->GetVertex(posVtx)->ResetBit(kIsReferenced);
337 nanoEv->GetVertex(posVtx)->SetUniqueID(0);
338 nanoEv->GetVertex(posVtx)->RemoveDaughters();
339 nanoEv->GetTrack(posit)->ResetBit(kIsReferenced);
340 nanoEv->GetTrack(posit)->SetUniqueID(0);
342 Int_t caloIndex = ((AliAODTrack*)fDielectron->GetTrackArray(0)->At(kj))->GetEMCALcluster();
343 if(caloIndex > 0 && (static_cast<AliAODEvent*>(InputEvent()))->GetCaloCluster(caloIndex)){
344 Int_t posCaloCls = nanoEv->AddCaloCluster(static_cast<AliAODEvent*>(InputEvent())->GetCaloCluster(caloIndex));
345 nanoEv->GetTrack(posit)->SetEMCALcluster(posCaloCls);
346 AliAODCaloCluster *clCls = nanoEv->GetCaloCluster(posCaloCls);
347 for(int u=0; u<clCls->GetNTracksMatched(); u++) clCls->RemoveTrackMatched(clCls->GetTrackMatched(u));
348 nanoEv->GetCaloCluster(posCaloCls)->AddTrackMatched((AliAODTrack*)nanoEv->GetTrack(posit));
350 // set references for vtx
351 nanoEv->GetTrack(posit)->SetProdVertex(nanoEv->GetVertex(posVtx));
354 for(int kj=0; kj<(fDielectron->GetTrackArray(1))->GetEntries(); kj++){
355 Int_t negat = nanoEv->AddTrack((AliAODTrack*)fDielectron->GetTrackArray(1)->At(kj));
356 Int_t negVtx = nanoEv->AddVertex(((AliAODTrack*)fDielectron->GetTrackArray(1)->At(kj))->GetProdVertex());
357 nanoEv->GetVertex(negVtx)->ResetBit(kIsReferenced);
358 nanoEv->GetVertex(negVtx)->SetUniqueID(0);
359 nanoEv->GetVertex(negVtx)->RemoveDaughters();
360 nanoEv->GetTrack(negat)->ResetBit(kIsReferenced);
361 nanoEv->GetTrack(negat)->SetUniqueID(0);
363 Int_t caloIndex = ((AliAODTrack*)fDielectron->GetTrackArray(1)->At(kj))->GetEMCALcluster();
364 if(caloIndex > 0 && (static_cast<AliAODEvent*>(InputEvent()))->GetCaloCluster(caloIndex)){
365 Int_t negCaloCls = nanoEv->AddCaloCluster(static_cast<AliAODEvent*>(InputEvent())->GetCaloCluster(caloIndex));
366 nanoEv->GetTrack(negat)->SetEMCALcluster(negCaloCls);
367 AliAODCaloCluster *clCls = nanoEv->GetCaloCluster(negCaloCls);
368 for(int u=0; u<clCls->GetNTracksMatched(); u++) clCls->RemoveTrackMatched(clCls->GetTrackMatched(u));
369 nanoEv->GetCaloCluster(negCaloCls)->AddTrackMatched((AliAODTrack*)nanoEv->GetTrack(negat));
371 nanoEv->GetTrack(negat)->SetProdVertex(nanoEv->GetVertex(negVtx));
373 delete tmp; delete tmpSpd;
374 nanoEv->GetTracks()->Expand(nTracks);
375 nanoEv->GetVertices()->Expand(nTracks+2);
376 nanoEv->GetCaloClusters()->Expand(nanoEv->GetNumberOfCaloClusters());
382 if(fCreateNanoAOD && isAOD && (!hasCand) && fStoreHeader)
385 extDielectron->GetAOD()->GetHeader()->SetEventplane((static_cast<AliAODEvent*>(InputEvent()))->GetHeader()->GetEventplaneP());
386 extDielectron->GetAOD()->GetHeader()->ResetEventplanePointer();
387 extDielectron->GetTree()->Fill(); // fill header for all events without tracks
390 PostData(1, const_cast<THashList*>(fDielectron->GetHistogramList()));
391 PostData(2,fEventStat);