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