]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGDQ/dielectron/AliAnalysisTaskReducedTree.cxx
including switch to set on/off iso-track core removal, cleaning and bug fix
[u/mrichter/AliRoot.git] / PWGDQ / dielectron / AliAnalysisTaskReducedTree.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 //    Analysis task for creating a reduced data tree                     //
19 //                                                                       //
20 ///////////////////////////////////////////////////////////////////////////
21
22
23 #include <TChain.h>
24 #include <TH1D.h>
25 #include <TFile.h>
26
27 #include <AliCFContainer.h>
28 #include <AliInputEventHandler.h>
29 #include <AliESDInputHandler.h>
30 #include <AliAODInputHandler.h>
31 #include <AliAnalysisManager.h>
32 #include <AliVEvent.h>
33 #include <AliESDEvent.h>
34 #include <AliAODEvent.h>
35 #include <AliESDHeader.h>
36 #include <AliAODHeader.h>
37 #include <AliAODTrack.h>
38 //#include <AliAODForwardMult.h>
39 //#include <AliForwardUtil.h>
40 #include <AliTriggerAnalysis.h>
41 #include <AliESDtrackCuts.h>
42 #include <AliVZDC.h>
43 #include <AliESDv0.h>
44 #include <AliESDv0Cuts.h>
45 #include <AliESDv0KineCuts.h>
46 #include <AliESDFMD.h>
47 #include <AliVCluster.h>
48 #include <AliAODTracklets.h>
49 #include <AliMultiplicity.h>
50 #include <AliPIDResponse.h>
51 #include "AliDielectron.h"
52 #include "AliDielectronHistos.h"
53 #include "AliDielectronMC.h"
54 #include "AliDielectronVarManager.h"
55 #include "AliFlowTrackCuts.h"
56 #include "AliFlowBayesianPID.h"
57
58 #include "AliReducedEvent.h"
59 #include "AliAnalysisTaskReducedTree.h"
60
61 #include <iostream>
62 using std::cout;
63 using std::endl;
64
65 ClassImp(AliAnalysisTaskReducedTree)
66
67
68 //_________________________________________________________________________________
69 AliAnalysisTaskReducedTree::AliAnalysisTaskReducedTree() :
70   AliAnalysisTaskSE(),
71   fListDielectron(),
72   fListHistos(),
73   fSelectPhysics(kFALSE),
74   fTriggerMask(AliVEvent::kAny),
75   fRejectPileup(kFALSE),
76   fFillTrackInfo(kTRUE),
77   fFillDielectronInfo(kTRUE),
78   fFillV0Info(kTRUE),
79   fFillGammaConversions(kTRUE),
80   fFillK0s(kTRUE),
81   fFillLambda(kTRUE),
82   fFillALambda(kTRUE),
83   fFillCaloClusterInfo(kTRUE),
84   fFillFMDSectorInfo(kFALSE),
85   fFillFMDChannelInfo(kFALSE),
86   //fFillCorrectedFMDInfo(kTRUE),
87   fFillFriendInfo(kTRUE),
88   fEventFilter(0x0),
89   fTrackFilter(0x0),
90   fFlowTrackFilter(0x0),
91   fK0sCuts(0x0),
92   fLambdaCuts(0x0),
93   fGammaConvCuts(0x0),
94   fK0sPionCuts(0x0),
95   fLambdaProtonCuts(0x0),
96   fLambdaPionCuts(0x0),
97   fGammaElectronCuts(0x0),
98   fV0OpenCuts(0x0),
99   fV0StrongCuts(0x0),
100   fK0sMassRange(),
101   fLambdaMassRange(),
102   fGammaMassRange(),
103   fV0Histos(0x0),
104   fTreeFile(0x0),
105   fTree(0x0),
106   fFriendTreeFile(0x0),
107   fFriendTree(0x0),
108   fReducedEvent(0x0),
109   fReducedEventFriend(0x0)
110 {
111   //
112   // Constructor
113   //
114 }
115
116 //_________________________________________________________________________________
117 AliAnalysisTaskReducedTree::AliAnalysisTaskReducedTree(const char *name) :
118   AliAnalysisTaskSE(name),
119   fListDielectron(),
120   fListHistos(),
121   fSelectPhysics(kFALSE),
122   fTriggerMask(AliVEvent::kAny),
123   fRejectPileup(kFALSE),
124   fFillTrackInfo(kTRUE),
125   fFillDielectronInfo(kTRUE),
126   fFillV0Info(kTRUE),
127   fFillGammaConversions(kTRUE),
128   fFillK0s(kTRUE),
129   fFillLambda(kTRUE),
130   fFillALambda(kTRUE),
131   fFillCaloClusterInfo(kTRUE),
132   fFillFMDSectorInfo(kFALSE),
133   fFillFMDChannelInfo(kFALSE),
134   //fFillCorrectedFMDInfo(kTRUE),
135   fFillFriendInfo(kTRUE),
136   fEventFilter(0x0),
137   fTrackFilter(0x0),
138   fFlowTrackFilter(0x0),
139   fK0sCuts(0x0),
140   fLambdaCuts(0x0),
141   fGammaConvCuts(0x0),
142   fK0sPionCuts(0x0),
143   fLambdaProtonCuts(0x0),
144   fLambdaPionCuts(0x0),
145   fGammaElectronCuts(0x0),
146   fV0OpenCuts(0x0),
147   fV0StrongCuts(0x0),
148   fK0sMassRange(),
149   fLambdaMassRange(),
150   fGammaMassRange(),
151   fV0Histos(0x0),
152   fTreeFile(0x0),
153   fTree(0x0),
154   fFriendTreeFile(0x0),
155   fFriendTree(0x0),
156   fReducedEvent(0x0),
157   fReducedEventFriend(0x0)
158 {
159   //
160   // Constructor
161   //
162   fK0sMassRange[0] = 0.4; fK0sMassRange[1] = 0.6;
163   fLambdaMassRange[0] = 1.08; fLambdaMassRange[1] = 1.15;
164   fGammaMassRange[0] = 0.0; fGammaMassRange[1] = 0.1;
165   
166   DefineInput(0,TChain::Class());
167   //DefineInput(2,AliAODForwardMult::Class());
168   DefineOutput(1, TList::Class());   // QA histograms
169   DefineOutput(2, TTree::Class());   // reduced information tree
170   //if(fFillFriendInfo) DefineOutput(3, TTree::Class());   // reduced information tree with friends
171   //DefineOutput(2, TTree::Class());   // reduced information tree with friends
172   //DefineOutput(2, TTree::Class());   // reduced information tree  
173
174   fListHistos.SetName("QAhistograms");
175   fListDielectron.SetOwner();
176   fListHistos.SetOwner(kFALSE);
177 }
178
179
180 //_________________________________________________________________________________
181 void AliAnalysisTaskReducedTree::UserCreateOutputObjects()
182 {
183   //
184   // Add all histogram manager histogram lists to the output TList
185   //
186
187   if (!fListHistos.IsEmpty() || fTree || fFriendTree) return; //already initialised
188
189   TIter nextDie(&fListDielectron);
190   AliDielectron *die=0;
191   while ( (die=static_cast<AliDielectron*>(nextDie())) ){
192     die->Init();
193     if (die->GetHistogramList()) fListHistos.Add(const_cast<THashList*>(die->GetHistogramList()));
194   }  
195   if(fV0Histos) fListHistos.Add(const_cast<THashList*>(fV0Histos->GetHistogramList()));
196
197   if(fFillFriendInfo) {
198     fFriendTree = new TTree("DstFriendTree","Reduced ESD information");
199     fReducedEventFriend = new AliReducedEventFriend();
200     fFriendTree->Branch("Event",&fReducedEventFriend,16000,99);
201   }
202   
203   //fTreeFile = new TFile("dstTree.root", "RECREATE");
204   OpenFile(2);
205   fTree = new TTree("DstTree","Reduced ESD information");
206   fReducedEvent = new AliReducedEvent("DstEvent");
207   fTree->Branch("Event",&fReducedEvent,16000,99);
208     
209   PostData(1, &fListHistos);
210   PostData(2, fTree);
211   //if(fFillFriendInfo) PostData(3, fFriendTree);
212   //PostData(2, fFriendTree);
213   //PostData(1, fTree);
214 }
215
216 //_________________________________________________________________________________
217 void AliAnalysisTaskReducedTree::UserExec(Option_t *)
218 {
219   //
220   // Main loop. Called for every event
221   //
222   AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
223   Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
224   Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
225   
226   AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
227   if (!inputHandler) return;
228   
229   if ( inputHandler->GetPIDResponse() ){
230     AliDielectronVarManager::SetPIDResponse( inputHandler->GetPIDResponse() );
231   } else {
232     AliFatal("This task needs the PID response attached to the input event handler!");
233   }
234
235   // Was event selected ?
236   UInt_t isSelected = AliVEvent::kAny;
237   if(fSelectPhysics && inputHandler){
238     if((isESD && inputHandler->GetEventSelection()) || isAOD){
239       isSelected = inputHandler->IsEventSelected();
240       isSelected&=fTriggerMask;
241     }
242   }
243
244   if(isSelected==0) {
245     return;
246   }
247 /*
248   cout<<"get AOD"<<endl;
249   
250   AliAODEvent* aodEvent = AliForwardUtil::GetAODEvent(this);
251   if (!aodEvent) return;
252   cout<<"got AOD"<<endl;
253
254   TObject* obj = aodEvent->FindListObject("Forward");  
255   if (!obj) return;
256   cout<<"got AOD forward"<<endl;
257
258   AliAODForwardMult* aodForward = static_cast<AliAODForwardMult*>(obj);
259
260    //if (!aodForward->CheckEvent(mask,ipZmin,ipZmax,cMin,cMax)) return 0;
261
262   Double_t ret = 0;
263   const TH2D& d2Ndetadphi = aodForward->GetHistogram();
264
265
266   cout<<d2Ndetadphi.GetXaxis()->GetNbins()<<endl;
267 */
268
269   // FMD corrections
270 //  AliAODEvent* aodEvent;
271 //  TObject* obj;
272 //  AliAODForwardMult* aodForward=NULL;
273 //
274 //  if(fFillCorrectedFMDInfo){
275 //  aodEvent = AliForwardUtil::GetAODEvent(this);
276 //  if (!aodEvent) return;
277 //
278 //  obj = aodEvent->FindListObject("Forward");  
279 //  if (!obj) return;}
280 //
281 //  aodForward = static_cast<AliAODForwardMult*>(obj);
282 //
283 //   //if (!aodForward->CheckE  vent(fTriggerMask,ipZmin,ipZmax,cMin,cMax)) return 0;
284 //
285 //  const TH2D& d2Ndetadphi = aodForward->GetHistogram();
286   
287   
288   // fill event histograms before event filter
289   Double_t values[AliDielectronVarManager::kNMaxValues]={0};
290   AliDielectronVarManager::Fill(InputEvent(),values);
291   
292   TIter nextDie(&fListDielectron);
293   AliDielectron *die=0;
294   while ( (die=static_cast<AliDielectron*>(nextDie())) ){
295     AliDielectronHistos *h=die->GetHistoManager();
296     if (h){
297       if (h->GetHistogramList()->FindObject("Event_noCuts"))
298         h->FillClass("Event_noCuts",AliDielectronVarManager::kNMaxValues,values);
299     }
300   }
301   nextDie.Reset();
302
303   //event filter
304   if (fEventFilter) {
305     if (!fEventFilter->IsSelected(InputEvent())) return;
306   }
307   
308   //pileup
309   if (fRejectPileup){
310     if (InputEvent()->IsPileupFromSPD(3,0.8,3.,2.,5.)) return;
311   }
312
313   //bz for AliKF
314   Double_t bz = InputEvent()->GetMagneticField();
315   AliKFParticle::SetField( bz );
316
317   //Process event in all AliDielectron instances
318   fReducedEvent->ClearEvent();
319   if(fFillFriendInfo) fReducedEventFriend->ClearEvent();
320   FillEventInfo();
321   //if(fFillCorrectedFMDInfo) FillCorrectedFMDInfo(d2Ndetadphi);   //Fill corrected FMD info
322   if(fFillV0Info) FillV0PairInfo();
323   
324   Short_t idie=0;
325   if(fFillDielectronInfo) {
326     while((die=static_cast<AliDielectron*>(nextDie()))){
327       die->Process(InputEvent());
328       FillDielectronPairInfo(die, idie);
329       ++idie;
330     }
331   }
332   nextDie.Reset();
333   
334   if(fFillTrackInfo) FillTrackInfo();
335   if(fFillFriendInfo) FillFriendEventInfo();              // Q-vector calculation
336   
337   fTree->Fill();
338   if(fFillFriendInfo) fFriendTree->Fill();
339       
340   // if there are candidate pairs, add the information to the reduced tree
341   PostData(1, &fListHistos);
342   PostData(2, fTree);
343   //if(fFillFriendInfo) PostData(3, fFriendTree);
344   //PostData(2, fFriendTree);
345   //PostData(2, fTree);
346 }
347
348
349 //_________________________________________________________________________________
350 void AliAnalysisTaskReducedTree::FillEventInfo() 
351 {
352   //
353   // fill reduced event information
354   //
355   AliVEvent* event = InputEvent();
356   // Was event selected ?
357   AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
358   Bool_t isESD = (event->IsA()==AliESDEvent::Class());
359   Bool_t isAOD = (event->IsA()==AliAODEvent::Class());
360   
361   AliESDEvent* esdEvent = 0x0;
362   if(isESD) esdEvent = static_cast<AliESDEvent*>(event);
363   AliAODEvent* aodEvent = 0x0;
364   if(isAOD) aodEvent = static_cast<AliAODEvent*>(event);
365   
366   AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
367   UInt_t isSelected = AliVEvent::kAny;
368   if(inputHandler){
369     if((isESD && inputHandler->GetEventSelection()) || isAOD){
370       isSelected = inputHandler->IsEventSelected();
371       isSelected&=fTriggerMask;
372     }
373   }
374   Double_t values[AliDielectronVarManager::kNMaxValues];
375   AliDielectronVarManager::Fill(event, values);
376   
377   fReducedEvent->fRunNo       = event->GetRunNumber();
378   fReducedEvent->fBC          = event->GetBunchCrossNumber();
379   fReducedEvent->fEventType   = event->GetEventType();
380   fReducedEvent->fTriggerMask = event->GetTriggerMask();
381   fReducedEvent->fIsPhysicsSelection = (isSelected!=0 ? kTRUE : kFALSE);
382   fReducedEvent->fIsSPDPileup = event->IsPileupFromSPD(3,0.8,3.,2.,5.);
383   fReducedEvent->fIsSPDPileupMultBins = event->IsPileupFromSPDInMultBins();
384   AliVVertex* eventVtx = 0x0;
385   if(isESD) eventVtx = const_cast<AliESDVertex*>(esdEvent->GetPrimaryVertexTracks());
386   if(isAOD) eventVtx = const_cast<AliAODVertex*>(aodEvent->GetPrimaryVertex());
387   if(eventVtx) {
388     fReducedEvent->fVtx[0] = (isESD ? ((AliESDVertex*)eventVtx)->GetXv() : ((AliAODVertex*)eventVtx)->GetX());
389     fReducedEvent->fVtx[1] = (isESD ? ((AliESDVertex*)eventVtx)->GetYv() : ((AliAODVertex*)eventVtx)->GetY());
390     fReducedEvent->fVtx[2] = (isESD ? ((AliESDVertex*)eventVtx)->GetZv() : ((AliAODVertex*)eventVtx)->GetZ());
391     fReducedEvent->fNVtxContributors = eventVtx->GetNContributors();
392   }
393   if(isESD) {
394     eventVtx = const_cast<AliESDVertex*>(esdEvent->GetPrimaryVertexTPC());
395     fReducedEvent->fEventNumberInFile = esdEvent->GetEventNumberInFile();
396     fReducedEvent->fL0TriggerInputs = esdEvent->GetHeader()->GetL0TriggerInputs();
397     fReducedEvent->fL1TriggerInputs = esdEvent->GetHeader()->GetL1TriggerInputs();
398     fReducedEvent->fL2TriggerInputs = esdEvent->GetHeader()->GetL2TriggerInputs();
399     fReducedEvent->fIRIntClosestIntMap[0] = esdEvent->GetHeader()->GetIRInt1ClosestInteractionMap();
400     fReducedEvent->fIRIntClosestIntMap[1] = esdEvent->GetHeader()->GetIRInt2ClosestInteractionMap();
401     if(eventVtx) {
402       fReducedEvent->fVtxTPC[0] = ((AliESDVertex*)eventVtx)->GetXv();
403       fReducedEvent->fVtxTPC[1] = ((AliESDVertex*)eventVtx)->GetYv();
404       fReducedEvent->fVtxTPC[2] = ((AliESDVertex*)eventVtx)->GetZv();
405       fReducedEvent->fNVtxTPCContributors = eventVtx->GetNContributors();
406     }
407     fReducedEvent->fTimeStamp     = esdEvent->GetTimeStamp();
408     fReducedEvent->fNpileupSPD    = esdEvent->GetNumberOfPileupVerticesSPD();
409     fReducedEvent->fNpileupTracks = esdEvent->GetNumberOfPileupVerticesTracks();
410     fReducedEvent->fNPMDtracks    = esdEvent->GetNumberOfPmdTracks();
411     fReducedEvent->fNTRDtracks    = esdEvent->GetNumberOfTrdTracks();
412     fReducedEvent->fNTRDtracklets = esdEvent->GetNumberOfTrdTracklets();
413     
414     AliESDZDC* zdc = esdEvent->GetESDZDC();
415     if(zdc) {
416       for(Int_t i=0; i<5; ++i)  fReducedEvent->fZDCnEnergy[i]   = zdc->GetZN1TowerEnergy()[i];
417       for(Int_t i=5; i<10; ++i)  fReducedEvent->fZDCnEnergy[i]   = zdc->GetZN2TowerEnergy()[i-5];
418       for(Int_t i=0; i<5; ++i)  fReducedEvent->fZDCpEnergy[i]   = zdc->GetZP1TowerEnergy()[i];
419       for(Int_t i=5; i<10; ++i)  fReducedEvent->fZDCpEnergy[i]   = zdc->GetZP2TowerEnergy()[i-5];
420     }
421   }
422   if(isAOD) {
423     fReducedEvent->fIRIntClosestIntMap[0] = aodEvent->GetHeader()->GetIRInt1ClosestInteractionMap();
424     fReducedEvent->fIRIntClosestIntMap[1] = aodEvent->GetHeader()->GetIRInt2ClosestInteractionMap();
425     fReducedEvent->fEventNumberInFile = aodEvent->GetHeader()->GetEventNumberESDFile();
426     fReducedEvent->fL0TriggerInputs = aodEvent->GetHeader()->GetL0TriggerInputs();
427     fReducedEvent->fL1TriggerInputs = aodEvent->GetHeader()->GetL1TriggerInputs();
428     fReducedEvent->fL2TriggerInputs = aodEvent->GetHeader()->GetL2TriggerInputs();
429     fReducedEvent->fTimeStamp     = 0;
430     fReducedEvent->fNpileupSPD    = aodEvent->GetNumberOfPileupVerticesSPD();
431     fReducedEvent->fNpileupTracks = aodEvent->GetNumberOfPileupVerticesTracks();
432     fReducedEvent->fNPMDtracks    = aodEvent->GetNPmdClusters();
433     fReducedEvent->fNTRDtracks    = 0;
434     fReducedEvent->fNTRDtracklets = 0;
435     
436     AliAODZDC* zdc = aodEvent->GetZDCData();
437     if(zdc) {
438       for(Int_t i=0; i<5; ++i)  fReducedEvent->fZDCnEnergy[i]   = zdc->GetZNATowerEnergy()[i];
439       for(Int_t i=5; i<10; ++i)  fReducedEvent->fZDCnEnergy[i]   = zdc->GetZNCTowerEnergy()[i-5];
440       for(Int_t i=0; i<5; ++i)  fReducedEvent->fZDCpEnergy[i]   = zdc->GetZPATowerEnergy()[i];
441       for(Int_t i=5; i<10; ++i)  fReducedEvent->fZDCpEnergy[i]   = zdc->GetZPCTowerEnergy()[i-5];
442     }
443   }
444   
445   // Fill TZERO information
446   if(isESD) {
447     const AliESDTZERO* tzero = esdEvent->GetESDTZERO();
448     if(tzero) {
449       fReducedEvent->fT0start = tzero->GetT0();
450       fReducedEvent->fT0zVertex = tzero->GetT0zVertex();
451       for(Int_t i = 0;i<24;i++)
452         fReducedEvent->fT0amplitude[i] = tzero->GetT0amplitude()[i];
453       for(Int_t i = 0;i<3;i++)
454         fReducedEvent->fT0TOF[i] = tzero->GetT0TOF()[i];
455       for(Int_t i = 0;i<3;i++)
456         fReducedEvent->fT0TOFbest[i] = tzero->GetT0TOFbest()[i];
457       fReducedEvent->fT0pileup = tzero->GetPileupFlag();
458       fReducedEvent->fT0sattelite = tzero->GetSatellite();
459     }
460   }
461   if(isAOD) {
462     AliAODTZERO* tzero = aodEvent->GetTZEROData();
463     if(tzero) {
464       fReducedEvent->fT0start = -999.;   // not available
465       fReducedEvent->fT0zVertex = tzero->GetT0zVertex();
466       for(Int_t i = 0;i<26;i++)
467         fReducedEvent->fT0amplitude[i] = tzero->GetAmp(i);
468       for(Int_t i = 0;i<3;i++)
469         fReducedEvent->fT0TOF[i] = tzero->GetT0TOF()[i];
470       for(Int_t i = 0;i<3;i++)
471         fReducedEvent->fT0TOFbest[i] = tzero->GetT0TOFbest()[i];
472       fReducedEvent->fT0pileup = tzero->GetPileupFlag();
473       fReducedEvent->fT0sattelite = tzero->GetSatellite();
474     }
475   }
476   
477   if(fFillFMDChannelInfo&&isESD) fReducedEvent->fIsFMDReduced = kFALSE;
478   if((fFillFMDSectorInfo||fFillFMDChannelInfo)&&isESD) FillFMDInfo();
479   
480   AliCentrality *centrality = event->GetCentrality();
481   if(centrality) {
482     fReducedEvent->fCentrality[0] = centrality->GetCentralityPercentile("V0M");
483     fReducedEvent->fCentrality[1] = centrality->GetCentralityPercentile("CL1");
484     fReducedEvent->fCentrality[2] = centrality->GetCentralityPercentile("TRK");
485     fReducedEvent->fCentrality[3] = centrality->GetCentralityPercentile("ZEMvsZDC");    
486     fReducedEvent->fCentQuality   = centrality->GetQuality();
487   }
488   
489   //cout << "event vtxZ/cent: " << fReducedEvent->fVtx[2] << "/" << fReducedEvent->fCentrality[0] << endl;
490   
491   fReducedEvent->fNtracks[0] = event->GetNumberOfTracks();
492   fReducedEvent->fSPDntracklets = GetSPDTrackletMultiplicity(event, -1.0, 1.0);
493   for(Int_t ieta=0; ieta<32; ++ieta)
494     fReducedEvent->fSPDntrackletsEta[ieta] = GetSPDTrackletMultiplicity(event, -1.6+0.1*ieta, -1.6+0.1*(ieta+1));
495   
496   AliVVZERO* vzero = event->GetVZEROData();
497   for(Int_t i=0;i<64;++i) 
498     fReducedEvent->fVZEROMult[i] = vzero->GetMultiplicity(i);  
499   
500   // EMCAL/PHOS clusters
501   if(fFillCaloClusterInfo) FillCaloClusters();
502   
503   // TODO FMD multiplicities
504   
505 }
506
507
508 //_________________________________________________________________________________
509 void AliAnalysisTaskReducedTree::FillCaloClusters() {
510   //
511   // Fill info about the calorimeter clusters
512   //
513   AliVEvent* event = InputEvent();
514   Int_t nclusters = event->GetNumberOfCaloClusters();
515
516   fReducedEvent->fNCaloClusters = 0;
517   for(Int_t iclus=0; iclus<nclusters; ++iclus) {
518     AliVCluster* cluster = event->GetCaloCluster(iclus);
519     
520     TClonesArray& clusters = *(fReducedEvent->fCaloClusters);
521     AliReducedCaloCluster *reducedCluster=new(clusters[fReducedEvent->fNCaloClusters]) AliReducedCaloCluster();
522     
523     reducedCluster->fType    = (cluster->IsEMCAL() ? AliReducedCaloCluster::kEMCAL : AliReducedCaloCluster::kPHOS);
524     reducedCluster->fEnergy  = cluster->E();
525     reducedCluster->fTrackDx = cluster->GetTrackDx();
526     reducedCluster->fTrackDz = cluster->GetTrackDz();
527     reducedCluster->fM20     = cluster->GetM20();
528     reducedCluster->fM02     = cluster->GetM02();
529     reducedCluster->fDispersion = cluster->GetDispersion();
530     fReducedEvent->fNCaloClusters += 1;
531   }  // end loop over clusters
532 }
533
534
535 //_________________________________________________________________________________
536 void AliAnalysisTaskReducedTree::FillFriendEventInfo() {
537   //
538   // Fill event info into the friend tree
539   //
540   // Add here calculated Q-vector components from all detectors
541   for(Int_t idet=0; idet<AliReducedEventFriend::kNdetectors; ++idet) {
542     fReducedEvent->GetQvector(fReducedEventFriend->fQvector[idet], idet);
543     for(Int_t ih=0; ih<fgkNMaxHarmonics; ++ih)
544       fReducedEventFriend->fEventPlaneStatus[idet][ih] = AliReducedEventFriend::kRaw;
545   }
546 }
547
548
549 //_________________________________________________________________________________
550 void AliAnalysisTaskReducedTree::FillFMDInfo()
551 {
552   //
553   // fill reduced FMD information
554   //
555   AliVEvent* event = InputEvent();
556   Bool_t isESD = (event->IsA()==AliESDEvent::Class());
557
558   if(!isESD) return;
559
560   AliESDEvent* esdEvent = 0x0;
561   if(isESD) esdEvent = static_cast<AliESDEvent*>(event);
562
563   AliESDFMD* esdFmd = esdEvent->GetFMDData();
564   //const AliFMDFloatMap multMap = esdFmd->MultiplicityMap();
565   //const AliFMDFloatMap etaMap  = esdFmd->EtaMap();
566
567   //esdFmd->Print();
568   Int_t nFMD=0;
569   Int_t id=-1;
570   Int_t maxDet=3;
571   Int_t maxRing=2;
572   Int_t maxSector;
573   Int_t maxStrip;
574   Float_t m=0.0;
575   Double_t phi;
576   Char_t ring;
577   Float_t fmdMult;
578   Float_t msum=0;
579   UShort_t fmdDet=0;
580   Int_t phiBin=0;
581     
582   for(UShort_t det = 1; det <= maxDet; ++det) {
583     (det == 1 ? maxRing=1 : maxRing=2);
584     for(UShort_t ir = 0; ir < maxRing; ++ir) {
585       ring = (ir == 0 ? 'I' : 'O');
586       (ir == 0 ? maxSector=20 : maxSector=40);
587       (ir == 0 ? maxStrip=512 : maxStrip=256);
588       nFMD=-1;
589       for(UShort_t sec = 0; sec < maxSector; ++sec) {
590         phi  =  esdFmd->Phi(det, ring, sec, 0)/180.*TMath::Pi();
591         phiBin = Int_t (phi/2/TMath::Pi()*maxSector);
592         fmdMult = 0;
593         for(UShort_t str = 0; str < maxStrip; ++str) {
594           ++id;
595           m  =  esdFmd->Multiplicity(det, ring, sec, str);
596           //cout << "det/ir/sec/str/m :: " << det << "/" << ir << "/" << sec << "/" << str << "/" << m << endl;
597           if(fFillFMDChannelInfo) 
598             if(m<1.e-6) continue;
599           if(m ==  AliESDFMD::kInvalidMult) m=0;
600           fmdMult += m;
601           msum+=m;
602           ++nFMD;
603             
604           if(fFillFMDChannelInfo){
605             if(m>15.) m=15.;
606             m = UShort_t(m*4369+0.5);
607             TClonesArray& fmd = *(fReducedEvent->GetFMD(fmdDet));
608             AliReducedFMD   *reducedFMD=new(fmd[nFMD]) AliReducedFMD();
609             fReducedEvent->fNFMDchannels[fmdDet] += 1;
610             reducedFMD->fMultiplicity     =  m;    
611             //reducedFMD->fEta              =  esdFmd->Eta(det, ring, 0, str);
612             reducedFMD->fId               =  id;
613           }  
614         }  // end loop over strips
615         
616         if(fFillFMDSectorInfo) {
617           TClonesArray& fmd = *(fReducedEvent->GetFMD(fmdDet));
618           AliReducedFMD   *reducedFMD=new(fmd[phiBin]) AliReducedFMD();
619           reducedFMD->fMultiplicity     = fmdMult;
620           fReducedEvent->fNFMDchannels[fmdDet] += 1;
621           //cout<<sec<<"  "<<fmdMult<<endl;
622           fmdMult=0.0;
623         }
624       }  // end loop over sectors      
625       
626       fReducedEvent->fFMDtotalMult[fmdDet] = msum;
627       msum=0.0;
628       ++fmdDet;
629       id=-1;
630     }  // end loop over rings
631   } // end loop over detectors
632 }
633
634 ////_________________________________________________________________________________
635 //void AliAnalysisTaskReducedTree::FillCorrectedFMDInfo(const TH2D& fmdhist) 
636 //{
637 //
638 //
639 //Int_t nEta = fmdhist.GetXaxis()->GetNbins();
640 //Int_t nPhi = fmdhist.GetYaxis()->GetNbins();
641 ////Int_t nBins= fmdhist.GetNbins();
642 //Float_t eta=0.0;
643 //Float_t phi=0.0;
644 //Float_t mult=0.0;
645 //
646 //
647 //Int_t nFMD=0;
648 ////fReducedEvent->fNCorFmdChannels = 0;
649 //for (Int_t e = 1; e <= nEta; e++) {
650 //    eta = fmdhist.GetXaxis()->GetBinCenter(e);
651 //    for (Int_t p = 1; p <= nPhi; p++) {
652 //         phi = fmdhist.GetYaxis()->GetBinCenter(p);
653 //         mult = fmdhist.GetBinContent(e, p);
654 //       //TClonesArray& Corfmd = *(fReducedEvent->fCorFMD);
655 //       //AliReducedFMD *reducedCorFMD=new(Corfmd[nFMD]) AliReducedCorFMD();
656 //    std::cout<<mult<<"  "<<eta<<"  "<<phi<<std::endl;
657 //      }
658 //
659 //      //fReducedEvent->fNCorFmdChannels += 1;
660 //      nFMD += 1;
661 ////reducedFMD->fCorMultiplicity = mult;
662 ////reducedFMD->fCorEta          = eta;
663 ////reducedFMD->fCorPhi          = phi;
664 //
665 //
666 //}
667 //
668 //
669 //}
670
671
672 //_________________________________________________________________________________
673 void AliAnalysisTaskReducedTree::FillTrackInfo() 
674 {
675   //
676   // fill reduced track information
677   //
678   AliVEvent* event = InputEvent();
679   Bool_t isESD = (event->IsA()==AliESDEvent::Class());
680   Bool_t isAOD = (event->IsA()==AliAODEvent::Class());
681
682   AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
683   AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
684   AliPIDResponse* pidResponse = inputHandler->GetPIDResponse();
685   
686   // find all the tracks which belong to a V0 stored in the reduced event
687   UShort_t trackIdsV0[4][20000]={{0}};
688   UShort_t trackIdsPureV0[4][20000]={{0}};
689   Int_t nV0LegsTagged[4] = {0}; Int_t nPureV0LegsTagged[4] = {0};
690   Bool_t leg1Found[4]; Bool_t leg2Found[4];
691   for(Int_t iv0=0;iv0<fReducedEvent->fNV0candidates[1];++iv0) {
692     AliReducedPair* pair = fReducedEvent->GetV0Pair(iv0);
693     if(!pair) continue;
694     Int_t pairId = 0; Bool_t isPureV0 = kFALSE;
695     if(pair->fCandidateId==AliReducedPair::kGammaConv) {
696       pairId=0;
697       if(pair->IsPureV0Gamma()) isPureV0 = kTRUE;
698     }
699     if(pair->fCandidateId==AliReducedPair::kK0sToPiPi) {
700       pairId=1;
701       if(pair->IsPureV0K0s()) isPureV0 = kTRUE;
702     }
703     if(pair->fCandidateId==AliReducedPair::kLambda0ToPPi) {
704       pairId=2;
705       if(pair->IsPureV0Lambda()) isPureV0 = kTRUE;
706     }
707     if(pair->fCandidateId==AliReducedPair::kALambda0ToPPi) {
708       pairId=3;
709       if(pair->IsPureV0ALambda()) isPureV0 = kTRUE;
710     }
711     
712     leg1Found[pairId] = kFALSE; leg2Found[pairId] = kFALSE;
713     for(Int_t it=0;it<nV0LegsTagged[pairId];++it) {
714       if(trackIdsV0[pairId][it]==pair->fLegIds[0]) leg1Found[pairId]=kTRUE;
715       if(trackIdsV0[pairId][it]==pair->fLegIds[1]) leg2Found[pairId]=kTRUE;
716     }
717     // if the legs of this V0 were not already stored then add them now to the list
718     if(!leg1Found[pairId]) {trackIdsV0[pairId][nV0LegsTagged[pairId]] = pair->fLegIds[0]; ++nV0LegsTagged[pairId];}
719     if(!leg2Found[pairId]) {trackIdsV0[pairId][nV0LegsTagged[pairId]] = pair->fLegIds[1]; ++nV0LegsTagged[pairId];}
720     
721     if(isPureV0) {
722       leg1Found[pairId] = kFALSE; leg2Found[pairId] = kFALSE;
723       for(Int_t it=0;it<nPureV0LegsTagged[pairId];++it) {
724         if(trackIdsPureV0[pairId][it]==pair->fLegIds[0]) leg1Found[pairId]=kTRUE;
725         if(trackIdsPureV0[pairId][it]==pair->fLegIds[1]) leg2Found[pairId]=kTRUE;
726       }
727       // if the legs of this pure V0 were not already stored then add them now to the list
728       if(!leg1Found[pairId]) {trackIdsPureV0[pairId][nPureV0LegsTagged[pairId]] = pair->fLegIds[0]; ++nPureV0LegsTagged[pairId];}
729       if(!leg2Found[pairId]) {trackIdsPureV0[pairId][nPureV0LegsTagged[pairId]] = pair->fLegIds[1]; ++nPureV0LegsTagged[pairId];}
730     }
731   }
732   
733   // find all the tracks which belong to a stored dielectron pair
734   UShort_t trackIdsDiele[20000]={0};
735   Int_t nDieleLegsTagged = 0;
736   for(Int_t idie=0;idie<fReducedEvent->NDielectrons();++idie) {
737     AliReducedPair* pair = fReducedEvent->GetDielectronPair(idie);
738     leg1Found[0]=kFALSE; leg2Found[0]=kFALSE;
739     for(Int_t it=0; it<nDieleLegsTagged; ++it) {
740       if(trackIdsDiele[it]==pair->fLegIds[0]) leg1Found[0]=kTRUE;
741       if(trackIdsDiele[it]==pair->fLegIds[1]) leg2Found[0]=kTRUE;
742     }
743     // if the legs of this dielectron were not already stored then add them now to the list
744     if(!leg1Found[0]) {trackIdsDiele[nDieleLegsTagged] = pair->fLegIds[0]; ++nDieleLegsTagged;}
745     if(!leg2Found[0]) {trackIdsDiele[nDieleLegsTagged] = pair->fLegIds[1]; ++nDieleLegsTagged;}
746   }
747     
748   AliESDtrack* esdTrack=0;
749   AliAODTrack* aodTrack=0;
750   Int_t ntracks=event->GetNumberOfTracks();
751   Int_t trackId = 0; 
752   Bool_t usedForV0[4] = {kFALSE}; 
753   Bool_t usedForPureV0[4] = {kFALSE};
754   Bool_t usedForV0Or = kFALSE;
755   Bool_t usedForDielectron = kFALSE;
756   for(Int_t itrack=0; itrack<ntracks; ++itrack){
757     AliVParticle *particle=event->GetTrack(itrack);
758     if(isESD) {
759       esdTrack=static_cast<AliESDtrack*>(particle);
760       trackId = esdTrack->GetID();
761     }
762     if(isAOD) {
763       aodTrack=static_cast<AliAODTrack*>(particle);
764       trackId = aodTrack->GetID();
765     }
766     // check whether this track belongs to a V0 stored in the reduced event
767     usedForV0Or = kFALSE;
768     for(Int_t i=0; i<4; ++i) {
769       usedForV0[i] = kFALSE;
770       for(Int_t ii=0; ii<nV0LegsTagged[i]; ++ii) {
771         if(UShort_t(trackId)==trackIdsV0[i][ii]) {
772           usedForV0[i] = kTRUE;
773           //cout << "track " << trackId << " used for V0 type " << i << endl;
774           break;
775         }
776       }
777       usedForV0Or = usedForV0Or || usedForV0[i];
778       usedForPureV0[i] = kFALSE;
779       for(Int_t ii=0; ii<nPureV0LegsTagged[i]; ++ii) {
780         if(UShort_t(trackId)==trackIdsPureV0[i][ii]) {
781           usedForPureV0[i] = kTRUE;
782           //cout << "track " << trackId << " used for pure V0 type " << i << endl;
783           break;
784         }
785       }
786     }
787     // check whether this track belongs to a dielectron stored in the reduced event
788     usedForDielectron = kFALSE;
789     for(Int_t ii=0; ii<nDieleLegsTagged; ++ii) {
790       if(UShort_t(trackId)==trackIdsDiele[ii]) {
791         usedForDielectron = kTRUE;
792         break;
793       }
794     }
795     
796     ULong_t status = (isESD ? esdTrack->GetStatus() : aodTrack->GetStatus());
797     //cout << "TRACK" << endl;
798     for(Int_t ibit=0; ibit<32; ++ibit) {
799       if(status & (ULong_t(1)<<ibit)) {
800         //cout << "bit " << ibit << endl;
801         fReducedEvent->fNtracksPerTrackingFlag[ibit] += 1;
802       }
803     }
804     
805     //apply track cuts
806     if(!usedForV0Or && !usedForDielectron && fTrackFilter && !fTrackFilter->IsSelected(particle)) continue;
807     //cout << "storing track " << trackId << endl;
808     
809     TClonesArray& tracks = *(fReducedEvent->fTracks);
810     AliReducedTrack *reducedParticle=new(tracks[fReducedEvent->fNtracks[1]]) AliReducedTrack();
811         
812     Double_t values[AliDielectronVarManager::kNMaxValues];
813     AliDielectronVarManager::Fill(particle, values);
814     reducedParticle->fStatus        = status;//(ULong_t)values[AliDielectronVarManager::kTrackStatus];
815     reducedParticle->fGlobalPhi     = values[AliDielectronVarManager::kPhi];
816     reducedParticle->fGlobalPt      = values[AliDielectronVarManager::kPt]*values[AliDielectronVarManager::kCharge];
817     reducedParticle->fGlobalEta     = values[AliDielectronVarManager::kEta];    
818     reducedParticle->fMomentumInner = values[AliDielectronVarManager::kPIn];
819     reducedParticle->fDCA[0]        = values[AliDielectronVarManager::kImpactParXY];
820     reducedParticle->fDCA[1]        = values[AliDielectronVarManager::kImpactParZ];
821     reducedParticle->fTrackLength   = values[AliDielectronVarManager::kTrackLength];
822     
823     reducedParticle->fITSclusterMap = (UChar_t)values[AliDielectronVarManager::kITSclusterMap];
824     reducedParticle->fITSsignal     = values[AliDielectronVarManager::kITSsignal];
825     reducedParticle->fITSnSig[0]    = values[AliDielectronVarManager::kITSnSigmaEle];
826     reducedParticle->fITSnSig[1]    = values[AliDielectronVarManager::kITSnSigmaPio];
827     reducedParticle->fITSnSig[2]    = values[AliDielectronVarManager::kITSnSigmaKao];
828     reducedParticle->fITSnSig[3]    = values[AliDielectronVarManager::kITSnSigmaPro];
829     reducedParticle->fITSchi2       = values[AliDielectronVarManager::kITSchi2Cl];
830     
831     reducedParticle->fTPCNcls      = (UChar_t)values[AliDielectronVarManager::kNclsTPC];
832     reducedParticle->fTPCNclsF     = (UChar_t)values[AliDielectronVarManager::kNFclsTPC];
833     reducedParticle->fTPCNclsIter1 = (UChar_t)values[AliDielectronVarManager::kNclsTPCiter1];
834     reducedParticle->fTPCsignal    = values[AliDielectronVarManager::kTPCsignal];
835     reducedParticle->fTPCsignalN   = values[AliDielectronVarManager::kTPCsignalN];
836     reducedParticle->fTPCnSig[0]   = values[AliDielectronVarManager::kTPCnSigmaEle];
837     reducedParticle->fTPCnSig[1]   = values[AliDielectronVarManager::kTPCnSigmaPio];
838     reducedParticle->fTPCnSig[2]   = values[AliDielectronVarManager::kTPCnSigmaKao];
839     reducedParticle->fTPCnSig[3]   = values[AliDielectronVarManager::kTPCnSigmaPro];
840     reducedParticle->fTPCClusterMap = EncodeTPCClusterMap(particle, isAOD);
841     reducedParticle->fTPCchi2       = values[AliDielectronVarManager::kTPCchi2Cl];
842     
843     reducedParticle->fTOFbeta      = values[AliDielectronVarManager::kTOFbeta];
844     reducedParticle->fTOFnSig[0]   = values[AliDielectronVarManager::kTOFnSigmaEle];
845     reducedParticle->fTOFnSig[1]   = values[AliDielectronVarManager::kTOFnSigmaPio];
846     reducedParticle->fTOFnSig[2]   = values[AliDielectronVarManager::kTOFnSigmaKao];
847     reducedParticle->fTOFnSig[3]   = values[AliDielectronVarManager::kTOFnSigmaPro];
848     
849     Double_t trdProbab[AliPID::kSPECIES]={0.0};
850         
851     if(fFlowTrackFilter) {
852       // switch on the first bit if this particle should be used for the event plane
853       if(fFlowTrackFilter->IsSelected(particle)) reducedParticle->fFlags |= (UShort_t(1)<<0);
854     }
855     for(Int_t iV0type=0;iV0type<4;++iV0type) {
856       if(usedForV0[iV0type]) reducedParticle->fFlags |= (UShort_t(1)<<(iV0type+1));
857       if(usedForPureV0[iV0type]) reducedParticle->fFlags |= (UShort_t(1)<<(iV0type+8));
858     }
859     
860     if(isESD){
861       //AliESDtrack *track=static_cast<AliESDtrack*>(particle);
862       reducedParticle->fTrackId          = (UShort_t)esdTrack->GetID();
863       reducedParticle->fTPCCrossedRows   = (UChar_t)esdTrack->GetTPCCrossedRows();
864       //reducedParticle->fTPCClusterMap    = EncodeTPCClusterMap(esdTrack);
865       const AliExternalTrackParam* tpcInner = esdTrack->GetInnerParam();
866       reducedParticle->fTPCPhi        = (tpcInner ? tpcInner->Phi() : 0.0);
867       reducedParticle->fTPCPt         = (tpcInner ? tpcInner->Pt() : 0.0);
868       reducedParticle->fTPCEta        = (tpcInner ? tpcInner->Eta() : 0.0);
869       
870       reducedParticle->fTOFdeltaBC    = esdTrack->GetTOFDeltaBC();
871       
872       reducedParticle->fTRDntracklets[0] = esdTrack->GetTRDntracklets();
873       reducedParticle->fTRDntracklets[1] = esdTrack->GetTRDntrackletsPID();
874       pidResponse->ComputeTRDProbability(esdTrack,AliPID::kSPECIES,trdProbab,AliTRDPIDResponse::kLQ1D);
875       reducedParticle->fTRDpid[0]    = trdProbab[AliPID::kElectron];
876       reducedParticle->fTRDpid[1]    = trdProbab[AliPID::kPion];
877       pidResponse->ComputeTRDProbability(esdTrack,AliPID::kSPECIES,trdProbab,AliTRDPIDResponse::kLQ2D);
878       reducedParticle->fTRDpidLQ2D[0]    = trdProbab[AliPID::kElectron];
879       reducedParticle->fTRDpidLQ2D[1]    = trdProbab[AliPID::kPion];
880             
881       for(Int_t idx=0; idx<3; ++idx) if(esdTrack->GetKinkIndex(idx)>0) reducedParticle->fFlags |= (1<<(5+idx));
882       if(esdTrack->IsEMCAL()) reducedParticle->fCaloClusterId = esdTrack->GetEMCALcluster();
883       if(esdTrack->IsPHOS()) reducedParticle->fCaloClusterId = esdTrack->GetPHOScluster();
884     }
885     if(isAOD) {
886       //AliAODTrack *track=static_cast<AliAODTrack*>(particle);
887       const AliExternalTrackParam* tpcInner = aodTrack->GetInnerParam();
888       reducedParticle->fTPCPhi        = (tpcInner ? tpcInner->Phi() : 0.0);
889       reducedParticle->fTPCPt         = (tpcInner ? tpcInner->Pt() : 0.0);
890       reducedParticle->fTPCEta        = (tpcInner ? tpcInner->Eta() : 0.0);
891       
892       reducedParticle->fTrackId = aodTrack->GetID(); 
893       reducedParticle->fITSsignal = aodTrack->GetITSsignal();
894       if(pidResponse) {
895         reducedParticle->fITSnSig[0]    = pidResponse->NumberOfSigmasITS(aodTrack,AliPID::kElectron);
896         reducedParticle->fITSnSig[1]    = pidResponse->NumberOfSigmasITS(aodTrack,AliPID::kPion);
897         reducedParticle->fITSnSig[2]    = pidResponse->NumberOfSigmasITS(aodTrack,AliPID::kKaon);
898         reducedParticle->fITSnSig[3]    = pidResponse->NumberOfSigmasITS(aodTrack,AliPID::kProton);
899       }
900       reducedParticle->fTRDntracklets[0] = aodTrack->GetTRDntrackletsPID();
901       reducedParticle->fTRDntracklets[1] = aodTrack->GetTRDntrackletsPID();
902       pidResponse->ComputeTRDProbability(aodTrack,AliPID::kSPECIES,trdProbab,AliTRDPIDResponse::kLQ1D);
903       reducedParticle->fTRDpid[0]    = trdProbab[AliPID::kElectron];
904       reducedParticle->fTRDpid[1]    = trdProbab[AliPID::kPion];
905       pidResponse->ComputeTRDProbability(aodTrack,AliPID::kSPECIES,trdProbab,AliTRDPIDResponse::kLQ2D);
906       reducedParticle->fTRDpidLQ2D[0]    = trdProbab[AliPID::kElectron];
907       reducedParticle->fTRDpidLQ2D[1]    = trdProbab[AliPID::kPion];
908       
909       if(aodTrack->IsEMCAL()) reducedParticle->fCaloClusterId = aodTrack->GetEMCALcluster();
910       if(aodTrack->IsPHOS()) reducedParticle->fCaloClusterId = aodTrack->GetPHOScluster();
911       if(values[AliDielectronVarManager::kKinkIndex0]>0.0) reducedParticle->fFlags |= (1<<5);
912     }
913
914     fReducedEvent->fNtracks[1] += 1;
915   }
916 }
917
918
919 //_________________________________________________________________________________
920 void AliAnalysisTaskReducedTree::FillDielectronPairInfo(AliDielectron* die, Short_t iDie) 
921 {
922   //
923   // fill reduced pair information
924   //
925   Bool_t hasMC=AliDielectronMC::Instance()->HasMC();
926
927   for(Int_t iType=0; iType<3; ++iType) {
928     
929     const TObjArray* array = die->GetPairArray(iType);
930     if(!array || array->GetEntriesFast()==0) continue;
931     
932     for(Int_t iCandidate=0; iCandidate<array->GetEntriesFast(); ++iCandidate) {
933       AliDielectronPair* pair = (AliDielectronPair*)array->At(iCandidate);
934       Double_t values[AliDielectronVarManager::kNMaxValues];
935       AliDielectronVarManager::Fill(pair, values);
936       
937       TClonesArray& tracks = *(fReducedEvent->fCandidates);
938       AliReducedPair *reducedParticle= 
939          new (tracks[fReducedEvent->fNV0candidates[1]+fReducedEvent->fNDielectronCandidates]) AliReducedPair();
940       // !!! hardcoded flag for dielectron id 
941       reducedParticle->fCandidateId  = (iDie==0 ? AliReducedPair::kJpsiToEE : AliReducedPair::kPhiToKK);
942       reducedParticle->fPairType     = (Char_t)values[AliDielectronVarManager::kPairType];
943       reducedParticle->fLegIds[0]    = (UShort_t)(static_cast<AliVTrack*>(pair->GetFirstDaughterP()))->GetID();
944       reducedParticle->fLegIds[1]    = (UShort_t)(static_cast<AliVTrack*>(pair->GetSecondDaughterP()))->GetID();
945       reducedParticle->fMass[0]      = values[AliDielectronVarManager::kM];
946       reducedParticle->fMass[1]      = -999.;
947       reducedParticle->fMass[2]      = -999.;
948       reducedParticle->fMass[3]      = -999.;
949       reducedParticle->fPhi          = values[AliDielectronVarManager::kPhi];  // in the [-pi,pi] interval
950       if(reducedParticle->fPhi<0.0) reducedParticle->fPhi = 2.0*TMath::Pi() + reducedParticle->fPhi;  // converted to [0,2pi]
951       reducedParticle->fPt           = values[AliDielectronVarManager::kPt];
952       reducedParticle->fEta          = values[AliDielectronVarManager::kEta];
953       reducedParticle->fLxy          = values[AliDielectronVarManager::kPseudoProperTime];
954       reducedParticle->fLxyErr       = values[AliDielectronVarManager::kPseudoProperTimeErr];
955       reducedParticle->fPointingAngle = values[AliDielectronVarManager::kCosPointingAngle];
956       
957       reducedParticle->fMCid         = 0;
958       if(hasMC) {
959         AliDielectronMC::Instance()->ConnectMCEvent();
960         const TObjArray* mcSignals = die->GetMCSignals();
961         for(Int_t iSig=0; iSig<mcSignals->GetEntries(); ++iSig) {
962           if(iSig>31) break;
963           AliDielectronMC *mc=AliDielectronMC::Instance();
964           if(mc->IsMCTruth(pair, (AliDielectronSignalMC*)mcSignals->At(iSig))) {
965             reducedParticle->fMCid = reducedParticle->fMCid | (1<<iSig);
966           }
967         }
968       }   // end if has MC
969       fReducedEvent->fNDielectronCandidates += 1;
970     }    // end loop over candidates
971   }    // end loop over pair type
972 }
973
974
975 //_________________________________________________________________________________
976 void AliAnalysisTaskReducedTree::FillV0PairInfo() 
977 {
978   //
979   // fill reduced pair information
980   //
981   AliESDEvent* esd = (AliESDEvent*)InputEvent();
982   const AliESDVertex *primaryVertex = esd->GetPrimaryVertex();
983   AliKFVertex primaryVertexKF(*primaryVertex);
984   
985   fReducedEvent->fNV0candidates[0] = InputEvent()->GetNumberOfV0s();
986   
987   if(!(fFillK0s || fFillLambda || fFillALambda || fFillGammaConversions)) return;
988     
989   Double_t valuesPos[AliDielectronVarManager::kNMaxValues];
990   Double_t valuesNeg[AliDielectronVarManager::kNMaxValues];
991   
992   if(fV0OpenCuts) {
993     fV0OpenCuts->SetEvent(esd);
994     fV0OpenCuts->SetPrimaryVertex(&primaryVertexKF);
995   }
996   if(fV0StrongCuts) {
997     fV0StrongCuts->SetEvent(esd);
998     fV0StrongCuts->SetPrimaryVertex(&primaryVertexKF);
999   }
1000   
1001   Int_t pdgV0=0; Int_t pdgP=0; Int_t pdgN=0;
1002   for(Int_t iV0=0; iV0<InputEvent()->GetNumberOfV0s(); ++iV0) {   // loop over V0s
1003     AliESDv0 *v0 = esd->GetV0(iV0);
1004        
1005     AliESDtrack* legPos = esd->GetTrack(v0->GetPindex());
1006     AliESDtrack* legNeg = esd->GetTrack(v0->GetNindex());
1007  
1008     if(legPos->GetSign() == legNeg->GetSign()) {
1009       continue;
1010     }
1011
1012     Bool_t v0ChargesAreCorrect = (legPos->GetSign()==+1 ? kTRUE : kFALSE);
1013     legPos = (!v0ChargesAreCorrect ? esd->GetTrack(v0->GetNindex()) : legPos);
1014     legNeg = (!v0ChargesAreCorrect ? esd->GetTrack(v0->GetPindex()) : legNeg); 
1015     
1016     pdgV0=0; pdgP=0; pdgN=0;
1017     Bool_t goodK0s = kTRUE; Bool_t goodLambda = kTRUE; Bool_t goodALambda = kTRUE; Bool_t goodGamma = kTRUE;
1018     if(fV0OpenCuts) {
1019       goodK0s = kFALSE; goodLambda = kFALSE; goodALambda = kFALSE; goodGamma = kFALSE;
1020       Bool_t processV0 = fV0OpenCuts->ProcessV0(v0, pdgV0, pdgP, pdgN);
1021       if(processV0 && TMath::Abs(pdgV0)==310 && TMath::Abs(pdgP)==211 && TMath::Abs(pdgN)==211) {
1022         goodK0s = kTRUE;
1023         if(fK0sPionCuts && (!fK0sPionCuts->IsSelected(legPos) || !fK0sPionCuts->IsSelected(legNeg))) goodK0s = kFALSE;
1024       }
1025       if(processV0 && pdgV0==3122 && (TMath::Abs(pdgP)==211 || TMath::Abs(pdgP)==2212) && (TMath::Abs(pdgN)==211 || TMath::Abs(pdgN)==2212)) {
1026         goodLambda = kTRUE;
1027         if(fLambdaProtonCuts && !fLambdaProtonCuts->IsSelected(legPos)) goodLambda = kFALSE;
1028         if(fLambdaPionCuts && !fLambdaPionCuts->IsSelected(legNeg)) goodLambda = kFALSE;
1029       }
1030       if(processV0 && pdgV0==-3122 && (TMath::Abs(pdgP)==211 || TMath::Abs(pdgP)==2212) && (TMath::Abs(pdgN)==211 || TMath::Abs(pdgN)==2212)) {
1031         goodALambda = kTRUE;
1032         if(fLambdaProtonCuts && !fLambdaProtonCuts->IsSelected(legNeg)) goodALambda = kFALSE;
1033         if(fLambdaPionCuts && !fLambdaPionCuts->IsSelected(legPos)) goodALambda = kFALSE;
1034       }
1035       if(processV0 && TMath::Abs(pdgV0)==22 && TMath::Abs(pdgP)==11 && TMath::Abs(pdgN)==11) {
1036         goodGamma = kTRUE;
1037         if(fGammaElectronCuts && (!fGammaElectronCuts->IsSelected(legPos) || !fGammaElectronCuts->IsSelected(legNeg))) goodGamma = kFALSE;
1038       }
1039       //cout << "open cuts  pdgV0/pdgP/pdgN/processV0 : " << pdgV0 << "/" << pdgP << "/" << pdgN << "/" << processV0 << endl;     
1040       //cout << "good K0s/Lambda/ALambda/Gamma : " << goodK0s << "/" << goodLambda << "/" << goodALambda << "/" << goodGamma << endl;
1041     }
1042     
1043     Bool_t veryGoodK0s = kFALSE; Bool_t veryGoodLambda = kFALSE; Bool_t veryGoodALambda = kFALSE; Bool_t veryGoodGamma = kFALSE;
1044     if(fV0StrongCuts && (goodK0s || goodLambda || goodALambda || goodGamma)) {
1045       pdgV0=0; pdgP=0; pdgN=0;
1046       Bool_t processV0 = fV0StrongCuts->ProcessV0(v0, pdgV0, pdgP, pdgN);
1047       if(processV0 && goodK0s && TMath::Abs(pdgV0)==310 && TMath::Abs(pdgP)==211 && TMath::Abs(pdgN)==211)
1048         veryGoodK0s = kTRUE;
1049       if(processV0 && goodLambda && pdgV0==3122 && (TMath::Abs(pdgP)==211 || TMath::Abs(pdgP)==2212) && (TMath::Abs(pdgN)==211 || TMath::Abs(pdgN)==2212))
1050         veryGoodLambda = kTRUE;
1051       if(processV0 && goodALambda && pdgV0==-3122 && (TMath::Abs(pdgP)==211 || TMath::Abs(pdgP)==2212) && (TMath::Abs(pdgN)==211 || TMath::Abs(pdgN)==2212))
1052         veryGoodALambda = kTRUE;
1053       if(processV0 && goodGamma && TMath::Abs(pdgV0)==22 && TMath::Abs(pdgP)==11 && TMath::Abs(pdgN)==11)
1054         veryGoodGamma = kTRUE;
1055       //cout << "strong cuts  pdgV0/pdgP/pdgN/processV0 : " << pdgV0 << "/" << pdgP << "/" << pdgN << "/" << processV0 << endl;     
1056       //cout << "very good K0s/Lambda/ALambda/Gamma : " << veryGoodK0s << "/" << veryGoodLambda << "/" << veryGoodALambda << "/" << veryGoodGamma << endl;
1057     }
1058               
1059     if(!((goodK0s && fFillK0s) || 
1060          (goodLambda && fFillLambda) || 
1061          (goodALambda && fFillALambda) || 
1062          (goodGamma && fFillGammaConversions))) continue;
1063     
1064     // Fill the V0 information into the tree for 4 hypothesis: K0s, Lambda, Anti-Lambda and gamma conversion
1065     AliReducedPair* k0sReducedPair     = FillV0PairInfo(v0, AliReducedPair::kK0sToPiPi,     legPos, legNeg, &primaryVertexKF, v0ChargesAreCorrect);
1066     AliReducedPair* lambdaReducedPair  = FillV0PairInfo(v0, AliReducedPair::kLambda0ToPPi,  legPos, legNeg, &primaryVertexKF, v0ChargesAreCorrect);
1067     AliReducedPair* alambdaReducedPair = FillV0PairInfo(v0, AliReducedPair::kALambda0ToPPi, legPos, legNeg, &primaryVertexKF, v0ChargesAreCorrect);
1068     AliReducedPair* gammaReducedPair   = FillV0PairInfo(v0, AliReducedPair::kGammaConv,     legPos, legNeg, &primaryVertexKF, v0ChargesAreCorrect);
1069     
1070     if(fFillK0s && goodK0s && k0sReducedPair->fMass[0]>fK0sMassRange[0] && k0sReducedPair->fMass[0]<fK0sMassRange[1]) {
1071       TClonesArray& tracks = *(fReducedEvent->fCandidates);
1072       AliReducedPair *goodK0sPair = new (tracks[fReducedEvent->fNV0candidates[1]]) AliReducedPair(*k0sReducedPair);
1073       goodK0sPair->fMass[0] = k0sReducedPair->fMass[0];
1074       goodK0sPair->fMass[1] = lambdaReducedPair->fMass[0];
1075       goodK0sPair->fMass[2] = alambdaReducedPair->fMass[0];
1076       goodK0sPair->fMass[3] = gammaReducedPair->fMass[0];
1077       if(veryGoodK0s) goodK0sPair->fMCid |= (UInt_t(1)<<1);
1078       fReducedEvent->fNV0candidates[1] += 1;
1079     } else {goodK0s=kFALSE;}
1080     if(fFillLambda && goodLambda && lambdaReducedPair->fMass[0]>fLambdaMassRange[0] && lambdaReducedPair->fMass[0]<fLambdaMassRange[1]) {
1081       TClonesArray& tracks = *(fReducedEvent->fCandidates);
1082       AliReducedPair *goodLambdaPair = new (tracks[fReducedEvent->fNV0candidates[1]]) AliReducedPair(*lambdaReducedPair);
1083       goodLambdaPair->fMass[0] = k0sReducedPair->fMass[0];
1084       goodLambdaPair->fMass[1] = lambdaReducedPair->fMass[0];
1085       goodLambdaPair->fMass[2] = alambdaReducedPair->fMass[0];
1086       goodLambdaPair->fMass[3] = gammaReducedPair->fMass[0];
1087       if(veryGoodLambda) goodLambdaPair->fMCid |= (UInt_t(1)<<2);
1088       fReducedEvent->fNV0candidates[1] += 1;
1089     } else {goodLambda=kFALSE;}
1090     if(fFillALambda && goodALambda && alambdaReducedPair->fMass[0]>fLambdaMassRange[0] && alambdaReducedPair->fMass[0]<fLambdaMassRange[1]) {
1091       TClonesArray& tracks = *(fReducedEvent->fCandidates);
1092       AliReducedPair *goodALambdaPair = new (tracks[fReducedEvent->fNV0candidates[1]]) AliReducedPair(*alambdaReducedPair);
1093       goodALambdaPair->fMass[0] = k0sReducedPair->fMass[0];
1094       goodALambdaPair->fMass[1] = lambdaReducedPair->fMass[0];
1095       goodALambdaPair->fMass[2] = alambdaReducedPair->fMass[0];
1096       goodALambdaPair->fMass[3] = gammaReducedPair->fMass[0];
1097       if(veryGoodALambda) goodALambdaPair->fMCid |= (UInt_t(1)<<3);
1098       fReducedEvent->fNV0candidates[1] += 1;
1099     } else {goodALambda = kFALSE;}
1100     //cout << "gamma mass: " << gammaReducedPair->fMass[0] << endl;
1101     if(fFillGammaConversions && goodGamma && gammaReducedPair->fMass[0]>fGammaMassRange[0] && gammaReducedPair->fMass[0]<fGammaMassRange[1]) {
1102       TClonesArray& tracks = *(fReducedEvent->fCandidates);
1103       AliReducedPair *goodGammaPair = new (tracks[fReducedEvent->fNV0candidates[1]]) AliReducedPair(*gammaReducedPair);
1104       goodGammaPair->fMass[0] = k0sReducedPair->fMass[0];
1105       goodGammaPair->fMass[1] = lambdaReducedPair->fMass[0];
1106       goodGammaPair->fMass[2] = alambdaReducedPair->fMass[0];
1107       goodGammaPair->fMass[3] = gammaReducedPair->fMass[0];
1108       if(veryGoodGamma) goodGammaPair->fMCid |= (UInt_t(1)<<4);
1109       fReducedEvent->fNV0candidates[1] += 1;
1110     } else {goodGamma=kFALSE;}
1111     delete k0sReducedPair;
1112     delete lambdaReducedPair;
1113     delete alambdaReducedPair;
1114     delete gammaReducedPair;
1115     
1116     if(!(goodK0s || goodLambda || goodALambda || goodGamma)) continue;
1117     
1118     //  Fill histograms and the CF container
1119     AliDielectronVarManager::Fill(legPos, valuesPos);
1120     AliDielectronVarManager::Fill(legNeg, valuesNeg);
1121     
1122     if(fV0Histos && fV0Histos->GetHistogramList()->FindObject("V0Track_Pos"))
1123       fV0Histos->FillClass("V0Track_Pos", AliDielectronVarManager::kNMaxValues, valuesPos);
1124     if(fV0Histos && fV0Histos->GetHistogramList()->FindObject("V0Track_Neg"))
1125       fV0Histos->FillClass("V0Track_Neg", AliDielectronVarManager::kNMaxValues, valuesNeg);    
1126   }   // end loop over V0s
1127 }
1128
1129
1130 //_________________________________________________________________________________
1131 AliReducedPair* AliAnalysisTaskReducedTree::FillV0PairInfo(AliESDv0* v0, Int_t id, 
1132                                                     AliESDtrack* legPos, AliESDtrack* legNeg,
1133                                                     AliKFVertex* vtxKF, Bool_t chargesAreCorrect) {
1134   //
1135   // Create a reduced V0 object and fill it
1136   //
1137   AliReducedPair* reducedPair=new AliReducedPair();  
1138   reducedPair->fCandidateId = id;
1139   reducedPair->fPairType    = v0->GetOnFlyStatus();    // on the fly status
1140   reducedPair->fLegIds[0]   = legPos->GetID();
1141   reducedPair->fLegIds[1]   = legNeg->GetID();
1142   if(!reducedPair->fPairType) {    // offline
1143     UInt_t pidPos = AliPID::kPion;
1144     if(id==AliReducedPair::kLambda0ToPPi) pidPos = AliPID::kProton;
1145     if(id==AliReducedPair::kGammaConv) pidPos = AliPID::kElectron;
1146     UInt_t pidNeg = AliPID::kPion;
1147     if(id==AliReducedPair::kALambda0ToPPi) pidNeg = AliPID::kProton;
1148     if(id==AliReducedPair::kGammaConv) pidNeg = AliPID::kElectron;
1149     reducedPair->fMass[0]      = v0->GetEffMass(pidPos, pidNeg);
1150     reducedPair->fPhi          = v0->Phi();
1151     if(reducedPair->fPhi<0.0) reducedPair->fPhi = 2.0*TMath::Pi() + reducedPair->fPhi;  // converted to [0,2pi]
1152     reducedPair->fPt           = v0->Pt();
1153     reducedPair->fEta          = v0->Eta();
1154     reducedPair->fLxy          = v0->GetRr();
1155     reducedPair->fPointingAngle = v0->GetV0CosineOfPointingAngle(vtxKF->GetX(), vtxKF->GetY(), vtxKF->GetZ());
1156     reducedPair->fChisquare    = v0->GetChi2V0();
1157   }
1158   else {
1159     const AliExternalTrackParam *negHelix=v0->GetParamN();
1160     const AliExternalTrackParam *posHelix=v0->GetParamP();
1161     if(!chargesAreCorrect) {
1162       negHelix = v0->GetParamP();
1163       posHelix = v0->GetParamN();
1164     }
1165     Int_t pdgPos = 211;
1166     if(id==AliReducedPair::kLambda0ToPPi) pdgPos = 2212;
1167     if(id==AliReducedPair::kGammaConv) pdgPos = -11;
1168     Int_t pdgNeg = -211;
1169     if(id==AliReducedPair::kALambda0ToPPi) pdgNeg = -2212;
1170     if(id==AliReducedPair::kGammaConv) pdgNeg = 11;
1171     AliKFParticle negKF(*(negHelix), pdgPos);
1172     AliKFParticle posKF(*(posHelix), pdgNeg);
1173     AliKFParticle v0Refit;
1174     v0Refit += negKF;
1175     v0Refit += posKF;
1176     Double_t massFit=0.0, massErrFit=0.0;
1177     v0Refit.GetMass(massFit,massErrFit);
1178     reducedPair->fMass[0] = massFit;
1179     reducedPair->fPhi          = v0Refit.GetPhi();
1180     if(reducedPair->fPhi<0.0) reducedPair->fPhi = 2.0*TMath::Pi() + reducedPair->fPhi;  // converted to [0,2pi]
1181     reducedPair->fPt           = v0Refit.GetPt();
1182     reducedPair->fEta          = v0Refit.GetEta();
1183     reducedPair->fLxy          = v0Refit.GetPseudoProperDecayTime(*vtxKF, massFit);
1184     Double_t deltaPos[3];
1185     deltaPos[0] = v0Refit.GetX() - vtxKF->GetX(); deltaPos[1] = v0Refit.GetY() - vtxKF->GetY(); deltaPos[2] = v0Refit.GetZ() - vtxKF->GetZ();
1186     Double_t momV02 = v0Refit.GetPx()*v0Refit.GetPx() + v0Refit.GetPy()*v0Refit.GetPy() + v0Refit.GetPz()*v0Refit.GetPz();
1187     Double_t deltaPos2 = deltaPos[0]*deltaPos[0] + deltaPos[1]*deltaPos[1] + deltaPos[2]*deltaPos[2];
1188     reducedPair->fPointingAngle = (deltaPos[0]*v0Refit.GetPx() + deltaPos[1]*v0Refit.GetPy() + deltaPos[2]*v0Refit.GetPz()) / 
1189                                   TMath::Sqrt(momV02*deltaPos2);
1190     reducedPair->fChisquare = v0Refit.GetChi2();                              
1191   }
1192   return reducedPair;
1193 }
1194
1195
1196 //_________________________________________________________________________________
1197 UChar_t AliAnalysisTaskReducedTree::EncodeTPCClusterMap(AliVParticle* track, Bool_t isAOD) {
1198   //
1199   // Encode the TPC cluster map into an UChar_t
1200   // Divide the 159 bits from the bit map into 8 groups of adiacent clusters
1201   // For each group enable its corresponding bit if in that group there are more clusters compared to
1202   // a threshold.
1203   //
1204   AliESDtrack* esdTrack=0x0;
1205   AliAODTrack* aodTrack=0x0;
1206   if(isAOD)
1207     aodTrack=static_cast<AliAODTrack*>(track);
1208   else
1209     esdTrack=static_cast<AliESDtrack*>(track);
1210   
1211   const UChar_t threshold=5;
1212   TBits tpcClusterMap = (isAOD ? aodTrack->GetTPCClusterMap() : esdTrack->GetTPCClusterMap());
1213   UChar_t map=0;
1214   UChar_t n=0;
1215   UChar_t j=0;
1216   for(UChar_t i=0; i<8; ++i) {
1217     n=0;
1218     for(j=i*20; j<(i+1)*20 && j<159; ++j) n+=tpcClusterMap.TestBitNumber(j);
1219     if(n>=threshold) map |= (1<<i);
1220   }
1221   return map;
1222 }
1223
1224
1225 //_________________________________________________________________________________
1226 Int_t AliAnalysisTaskReducedTree::GetSPDTrackletMultiplicity(AliVEvent* event, Float_t lowEta, Float_t highEta) {
1227   //
1228   // Count the number of SPD tracklets in a given eta range
1229   //
1230   if (!event) return -1;
1231   
1232   Int_t nTracklets = 0;
1233   Int_t nAcc = 0;
1234   
1235   if(event->IsA() == AliAODEvent::Class()) {
1236     AliAODTracklets *tracklets = ((AliAODEvent*)event)->GetTracklets();
1237     nTracklets = tracklets->GetNumberOfTracklets();
1238     for(Int_t nn=0; nn<nTracklets; ++nn) {
1239       Double_t theta = tracklets->GetTheta(nn);
1240       Double_t eta = -TMath::Log(TMath::Tan(theta/2.0));
1241       if(eta < lowEta) continue;
1242       if(eta > highEta) continue;
1243       ++nAcc;
1244     }
1245   } else if(event->IsA() == AliESDEvent::Class()) {
1246     nTracklets = ((AliESDEvent*)event)->GetMultiplicity()->GetNumberOfTracklets();
1247     for(Int_t nn=0; nn<nTracklets; ++nn) {
1248       Double_t eta = ((AliESDEvent*)event)->GetMultiplicity()->GetEta(nn);
1249       if(eta < lowEta) continue;
1250       if(eta > highEta) continue; 
1251       ++nAcc;
1252     }
1253   } else return -1;
1254   
1255   return nAcc;
1256 }
1257
1258
1259 //_________________________________________________________________________________
1260 void AliAnalysisTaskReducedTree::FinishTaskOutput()
1261 {
1262   //
1263   // Finish Task 
1264   //
1265   
1266   //fTreeFile->Write();
1267   //fTreeFile->Close();
1268 }