-add cut qa class
[u/mrichter/AliRoot.git] / PWGDQ / dielectron / AliAnalysisTaskMultiDielectron.cxx
1 /*************************************************************************
2 * Copyright(c) 1998-2009, 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 //                        Basic Analysis Task                            //
19 //                                                                       //
20 ///////////////////////////////////////////////////////////////////////////
21
22 #include <TChain.h>
23 #include <TH1D.h>
24
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>
34
35 #include "AliDielectron.h"
36 #include "AliDielectronHistos.h"
37 #include "AliDielectronCF.h"
38 #include "AliDielectronMC.h"
39 #include "AliDielectronMixingHandler.h"
40 #include "AliAnalysisTaskMultiDielectron.h"
41
42 ClassImp(AliAnalysisTaskMultiDielectron)
43
44 //_________________________________________________________________________________
45 AliAnalysisTaskMultiDielectron::AliAnalysisTaskMultiDielectron() :
46   AliAnalysisTaskSE(),
47   fListDielectron(),
48   fListHistos(),
49   fListCF(),
50   fSelectPhysics(kFALSE),
51   fTriggerMask(AliVEvent::kMB),
52   fExcludeTriggerMask(0),
53   fTriggerOnV0AND(kFALSE),
54   fFiredTrigger(""),
55   fFiredExclude(kFALSE),
56   fRejectPileup(kFALSE),
57   fBeamEnergy(-1.),
58   fTriggerLogic(kAny),
59   fTriggerAnalysis(0x0),
60   fEventFilter(0x0),
61   fEventStat(0x0)
62 {
63   //
64   // Constructor
65   //
66 }
67
68 //_________________________________________________________________________________
69 AliAnalysisTaskMultiDielectron::AliAnalysisTaskMultiDielectron(const char *name) :
70   AliAnalysisTaskSE(name),
71   fListDielectron(),
72   fListHistos(),
73   fListCF(),
74   fSelectPhysics(kFALSE),
75   fTriggerMask(AliVEvent::kMB),
76   fExcludeTriggerMask(0),
77   fTriggerOnV0AND(kFALSE),
78   fFiredTrigger(""),
79   fFiredExclude(kFALSE),
80   fRejectPileup(kFALSE),
81   fBeamEnergy(-1.),
82   fTriggerLogic(kAny),
83   fTriggerAnalysis(0x0),
84   fEventFilter(0x0),
85   fEventStat(0x0)
86 {
87   //
88   // Constructor
89   //
90   DefineInput(0,TChain::Class());
91   DefineOutput(1, TList::Class());
92   DefineOutput(2, TList::Class());
93   DefineOutput(3, TH1D::Class());
94   fListHistos.SetName("Dielectron_Histos_Multi");
95   fListCF.SetName("Dielectron_CF_Multi");
96   fListDielectron.SetOwner();
97   fListHistos.SetOwner();
98   fListCF.SetOwner();
99 }
100
101 //_________________________________________________________________________________
102 AliAnalysisTaskMultiDielectron::~AliAnalysisTaskMultiDielectron()
103 {
104   //
105   // Destructor
106   //
107
108   //histograms and CF are owned by the dielectron framework.
109   //however they are streamed to file, so in the first place the
110   //lists need to be owner...
111   fListHistos.SetOwner(kFALSE);
112   fListCF.SetOwner(kFALSE);
113   
114   // try to reduce memory issues
115   if(fEventStat)       { delete fEventStat;       fEventStat=0; }
116   if(fTriggerAnalysis) { delete fTriggerAnalysis; fTriggerAnalysis=0; }
117 }
118 //_________________________________________________________________________________
119 void AliAnalysisTaskMultiDielectron::UserCreateOutputObjects()
120 {
121   //
122   // Add all histogram manager histogram lists to the output TList
123   //
124
125   if (!fListHistos.IsEmpty()||!fListCF.IsEmpty()) return; //already initialised
126
127 //   AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
128 //   Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
129 //   Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
130   
131   TIter nextDie(&fListDielectron);
132   AliDielectron *die=0;
133   while ( (die=static_cast<AliDielectron*>(nextDie())) ){
134     die->Init();
135     if (die->GetHistogramList())    fListHistos.Add(const_cast<THashList*>(die->GetHistogramList()));
136     if (die->GetHistogramArray())   fListHistos.Add(const_cast<TObjArray*>(die->GetHistogramArray()));
137     if (die->GetQAHistArray())      fListHistos.Add(const_cast<TObjArray*>(die->GetQAHistArray()));
138     if (die->GetCFManagerPair())    fListCF.Add(const_cast<AliCFContainer*>(die->GetCFManagerPair()->GetContainer()));
139   }
140
141   Int_t cuts=fListDielectron.GetEntries();
142   Int_t nbins=kNbinsEvent+2*cuts;
143   if (!fEventStat){
144     fEventStat=new TH1D("hEventStat","Event statistics",nbins,0,nbins);
145     fEventStat->GetXaxis()->SetBinLabel(1,"Before Phys. Sel.");
146     fEventStat->GetXaxis()->SetBinLabel(2,"After Phys. Sel.");
147
148     //default names
149     fEventStat->GetXaxis()->SetBinLabel(3,"Bin3 not used");
150     fEventStat->GetXaxis()->SetBinLabel(4,"Bin4 not used");
151     fEventStat->GetXaxis()->SetBinLabel(5,"Bin5 not used");
152     
153     if(fTriggerOnV0AND) fEventStat->GetXaxis()->SetBinLabel(3,"V0and triggers");
154     if (fEventFilter) fEventStat->GetXaxis()->SetBinLabel(4,"After Event Filter");
155     if (fRejectPileup) fEventStat->GetXaxis()->SetBinLabel(5,"After Pileup rejection");
156     
157     for (Int_t i=0; i<cuts; ++i){
158       fEventStat->GetXaxis()->SetBinLabel((kNbinsEvent+1)+2*i,Form("#splitline{1 candidate}{%s}",fListDielectron.At(i)->GetName()));
159       fEventStat->GetXaxis()->SetBinLabel((kNbinsEvent+2)+2*i,Form("#splitline{With >1 candidate}{%s}",fListDielectron.At(i)->GetName()));
160     }
161   }
162
163   if (!fTriggerAnalysis) fTriggerAnalysis=new AliTriggerAnalysis;
164   fTriggerAnalysis->EnableHistograms();
165   fTriggerAnalysis->SetAnalyzeMC(AliDielectronMC::Instance()->HasMC());
166   
167   PostData(1, &fListHistos);
168   PostData(2, &fListCF);
169   PostData(3, fEventStat);
170 }
171
172 //_________________________________________________________________________________
173 void AliAnalysisTaskMultiDielectron::UserExec(Option_t *)
174 {
175   //
176   // Main loop. Called for every event
177   //
178
179   if (fListHistos.IsEmpty()&&fListCF.IsEmpty()) return;
180
181   AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
182   Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
183   Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
184   
185   AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
186   if (!inputHandler) return;
187   
188 //   AliPIDResponse *pidRes=inputHandler->GetPIDResponse();
189   if ( inputHandler->GetPIDResponse() ){
190     // for the 2.76 pass2 MC private train. Together with a sigma shift of -0.169
191 //    pidRes->GetTPCResponse().SetSigma(4.637e-3,2.41332105409873257e+04);
192     AliDielectronVarManager::SetPIDResponse( inputHandler->GetPIDResponse() );
193   } else {
194     AliFatal("This task needs the PID response attached to the input event handler!");
195   }
196   
197   // Was event selected ?
198   ULong64_t isSelected = AliVEvent::kAny;
199   Bool_t isRejected = kFALSE;
200   if( fSelectPhysics && inputHandler){
201     if((isESD && inputHandler->GetEventSelection()) || isAOD){
202       isSelected = inputHandler->IsEventSelected();
203       if (fExcludeTriggerMask && (isSelected&fExcludeTriggerMask)) isRejected=kTRUE;
204       if (fTriggerLogic==kAny) isSelected&=fTriggerMask;
205       else if (fTriggerLogic==kExact) isSelected=((isSelected&fTriggerMask)==fTriggerMask);
206    
207       TString firedTriggerClasses=InputEvent()->GetFiredTriggerClasses();
208       if(!fFiredTrigger.IsNull()) isSelected=(firedTriggerClasses.Contains(fFiredTrigger))^fFiredExclude;
209     }
210    }
211  
212  
213   //Before physics selection
214   fEventStat->Fill(kAllEvents);
215   if (isSelected==0||isRejected) {
216     PostData(3,fEventStat);
217     return;
218   }
219   //after physics selection
220   fEventStat->Fill(kSelectedEvents);
221
222   //V0and
223   if(fTriggerOnV0AND){
224   if(isESD){if (!fTriggerAnalysis->IsOfflineTriggerFired(static_cast<AliESDEvent*>(InputEvent()), AliTriggerAnalysis::kV0AND))
225             return;}
226   if(isAOD){if(!((static_cast<AliAODEvent*>(InputEvent()))->GetVZEROData()->GetV0ADecision() == AliVVZERO::kV0BB &&
227             (static_cast<AliAODEvent*>(InputEvent()))->GetVZEROData()->GetV0CDecision() == AliVVZERO::kV0BB) )
228             return;}
229    }
230   
231
232   fEventStat->Fill(kV0andEvents);
233
234   //Fill Event histograms before the event filter
235   TIter nextDie(&fListDielectron);
236   AliDielectron *die=0;
237   Bool_t hasMC=AliDielectronMC::Instance()->HasMC();
238   while ( (die=static_cast<AliDielectron*>(nextDie())) ){
239     AliDielectronHistos *h=die->GetHistoManager();
240     if (h){
241       if (hasMC && AliDielectronMC::Instance()->ConnectMCEvent() && h->GetHistogramList()->FindObject("MCEvent_noCuts")) {
242         AliDielectronVarManager::SetEvent(AliDielectronMC::Instance()->GetMCEvent());
243         h->FillClass("MCEvent_noCuts",AliDielectronVarManager::kNMaxValues,AliDielectronVarManager::GetData());
244       }
245       if (h->GetHistogramList()->FindObject("Event_noCuts")) {
246         AliDielectronVarManager::SetEvent(InputEvent());
247         h->FillClass("Event_noCuts",AliDielectronVarManager::kNMaxValues,AliDielectronVarManager::GetData());
248       }
249     }
250   }
251   nextDie.Reset();
252   
253   //event filter
254   if (fEventFilter) {
255     if (!fEventFilter->IsSelected(InputEvent())) return;
256   }
257   fEventStat->Fill(kFilteredEvents);
258   
259   //pileup
260   if (fRejectPileup){
261     if (InputEvent()->IsPileupFromSPD(3,0.8,3.,2.,5.)) return;
262   }
263   fEventStat->Fill(kPileupEvents);
264   
265   //bz for AliKF
266   Double_t bz = InputEvent()->GetMagneticField();
267   AliKFParticle::SetField( bz );
268
269   AliDielectronPID::SetCorrVal((Double_t)InputEvent()->GetRunNumber());
270   AliDielectronPair::SetBeamEnergy(InputEvent(), fBeamEnergy);
271   
272   //Process event in all AliDielectron instances
273   //   TIter nextDie(&fListDielectron);
274   //   AliDielectron *die=0;
275   Int_t idie=0;
276   while ( (die=static_cast<AliDielectron*>(nextDie())) ){
277     die->Process(InputEvent());
278     if (die->HasCandidates()){
279       Int_t ncandidates=die->GetPairArray(1)->GetEntriesFast();
280       if (ncandidates==1) fEventStat->Fill((kNbinsEvent)+2*idie);
281       else if (ncandidates>1) fEventStat->Fill((kNbinsEvent+1)+2*idie);
282     }
283     ++idie;
284   }
285   
286   PostData(1, &fListHistos);
287   PostData(2, &fListCF);
288   PostData(3,fEventStat);
289 }
290
291 //_________________________________________________________________________________
292 void AliAnalysisTaskMultiDielectron::FinishTaskOutput()
293 {
294   //
295   // Write debug tree
296   //
297   TIter nextDie(&fListDielectron);
298   AliDielectron *die=0;
299   while ( (die=static_cast<AliDielectron*>(nextDie())) ){
300     die->SaveDebugTree();
301     AliDielectronMixingHandler *mix=die->GetMixingHandler();
302 //    printf("\n\n\n===============\ncall mix in Terminate: %p (%p)\n=================\n\n",mix,die);
303     if (mix) mix->MixRemaining(die);
304   }
305   PostData(1, &fListHistos);
306   PostData(2, &fListCF);
307 }
308