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 <AliCFContainer.h>
26 #include <AliInputEventHandler.h>
27 #include <AliESDInputHandler.h>
28 #include <AliAODInputHandler.h>
29 #include <AliAnalysisManager.h>
30 #include <AliVEvent.h>
31 #include <AliTriggerAnalysis.h>
32 #include <AliPIDResponse.h>
33 #include <AliTPCPIDResponse.h>
35 #include "AliDielectron.h"
36 #include "AliDielectronHistos.h"
37 #include "AliDielectronCF.h"
38 #include "AliDielectronMC.h"
39 #include "AliDielectronMixingHandler.h"
40 #include "AliAnalysisTaskMultiDielectron.h"
42 ClassImp(AliAnalysisTaskMultiDielectron)
44 //_________________________________________________________________________________
45 AliAnalysisTaskMultiDielectron::AliAnalysisTaskMultiDielectron() :
51 fSelectPhysics(kFALSE),
52 fTriggerMask(AliVEvent::kMB),
53 fExcludeTriggerMask(0),
54 fTriggerOnV0AND(kFALSE),
56 fFiredExclude(kFALSE),
57 fRejectPileup(kFALSE),
60 fTriggerAnalysis(0x0),
69 //_________________________________________________________________________________
70 AliAnalysisTaskMultiDielectron::AliAnalysisTaskMultiDielectron(const char *name) :
71 AliAnalysisTaskSE(name),
76 fSelectPhysics(kFALSE),
77 fTriggerMask(AliVEvent::kMB),
78 fExcludeTriggerMask(0),
79 fTriggerOnV0AND(kFALSE),
81 fFiredExclude(kFALSE),
82 fRejectPileup(kFALSE),
85 fTriggerAnalysis(0x0),
92 DefineInput(0,TChain::Class());
93 DefineOutput(1, TList::Class());
94 DefineOutput(2, TList::Class());
95 DefineOutput(3, TH1D::Class());
96 fListHistos.SetName("Dielectron_Histos_Multi");
97 fListCF.SetName("Dielectron_CF_Multi");
98 fListDielectron.SetOwner();
99 fListHistos.SetOwner();
103 //_________________________________________________________________________________
104 AliAnalysisTaskMultiDielectron::~AliAnalysisTaskMultiDielectron()
110 //histograms and CF are owned by the dielectron framework.
111 //however they are streamed to file, so in the first place the
112 //lists need to be owner...
113 fListHistos.SetOwner(kFALSE);
114 fListCF.SetOwner(kFALSE);
116 // if(fPairArray) { delete fPairArray; fPairArray=0; }
117 // try to reduce memory issues
118 if(fEventStat) { delete fEventStat; fEventStat=0; }
119 if(fTriggerAnalysis) { delete fTriggerAnalysis; fTriggerAnalysis=0; }
121 //_________________________________________________________________________________
122 void AliAnalysisTaskMultiDielectron::UserCreateOutputObjects()
125 // Add all histogram manager histogram lists to the output TList
128 if (!fListHistos.IsEmpty()||!fListCF.IsEmpty()) return; //already initialised
130 // AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
131 // Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
132 // Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
134 TIter nextDie(&fListDielectron);
135 AliDielectron *die=0;
136 while ( (die=static_cast<AliDielectron*>(nextDie())) ){
138 if (die->GetHistogramList()) fListHistos.Add(const_cast<THashList*>(die->GetHistogramList()));
139 if (die->GetHistogramArray()) fListHistos.Add(const_cast<TObjArray*>(die->GetHistogramArray()));
140 if (die->GetQAHistArray()) fListHistos.Add(const_cast<TObjArray*>(die->GetQAHistArray()));
141 if (die->GetCFManagerPair()) fListCF.Add(const_cast<AliCFContainer*>(die->GetCFManagerPair()->GetContainer()));
144 Int_t cuts=fListDielectron.GetEntries();
145 Int_t nbins=kNbinsEvent+2*cuts;
147 fEventStat=new TH1D("hEventStat","Event statistics",nbins,0,nbins);
148 fEventStat->GetXaxis()->SetBinLabel(1,"Before Phys. Sel.");
149 fEventStat->GetXaxis()->SetBinLabel(2,"After Phys. Sel.");
152 fEventStat->GetXaxis()->SetBinLabel(3,"Bin3 not used");
153 fEventStat->GetXaxis()->SetBinLabel(4,"Bin4 not used");
154 fEventStat->GetXaxis()->SetBinLabel(5,"Bin5 not used");
156 if(fTriggerOnV0AND) fEventStat->GetXaxis()->SetBinLabel(3,"V0and triggers");
157 if (fEventFilter) fEventStat->GetXaxis()->SetBinLabel(4,"After Event Filter");
158 if (fRejectPileup) fEventStat->GetXaxis()->SetBinLabel(5,"After Pileup rejection");
160 for (Int_t i=0; i<cuts; ++i){
161 fEventStat->GetXaxis()->SetBinLabel((kNbinsEvent+1)+2*i,Form("#splitline{1 candidate}{%s}",fListDielectron.At(i)->GetName()));
162 fEventStat->GetXaxis()->SetBinLabel((kNbinsEvent+2)+2*i,Form("#splitline{With >1 candidate}{%s}",fListDielectron.At(i)->GetName()));
166 if (!fTriggerAnalysis) fTriggerAnalysis=new AliTriggerAnalysis;
167 fTriggerAnalysis->EnableHistograms();
168 fTriggerAnalysis->SetAnalyzeMC(AliDielectronMC::Instance()->HasMC());
170 PostData(1, &fListHistos);
171 PostData(2, &fListCF);
172 PostData(3, fEventStat);
175 //_________________________________________________________________________________
176 void AliAnalysisTaskMultiDielectron::UserExec(Option_t *)
179 // Main loop. Called for every event
182 if (fListHistos.IsEmpty()&&fListCF.IsEmpty()) return;
184 AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
185 Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
186 Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
188 AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
189 if (!inputHandler) return;
191 // AliPIDResponse *pidRes=inputHandler->GetPIDResponse();
192 if ( inputHandler->GetPIDResponse() ){
193 // for the 2.76 pass2 MC private train. Together with a sigma shift of -0.169
194 // pidRes->GetTPCResponse().SetSigma(4.637e-3,2.41332105409873257e+04);
195 AliDielectronVarManager::SetPIDResponse( inputHandler->GetPIDResponse() );
197 AliFatal("This task needs the PID response attached to the input event handler!");
200 // Was event selected ?
201 ULong64_t isSelected = AliVEvent::kAny;
202 Bool_t isRejected = kFALSE;
203 if( fSelectPhysics && inputHandler){
204 if((isESD && inputHandler->GetEventSelection()) || isAOD){
205 isSelected = inputHandler->IsEventSelected();
206 if (fExcludeTriggerMask && (isSelected&fExcludeTriggerMask)) isRejected=kTRUE;
207 if (fTriggerLogic==kAny) isSelected&=fTriggerMask;
208 else if (fTriggerLogic==kExact) isSelected=((isSelected&fTriggerMask)==fTriggerMask);
210 TString firedTriggerClasses=InputEvent()->GetFiredTriggerClasses();
211 if(!fFiredTrigger.IsNull()) isSelected=(firedTriggerClasses.Contains(fFiredTrigger))^fFiredExclude;
216 //Before physics selection
217 fEventStat->Fill(kAllEvents);
218 if (isSelected==0||isRejected) {
219 PostData(3,fEventStat);
222 //after physics selection
223 fEventStat->Fill(kSelectedEvents);
227 if(isESD){if (!fTriggerAnalysis->IsOfflineTriggerFired(static_cast<AliESDEvent*>(InputEvent()), AliTriggerAnalysis::kV0AND))
229 if(isAOD){if(!((static_cast<AliAODEvent*>(InputEvent()))->GetVZEROData()->GetV0ADecision() == AliVVZERO::kV0BB &&
230 (static_cast<AliAODEvent*>(InputEvent()))->GetVZEROData()->GetV0CDecision() == AliVVZERO::kV0BB) )
235 fEventStat->Fill(kV0andEvents);
237 //Fill Event histograms before the event filter
238 TIter nextDie(&fListDielectron);
239 AliDielectron *die=0;
240 Bool_t hasMC=AliDielectronMC::Instance()->HasMC();
241 while ( (die=static_cast<AliDielectron*>(nextDie())) ){
242 AliDielectronHistos *h=die->GetHistoManager();
244 if (hasMC && AliDielectronMC::Instance()->ConnectMCEvent() && h->GetHistogramList()->FindObject("MCEvent_noCuts")) {
245 AliDielectronVarManager::SetEvent(AliDielectronMC::Instance()->GetMCEvent());
246 h->FillClass("MCEvent_noCuts",AliDielectronVarManager::kNMaxValues,AliDielectronVarManager::GetData());
248 if (h->GetHistogramList()->FindObject("Event_noCuts")) {
249 AliDielectronVarManager::SetEvent(InputEvent());
250 h->FillClass("Event_noCuts",AliDielectronVarManager::kNMaxValues,AliDielectronVarManager::GetData());
258 if (!fEventFilter->IsSelected(InputEvent())) return;
260 fEventStat->Fill(kFilteredEvents);
264 if (InputEvent()->IsPileupFromSPD(3,0.8,3.,2.,5.)) return;
266 fEventStat->Fill(kPileupEvents);
269 Double_t bz = InputEvent()->GetMagneticField();
270 AliKFParticle::SetField( bz );
272 AliDielectronPID::SetCorrVal((Double_t)InputEvent()->GetRunNumber());
273 AliDielectronPair::SetBeamEnergy(InputEvent(), fBeamEnergy);
275 //Process event in all AliDielectron instances
276 // TIter nextDie(&fListDielectron);
277 // AliDielectron *die=0;
280 while ( (die=static_cast<AliDielectron*>(nextDie())) ){
281 if(die->DoEventProcess()) {
282 sel= die->Process(InputEvent());
283 // input for internal train
284 if(die->DontClearArrays()) {
285 fPairArray = (*(die->GetPairArraysPointer()));
291 if(sel) die->Process(fPairArray);
294 if (die->HasCandidates()){
295 Int_t ncandidates=die->GetPairArray(1)->GetEntriesFast();
296 if (ncandidates==1) fEventStat->Fill((kNbinsEvent)+2*idie);
297 else if (ncandidates>1) fEventStat->Fill((kNbinsEvent+1)+2*idie);
302 PostData(1, &fListHistos);
303 PostData(2, &fListCF);
304 PostData(3,fEventStat);
307 //_________________________________________________________________________________
308 void AliAnalysisTaskMultiDielectron::FinishTaskOutput()
313 TIter nextDie(&fListDielectron);
315 AliDielectron *die=0;
316 AliDielectron *die2=0;
319 while ( (die=static_cast<AliDielectron*>(nextDie())) ){
323 die->SaveDebugTree();
325 // skip internal train tasks in main loop
326 if(!die->DoEventProcess()) continue;
329 AliDielectronMixingHandler *mix=die->GetMixingHandler();
330 if (!mix || !mix->GetMixUncomplete()) continue;
332 // loop over all pools
333 for (Int_t ipool=0; ipool<mix->GetNumberOfBins(); ++ipool){
334 // printf("mix remaining %04d/%04d \n",ipool,mix->GetNumberOfBins());
335 mix->MixRemaining(die, ipool);
336 fPairArray = (*(die->GetPairArraysPointer()));
337 if(!fPairArray) continue;
339 // loop over internal train task candidates
340 for(Int_t i=ic; i<fListDielectron.GetEntries(); i++) {
341 die2 = static_cast<AliDielectron*>(fListDielectron.At(i));
342 if(die2->DoEventProcess()) continue;
343 // fill internal train output
344 die2->SetPairArraysPointer(fPairArray);
345 // printf(" --> fill internal train output %s \n",die2->GetName());
346 die2->FillHistogramsFromPairArray(kTRUE);
348 // printf("\n\n\n===============\ncall mix in Terminate: %p (%p)\n=================\n\n",mix,die);
354 PostData(1, &fListHistos);
355 PostData(2, &fListCF);