]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGDQ/dielectron/AliAnalysisTaskReducedTree.cxx
- setevent again at the beginnning otherwise prefilter pair variable calculation...
[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 <AliAODTrack.h>
36 #include <AliTriggerAnalysis.h>
37 #include <AliESDtrackCuts.h>
38 #include <AliVZDC.h>
39 #include <AliESDv0.h>
40 #include <AliESDv0Cuts.h>
41 #include <AliESDv0KineCuts.h>
42 #include <AliVCluster.h>
43 #include <AliAODTracklets.h>
44 #include <AliMultiplicity.h>
45 #include <AliPIDResponse.h>
46 #include "AliDielectron.h"
47 #include "AliDielectronHistos.h"
48 #include "AliDielectronMC.h"
49 #include "AliDielectronVarManager.h"
50 #include "AliFlowTrackCuts.h"
51 #include "AliFlowBayesianPID.h"
52
53 #include "AliReducedEvent.h"
54 #include "AliAnalysisTaskReducedTree.h"
55
56 #include <iostream>
57 using std::cout;
58 using std::endl;
59
60 ClassImp(AliAnalysisTaskReducedTree)
61
62
63 //_________________________________________________________________________________
64 AliAnalysisTaskReducedTree::AliAnalysisTaskReducedTree() :
65   AliAnalysisTaskSE(),
66   fListDielectron(),
67   fListHistos(),
68   fSelectPhysics(kFALSE),
69   fTriggerMask(AliVEvent::kAny),
70   fRejectPileup(kFALSE),
71   fFillTrackInfo(kTRUE),
72   fFillDielectronInfo(kTRUE),
73   fFillV0Info(kTRUE),
74   fFillGammaConversions(kTRUE),
75   fFillK0s(kTRUE),
76   fFillLambda(kTRUE),
77   fFillALambda(kTRUE),
78   fFillCaloClusterInfo(kTRUE),
79   fFillFriendInfo(kTRUE),
80   fEventFilter(0x0),
81   fTrackFilter(0x0),
82   fFlowTrackFilter(0x0),
83   fK0sCuts(0x0),
84   fLambdaCuts(0x0),
85   fGammaConvCuts(0x0),
86   fK0sPionCuts(0x0),
87   fLambdaProtonCuts(0x0),
88   fLambdaPionCuts(0x0),
89   fGammaElectronCuts(0x0),
90   fV0OpenCuts(0x0),
91   fV0StrongCuts(0x0),
92   fK0sMassRange(),
93   fLambdaMassRange(),
94   fGammaMassRange(),
95   fV0Histos(0x0),
96   fTreeFile(0x0),
97   fTree(0x0),
98   fFriendTreeFile(0x0),
99   fFriendTree(0x0),
100   fReducedEvent(0x0),
101   fReducedEventFriend(0x0)
102 {
103   //
104   // Constructor
105   //
106 }
107
108 //_________________________________________________________________________________
109 AliAnalysisTaskReducedTree::AliAnalysisTaskReducedTree(const char *name) :
110   AliAnalysisTaskSE(name),
111   fListDielectron(),
112   fListHistos(),
113   fSelectPhysics(kFALSE),
114   fTriggerMask(AliVEvent::kAny),
115   fRejectPileup(kFALSE),
116   fFillTrackInfo(kTRUE),
117   fFillDielectronInfo(kTRUE),
118   fFillV0Info(kTRUE),
119   fFillGammaConversions(kTRUE),
120   fFillK0s(kTRUE),
121   fFillLambda(kTRUE),
122   fFillALambda(kTRUE),
123   fFillCaloClusterInfo(kTRUE),
124   fFillFriendInfo(kTRUE),
125   fEventFilter(0x0),
126   fTrackFilter(0x0),
127   fFlowTrackFilter(0x0),
128   fK0sCuts(0x0),
129   fLambdaCuts(0x0),
130   fGammaConvCuts(0x0),
131   fK0sPionCuts(0x0),
132   fLambdaProtonCuts(0x0),
133   fLambdaPionCuts(0x0),
134   fGammaElectronCuts(0x0),
135   fV0OpenCuts(0x0),
136   fV0StrongCuts(0x0),
137   fK0sMassRange(),
138   fLambdaMassRange(),
139   fGammaMassRange(),
140   fV0Histos(0x0),
141   fTreeFile(0x0),
142   fTree(0x0),
143   fFriendTreeFile(0x0),
144   fFriendTree(0x0),
145   fReducedEvent(0x0),
146   fReducedEventFriend(0x0)
147 {
148   //
149   // Constructor
150   //
151   fK0sMassRange[0] = 0.4; fK0sMassRange[1] = 0.6;
152   fLambdaMassRange[0] = 1.08; fLambdaMassRange[1] = 1.15;
153   fGammaMassRange[0] = 0.0; fGammaMassRange[1] = 0.1;
154   
155   DefineInput(0,TChain::Class());
156   DefineOutput(1, TList::Class());   // QA histograms
157   DefineOutput(2, TTree::Class());   // reduced information tree
158   //if(fFillFriendInfo) DefineOutput(3, TTree::Class());   // reduced information tree with friends
159   //DefineOutput(2, TTree::Class());   // reduced information tree with friends
160   //DefineOutput(2, TTree::Class());   // reduced information tree  
161
162   fListHistos.SetName("QAhistograms");
163   fListDielectron.SetOwner();
164   fListHistos.SetOwner(kFALSE);
165 }
166
167
168 //_________________________________________________________________________________
169 void AliAnalysisTaskReducedTree::UserCreateOutputObjects()
170 {
171   //
172   // Add all histogram manager histogram lists to the output TList
173   //
174
175   if (!fListHistos.IsEmpty() || fTree || fFriendTree) return; //already initialised
176
177   TIter nextDie(&fListDielectron);
178   AliDielectron *die=0;
179   while ( (die=static_cast<AliDielectron*>(nextDie())) ){
180     die->Init();
181     if (die->GetHistogramList()) fListHistos.Add(const_cast<THashList*>(die->GetHistogramList()));
182   }  
183   if(fV0Histos) fListHistos.Add(const_cast<THashList*>(fV0Histos->GetHistogramList()));
184
185   if(fFillFriendInfo) {
186     fFriendTree = new TTree("DstFriendTree","Reduced ESD information");
187     fReducedEventFriend = new AliReducedEventFriend();
188     fFriendTree->Branch("Event",&fReducedEventFriend,16000,99);
189   }
190   
191   //fTreeFile = new TFile("dstTree.root", "RECREATE");
192   OpenFile(2);
193   fTree = new TTree("DstTree","Reduced ESD information");
194   fReducedEvent = new AliReducedEvent("DstEvent");
195   fTree->Branch("Event",&fReducedEvent,16000,99);
196     
197   PostData(1, &fListHistos);
198   PostData(2, fTree);
199   //if(fFillFriendInfo) PostData(3, fFriendTree);
200   //PostData(2, fFriendTree);
201   //PostData(1, fTree);
202 }
203
204 //_________________________________________________________________________________
205 void AliAnalysisTaskReducedTree::UserExec(Option_t *option)
206 {
207   //
208   // Main loop. Called for every event
209   //  
210   option = option;
211   AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
212   Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
213   Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
214   
215   AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
216   if (!inputHandler) return;
217   
218   if ( inputHandler->GetPIDResponse() ){
219     AliDielectronVarManager::SetPIDResponse( inputHandler->GetPIDResponse() );
220   } else {
221     AliFatal("This task needs the PID response attached to the input event handler!");
222   }
223
224   // Was event selected ?
225   UInt_t isSelected = AliVEvent::kAny;
226   if(fSelectPhysics && inputHandler){
227     if((isESD && inputHandler->GetEventSelection()) || isAOD){
228       isSelected = inputHandler->IsEventSelected();
229       isSelected&=fTriggerMask;
230     }
231   }
232
233   if(isSelected==0) {
234     return;
235   }
236
237   // fill event histograms before event filter
238   Double_t values[AliDielectronVarManager::kNMaxValues]={0};
239   AliDielectronVarManager::Fill(InputEvent(),values);
240   
241   TIter nextDie(&fListDielectron);
242   AliDielectron *die=0;
243   while ( (die=static_cast<AliDielectron*>(nextDie())) ){
244     AliDielectronHistos *h=die->GetHistoManager();
245     if (h){
246       if (h->GetHistogramList()->FindObject("Event_noCuts"))
247         h->FillClass("Event_noCuts",AliDielectronVarManager::kNMaxValues,values);
248     }
249   }
250   nextDie.Reset();
251
252   //event filter
253   if (fEventFilter) {
254     if (!fEventFilter->IsSelected(InputEvent())) return;
255   }
256   
257   //pileup
258   if (fRejectPileup){
259     if (InputEvent()->IsPileupFromSPD(3,0.8,3.,2.,5.)) return;
260   }
261
262   //bz for AliKF
263   Double_t bz = InputEvent()->GetMagneticField();
264   AliKFParticle::SetField( bz );
265
266   //Process event in all AliDielectron instances
267   fReducedEvent->ClearEvent();
268   if(fFillFriendInfo) fReducedEventFriend->ClearEvent();
269   FillEventInfo();
270   if(fFillV0Info) FillV0PairInfo();
271   
272   Short_t idie=0;
273   if(fFillDielectronInfo) {
274     while((die=static_cast<AliDielectron*>(nextDie()))){
275       die->Process(InputEvent());
276       FillDielectronPairInfo(die, idie);
277       ++idie;
278     }
279   }
280   nextDie.Reset();
281   
282   if(fFillTrackInfo) FillTrackInfo();
283   if(fFillFriendInfo) FillFriendEventInfo();              // Q-vector calculation
284   
285   fTree->Fill();
286   if(fFillFriendInfo) fFriendTree->Fill();
287       
288   // if there are candidate pairs, add the information to the reduced tree
289   PostData(1, &fListHistos);
290   PostData(2, fTree);
291   //if(fFillFriendInfo) PostData(3, fFriendTree);
292   //PostData(2, fFriendTree);
293   //PostData(2, fTree);
294 }
295
296
297 //_________________________________________________________________________________
298 void AliAnalysisTaskReducedTree::FillEventInfo() 
299 {
300   //
301   // fill reduced event information
302   //
303   AliVEvent* event = InputEvent();
304   // Was event selected ?
305   AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
306   Bool_t isESD = (event->IsA()==AliESDEvent::Class());
307   Bool_t isAOD = (event->IsA()==AliAODEvent::Class());
308   
309   AliESDEvent* esdEvent = 0x0;
310   if(isESD) esdEvent = static_cast<AliESDEvent*>(event);
311   AliAODEvent* aodEvent = 0x0;
312   if(isAOD) aodEvent = static_cast<AliAODEvent*>(event);
313   
314   AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
315   UInt_t isSelected = AliVEvent::kAny;
316   if(inputHandler){
317     if((isESD && inputHandler->GetEventSelection()) || isAOD){
318       isSelected = inputHandler->IsEventSelected();
319       isSelected&=fTriggerMask;
320     }
321   }
322   Double_t values[AliDielectronVarManager::kNMaxValues];
323   AliDielectronVarManager::Fill(event, values);
324   
325   fReducedEvent->fRunNo       = event->GetRunNumber();
326   fReducedEvent->fBC          = event->GetBunchCrossNumber();
327   fReducedEvent->fEventType   = event->GetEventType();
328   fReducedEvent->fTriggerMask = event->GetTriggerMask();
329   fReducedEvent->fIsPhysicsSelection = (isSelected!=0 ? kTRUE : kFALSE);
330   fReducedEvent->fIsSPDPileup = event->IsPileupFromSPD(3,0.8,3.,2.,5.);
331   AliVVertex* eventVtx = 0x0;
332   if(isESD) eventVtx = const_cast<AliESDVertex*>(esdEvent->GetPrimaryVertexTracks());
333   if(isAOD) eventVtx = const_cast<AliAODVertex*>(aodEvent->GetPrimaryVertex());
334   if(eventVtx) {
335     fReducedEvent->fVtx[0] = (isESD ? ((AliESDVertex*)eventVtx)->GetXv() : ((AliAODVertex*)eventVtx)->GetX());
336     fReducedEvent->fVtx[1] = (isESD ? ((AliESDVertex*)eventVtx)->GetYv() : ((AliAODVertex*)eventVtx)->GetY());
337     fReducedEvent->fVtx[2] = (isESD ? ((AliESDVertex*)eventVtx)->GetZv() : ((AliAODVertex*)eventVtx)->GetZ());
338     fReducedEvent->fNVtxContributors = eventVtx->GetNContributors();
339   }
340   if(isESD) {
341     eventVtx = const_cast<AliESDVertex*>(esdEvent->GetPrimaryVertexTPC());
342     if(eventVtx) {
343       fReducedEvent->fVtxTPC[0] = ((AliESDVertex*)eventVtx)->GetXv();
344       fReducedEvent->fVtxTPC[1] = ((AliESDVertex*)eventVtx)->GetYv();
345       fReducedEvent->fVtxTPC[2] = ((AliESDVertex*)eventVtx)->GetZv();
346       fReducedEvent->fNVtxTPCContributors = eventVtx->GetNContributors();
347     }
348     fReducedEvent->fTimeStamp     = esdEvent->GetTimeStamp();
349     fReducedEvent->fNpileupSPD    = esdEvent->GetNumberOfPileupVerticesSPD();
350     fReducedEvent->fNpileupTracks = esdEvent->GetNumberOfPileupVerticesTracks();
351     fReducedEvent->fNPMDtracks    = esdEvent->GetNumberOfPmdTracks();
352     fReducedEvent->fNTRDtracks    = esdEvent->GetNumberOfTrdTracks();
353     fReducedEvent->fNTRDtracklets = esdEvent->GetNumberOfTrdTracklets();
354     
355     AliESDZDC* zdc = esdEvent->GetESDZDC();
356     if(zdc) {
357       for(Int_t i=0; i<4; ++i)  fReducedEvent->fZDCnEnergy[i]   = zdc->GetZN1TowerEnergy()[i];
358       for(Int_t i=4; i<8; ++i)  fReducedEvent->fZDCnEnergy[i]   = zdc->GetZN2TowerEnergy()[i-4];
359     }
360   }
361   if(isAOD) {
362     fReducedEvent->fTimeStamp     = 0;
363     fReducedEvent->fNpileupSPD    = aodEvent->GetNumberOfPileupVerticesSPD();
364     fReducedEvent->fNpileupTracks = aodEvent->GetNumberOfPileupVerticesTracks();
365     fReducedEvent->fNPMDtracks    = aodEvent->GetNPmdClusters();
366     fReducedEvent->fNTRDtracks    = 0;
367     fReducedEvent->fNTRDtracklets = 0;
368     
369     AliAODZDC* zdc = aodEvent->GetZDCData();
370     if(zdc) {
371       for(Int_t i=0; i<4; ++i)  fReducedEvent->fZDCnEnergy[i]   = zdc->GetZNATowerEnergy()[i];
372       for(Int_t i=4; i<8; ++i)  fReducedEvent->fZDCnEnergy[i]   = zdc->GetZNCTowerEnergy()[i-4];
373     }
374   }
375   
376   AliCentrality *centrality = event->GetCentrality();
377   if(centrality) {
378     fReducedEvent->fCentrality[0] = centrality->GetCentralityPercentile("V0M");
379     fReducedEvent->fCentrality[1] = centrality->GetCentralityPercentile("CL1");
380     fReducedEvent->fCentrality[2] = centrality->GetCentralityPercentile("TRK");
381     fReducedEvent->fCentrality[3] = centrality->GetCentralityPercentile("ZEMvsZDC");    
382     fReducedEvent->fCentQuality   = centrality->GetQuality();
383   }
384   
385   //cout << "event vtxZ/cent: " << fReducedEvent->fVtx[2] << "/" << fReducedEvent->fCentrality[0] << endl;
386   
387   fReducedEvent->fNtracks[0] = event->GetNumberOfTracks();
388   fReducedEvent->fSPDntracklets = GetSPDTrackletMultiplicity(event, -1.0, 1.0);
389   for(Int_t ieta=0; ieta<16; ++ieta)
390     fReducedEvent->fSPDntrackletsEta[ieta] = GetSPDTrackletMultiplicity(event, -1.6+0.2*ieta, -1.6+0.2*(ieta+1));
391   
392   AliVVZERO* vzero = event->GetVZEROData();
393   for(Int_t i=0;i<64;++i) 
394     fReducedEvent->fVZEROMult[i] = vzero->GetMultiplicity(i);  
395   
396   // EMCAL/PHOS clusters
397   if(fFillCaloClusterInfo) FillCaloClusters();
398   
399   // TODO FMD multiplicities
400   
401 }
402
403
404 //_________________________________________________________________________________
405 void AliAnalysisTaskReducedTree::FillCaloClusters() {
406   //
407   // Fill info about the calorimeter clusters
408   //
409   AliVEvent* event = InputEvent();
410   Int_t nclusters = event->GetNumberOfCaloClusters();
411
412   fReducedEvent->fNCaloClusters = 0;
413   for(Int_t iclus=0; iclus<nclusters; ++iclus) {
414     AliVCluster* cluster = event->GetCaloCluster(iclus);
415     
416     TClonesArray& clusters = *(fReducedEvent->fCaloClusters);
417     AliReducedCaloCluster *reducedCluster=new(clusters[fReducedEvent->fNCaloClusters]) AliReducedCaloCluster();
418     
419     reducedCluster->fType    = (cluster->IsEMCAL() ? AliReducedCaloCluster::kEMCAL : AliReducedCaloCluster::kPHOS);
420     reducedCluster->fEnergy  = cluster->E();
421     reducedCluster->fTrackDx = cluster->GetTrackDx();
422     reducedCluster->fTrackDz = cluster->GetTrackDz();
423     reducedCluster->fM20     = cluster->GetM20();
424     reducedCluster->fM02     = cluster->GetM02();
425     reducedCluster->fDispersion = cluster->GetDispersion();
426     fReducedEvent->fNCaloClusters += 1;
427   }  // end loop over clusters
428 }
429
430
431 //_________________________________________________________________________________
432 void AliAnalysisTaskReducedTree::FillFriendEventInfo() {
433   //
434   // Fill event info into the friend tree
435   //
436   // Add here calculated Q-vector components from all detectors
437   for(Int_t idet=0; idet<AliReducedEventFriend::kNdetectors; ++idet) {
438     fReducedEvent->GetQvector(fReducedEventFriend->fQvector[idet], idet);
439     for(Int_t ih=0; ih<fgkNMaxHarmonics; ++ih)
440       fReducedEventFriend->fEventPlaneStatus[idet][ih] = AliReducedEventFriend::kRaw;
441   }
442 }
443
444
445 //_________________________________________________________________________________
446 void AliAnalysisTaskReducedTree::FillTrackInfo() 
447 {
448   //
449   // fill reduced track information
450   //
451   AliVEvent* event = InputEvent();
452   Bool_t isESD = (event->IsA()==AliESDEvent::Class());
453   Bool_t isAOD = (event->IsA()==AliAODEvent::Class());
454
455   AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
456   AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
457   AliPIDResponse* pidResponse = inputHandler->GetPIDResponse();
458   
459   // find all the tracks which belong to a V0 stored in the reduced event
460   UShort_t trackIdsV0[4][20000]={{0}};
461   Int_t nV0LegsTagged[4] = {0};
462   Bool_t leg1Found[4]; Bool_t leg2Found[4];
463   for(Int_t iv0=0;iv0<fReducedEvent->fNV0candidates[1];++iv0) {
464     AliReducedPair* pair = fReducedEvent->GetV0Pair(iv0);
465     if(!pair) continue;
466     Int_t pairId = 0;
467     if(pair->fCandidateId==AliReducedPair::kGammaConv) pairId=0;
468     if(pair->fCandidateId==AliReducedPair::kK0sToPiPi) pairId=1;
469     if(pair->fCandidateId==AliReducedPair::kLambda0ToPPi) pairId=2;
470     if(pair->fCandidateId==AliReducedPair::kALambda0ToPPi) pairId=3;
471     leg1Found[pairId] = kFALSE; leg2Found[pairId] = kFALSE;
472     for(Int_t it=0;it<nV0LegsTagged[pairId];++it) {
473       if(trackIdsV0[pairId][it]==pair->fLegIds[0]) leg1Found[pairId]=kTRUE;
474       if(trackIdsV0[pairId][it]==pair->fLegIds[1]) leg2Found[pairId]=kTRUE;
475     }
476     // if the legs of this V0 were not already stored then add them now to the list
477     if(!leg1Found[pairId]) {trackIdsV0[pairId][nV0LegsTagged[pairId]] = pair->fLegIds[0]; ++nV0LegsTagged[pairId];}
478     if(!leg2Found[pairId]) {trackIdsV0[pairId][nV0LegsTagged[pairId]] = pair->fLegIds[1]; ++nV0LegsTagged[pairId];}
479   }
480   
481   // find all the tracks which belong to a stored dielectron pair
482   UShort_t trackIdsDiele[20000]={0};
483   Int_t nDieleLegsTagged = 0;
484   for(Int_t idie=0;idie<fReducedEvent->NDielectrons();++idie) {
485     AliReducedPair* pair = fReducedEvent->GetDielectronPair(idie);
486     leg1Found[0]=kFALSE; leg2Found[0]=kFALSE;
487     for(Int_t it=0; it<nDieleLegsTagged; ++it) {
488       if(trackIdsDiele[it]==pair->fLegIds[0]) leg1Found[0]=kTRUE;
489       if(trackIdsDiele[it]==pair->fLegIds[1]) leg2Found[0]=kTRUE;
490     }
491     // if the legs of this dielectron were not already stored then add them now to the list
492     if(!leg1Found[0]) {trackIdsDiele[nDieleLegsTagged] = pair->fLegIds[0]; ++nDieleLegsTagged;}
493     if(!leg2Found[0]) {trackIdsDiele[nDieleLegsTagged] = pair->fLegIds[1]; ++nDieleLegsTagged;}
494   }
495     
496   AliESDtrack* esdTrack=0;
497   AliAODTrack* aodTrack=0;
498   Int_t ntracks=event->GetNumberOfTracks();
499   Int_t trackId = 0; Bool_t usedForV0[4] = {kFALSE}; Bool_t usedForV0Or = kFALSE;
500   Bool_t usedForDielectron = kFALSE;
501   for(Int_t itrack=0; itrack<ntracks; ++itrack){
502     AliVParticle *particle=event->GetTrack(itrack);
503     if(isESD) {
504       esdTrack=static_cast<AliESDtrack*>(particle);
505       trackId = esdTrack->GetID();
506     }
507     if(isAOD) {
508       aodTrack=static_cast<AliAODTrack*>(particle);
509       trackId = aodTrack->GetID();
510     }
511     // check whether this track belongs to a V0 stored in the reduced event
512     usedForV0Or = kFALSE;
513     for(Int_t i=0; i<4; ++i) {
514       usedForV0[i] = kFALSE;
515       for(Int_t ii=0; ii<nV0LegsTagged[i]; ++ii) {
516         if(UShort_t(trackId)==trackIdsV0[i][ii]) {
517           usedForV0[i] = kTRUE;
518           //cout << "track " << trackId << " used for V0 type " << i << endl;
519           break;
520         }
521       }
522       usedForV0Or |= usedForV0[i];
523     }
524     // check whether this track belongs to a dielectron stored in the reduced event
525     usedForDielectron = kFALSE;
526     for(Int_t ii=0; ii<nDieleLegsTagged; ++ii) {
527       if(UShort_t(trackId)==trackIdsDiele[ii]) {
528         usedForDielectron = kTRUE;
529         break;
530       }
531     }
532     
533     ULong_t status = (isESD ? esdTrack->GetStatus() : aodTrack->GetStatus());
534     //cout << "TRACK" << endl;
535     for(Int_t ibit=0; ibit<32; ++ibit) {
536       if(status & (ULong_t(1)<<ibit)) {
537         //cout << "bit " << ibit << endl;
538         fReducedEvent->fNtracksPerTrackingFlag[ibit] += 1;
539       }
540     }
541     
542     //apply track cuts
543     if(!usedForV0Or && !usedForDielectron && fTrackFilter && !fTrackFilter->IsSelected(particle)) continue;
544     //cout << "storing track " << trackId << endl;
545     
546     TClonesArray& tracks = *(fReducedEvent->fTracks);
547     AliReducedTrack *reducedParticle=new(tracks[fReducedEvent->fNtracks[1]]) AliReducedTrack();
548         
549     Double_t values[AliDielectronVarManager::kNMaxValues];
550     AliDielectronVarManager::Fill(particle, values);
551     reducedParticle->fStatus        = status;//(ULong_t)values[AliDielectronVarManager::kTrackStatus];
552     reducedParticle->fGlobalPhi     = values[AliDielectronVarManager::kPhi];
553     reducedParticle->fGlobalPt      = values[AliDielectronVarManager::kPt]*values[AliDielectronVarManager::kCharge];
554     reducedParticle->fGlobalEta     = values[AliDielectronVarManager::kEta];    
555     reducedParticle->fMomentumInner = values[AliDielectronVarManager::kPIn];
556     reducedParticle->fDCA[0]        = values[AliDielectronVarManager::kImpactParXY];
557     reducedParticle->fDCA[1]        = values[AliDielectronVarManager::kImpactParZ];
558     
559     reducedParticle->fITSclusterMap = (UChar_t)values[AliDielectronVarManager::kITSclusterMap];
560     reducedParticle->fITSsignal     = values[AliDielectronVarManager::kITSsignal];
561     reducedParticle->fITSnSig[0]    = values[AliDielectronVarManager::kITSnSigmaEle];
562     reducedParticle->fITSnSig[1]    = values[AliDielectronVarManager::kITSnSigmaPio];
563     reducedParticle->fITSnSig[2]    = values[AliDielectronVarManager::kITSnSigmaKao];
564     reducedParticle->fITSnSig[3]    = values[AliDielectronVarManager::kITSnSigmaPro];
565     
566     reducedParticle->fTPCNcls      = (UChar_t)values[AliDielectronVarManager::kNclsTPC];
567     reducedParticle->fTPCNclsF     = (UChar_t)values[AliDielectronVarManager::kNFclsTPC];
568     reducedParticle->fTPCNclsIter1 = (UChar_t)values[AliDielectronVarManager::kNclsTPCiter1];
569     reducedParticle->fTPCsignal    = values[AliDielectronVarManager::kTPCsignal];
570     reducedParticle->fTPCnSig[0]   = values[AliDielectronVarManager::kTPCnSigmaEle];
571     reducedParticle->fTPCnSig[1]   = values[AliDielectronVarManager::kTPCnSigmaPio];
572     reducedParticle->fTPCnSig[2]   = values[AliDielectronVarManager::kTPCnSigmaKao];
573     reducedParticle->fTPCnSig[3]   = values[AliDielectronVarManager::kTPCnSigmaPro];
574     reducedParticle->fTPCClusterMap = EncodeTPCClusterMap(particle, isAOD);
575     
576     reducedParticle->fTOFbeta      = values[AliDielectronVarManager::kTOFbeta];
577     reducedParticle->fTOFnSig[0]   = values[AliDielectronVarManager::kTOFnSigmaEle];
578     reducedParticle->fTOFnSig[1]   = values[AliDielectronVarManager::kTOFnSigmaPio];
579     reducedParticle->fTOFnSig[2]   = values[AliDielectronVarManager::kTOFnSigmaKao];
580     reducedParticle->fTOFnSig[3]   = values[AliDielectronVarManager::kTOFnSigmaPro];
581
582     Double_t trdProbab[AliPID::kSPECIES]={0.0};
583         
584     if(fFlowTrackFilter) {
585       // switch on the first bit if this particle should be used for the event plane
586       if(fFlowTrackFilter->IsSelected(particle)) reducedParticle->fFlags |= (1<<0);
587     }
588     for(Int_t iV0type=0;iV0type<4;++iV0type) {
589       if(usedForV0[iV0type]) reducedParticle->fFlags |= (1<<(iV0type+1));
590     }
591     
592     if(isESD){
593       //AliESDtrack *track=static_cast<AliESDtrack*>(particle);
594       reducedParticle->fTrackId          = (UShort_t)esdTrack->GetID();
595       reducedParticle->fTPCCrossedRows   = (UChar_t)esdTrack->GetTPCCrossedRows();
596       //reducedParticle->fTPCClusterMap    = EncodeTPCClusterMap(esdTrack);
597       const AliExternalTrackParam* tpcInner = esdTrack->GetTPCInnerParam();
598       reducedParticle->fTPCPhi        = (tpcInner ? tpcInner->Phi() : 0.0);
599       reducedParticle->fTPCPt         = (tpcInner ? tpcInner->Pt() : 0.0);
600       reducedParticle->fTPCEta        = (tpcInner ? tpcInner->Eta() : 0.0);
601       
602       reducedParticle->fTRDntracklets[0] = esdTrack->GetTRDntracklets();
603       reducedParticle->fTRDntracklets[1] = esdTrack->GetTRDntrackletsPID();
604       pidResponse->ComputeTRDProbability(esdTrack,AliPID::kSPECIES,trdProbab,AliTRDPIDResponse::kLQ2D);
605       reducedParticle->fTRDpid[0]    = trdProbab[AliPID::kElectron];
606       reducedParticle->fTRDpid[1]    = trdProbab[AliPID::kPion];
607       
608       for(Int_t idx=0; idx<3; ++idx) if(esdTrack->GetKinkIndex(idx)>0) reducedParticle->fFlags |= (1<<(5+idx));
609       if(esdTrack->IsEMCAL()) reducedParticle->fCaloClusterId = esdTrack->GetEMCALcluster();
610       if(esdTrack->IsPHOS()) reducedParticle->fCaloClusterId = esdTrack->GetPHOScluster();
611     }
612     if(isAOD) {
613       //AliAODTrack *track=static_cast<AliAODTrack*>(particle);
614       reducedParticle->fTrackId = aodTrack->GetID(); 
615       reducedParticle->fITSsignal = aodTrack->GetITSsignal();
616       if(pidResponse) {
617         reducedParticle->fITSnSig[0]    = pidResponse->NumberOfSigmasITS(aodTrack,AliPID::kElectron);
618         reducedParticle->fITSnSig[1]    = pidResponse->NumberOfSigmasITS(aodTrack,AliPID::kPion);
619         reducedParticle->fITSnSig[2]    = pidResponse->NumberOfSigmasITS(aodTrack,AliPID::kKaon);
620         reducedParticle->fITSnSig[3]    = pidResponse->NumberOfSigmasITS(aodTrack,AliPID::kProton);
621       }
622       reducedParticle->fTRDntracklets[0] = aodTrack->GetTRDntrackletsPID();
623       reducedParticle->fTRDntracklets[1] = aodTrack->GetTRDntrackletsPID();
624       pidResponse->ComputeTRDProbability(aodTrack,AliPID::kSPECIES,trdProbab,AliTRDPIDResponse::kLQ2D);
625       reducedParticle->fTRDpid[0]    = trdProbab[AliPID::kElectron];
626       reducedParticle->fTRDpid[1]    = trdProbab[AliPID::kPion];
627       
628       if(aodTrack->IsEMCAL()) reducedParticle->fCaloClusterId = aodTrack->GetEMCALcluster();
629       if(aodTrack->IsPHOS()) reducedParticle->fCaloClusterId = aodTrack->GetPHOScluster();
630       if(values[AliDielectronVarManager::kKinkIndex0]>0.0) reducedParticle->fFlags |= (1<<5);
631     }
632
633     fReducedEvent->fNtracks[1] += 1;
634   }
635 }
636
637
638 //_________________________________________________________________________________
639 void AliAnalysisTaskReducedTree::FillDielectronPairInfo(AliDielectron* die, Short_t iDie) 
640 {
641   //
642   // fill reduced pair information
643   //
644   Bool_t hasMC=AliDielectronMC::Instance()->HasMC();
645
646   for(Int_t iType=0; iType<3; ++iType) {
647     
648     const TObjArray* array = die->GetPairArray(iType);
649     if(!array || array->GetEntriesFast()==0) continue;
650     
651     for(Int_t iCandidate=0; iCandidate<array->GetEntriesFast(); ++iCandidate) {
652       AliDielectronPair* pair = (AliDielectronPair*)array->At(iCandidate);
653       Double_t values[AliDielectronVarManager::kNMaxValues];
654       AliDielectronVarManager::Fill(pair, values);
655       
656       TClonesArray& tracks = *(fReducedEvent->fCandidates);
657       AliReducedPair *reducedParticle= 
658          new (tracks[fReducedEvent->fNV0candidates[1]+fReducedEvent->fNDielectronCandidates]) AliReducedPair();
659       // !!! hardcoded flag for dielectron id 
660       reducedParticle->fCandidateId  = (iDie==0 ? AliReducedPair::kJpsiToEE : AliReducedPair::kPhiToKK);
661       reducedParticle->fPairType     = (Char_t)values[AliDielectronVarManager::kPairType];
662       reducedParticle->fLegIds[0]    = (UShort_t)(static_cast<AliVTrack*>(pair->GetFirstDaughter()))->GetID();
663       reducedParticle->fLegIds[1]    = (UShort_t)(static_cast<AliVTrack*>(pair->GetSecondDaughter()))->GetID();
664       reducedParticle->fMass[0]      = values[AliDielectronVarManager::kM];
665       reducedParticle->fMass[1]      = -999.;
666       reducedParticle->fMass[2]      = -999.;
667       reducedParticle->fMass[3]      = -999.;
668       reducedParticle->fPhi          = values[AliDielectronVarManager::kPhi];  // in the [-pi,pi] interval
669       if(reducedParticle->fPhi<0.0) reducedParticle->fPhi = 2.0*TMath::Pi() + reducedParticle->fPhi;  // converted to [0,2pi]
670       reducedParticle->fPt           = values[AliDielectronVarManager::kPt];
671       reducedParticle->fEta          = values[AliDielectronVarManager::kEta];
672       reducedParticle->fLxy          = values[AliDielectronVarManager::kPseudoProperTime];
673       reducedParticle->fLxyErr       = values[AliDielectronVarManager::kPseudoProperTimeErr];
674       reducedParticle->fPointingAngle = values[AliDielectronVarManager::kCosPointingAngle];
675       
676       reducedParticle->fMCid         = 0;
677       if(hasMC) {
678         AliDielectronMC::Instance()->ConnectMCEvent();
679         const TObjArray* mcSignals = die->GetMCSignals();
680         for(Int_t iSig=0; iSig<mcSignals->GetEntries(); ++iSig) {
681           if(iSig>31) break;
682           AliDielectronMC *mc=AliDielectronMC::Instance();
683           if(mc->IsMCTruth(pair, (AliDielectronSignalMC*)mcSignals->At(iSig))) {
684             reducedParticle->fMCid = reducedParticle->fMCid | (1<<iSig);
685           }
686         }
687       }   // end if has MC
688       fReducedEvent->fNDielectronCandidates += 1;
689     }    // end loop over candidates
690   }    // end loop over pair type
691 }
692
693
694 //_________________________________________________________________________________
695 void AliAnalysisTaskReducedTree::FillV0PairInfo() 
696 {
697   //
698   // fill reduced pair information
699   //
700   AliESDEvent* esd = (AliESDEvent*)InputEvent();
701   const AliESDVertex *primaryVertex = esd->GetPrimaryVertex();
702   AliKFVertex primaryVertexKF(*primaryVertex);
703   
704   fReducedEvent->fNV0candidates[0] = InputEvent()->GetNumberOfV0s();
705   
706   if(!(fFillK0s || fFillLambda || fFillALambda || fFillGammaConversions)) return;
707     
708   Double_t valuesPos[AliDielectronVarManager::kNMaxValues];
709   Double_t valuesNeg[AliDielectronVarManager::kNMaxValues];
710   
711   if(fV0OpenCuts) {
712     fV0OpenCuts->SetEvent(esd);
713     fV0OpenCuts->SetPrimaryVertex(&primaryVertexKF);
714   }
715   if(fV0StrongCuts) {
716     fV0StrongCuts->SetEvent(esd);
717     fV0StrongCuts->SetPrimaryVertex(&primaryVertexKF);
718   }
719   
720   Int_t pdgV0=0; Int_t pdgP=0; Int_t pdgN=0;
721   for(Int_t iV0=0; iV0<InputEvent()->GetNumberOfV0s(); ++iV0) {   // loop over V0s
722     AliESDv0 *v0 = esd->GetV0(iV0);
723        
724     AliESDtrack* legPos = esd->GetTrack(v0->GetPindex());
725     AliESDtrack* legNeg = esd->GetTrack(v0->GetNindex());
726  
727     if(legPos->GetSign() == legNeg->GetSign()) {
728       continue;
729     }
730
731     Bool_t v0ChargesAreCorrect = (legPos->GetSign()==+1 ? kTRUE : kFALSE);
732     legPos = (!v0ChargesAreCorrect ? esd->GetTrack(v0->GetNindex()) : legPos);
733     legNeg = (!v0ChargesAreCorrect ? esd->GetTrack(v0->GetPindex()) : legNeg); 
734     
735     pdgV0=0; pdgP=0; pdgN=0;
736     Bool_t goodK0s = kTRUE; Bool_t goodLambda = kTRUE; Bool_t goodALambda = kTRUE; Bool_t goodGamma = kTRUE;
737     if(fV0OpenCuts) {
738       goodK0s = kFALSE; goodLambda = kFALSE; goodALambda = kFALSE; goodGamma = kFALSE;
739       Bool_t processV0 = fV0OpenCuts->ProcessV0(v0, pdgV0, pdgP, pdgN);
740       if(processV0 && TMath::Abs(pdgV0)==310 && TMath::Abs(pdgP)==211 && TMath::Abs(pdgN)==211) {
741         goodK0s = kTRUE;
742         if(fK0sPionCuts && (!fK0sPionCuts->IsSelected(legPos) || !fK0sPionCuts->IsSelected(legNeg))) goodK0s = kFALSE;
743       }
744       if(processV0 && pdgV0==3122 && (TMath::Abs(pdgP)==211 || TMath::Abs(pdgP)==2212) && (TMath::Abs(pdgN)==211 || TMath::Abs(pdgN)==2212)) {
745         goodLambda = kTRUE;
746         if(fLambdaProtonCuts && !fLambdaProtonCuts->IsSelected(legPos)) goodLambda = kFALSE;
747         if(fLambdaPionCuts && !fLambdaPionCuts->IsSelected(legNeg)) goodLambda = kFALSE;
748       }
749       if(processV0 && pdgV0==-3122 && (TMath::Abs(pdgP)==211 || TMath::Abs(pdgP)==2212) && (TMath::Abs(pdgN)==211 || TMath::Abs(pdgN)==2212)) {
750         goodALambda = kTRUE;
751         if(fLambdaProtonCuts && !fLambdaProtonCuts->IsSelected(legNeg)) goodALambda = kFALSE;
752         if(fLambdaPionCuts && !fLambdaPionCuts->IsSelected(legPos)) goodALambda = kFALSE;
753       }
754       if(processV0 && TMath::Abs(pdgV0)==22 && TMath::Abs(pdgP)==11 && TMath::Abs(pdgN)==11) {
755         goodGamma = kTRUE;
756         if(fGammaElectronCuts && (!fGammaElectronCuts->IsSelected(legPos) || !fGammaElectronCuts->IsSelected(legNeg))) goodGamma = kFALSE;
757       }
758       //cout << "open cuts  pdgV0/pdgP/pdgN/processV0 : " << pdgV0 << "/" << pdgP << "/" << pdgN << "/" << processV0 << endl;     
759       //cout << "good K0s/Lambda/ALambda/Gamma : " << goodK0s << "/" << goodLambda << "/" << goodALambda << "/" << goodGamma << endl;
760     }
761     
762     Bool_t veryGoodK0s = kFALSE; Bool_t veryGoodLambda = kFALSE; Bool_t veryGoodALambda = kFALSE; Bool_t veryGoodGamma = kFALSE;
763     if(fV0StrongCuts && (goodK0s || goodLambda || goodALambda || goodGamma)) {
764       pdgV0=0; pdgP=0; pdgN=0;
765       Bool_t processV0 = fV0StrongCuts->ProcessV0(v0, pdgV0, pdgP, pdgN);
766       if(processV0 && goodK0s && TMath::Abs(pdgV0)==310 && TMath::Abs(pdgP)==211 && TMath::Abs(pdgN)==211)
767         veryGoodK0s = kTRUE;
768       if(processV0 && goodLambda && pdgV0==3122 && (TMath::Abs(pdgP)==211 || TMath::Abs(pdgP)==2212) && (TMath::Abs(pdgN)==211 || TMath::Abs(pdgN)==2212))
769         veryGoodLambda = kTRUE;
770       if(processV0 && goodALambda && pdgV0==-3122 && (TMath::Abs(pdgP)==211 || TMath::Abs(pdgP)==2212) && (TMath::Abs(pdgN)==211 || TMath::Abs(pdgN)==2212))
771         veryGoodALambda = kTRUE;
772       if(processV0 && goodGamma && TMath::Abs(pdgV0)==22 && TMath::Abs(pdgP)==11 && TMath::Abs(pdgN)==11)
773         veryGoodGamma = kTRUE;
774       //cout << "strong cuts  pdgV0/pdgP/pdgN/processV0 : " << pdgV0 << "/" << pdgP << "/" << pdgN << "/" << processV0 << endl;     
775       //cout << "very good K0s/Lambda/ALambda/Gamma : " << veryGoodK0s << "/" << veryGoodLambda << "/" << veryGoodALambda << "/" << veryGoodGamma << endl;
776     }
777               
778     if(!((goodK0s && fFillK0s) || 
779          (goodLambda && fFillLambda) || 
780          (goodALambda && fFillALambda) || 
781          (goodGamma && fFillGammaConversions))) continue;
782     
783     // Fill the V0 information into the tree for 4 hypothesis: K0s, Lambda, Anti-Lambda and gamma conversion
784     AliReducedPair* k0sReducedPair     = FillV0PairInfo(v0, AliReducedPair::kK0sToPiPi,     legPos, legNeg, &primaryVertexKF, v0ChargesAreCorrect);
785     AliReducedPair* lambdaReducedPair  = FillV0PairInfo(v0, AliReducedPair::kLambda0ToPPi,  legPos, legNeg, &primaryVertexKF, v0ChargesAreCorrect);
786     AliReducedPair* alambdaReducedPair = FillV0PairInfo(v0, AliReducedPair::kALambda0ToPPi, legPos, legNeg, &primaryVertexKF, v0ChargesAreCorrect);
787     AliReducedPair* gammaReducedPair   = FillV0PairInfo(v0, AliReducedPair::kGammaConv,     legPos, legNeg, &primaryVertexKF, v0ChargesAreCorrect);
788     
789     if(fFillK0s && goodK0s && k0sReducedPair->fMass[0]>fK0sMassRange[0] && k0sReducedPair->fMass[0]<fK0sMassRange[1]) {
790       TClonesArray& tracks = *(fReducedEvent->fCandidates);
791       AliReducedPair *goodK0sPair = new (tracks[fReducedEvent->fNV0candidates[1]]) AliReducedPair(*k0sReducedPair);
792       goodK0sPair->fMass[0] = k0sReducedPair->fMass[0];
793       goodK0sPair->fMass[1] = lambdaReducedPair->fMass[0];
794       goodK0sPair->fMass[2] = alambdaReducedPair->fMass[0];
795       goodK0sPair->fMass[3] = gammaReducedPair->fMass[0];
796       if(veryGoodK0s) goodK0sPair->fMCid |= (UInt_t(1)<<1);
797       fReducedEvent->fNV0candidates[1] += 1;
798     } else {goodK0s=kFALSE;}
799     if(fFillLambda && goodLambda && lambdaReducedPair->fMass[0]>fLambdaMassRange[0] && lambdaReducedPair->fMass[0]<fLambdaMassRange[1]) {
800       TClonesArray& tracks = *(fReducedEvent->fCandidates);
801       AliReducedPair *goodLambdaPair = new (tracks[fReducedEvent->fNV0candidates[1]]) AliReducedPair(*lambdaReducedPair);
802       goodLambdaPair->fMass[0] = k0sReducedPair->fMass[0];
803       goodLambdaPair->fMass[1] = lambdaReducedPair->fMass[0];
804       goodLambdaPair->fMass[2] = alambdaReducedPair->fMass[0];
805       goodLambdaPair->fMass[3] = gammaReducedPair->fMass[0];
806       if(veryGoodLambda) goodLambdaPair->fMCid |= (UInt_t(1)<<2);
807       fReducedEvent->fNV0candidates[1] += 1;
808     } else {goodLambda=kFALSE;}
809     if(fFillALambda && goodALambda && alambdaReducedPair->fMass[0]>fLambdaMassRange[0] && alambdaReducedPair->fMass[0]<fLambdaMassRange[1]) {
810       TClonesArray& tracks = *(fReducedEvent->fCandidates);
811       AliReducedPair *goodALambdaPair = new (tracks[fReducedEvent->fNV0candidates[1]]) AliReducedPair(*alambdaReducedPair);
812       goodALambdaPair->fMass[0] = k0sReducedPair->fMass[0];
813       goodALambdaPair->fMass[1] = lambdaReducedPair->fMass[0];
814       goodALambdaPair->fMass[2] = alambdaReducedPair->fMass[0];
815       goodALambdaPair->fMass[3] = gammaReducedPair->fMass[0];
816       if(veryGoodALambda) goodALambdaPair->fMCid |= (UInt_t(1)<<3);
817       fReducedEvent->fNV0candidates[1] += 1;
818     } else {goodALambda = kFALSE;}
819     //cout << "gamma mass: " << gammaReducedPair->fMass[0] << endl;
820     if(fFillGammaConversions && goodGamma && gammaReducedPair->fMass[0]>fGammaMassRange[0] && gammaReducedPair->fMass[0]<fGammaMassRange[1]) {
821       TClonesArray& tracks = *(fReducedEvent->fCandidates);
822       AliReducedPair *goodGammaPair = new (tracks[fReducedEvent->fNV0candidates[1]]) AliReducedPair(*gammaReducedPair);
823       goodGammaPair->fMass[0] = k0sReducedPair->fMass[0];
824       goodGammaPair->fMass[1] = lambdaReducedPair->fMass[0];
825       goodGammaPair->fMass[2] = alambdaReducedPair->fMass[0];
826       goodGammaPair->fMass[3] = gammaReducedPair->fMass[0];
827       if(veryGoodGamma) goodGammaPair->fMCid |= (UInt_t(1)<<4);
828       fReducedEvent->fNV0candidates[1] += 1;
829     } else {goodGamma=kFALSE;}
830     delete k0sReducedPair;
831     delete lambdaReducedPair;
832     delete alambdaReducedPair;
833     delete gammaReducedPair;
834     
835     if(!(goodK0s || goodLambda || goodALambda || goodGamma)) continue;
836     
837     //  Fill histograms and the CF container
838     AliDielectronVarManager::Fill(legPos, valuesPos);
839     AliDielectronVarManager::Fill(legNeg, valuesNeg);
840     
841     if(fV0Histos && fV0Histos->GetHistogramList()->FindObject("V0Track_Pos"))
842       fV0Histos->FillClass("V0Track_Pos", AliDielectronVarManager::kNMaxValues, valuesPos);
843     if(fV0Histos && fV0Histos->GetHistogramList()->FindObject("V0Track_Neg"))
844       fV0Histos->FillClass("V0Track_Neg", AliDielectronVarManager::kNMaxValues, valuesNeg);    
845   }   // end loop over V0s
846 }
847
848
849 //_________________________________________________________________________________
850 AliReducedPair* AliAnalysisTaskReducedTree::FillV0PairInfo(AliESDv0* v0, Int_t id, 
851                                                     AliESDtrack* legPos, AliESDtrack* legNeg,
852                                                     AliKFVertex* vtxKF, Bool_t chargesAreCorrect) {
853   //
854   // Create a reduced V0 object and fill it
855   //
856   AliReducedPair* reducedPair=new AliReducedPair();  
857   reducedPair->fCandidateId = id;
858   reducedPair->fPairType    = v0->GetOnFlyStatus();    // on the fly status
859   //reducedPair->fOnTheFly    = v0->GetOnFlyStatus();
860   reducedPair->fLegIds[0]   = legPos->GetID();
861   reducedPair->fLegIds[1]   = legNeg->GetID();
862   if(!reducedPair->fPairType) {    // offline
863     UInt_t pidPos = AliPID::kPion;
864     if(id==AliReducedPair::kLambda0ToPPi) pidPos = AliPID::kProton;
865     if(id==AliReducedPair::kGammaConv) pidPos = AliPID::kElectron;
866     UInt_t pidNeg = AliPID::kPion;
867     if(id==AliReducedPair::kALambda0ToPPi) pidNeg = AliPID::kProton;
868     if(id==AliReducedPair::kGammaConv) pidNeg = AliPID::kElectron;
869     reducedPair->fMass[0]      = v0->GetEffMass(pidPos, pidNeg);
870     reducedPair->fPhi          = v0->Phi();
871     if(reducedPair->fPhi<0.0) reducedPair->fPhi = 2.0*TMath::Pi() + reducedPair->fPhi;  // converted to [0,2pi]
872     reducedPair->fPt           = v0->Pt();
873     reducedPair->fEta          = v0->Eta();
874     reducedPair->fLxy          = v0->GetRr();
875     reducedPair->fPointingAngle = v0->GetV0CosineOfPointingAngle(vtxKF->GetX(), vtxKF->GetY(), vtxKF->GetZ());
876     reducedPair->fChisquare    = v0->GetChi2V0();
877   }
878   else {
879     const AliExternalTrackParam *negHelix=v0->GetParamN();
880     const AliExternalTrackParam *posHelix=v0->GetParamP();
881     if(!chargesAreCorrect) {
882       negHelix = v0->GetParamP();
883       posHelix = v0->GetParamN();
884     }
885     Int_t pdgPos = 211;
886     if(id==AliReducedPair::kLambda0ToPPi) pdgPos = 2212;
887     if(id==AliReducedPair::kGammaConv) pdgPos = -11;
888     Int_t pdgNeg = -211;
889     if(id==AliReducedPair::kALambda0ToPPi) pdgNeg = -2212;
890     if(id==AliReducedPair::kGammaConv) pdgNeg = 11;
891     AliKFParticle negKF(*(negHelix), pdgPos);
892     AliKFParticle posKF(*(posHelix), pdgNeg);
893     AliKFParticle v0Refit;
894     v0Refit += negKF;
895     v0Refit += posKF;
896     Double_t massFit=0.0, massErrFit=0.0;
897     v0Refit.GetMass(massFit,massErrFit);
898     reducedPair->fMass[0] = massFit;
899     reducedPair->fPhi          = v0Refit.GetPhi();
900     if(reducedPair->fPhi<0.0) reducedPair->fPhi = 2.0*TMath::Pi() + reducedPair->fPhi;  // converted to [0,2pi]
901     reducedPair->fPt           = v0Refit.GetPt();
902     reducedPair->fEta          = v0Refit.GetEta();
903     reducedPair->fLxy          = v0Refit.GetPseudoProperDecayTime(*vtxKF, massFit);
904     Double_t deltaPos[3];
905     deltaPos[0] = v0Refit.GetX() - vtxKF->GetX(); deltaPos[1] = v0Refit.GetY() - vtxKF->GetY(); deltaPos[2] = v0Refit.GetZ() - vtxKF->GetZ();
906     Double_t momV02 = v0Refit.GetPx()*v0Refit.GetPx() + v0Refit.GetPy()*v0Refit.GetPy() + v0Refit.GetPz()*v0Refit.GetPz();
907     Double_t deltaPos2 = deltaPos[0]*deltaPos[0] + deltaPos[1]*deltaPos[1] + deltaPos[2]*deltaPos[2];
908     reducedPair->fPointingAngle = (deltaPos[0]*v0Refit.GetPx() + deltaPos[1]*v0Refit.GetPy() + deltaPos[2]*v0Refit.GetPz()) / 
909                                   TMath::Sqrt(momV02*deltaPos2);
910     reducedPair->fChisquare = v0Refit.GetChi2();                              
911   }
912   return reducedPair;
913 }
914
915
916 //_________________________________________________________________________________
917 UChar_t AliAnalysisTaskReducedTree::EncodeTPCClusterMap(AliVParticle* track, Bool_t isAOD) {
918   //
919   // Encode the TPC cluster map into an UChar_t
920   // Divide the 159 bits from the bit map into 8 groups of adiacent clusters
921   // For each group enable its corresponding bit if in that group there are more clusters compared to
922   // a threshold.
923   //
924   AliESDtrack* esdTrack=0x0;
925   AliAODTrack* aodTrack=0x0;
926   if(isAOD)
927     aodTrack=static_cast<AliAODTrack*>(track);
928   else
929     esdTrack=static_cast<AliESDtrack*>(track);
930   
931   const UChar_t threshold=5;
932   TBits tpcClusterMap = (isAOD ? aodTrack->GetTPCClusterMap() : esdTrack->GetTPCClusterMap());
933   UChar_t map=0;
934   UChar_t n=0;
935   UChar_t j=0;
936   for(UChar_t i=0; i<8; ++i) {
937     n=0;
938     for(j=i*20; j<(i+1)*20 && j<159; ++j) n+=tpcClusterMap.TestBitNumber(j);
939     if(n>=threshold) map |= (1<<i);
940   }
941   return map;
942 }
943
944
945 //_________________________________________________________________________________
946 Int_t AliAnalysisTaskReducedTree::GetSPDTrackletMultiplicity(AliVEvent* event, Float_t lowEta, Float_t highEta) {
947   //
948   // Count the number of SPD tracklets in a given eta range
949   //
950   if (!event) return -1;
951   
952   Int_t nTracklets = 0;
953   Int_t nAcc = 0;
954   
955   if(event->IsA() == AliAODEvent::Class()) {
956     AliAODTracklets *tracklets = ((AliAODEvent*)event)->GetTracklets();
957     nTracklets = tracklets->GetNumberOfTracklets();
958     for(Int_t nn=0; nn<nTracklets; ++nn) {
959       Double_t theta = tracklets->GetTheta(nn);
960       Double_t eta = -TMath::Log(TMath::Tan(theta/2.0));
961       if(eta < lowEta) continue;
962       if(eta > highEta) continue;
963       ++nAcc;
964     }
965   } else if(event->IsA() == AliESDEvent::Class()) {
966     nTracklets = ((AliESDEvent*)event)->GetMultiplicity()->GetNumberOfTracklets();
967     for(Int_t nn=0; nn<nTracklets; ++nn) {
968       Double_t eta = ((AliESDEvent*)event)->GetMultiplicity()->GetEta(nn);
969       if(eta < lowEta) continue;
970       if(eta > highEta) continue; 
971       ++nAcc;
972     }
973   } else return -1;
974   
975   return nAcc;
976 }
977
978
979 //_________________________________________________________________________________
980 void AliAnalysisTaskReducedTree::FinishTaskOutput()
981 {
982   //
983   // Finish Task 
984   //
985   
986   //fTreeFile->Write();
987   //fTreeFile->Close();
988 }