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