missing [] in array delete
[u/mrichter/AliRoot.git] / ANALYSIS / ESDfilter / AliAnalysisTaskESDfilter.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, 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 /* $Id$ */
17  
18 #include <Riostream.h>
19 #include <TChain.h>
20 #include <TTree.h>
21 #include <TList.h>
22 #include <TArrayI.h>
23 #include <TParameter.h>
24 #include <TRandom.h>
25 #include <TParticle.h>
26 #include <TFile.h>
27 #include <TVector3.h>
28
29 #include "AliAnalysisTaskESDfilter.h"
30 #include "AliAnalysisManager.h"
31 #include "AliESDEvent.h"
32 #include "AliESDRun.h"
33 #include "AliStack.h"
34 #include "AliAODEvent.h"
35 #include "AliMCEvent.h"
36 #include "AliMCEventHandler.h"
37 #include "AliESDInputHandler.h"
38 #include "AliAODHandler.h"
39 #include "AliAODMCParticle.h"
40 #include "AliAnalysisFilter.h"
41 #include "AliESDMuonTrack.h"
42 #include "AliESDVertex.h"
43 #include "AliCentrality.h"
44 #include "AliEventplane.h"
45 #include "AliESDv0.h"
46 #include "AliESDkink.h"
47 #include "AliESDcascade.h"
48 #include "AliESDPmdTrack.h"
49 #include "AliESDCaloCluster.h"
50 #include "AliESDCaloCells.h"
51 #include "AliMultiplicity.h"
52 #include "AliLog.h"
53 #include "AliCodeTimer.h"
54 #include "AliESDtrackCuts.h"
55 #include "AliESDpid.h"
56 #include "AliAODHMPIDrings.h"
57 #include "AliV0vertexer.h"
58 #include "AliCascadeVertexer.h"
59 #include "AliExternalTrackParam.h"
60 #include "AliTrackerBase.h"
61 #include "AliTPCdEdxInfo.h"
62
63 #include "AliESDTrdTrack.h"
64 #include "AliESDTrdTracklet.h"
65 #include "AliAODTrdTrack.h"
66 #include "AliAODTrdTracklet.h"
67 #include "AliEMCALRecoUtils.h"
68 #include "AliESDUtils.h"
69
70 using std::cout;
71 using std::endl;
72 ClassImp(AliAnalysisTaskESDfilter)
73
74 ////////////////////////////////////////////////////////////////////////
75
76 AliAnalysisTaskESDfilter::AliAnalysisTaskESDfilter():
77   AliAnalysisTaskSE(),
78   fTrackFilter(0x0),
79   fKinkFilter(0x0),
80   fV0Filter(0x0),
81   fCascadeFilter(0x0),
82   fHighPthreshold(0),
83   fPtshape(0x0),
84   fEnableFillAOD(kTRUE),
85   fUsedTrack(0x0),
86   fUsedTrackCopy(0x0),
87   fUsedKink(0x0),
88   fUsedV0(0x0),
89   fAODTrackRefs(0x0),
90   fAODV0VtxRefs(0x0),
91   fAODV0Refs(0x0),
92   fMChandler(0x0),
93   fNumberOfTracks(0),
94   fNumberOfPositiveTracks(0),
95   fNumberOfV0s(0),
96   fNumberOfVertices(0),
97   fNumberOfCascades(0),
98   fNumberOfKinks(0),
99   fOldESDformat(kFALSE),
100   fPrimaryVertex(0x0),
101   fTPCConstrainedFilterMask(0),
102   fHybridFilterMaskTPCCG(0),
103   fWriteHybridTPCCOnly(kFALSE),
104   fGlobalConstrainedFilterMask(0),
105   fHybridFilterMaskGCG(0),
106   fWriteHybridGCOnly(kFALSE),
107   fIsVZEROEnabled(kTRUE),
108   fIsTZEROEnabled(kTRUE),
109   fIsZDCEnabled(kTRUE),
110   fIsHMPIDEnabled(kTRUE), 
111   fIsV0CascadeRecoEnabled(kFALSE),
112   fAreCascadesEnabled(kTRUE),
113   fAreV0sEnabled(kTRUE),
114   fAreKinksEnabled(kTRUE),
115   fAreTracksEnabled(kTRUE),
116   fArePmdClustersEnabled(kTRUE),
117   fAreCaloClustersEnabled(kTRUE),
118   fAreEMCALCellsEnabled(kTRUE),
119   fArePHOSCellsEnabled(kTRUE),
120   fAreEMCALTriggerEnabled(kTRUE),
121   fArePHOSTriggerEnabled(kTRUE),
122   fAreTrackletsEnabled(kTRUE),
123   fIsTRDEnabled(kTRUE),
124   fESDpid(0x0),
125   fIsPidOwner(kFALSE),
126   fTPCaloneTrackCuts(0),
127   fDoPropagateTrackToEMCal(kTRUE),
128   fEMCalSurfaceDistance(440),
129   fRefitVertexTracks(-1),
130   fRefitVertexTracksCuts(0)
131 {
132   // Default constructor
133     fV0Cuts[0] =  33.   ;   // max allowed chi2
134     fV0Cuts[1] =   0.1  ;   // min allowed impact parameter for the 1st daughter
135     fV0Cuts[2] =   0.1  ;   // min allowed impact parameter for the 2nd daughter
136     fV0Cuts[3] =   1.   ;   // max allowed DCA between the daughter tracks
137     fV0Cuts[4] =    .998;   // min allowed cosine of V0's pointing angle
138     fV0Cuts[5] =   0.9  ;   // min radius of the fiducial volume
139     fV0Cuts[6] = 100.   ;   // max radius of the fiducial volume
140
141     fCascadeCuts[0] =  33.   ; // max allowed chi2 (same as PDC07)
142     fCascadeCuts[1] =   0.05 ; // min allowed V0 impact parameter
143     fCascadeCuts[2] =   0.008; // "window" around the Lambda mass
144     fCascadeCuts[3] =   0.03 ; // min allowed bachelor's impact parameter
145     fCascadeCuts[4] =   0.3  ; // max allowed DCA between the V0 and the bachelor
146     fCascadeCuts[5] =   0.999; // min allowed cosine of the cascade pointing angle
147     fCascadeCuts[6] =   0.9  ; // min radius of the fiducial volume
148     fCascadeCuts[7] = 100.   ; // max radius of the fiducial volume
149 }
150
151 //______________________________________________________________________________
152 AliAnalysisTaskESDfilter::AliAnalysisTaskESDfilter(const char* name):
153     AliAnalysisTaskSE(name),
154     fTrackFilter(0x0),
155     fKinkFilter(0x0),
156     fV0Filter(0x0),
157     fCascadeFilter(0x0),
158     fHighPthreshold(0),
159     fPtshape(0x0),
160     fEnableFillAOD(kTRUE),
161     fUsedTrack(0x0),
162     fUsedTrackCopy(0x0),
163     fUsedKink(0x0),
164     fUsedV0(0x0),
165     fAODTrackRefs(0x0),
166     fAODV0VtxRefs(0x0),
167     fAODV0Refs(0x0),
168     fMChandler(0x0),
169     fNumberOfTracks(0),
170     fNumberOfPositiveTracks(0),
171     fNumberOfV0s(0),
172     fNumberOfVertices(0),
173     fNumberOfCascades(0),
174     fNumberOfKinks(0),
175     fOldESDformat(kFALSE),
176     fPrimaryVertex(0x0),
177   fTPCConstrainedFilterMask(0),
178   fHybridFilterMaskTPCCG(0),
179   fWriteHybridTPCCOnly(kFALSE),
180   fGlobalConstrainedFilterMask(0),
181   fHybridFilterMaskGCG(0),
182   fWriteHybridGCOnly(kFALSE),
183     fIsVZEROEnabled(kTRUE),
184     fIsTZEROEnabled(kTRUE),
185     fIsZDCEnabled(kTRUE),
186     fIsHMPIDEnabled(kTRUE), 
187     fIsV0CascadeRecoEnabled(kFALSE),
188     fAreCascadesEnabled(kTRUE),
189     fAreV0sEnabled(kTRUE),
190     fAreKinksEnabled(kTRUE),
191     fAreTracksEnabled(kTRUE),
192     fArePmdClustersEnabled(kTRUE),
193     fAreCaloClustersEnabled(kTRUE),
194     fAreEMCALCellsEnabled(kTRUE),
195     fArePHOSCellsEnabled(kTRUE),
196                 fAreEMCALTriggerEnabled(kTRUE),
197                 fArePHOSTriggerEnabled(kTRUE),
198                 fAreTrackletsEnabled(kTRUE),
199     fIsTRDEnabled(kTRUE),
200     fESDpid(0x0),
201     fIsPidOwner(kFALSE),
202     fTPCaloneTrackCuts(0),
203     fDoPropagateTrackToEMCal(kTRUE),
204     fEMCalSurfaceDistance(440),
205     fRefitVertexTracks(-1),
206     fRefitVertexTracksCuts(0)
207 {
208   // Constructor
209
210     fV0Cuts[0] =  33.   ;   // max allowed chi2
211     fV0Cuts[1] =   0.1  ;   // min allowed impact parameter for the 1st daughter
212     fV0Cuts[2] =   0.1  ;   // min allowed impact parameter for the 2nd daughter
213     fV0Cuts[3] =   1.   ;   // max allowed DCA between the daughter tracks
214     fV0Cuts[4] =    .998;   // min allowed cosine of V0's pointing angle
215     fV0Cuts[5] =   0.9  ;   // min radius of the fiducial volume
216     fV0Cuts[6] = 100.   ;   // max radius of the fiducial volume
217
218     fCascadeCuts[0] =  33.   ; // max allowed chi2 (same as PDC07)
219     fCascadeCuts[1] =   0.05 ; // min allowed V0 impact parameter
220     fCascadeCuts[2] =   0.008; // "window" around the Lambda mass
221     fCascadeCuts[3] =   0.03 ; // min allowed bachelor's impact parameter
222     fCascadeCuts[4] =   0.3  ; // max allowed DCA between the V0 and the bachelor
223     fCascadeCuts[5] =   0.999; // min allowed cosine of the cascade pointing angle
224     fCascadeCuts[6] =   0.9  ; // min radius of the fiducial volume
225     fCascadeCuts[7] = 100.   ; // max radius of the fiducial volume
226
227
228
229 }
230 AliAnalysisTaskESDfilter::~AliAnalysisTaskESDfilter(){
231     if(fIsPidOwner) delete fESDpid;
232     delete[] fRefitVertexTracksCuts;
233 }
234
235 //______________________________________________________________________________
236 void AliAnalysisTaskESDfilter::UserCreateOutputObjects()
237 {
238   //
239   // Create Output Objects conenct filter to outputtree
240   // 
241   if(OutputTree())
242   {
243     OutputTree()->GetUserInfo()->Add(fTrackFilter);
244   }
245   else
246   {
247     AliError("No OutputTree() for adding the track filter");
248   }
249   fTPCaloneTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
250 }
251
252 //______________________________________________________________________________
253 void AliAnalysisTaskESDfilter::Init()
254 {
255   // Initialization
256   if (fDebug > 1) AliInfo("Init() \n");
257   // Call configuration file
258 }
259
260 //______________________________________________________________________________
261 Bool_t AliAnalysisTaskESDfilter::Notify()
262 {
263 // Notify method.
264    AddMetadataToUserInfo();
265    return kTRUE;
266 }   
267
268 //______________________________________________________________________________
269 Bool_t AliAnalysisTaskESDfilter::AddMetadataToUserInfo()
270 {
271 // Copy metadata to AOD user info.
272   static Bool_t copyFirst = kFALSE;
273   if (!copyFirst) {
274     AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
275     if (!mgr) {
276        AliError("AliAnalysisTaskESDfilter::AddMetadataToUserInfo() : No analysis manager !");
277        return kFALSE;
278     }   
279     TTree *esdTree = mgr->GetTree()->GetTree();
280     if (!esdTree) return kFALSE;
281     TNamed *alirootVersion = (TNamed*)esdTree->GetUserInfo()->FindObject("alirootVersion");
282     if (!alirootVersion) return kFALSE;    
283     AliAODHandler *aodHandler = dynamic_cast<AliAODHandler*>(mgr->GetOutputEventHandler());
284          if (!aodHandler) return kFALSE;
285     TTree *aodTree = aodHandler->GetTree();
286     if (!aodTree) return kFALSE;
287     aodTree->GetUserInfo()->Add(new TNamed(*alirootVersion));
288     copyFirst = kTRUE;
289   }
290   return kTRUE;
291 }
292
293 //______________________________________________________________________________
294 void AliAnalysisTaskESDfilter::PrintTask(Option_t *option, Int_t indent) const
295 {
296 // Print selection task information
297   AliInfo("");
298   
299   AliAnalysisTaskSE::PrintTask(option,indent);
300   
301   TString spaces(' ',indent+3);
302   
303         cout << spaces.Data() << Form("Cascades       are %s",fAreCascadesEnabled ? "ENABLED":"DISABLED") << endl;
304         cout << spaces.Data() << Form("V0s            are %s",fAreV0sEnabled ? "ENABLED":"DISABLED") << endl;
305         cout << spaces.Data() << Form("Kinks          are %s",fAreKinksEnabled ? "ENABLED":"DISABLED") << endl;
306         cout << spaces.Data() << Form("Tracks         are %s",fAreTracksEnabled ? "ENABLED":"DISABLED") << endl;
307         cout << spaces.Data() << Form("PmdClusters    are %s",fArePmdClustersEnabled ? "ENABLED":"DISABLED") << endl;
308         cout << spaces.Data() << Form("CaloClusters   are %s",fAreCaloClustersEnabled ? "ENABLED":"DISABLED") << endl;
309   cout << spaces.Data() << Form("EMCAL cells    are %s",fAreEMCALCellsEnabled ? "ENABLED":"DISABLED") << endl;
310         cout << spaces.Data() << Form("EMCAL triggers are %s",fAreEMCALTriggerEnabled ? "ENABLED":"DISABLED") << endl;
311         cout << spaces.Data() << Form("PHOS triggers  are %s",fArePHOSTriggerEnabled ? "ENABLED":"DISABLED") << endl;
312         cout << spaces.Data() << Form("Tracklets      are %s",fAreTrackletsEnabled ? "ENABLED":"DISABLED") << endl;  
313         cout << spaces.Data() << Form("PropagateTrackToEMCal  is %s", fDoPropagateTrackToEMCal ? "ENABLED":"DISABLED") << endl; 
314         if (fRefitVertexTracks<0) cout << spaces.Data() << Form("RefitVerteTracks is DISABLED") << endl;
315         else cout << spaces.Data() << Form("RefitVerteTracks is ENABLED to %d",fRefitVertexTracks) << endl;
316 }
317
318 //______________________________________________________________________________
319 void AliAnalysisTaskESDfilter::UserExec(Option_t */*option*/)
320 {
321 // Execute analysis for current event
322 //
323                                             
324   Long64_t ientry = Entry();
325   
326   if (fDebug > 0) {
327       printf("Filter: Analysing event # %5d\n", (Int_t) ientry);
328       if (fHighPthreshold == 0) AliInfo("detector PID signals are stored in each track");
329       if (!fPtshape) AliInfo("detector PID signals are not stored below the pt threshold");
330   }
331   // Filters must explicitely enable AOD filling in their UserExec (AG)
332   if (!AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()) AliFatal("Cannot run ESD filter without an output event handler");
333   if(fEnableFillAOD) {
334      AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillAOD(kTRUE);
335      AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillExtension(kTRUE);
336   }   
337   ConvertESDtoAOD();
338 }
339
340 //______________________________________________________________________________
341 TClonesArray& AliAnalysisTaskESDfilter::Cascades()
342 {
343   return *(AODEvent()->GetCascades());
344 }
345
346 //______________________________________________________________________________
347 TClonesArray& AliAnalysisTaskESDfilter::Tracks()
348 {
349   return *(AODEvent()->GetTracks());
350 }
351
352 //______________________________________________________________________________
353 TClonesArray& AliAnalysisTaskESDfilter::V0s()
354 {
355   return *(AODEvent()->GetV0s());
356 }
357
358 //______________________________________________________________________________
359 TClonesArray& AliAnalysisTaskESDfilter::Vertices()
360 {
361   return *(AODEvent()->GetVertices());
362 }
363
364 //______________________________________________________________________________
365 AliAODHeader* AliAnalysisTaskESDfilter::ConvertHeader(const AliESDEvent& esd)
366 {
367 // Convert header information
368
369   AliCodeTimerAuto("",0);
370   
371   AliAODHeader* header = AODEvent()->GetHeader();
372   
373   header->SetRunNumber(esd.GetRunNumber());
374   header->SetOfflineTrigger(fInputHandler->IsEventSelected()); // propagate the decision of the physics selection
375   header->SetNumberOfESDTracks(esd.GetNumberOfTracks());
376
377   TTree* tree = fInputHandler->GetTree();
378   if (tree) {
379     TFile* file = tree->GetCurrentFile();
380     if (file) header->SetESDFileName(file->GetName());
381   }
382   
383   if (fOldESDformat) {
384     header->SetBunchCrossNumber(0);
385     header->SetOrbitNumber(0);
386     header->SetPeriodNumber(0);
387     header->SetEventType(0);
388     header->SetMuonMagFieldScale(-999.);
389     header->SetCentrality(0);       
390     header->SetEventplane(0);
391   } else {
392     header->SetBunchCrossNumber(esd.GetBunchCrossNumber());
393     header->SetOrbitNumber(esd.GetOrbitNumber());
394     header->SetPeriodNumber(esd.GetPeriodNumber());
395     header->SetEventType(esd.GetEventType());
396     
397     header->SetEventNumberESDFile(esd.GetHeader()->GetEventNumberInFile());
398     if(const_cast<AliESDEvent&>(esd).GetCentrality()){
399       header->SetCentrality(const_cast<AliESDEvent&>(esd).GetCentrality());
400     }
401     else{
402       header->SetCentrality(0);
403     }
404     if(const_cast<AliESDEvent&>(esd).GetEventplane()){
405       header->SetEventplane(const_cast<AliESDEvent&>(esd).GetEventplane());
406     }
407     else{
408       header->SetEventplane(0);
409     }
410   }
411   
412   // Trigger
413   header->SetFiredTriggerClasses(esd.GetFiredTriggerClasses());
414   header->SetTriggerMask(esd.GetTriggerMask()); 
415   header->SetTriggerCluster(esd.GetTriggerCluster());
416   header->SetL0TriggerInputs(esd.GetHeader()->GetL0TriggerInputs());    
417   header->SetL1TriggerInputs(esd.GetHeader()->GetL1TriggerInputs());    
418   header->SetL2TriggerInputs(esd.GetHeader()->GetL2TriggerInputs());    
419   
420   header->SetMagneticField(esd.GetMagneticField());
421   header->SetMuonMagFieldScale(esd.GetCurrentDip()/6000.);
422   header->SetZDCN1Energy(esd.GetZDCN1Energy());
423   header->SetZDCP1Energy(esd.GetZDCP1Energy());
424   header->SetZDCN2Energy(esd.GetZDCN2Energy());
425   header->SetZDCP2Energy(esd.GetZDCP2Energy());
426   header->SetZDCEMEnergy(esd.GetZDCEMEnergy(0),esd.GetZDCEMEnergy(1));
427
428   header->SetIRInt2InteractionMap(esd.GetHeader()->GetIRInt2InteractionMap());
429   header->SetIRInt1InteractionMap(esd.GetHeader()->GetIRInt1InteractionMap());
430   
431   // ITS Cluster Multiplicty
432   const AliMultiplicity *mult = esd.GetMultiplicity();
433   for (Int_t ilay = 0; ilay < 6; ilay++) header->SetITSClusters(ilay, mult->GetNumberOfITSClusters(ilay));
434   
435   // TPC only Reference Multiplicty
436   Int_t refMult  = fTPCaloneTrackCuts ? (Short_t)fTPCaloneTrackCuts->GetReferenceMultiplicity(&esd, kTRUE) : -1;
437   header->SetTPConlyRefMultiplicity(refMult);
438   //
439   AliESDtrackCuts::MultEstTrackType estType = esd.GetPrimaryVertexTracks()->GetStatus() ? AliESDtrackCuts::kTrackletsITSTPC : AliESDtrackCuts::kTracklets;
440   header->SetRefMultiplicityComb05(AliESDtrackCuts::GetReferenceMultiplicity(&esd,estType,0.5));
441   header->SetRefMultiplicityComb08(AliESDtrackCuts::GetReferenceMultiplicity(&esd,estType,0.8));
442   //
443   Float_t diamxy[2]={esd.GetDiamondX(),esd.GetDiamondY()};
444   Float_t diamcov[3]; 
445   esd.GetDiamondCovXY(diamcov);
446   header->SetDiamond(diamxy,diamcov);
447   header->SetDiamondZ(esd.GetDiamondZ(),esd.GetSigma2DiamondZ());
448   
449   // VZERO channel equalization factors for event-plane reconstruction   
450   header->SetVZEROEqFactors(esd.GetVZEROEqFactors());
451
452   // T0 Resolution information                                                                                                                                          
453   const AliESDRun* esdRun = esd.GetESDRun();
454   for (Int_t i=0;i<AliESDRun::kT0spreadSize;i++) header->SetT0spread(i,esdRun->GetT0spread(i));
455
456   return header;
457 }
458
459 //______________________________________________________________________________
460 void AliAnalysisTaskESDfilter::ConvertCascades(const AliESDEvent& esd) 
461 {
462
463   // Convert the cascades part of the ESD.
464   // Return the number of cascades
465  
466   AliCodeTimerAuto("",0);
467   
468   // Create vertices starting from the most complex objects
469   Double_t chi2 = 0.;
470   
471   const AliESDVertex* vtx = esd.GetPrimaryVertex();
472   Double_t pos[3] = { 0. };
473   Double_t covVtx[6] = { 0. };
474   Double_t momBach[3]={0.};
475   Double_t covTr[21]={0.};
476   Double_t pid[10]={0.};
477   AliAODPid* detpid(0x0);
478   AliAODVertex* vV0FromCascade(0x0);
479   AliAODv0* aodV0(0x0);
480   AliAODcascade* aodCascade(0x0);
481   AliAODTrack* aodTrack(0x0);
482   Double_t momPos[3]={0.};
483   Double_t momNeg[3] = { 0. };
484   Double_t momPosAtV0vtx[3]={0.};
485   Double_t momNegAtV0vtx[3]={0.};
486   Int_t    tofLabel[3] = {0};
487   TClonesArray& verticesArray = Vertices();
488   TClonesArray& tracksArray = Tracks();
489   TClonesArray& cascadesArray = Cascades();
490   
491   // Cascades (Modified by A.Maire - February 2009)
492   for (Int_t nCascade = 0; nCascade < esd.GetNumberOfCascades(); ++nCascade) {
493     
494     // 0- Preparation
495     //
496     AliESDcascade *esdCascade = esd.GetCascade(nCascade);
497                 Int_t  idxPosFromV0Dghter  = esdCascade->GetPindex();
498                 Int_t  idxNegFromV0Dghter  = esdCascade->GetNindex();
499                 Int_t  idxBachFromCascade  = esdCascade->GetBindex();
500     
501     AliESDtrack  *esdCascadePos  = esd.GetTrack( idxPosFromV0Dghter);
502     AliESDtrack  *esdCascadeNeg  = esd.GetTrack( idxNegFromV0Dghter);
503     AliESDtrack  *esdCascadeBach = esd.GetTrack( idxBachFromCascade);
504     
505     // Identification of the V0 within the esdCascade (via both daughter track indices)
506     AliESDv0 * currentV0   = 0x0;
507     Int_t      idxV0FromCascade = -1;
508     
509     for (Int_t iV0=0; iV0<esd.GetNumberOfV0s(); ++iV0) {
510       
511       currentV0 = esd.GetV0(iV0);
512       Int_t posCurrentV0 = currentV0->GetPindex();
513       Int_t negCurrentV0 = currentV0->GetNindex();
514       
515       if (posCurrentV0==idxPosFromV0Dghter && negCurrentV0==idxNegFromV0Dghter) {
516         idxV0FromCascade = iV0;
517         break;
518       }
519     }
520     
521     if(idxV0FromCascade < 0){
522       printf("Cascade - no matching for the V0 (index V0 = -1) ! Skip ... \n");
523       continue;
524     }// a priori, useless check, but safer ... in case of pb with tracks "out of bounds"
525     
526     AliESDv0 *esdV0FromCascade   = esd.GetV0(idxV0FromCascade);
527         
528     // 1 - Cascade selection 
529     
530     //  AliESDVertex *esdPrimVtx = new AliESDVertex(*(esd.GetPrimaryVertex()));
531     //  TList cascadeObjects;
532     //  cascadeObjects.AddAt(esdV0FromCascade, 0);
533     //  cascadeObjects.AddAt(esdCascadePos,    1);
534     //  cascadeObjects.AddAt(esdCascadeNeg,    2);
535     //  cascadeObjects.AddAt(esdCascade,       3);
536     //  cascadeObjects.AddAt(esdCascadeBach,   4);
537     //  cascadeObjects.AddAt(esdPrimVtx,       5);
538     // 
539     //  UInt_t selectCascade = 0;
540     //  if (fCascadeFilter) {
541     //    // selectCascade = fCascadeFilter->IsSelected(&cascadeObjects); 
542     //          // FIXME AliESDCascadeCuts to be implemented ...
543     // 
544     //          // Here we may encounter a moot point at the V0 level 
545     //          // between the cascade selections and the V0 ones :
546     //          // the V0 selected along with the cascade (secondary V0) may 
547     //          // usually be removed from the dedicated V0 selections (prim V0) ...
548     //          // -> To be discussed !
549     // 
550     //    // this is a little awkward but otherwise the 
551     //    // list wants to access the pointer (delete it) 
552     //    // again when going out of scope
553     //    delete cascadeObjects.RemoveAt(5); // esdPrimVtx created via copy construct
554     //    esdPrimVtx = 0;
555     //    if (!selectCascade) 
556     //      continue;
557     //  }
558     //  else{
559     //    delete cascadeObjects.RemoveAt(5); // esdPrimVtx created via copy construct
560     //    esdPrimVtx = 0;
561     //  }
562     
563     // 2 - Add the cascade vertex
564     
565     esdCascade->GetXYZcascade(pos[0], pos[1], pos[2]);
566     esdCascade->GetPosCovXi(covVtx);
567     chi2 = esdCascade->GetChi2Xi(); 
568     
569     AliAODVertex *vCascade = new(verticesArray[fNumberOfVertices++]) AliAODVertex( pos,
570                                                                      covVtx,
571                                                                      chi2, // FIXME = Chi2/NDF will be needed
572                                                                      fPrimaryVertex,
573                                                                      nCascade, // id
574                                                                      AliAODVertex::kCascade);
575     fPrimaryVertex->AddDaughter(vCascade);
576     
577 //    if (fDebug > 2) {
578 //      printf("---- Cascade / Cascade Vertex (AOD) : \n");
579 //      vCascade->Print();
580 //    }
581     
582 //    if(esd.GetTOFHeader() && fIsPidOwner) fESDpid->SetTOFResponse(const_cast<AliESDEvent*>(&esd), (AliESDpid::EStartTimeType_t)fTimeZeroType); //in case of AOD production starting form LHC10e without Tender. 
583
584
585     // 3 - Add the bachelor track from the cascade
586     
587     if (!fUsedTrack[idxBachFromCascade]) {
588       
589       esdCascadeBach->GetPxPyPz(momBach);
590       esdCascadeBach->GetXYZ(pos);
591       esdCascadeBach->GetCovarianceXYZPxPyPz(covTr);
592       esdCascadeBach->GetESDpid(pid);
593       esdCascadeBach->GetTOFLabel(tofLabel);
594
595             fUsedTrack[idxBachFromCascade] = kTRUE;
596             UInt_t selectInfo = 0;
597             if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdCascadeBach);
598             if (fMChandler) fMChandler->SelectParticle(esdCascadeBach->GetLabel());
599             aodTrack = new(tracksArray[fNumberOfTracks++]) AliAODTrack(esdCascadeBach->GetID(),
600                                                                            esdCascadeBach->GetLabel(), 
601                                                                            momBach, 
602                                                                            kTRUE,
603                                                                            pos,
604                                                                            kFALSE, // Why kFALSE for "isDCA" ? FIXME
605                                                                            covTr, 
606                                                                            (Short_t)esdCascadeBach->GetSign(),
607                                                                            esdCascadeBach->GetITSClusterMap(), 
608                                                                            pid,
609                                                                            vCascade,
610                                                                            kTRUE,  // usedForVtxFit = kFALSE ? FIXME
611                                                                            vtx->UsesTrack(esdCascadeBach->GetID()),
612                                                                            AliAODTrack::kSecondary,
613                                                                            selectInfo);
614             aodTrack->SetTPCFitMap(esdCascadeBach->GetTPCFitMap());
615             aodTrack->SetTPCClusterMap(esdCascadeBach->GetTPCClusterMap());
616             aodTrack->SetTPCSharedMap (esdCascadeBach->GetTPCSharedMap());
617             aodTrack->SetChi2perNDF(Chi2perNDF(esdCascadeBach));
618             aodTrack->SetTPCPointsF(esdCascadeBach->GetTPCNclsF());
619             aodTrack->SetTPCNCrossedRows(UShort_t(esdCascadeBach->GetTPCCrossedRows()));
620             aodTrack->SetIntegratedLength(esdCascadeBach->GetIntegratedLength());
621             aodTrack->SetTOFLabel(tofLabel);
622             fAODTrackRefs->AddAt(aodTrack,idxBachFromCascade);
623             
624             if (esdCascadeBach->GetSign() > 0) ++fNumberOfPositiveTracks;
625             aodTrack->ConvertAliPIDtoAODPID();
626             aodTrack->SetFlags(esdCascadeBach->GetStatus());
627             SetAODPID(esdCascadeBach,aodTrack,detpid);
628     }
629     else {
630             aodTrack = static_cast<AliAODTrack*>( fAODTrackRefs->At(idxBachFromCascade) );
631     }
632     
633     vCascade->AddDaughter(aodTrack);
634     
635 //    if (fDebug > 4) {
636 //      printf("---- Cascade / bach dghter : \n");
637 //      aodTrack->Print();
638 //    }
639     
640     
641     // 4 - Add the V0 from the cascade. 
642     // = V0vtx + both pos and neg daughter tracks + the aodV0 itself
643     //
644     
645     if ( !fUsedV0[idxV0FromCascade] ) {
646       // 4.A - if VO structure hasn't been created yet
647       
648       // 4.A.1 - Create the V0 vertex of the cascade
649       
650       esdV0FromCascade->GetXYZ(pos[0], pos[1], pos[2]);
651       esdV0FromCascade->GetPosCov(covVtx);
652       chi2 = esdV0FromCascade->GetChi2V0();  // = chi2/NDF since NDF = 2*2-3 ?
653                         
654       vV0FromCascade = new(verticesArray[fNumberOfVertices++]) AliAODVertex(pos,
655                                                                          covVtx,
656                                                                          chi2,
657                                                                          vCascade,
658                                                                          idxV0FromCascade, //id of ESDv0
659                                                                          AliAODVertex::kV0);
660       // Note:
661       //    one V0 can be used by several cascades.
662       // So, one AOD V0 vtx can have several parent vtx.
663       // This is not directly allowed by AliAODvertex.
664       // Setting the parent vtx (here = param "vCascade") doesn't lead to a crash
665       // but to a problem of consistency within AODEvent.
666       // -> See below paragraph 4.B, for the proposed treatment of such a case.
667       
668       // Add the vV0FromCascade to the aodVOVtxRefs
669       fAODV0VtxRefs->AddAt(vV0FromCascade,idxV0FromCascade);
670       
671       
672       // 4.A.2 - Add the positive tracks from the V0
673       
674       esdCascadePos->GetPxPyPz(momPos);
675       esdCascadePos->GetXYZ(pos);
676       esdCascadePos->GetCovarianceXYZPxPyPz(covTr);
677       esdCascadePos->GetESDpid(pid);
678       esdCascadePos->GetTOFLabel(tofLabel);      
679       
680       if (!fUsedTrack[idxPosFromV0Dghter]) {
681         fUsedTrack[idxPosFromV0Dghter] = kTRUE;
682         
683         UInt_t selectInfo = 0;
684         if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdCascadePos);
685         if(fMChandler) fMChandler->SelectParticle(esdCascadePos->GetLabel());
686         aodTrack = new(tracksArray[fNumberOfTracks++]) 
687         AliAODTrack(  esdCascadePos->GetID(),
688                     esdCascadePos->GetLabel(), 
689                     momPos, 
690                     kTRUE,
691                     pos,
692                     kFALSE, // Why kFALSE for "isDCA" ? FIXME
693                     covTr, 
694                     (Short_t)esdCascadePos->GetSign(),
695                     esdCascadePos->GetITSClusterMap(), 
696                     pid,
697                     vV0FromCascade,
698                     kTRUE,  // usedForVtxFit = kFALSE ? FIXME
699                     vtx->UsesTrack(esdCascadePos->GetID()),
700                     AliAODTrack::kSecondary,
701                     selectInfo);
702         aodTrack->SetTPCFitMap(esdCascadePos->GetTPCFitMap());
703         aodTrack->SetTPCClusterMap(esdCascadePos->GetTPCClusterMap());
704         aodTrack->SetTPCSharedMap (esdCascadePos->GetTPCSharedMap());
705         aodTrack->SetChi2perNDF(Chi2perNDF(esdCascadePos));
706         aodTrack->SetTPCPointsF(esdCascadePos->GetTPCNclsF());
707         aodTrack->SetTPCNCrossedRows(UShort_t(esdCascadePos->GetTPCCrossedRows()));
708         aodTrack->SetIntegratedLength(esdCascadePos->GetIntegratedLength());
709         aodTrack->SetTOFLabel(tofLabel);
710         fAODTrackRefs->AddAt(aodTrack,idxPosFromV0Dghter);
711         
712         if (esdCascadePos->GetSign() > 0) ++fNumberOfPositiveTracks;
713         aodTrack->ConvertAliPIDtoAODPID();
714         aodTrack->SetFlags(esdCascadePos->GetStatus());
715         SetAODPID(esdCascadePos,aodTrack,detpid);
716       }
717       else {
718         aodTrack = static_cast<AliAODTrack*>(fAODTrackRefs->At(idxPosFromV0Dghter));
719       }
720       vV0FromCascade->AddDaughter(aodTrack);
721       
722       
723       // 4.A.3 - Add the negative tracks from the V0
724       
725       esdCascadeNeg->GetPxPyPz(momNeg);
726       esdCascadeNeg->GetXYZ(pos);
727       esdCascadeNeg->GetCovarianceXYZPxPyPz(covTr);
728       esdCascadeNeg->GetESDpid(pid);
729       esdCascadeNeg->GetTOFLabel(tofLabel);
730       
731       
732       if (!fUsedTrack[idxNegFromV0Dghter]) {
733         fUsedTrack[idxNegFromV0Dghter] = kTRUE;
734         
735         UInt_t selectInfo = 0;
736         if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdCascadeNeg);
737         if(fMChandler)fMChandler->SelectParticle(esdCascadeNeg->GetLabel());
738         aodTrack = new(tracksArray[fNumberOfTracks++]) AliAODTrack(  esdCascadeNeg->GetID(),
739                                                       esdCascadeNeg->GetLabel(),
740                                                       momNeg,
741                                                       kTRUE,
742                                                       pos,
743                                                       kFALSE, // Why kFALSE for "isDCA" ? FIXME
744                                                       covTr, 
745                                                       (Short_t)esdCascadeNeg->GetSign(),
746                                                       esdCascadeNeg->GetITSClusterMap(), 
747                                                       pid,
748                                                       vV0FromCascade,
749                                                       kTRUE,  // usedForVtxFit = kFALSE ? FIXME
750                                                       vtx->UsesTrack(esdCascadeNeg->GetID()),
751                                                       AliAODTrack::kSecondary,
752                                                       selectInfo);
753         aodTrack->SetTPCFitMap(esdCascadeNeg->GetTPCFitMap());
754         aodTrack->SetTPCClusterMap(esdCascadeNeg->GetTPCClusterMap());
755         aodTrack->SetTPCSharedMap (esdCascadeNeg->GetTPCSharedMap());
756         aodTrack->SetChi2perNDF(Chi2perNDF(esdCascadeNeg));
757         aodTrack->SetTPCPointsF(esdCascadeNeg->GetTPCNclsF());
758         aodTrack->SetTPCNCrossedRows(UShort_t(esdCascadeNeg->GetTPCCrossedRows()));
759         aodTrack->SetIntegratedLength(esdCascadeNeg->GetIntegratedLength());
760         aodTrack->SetTOFLabel(tofLabel);
761         fAODTrackRefs->AddAt(aodTrack,idxNegFromV0Dghter);
762         
763         if (esdCascadeNeg->GetSign() > 0) ++fNumberOfPositiveTracks;
764         aodTrack->ConvertAliPIDtoAODPID();
765         aodTrack->SetFlags(esdCascadeNeg->GetStatus());
766         SetAODPID(esdCascadeNeg,aodTrack,detpid);
767       }
768       else {
769         aodTrack = static_cast<AliAODTrack*>(fAODTrackRefs->At(idxNegFromV0Dghter));
770       }
771       
772       vV0FromCascade->AddDaughter(aodTrack);
773       
774                         
775       // 4.A.4 - Add the V0 from cascade to the V0 array
776       
777       Double_t  dcaV0Daughters      = esdV0FromCascade->GetDcaV0Daughters();
778       Double_t  dcaV0ToPrimVertex   = esdV0FromCascade->GetD( esd.GetPrimaryVertex()->GetX(),
779                                                              esd.GetPrimaryVertex()->GetY(),
780                                                              esd.GetPrimaryVertex()->GetZ() );
781       esdV0FromCascade->GetPPxPyPz( momPosAtV0vtx[0],momPosAtV0vtx[1],momPosAtV0vtx[2] ); 
782       esdV0FromCascade->GetNPxPyPz( momNegAtV0vtx[0],momNegAtV0vtx[1],momNegAtV0vtx[2] ); 
783       
784       Double_t dcaDaughterToPrimVertex[2] = { 999., 999.}; // ..[0] = DCA in (x,y) for Pos and ..[1] = Neg
785       dcaDaughterToPrimVertex[0] = TMath::Abs(esdCascadePos->GetD(      esd.GetPrimaryVertex()->GetX(),
786                                                                   esd.GetPrimaryVertex()->GetY(),
787                                                                   esd.GetMagneticField())        );
788       dcaDaughterToPrimVertex[1] = TMath::Abs(esdCascadeNeg->GetD(      esd.GetPrimaryVertex()->GetX(),
789                                                                   esd.GetPrimaryVertex()->GetY(),
790                                                                   esd.GetMagneticField())        );
791       
792       aodV0 = new(V0s()[fNumberOfV0s++]) AliAODv0( vV0FromCascade, 
793                                                   dcaV0Daughters,
794                                                   dcaV0ToPrimVertex, 
795                                                   momPosAtV0vtx, 
796                                                   momNegAtV0vtx, 
797                                                   dcaDaughterToPrimVertex); 
798       // set the aod v0 on-the-fly status
799       aodV0->SetOnFlyStatus(esdV0FromCascade->GetOnFlyStatus());
800       
801       // Add the aodV0 to the aodVORefs
802       fAODV0Refs->AddAt(aodV0,idxV0FromCascade);
803       
804       fUsedV0[idxV0FromCascade] = kTRUE;
805       
806     } else { 
807       // 4.B - if V0 structure already used
808       
809       // Note :
810       //    one V0 can be used by several cascades (frequent in PbPb evts) : 
811       // same V0 which used but attached to different bachelor tracks
812       // -> aodVORefs and fAODV0VtxRefs are needed.
813       // Goal : avoid a redundancy of the info in "Vertices" and "v0s" clones array.
814       
815       vV0FromCascade = static_cast<AliAODVertex*>( fAODV0VtxRefs->At(idxV0FromCascade) );
816       aodV0          = static_cast<AliAODv0*>    ( fAODV0Refs   ->At(idxV0FromCascade) );
817       
818       // - Treatment of the parent for such a "re-used" V0 :
819       // Insert the cascade that reuses the V0 vertex in the lineage chain
820       // Before : vV0 -> vCascade1 -> vPrimary
821       //  - Hyp : cascade2 uses the same V0 as cascade1
822       //  After :  vV0 -> vCascade2 -> vCascade1 -> vPrimary
823       
824       AliAODVertex *vCascadePreviousParent = static_cast<AliAODVertex*> (vV0FromCascade->GetParent());
825                         vV0FromCascade->SetParent(vCascade);
826                         vCascade      ->SetParent(vCascadePreviousParent);
827       
828 //      if(fDebug > 2)  
829 //        printf("---- Cascade / Lineage insertion\n"
830 //               "Parent of V0 vtx                 = Cascade vtx %p\n"
831 //               "Parent of the cascade vtx        = Cascade vtx %p\n"
832 //               "Parent of the parent cascade vtx = Cascade vtx %p\n", 
833 //               static_cast<void*> (vV0FromCascade->GetParent()),
834 //               static_cast<void*> (vCascade->GetParent()),
835 //               static_cast<void*> (vCascadePreviousParent->GetParent()) );
836       
837     }// end if V0 structure already used
838     
839 //    if (fDebug > 2) {
840 //      printf("---- Cascade / V0 vertex: \n");
841 //      vV0FromCascade->Print();
842 //    }
843 //    
844 //    if (fDebug > 4) {
845 //      printf("---- Cascade / pos dghter : \n");
846 //                      aodTrack->Print();
847 //      printf("---- Cascade / neg dghter : \n");
848 //                      aodTrack->Print();
849 //      printf("---- Cascade / aodV0 : \n");
850 //                      aodV0->Print();
851 //    }
852     
853     // In any case (used V0 or not), add the V0 vertex to the cascade one.
854     vCascade->AddDaughter(vV0FromCascade);      
855     
856                 
857     // 5 - Add the primary track of the cascade (if any)
858     
859     
860     // 6 - Add the cascade to the AOD array of cascades
861     
862     Double_t dcaBachToPrimVertexXY = TMath::Abs(esdCascadeBach->GetD(esd.GetPrimaryVertex()->GetX(),
863                                                                      esd.GetPrimaryVertex()->GetY(),
864                                                                      esd.GetMagneticField())        );
865     
866     Double_t momBachAtCascadeVtx[3]={0.};
867
868     esdCascade->GetBPxPyPz(momBachAtCascadeVtx[0], momBachAtCascadeVtx[1], momBachAtCascadeVtx[2]);
869     
870     aodCascade = new(cascadesArray[fNumberOfCascades++]) AliAODcascade(  vCascade,
871                                                           esdCascade->Charge(),
872                                                           esdCascade->GetDcaXiDaughters(),
873                                                           -999.,
874                                                           // DCAXiToPrimVtx -> needs to be calculated   ----|
875                                                           // doesn't exist at ESD level;
876                                                           // See AODcascade::DcaXiToPrimVertex(Double, Double, Double)
877                                                           dcaBachToPrimVertexXY,
878                                                           momBachAtCascadeVtx,
879                                                           *aodV0);
880     
881     if (fDebug > 10) {
882       printf("---- Cascade / AOD cascade : \n\n");
883       aodCascade->PrintXi(fPrimaryVertex->GetX(), fPrimaryVertex->GetY(), fPrimaryVertex->GetZ());
884     }
885     
886   } // end of the loop on cascades
887   
888   Cascades().Expand(fNumberOfCascades);
889 }
890
891 //______________________________________________________________________________
892 void AliAnalysisTaskESDfilter::ConvertV0s(const AliESDEvent& esd)
893 {
894   // Access to the AOD container of V0s
895   
896   AliCodeTimerAuto("",0);
897
898   //
899   // V0s
900   //
901   
902   Double_t pos[3] = { 0. };      
903   Double_t chi2(0.0);
904   Double_t covVtx[6] = { 0. };
905   Double_t momPos[3]={0.};
906   Double_t covTr[21]={0.};
907   Double_t pid[10]={0.};
908   AliAODTrack* aodTrack(0x0);
909   AliAODPid* detpid(0x0);
910   Double_t momNeg[3]={0.};
911   Double_t momPosAtV0vtx[3]={0.};
912   Double_t momNegAtV0vtx[3]={0.};
913   Int_t    tofLabel[3] = {0};
914   for (Int_t nV0 = 0; nV0 < esd.GetNumberOfV0s(); ++nV0) 
915   {
916     if (fUsedV0[nV0]) continue; // skip if already added to the AOD
917     
918     AliESDv0 *v0 = esd.GetV0(nV0);
919     Int_t posFromV0 = v0->GetPindex();
920     Int_t negFromV0 = v0->GetNindex();
921     
922     // V0 selection 
923     //
924     AliESDVertex *esdVtx   = new AliESDVertex(*(esd.GetPrimaryVertex()));
925     AliESDtrack  *esdV0Pos = esd.GetTrack(posFromV0);
926     AliESDtrack  *esdV0Neg = esd.GetTrack(negFromV0);
927     TList v0objects;
928     v0objects.AddAt(v0,                      0);
929     v0objects.AddAt(esdV0Pos,                1);
930     v0objects.AddAt(esdV0Neg,                2);
931     v0objects.AddAt(esdVtx,                  3);
932     UInt_t selectV0 = 0;
933     if (fV0Filter) {
934       selectV0 = fV0Filter->IsSelected(&v0objects);
935       // this is a little awkward but otherwise the 
936       // list wants to access the pointer (delete it) 
937       // again when going out of scope
938       delete v0objects.RemoveAt(3); // esdVtx created via copy construct
939       esdVtx = 0;
940       if (!selectV0) 
941         continue;
942     }
943     else{
944       delete v0objects.RemoveAt(3); // esdVtx created via copy construct
945       esdVtx = 0;
946     }
947     
948     v0->GetXYZ(pos[0], pos[1], pos[2]);
949     
950     if (!fOldESDformat) {
951             chi2 = v0->GetChi2V0(); // = chi2/NDF since NDF = 2*2-3
952             v0->GetPosCov(covVtx);
953     } else {
954             chi2 = -999.;
955             for (Int_t i = 0; i < 6; i++)  covVtx[i] = 0.;
956     }
957     
958     
959     AliAODVertex * vV0 = 
960           new(Vertices()[fNumberOfVertices++]) AliAODVertex(pos,
961                                                       covVtx,
962                                                       chi2,
963                                                       fPrimaryVertex,
964                                                       nV0,
965                                                       AliAODVertex::kV0);
966     fPrimaryVertex->AddDaughter(vV0);
967     
968     
969     // Add the positive tracks from the V0
970     
971
972     esdV0Pos->GetPxPyPz(momPos);
973     esdV0Pos->GetXYZ(pos);
974     esdV0Pos->GetCovarianceXYZPxPyPz(covTr);
975     esdV0Pos->GetESDpid(pid);
976     esdV0Pos->GetTOFLabel(tofLabel);
977     
978     const AliESDVertex *vtx = esd.GetPrimaryVertex();
979
980     if (!fUsedTrack[posFromV0]) {
981             fUsedTrack[posFromV0] = kTRUE;
982             UInt_t selectInfo = 0;
983             if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdV0Pos);
984             if(fMChandler)fMChandler->SelectParticle(esdV0Pos->GetLabel());
985             aodTrack = new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdV0Pos->GetID(),
986                                                     esdV0Pos->GetLabel(), 
987                                                     momPos, 
988                                                     kTRUE,
989                                                     pos,
990                                                     kFALSE,
991                                                     covTr, 
992                                                     (Short_t)esdV0Pos->GetSign(),
993                                                     esdV0Pos->GetITSClusterMap(), 
994                                                     pid,
995                                                     vV0,
996                                                     kTRUE,  // check if this is right
997                                                     vtx->UsesTrack(esdV0Pos->GetID()),
998                                                     AliAODTrack::kSecondary,
999                                                     selectInfo);
1000             aodTrack->SetTPCFitMap(esdV0Pos->GetTPCFitMap());
1001             aodTrack->SetTPCClusterMap(esdV0Pos->GetTPCClusterMap());
1002             aodTrack->SetTPCSharedMap (esdV0Pos->GetTPCSharedMap());
1003             aodTrack->SetChi2perNDF(Chi2perNDF(esdV0Pos));
1004             aodTrack->SetTPCPointsF(esdV0Pos->GetTPCNclsF());
1005             aodTrack->SetTPCNCrossedRows(UShort_t(esdV0Pos->GetTPCCrossedRows()));
1006             aodTrack->SetIntegratedLength(esdV0Pos->GetIntegratedLength());
1007             aodTrack->SetTOFLabel(tofLabel);
1008             CopyCaloProps(esdV0Pos,aodTrack);
1009             fAODTrackRefs->AddAt(aodTrack,posFromV0);
1010             //      if (fDebug > 0) printf("-------------------Bo: pos track from original pt %.3f \n",aodTrack->Pt());
1011             if (esdV0Pos->GetSign() > 0) ++fNumberOfPositiveTracks;
1012             aodTrack->ConvertAliPIDtoAODPID();
1013             aodTrack->SetFlags(esdV0Pos->GetStatus());
1014             SetAODPID(esdV0Pos,aodTrack,detpid);
1015     }
1016     else {
1017             aodTrack = static_cast<AliAODTrack*>(fAODTrackRefs->At(posFromV0));
1018             //      if (fDebug > 0) printf("-------------------Bo pos track from refArray pt %.3f \n",aodTrack->Pt());
1019     }
1020     vV0->AddDaughter(aodTrack);
1021     
1022     // Add the negative tracks from the V0
1023     
1024     esdV0Neg->GetPxPyPz(momNeg);
1025     esdV0Neg->GetXYZ(pos);
1026     esdV0Neg->GetCovarianceXYZPxPyPz(covTr);
1027     esdV0Neg->GetESDpid(pid);
1028     esdV0Neg->GetTOFLabel(tofLabel);
1029     
1030     if (!fUsedTrack[negFromV0]) {
1031             fUsedTrack[negFromV0] = kTRUE;
1032             UInt_t selectInfo = 0;
1033             if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdV0Neg);
1034             if(fMChandler)fMChandler->SelectParticle(esdV0Neg->GetLabel());
1035             aodTrack = new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdV0Neg->GetID(),
1036                                                     esdV0Neg->GetLabel(),
1037                                                     momNeg,
1038                                                     kTRUE,
1039                                                     pos,
1040                                                     kFALSE,
1041                                                     covTr, 
1042                                                     (Short_t)esdV0Neg->GetSign(),
1043                                                     esdV0Neg->GetITSClusterMap(), 
1044                                                     pid,
1045                                                     vV0,
1046                                                     kTRUE,  // check if this is right
1047                                                     vtx->UsesTrack(esdV0Neg->GetID()),
1048                                                     AliAODTrack::kSecondary,
1049                                                     selectInfo);
1050             aodTrack->SetTPCFitMap(esdV0Neg->GetTPCFitMap());
1051             aodTrack->SetTPCClusterMap(esdV0Neg->GetTPCClusterMap());
1052             aodTrack->SetTPCSharedMap (esdV0Neg->GetTPCSharedMap());
1053             aodTrack->SetChi2perNDF(Chi2perNDF(esdV0Neg));
1054             aodTrack->SetTPCPointsF(esdV0Neg->GetTPCNclsF());
1055             aodTrack->SetTPCNCrossedRows(UShort_t(esdV0Neg->GetTPCCrossedRows()));
1056             aodTrack->SetIntegratedLength(esdV0Neg->GetIntegratedLength());
1057             aodTrack->SetTOFLabel(tofLabel);
1058             CopyCaloProps(esdV0Neg,aodTrack);
1059             fAODTrackRefs->AddAt(aodTrack,negFromV0);
1060             //      if (fDebug > 0) printf("-------------------Bo: neg track from original pt %.3f \n",aodTrack->Pt());
1061             if (esdV0Neg->GetSign() > 0) ++fNumberOfPositiveTracks;
1062             aodTrack->ConvertAliPIDtoAODPID();
1063             aodTrack->SetFlags(esdV0Neg->GetStatus());
1064             SetAODPID(esdV0Neg,aodTrack,detpid);
1065     }
1066     else {
1067             aodTrack = static_cast<AliAODTrack*>(fAODTrackRefs->At(negFromV0));
1068             //      if (fDebug > 0) printf("-------------------Bo neg track from refArray pt %.3f \n",aodTrack->Pt());
1069     }
1070     vV0->AddDaughter(aodTrack);
1071     
1072     
1073     // Add the V0 the V0 array as well
1074     
1075     Double_t  dcaV0Daughters      = v0->GetDcaV0Daughters();
1076     Double_t  dcaV0ToPrimVertex   = v0->GetD(esd.GetPrimaryVertex()->GetX(),
1077                                              esd.GetPrimaryVertex()->GetY(),
1078                                              esd.GetPrimaryVertex()->GetZ());
1079     
1080     v0->GetPPxPyPz(momPosAtV0vtx[0],momPosAtV0vtx[1],momPosAtV0vtx[2]); 
1081     v0->GetNPxPyPz(momNegAtV0vtx[0],momNegAtV0vtx[1],momNegAtV0vtx[2]); 
1082     
1083     Double_t dcaDaughterToPrimVertex[2] = { 999., 999.}; // ..[0] = DCA in (x,y) for Pos and ..[1] = Neg
1084     dcaDaughterToPrimVertex[0] = TMath::Abs(esdV0Pos->GetD(  esd.GetPrimaryVertex()->GetX(),
1085                                                            esd.GetPrimaryVertex()->GetY(),
1086                                                            esd.GetMagneticField()) );
1087     dcaDaughterToPrimVertex[1] = TMath::Abs(esdV0Neg->GetD(  esd.GetPrimaryVertex()->GetX(),
1088                                                            esd.GetPrimaryVertex()->GetY(),
1089                                                            esd.GetMagneticField()) );
1090     
1091     AliAODv0* aodV0 = new(V0s()[fNumberOfV0s++]) AliAODv0(vV0, 
1092                                                 dcaV0Daughters,
1093                                                 dcaV0ToPrimVertex,
1094                                                 momPosAtV0vtx,
1095                                                 momNegAtV0vtx,
1096                                                 dcaDaughterToPrimVertex);
1097     
1098     // set the aod v0 on-the-fly status
1099     aodV0->SetOnFlyStatus(v0->GetOnFlyStatus());
1100   }//End of loop on V0s 
1101   
1102   V0s().Expand(fNumberOfV0s);    
1103 }
1104
1105 //______________________________________________________________________________
1106 void AliAnalysisTaskESDfilter::ConvertTPCOnlyTracks(const AliESDEvent& esd)
1107 {
1108   // Convert TPC only tracks
1109   // Here we have wo hybrid appraoch to remove fakes
1110   // ******* ITSTPC ********
1111   // Uses a cut on the ITS properties to select global tracks
1112   // which are than marked as HybdridITSTPC for the remainder 
1113   // the TPC only tracks are flagged as HybridITSTPConly. 
1114   // Note, in order not to get fakes back in the TPC cuts, one needs 
1115   // two "ITS" cuts one tight (1) (to throw out fakes) and one lose (2) (to NOT flag the trakcs in the TPC only)
1116   // using cut number (3)
1117   // so fHybridFilterMask == (1)|(2) fTPCFilterMask = (3), Usercode needs to slect with mask = (1)|(3) and track->IsHybridITSTPC()
1118   // ******* TPC ********
1119   // Here, only TPC tracks are flagged that pass the tight ITS cuts and tracks that pass the TPC cuts and NOT the loose ITS cuts
1120   // the ITS cuts neeed to be added to the filter as extra cuts, since here the selections info is reset in the global and put to the TPC only track
1121
1122   AliCodeTimerAuto("",0);
1123   
1124   // Loop over the tracks and extract and mask out all aod tracks that pass the selections for AODt racks
1125   for(int it = 0;it < fNumberOfTracks;++it)
1126   {
1127     AliAODTrack *tr = (AliAODTrack*)(Tracks().At(it));
1128     if(!tr)continue;
1129     UInt_t map = tr->GetFilterMap();
1130     if(map&fTPCConstrainedFilterMask){
1131       // we only reset the track select ionfo, no deletion...
1132       tr->SetFilterMap(map&~fTPCConstrainedFilterMask);
1133     }
1134     if(map&fHybridFilterMaskTPCCG){
1135       // this is one part of the hybrid tracks
1136       // the others not passing the selection will be TPC only selected below
1137       tr->SetIsHybridTPCConstrainedGlobal(kTRUE);
1138     }
1139   }
1140   // Loop over the ESD trcks and pick out the tracks passing TPC only cuts
1141   
1142   
1143   const AliESDVertex *vtxSPD = esd.GetPrimaryVertexSPD();
1144   const AliESDVertex *vtx = esd.GetPrimaryVertex();
1145
1146   Double_t pos[3] = { 0. };      
1147   Double_t covTr[21]={0.};
1148   Double_t pid[10]={0.};  
1149
1150
1151   Double_t p[3] = { 0. };
1152
1153   Double_t pDCA[3] = { 0. }; // momentum at DCA
1154   Double_t rDCA[3] = { 0. }; // position at DCA
1155   Float_t  dDCA[2] = {0.};    // DCA to the vertex d and z
1156   Float_t  cDCA[3] = {0.};    // covariance of impact parameters
1157   Int_t    tofLabel[3] = {0};
1158
1159   AliAODTrack* aodTrack(0x0);
1160   //  AliAODPid* detpid(0x0);
1161
1162   // account for change in pT after the constraint
1163   Float_t ptMax = 1E10;
1164   Float_t ptMin = 0;
1165   for(int i = 0;i<32;i++){
1166     if(fTPCConstrainedFilterMask&(1<<i)){
1167       AliESDtrackCuts*cuts = (AliESDtrackCuts*)fTrackFilter->GetCuts()->At(i);
1168       Float_t tmp1= 0,tmp2 = 0;
1169       cuts->GetPtRange(tmp1,tmp2);
1170       if(tmp1>ptMin)ptMin=tmp1;
1171       if(tmp2<ptMax)ptMax=tmp2;
1172     }
1173   } 
1174
1175   for (Int_t nTrack = 0; nTrack < esd.GetNumberOfTracks(); ++nTrack) 
1176   {
1177     AliESDtrack* esdTrack = esd.GetTrack(nTrack); //carefull do not modify it othwise  need to work with a copy 
1178     
1179     UInt_t selectInfo = 0;
1180     Bool_t isHybridITSTPC = false;
1181     //
1182     // Track selection
1183     if (fTrackFilter) {
1184       selectInfo = fTrackFilter->IsSelected(esdTrack);
1185     }
1186
1187     if(!(selectInfo&fHybridFilterMaskTPCCG)){
1188       // not already selected tracks, use second part of hybrid tracks
1189       isHybridITSTPC = true;
1190       // too save space one could only store these...
1191     }
1192
1193     selectInfo &= fTPCConstrainedFilterMask;
1194     if (!selectInfo)continue;
1195     if (fWriteHybridTPCCOnly&&!isHybridITSTPC)continue; // write only complementary tracks
1196     // create a tpc only tracl
1197     AliESDtrack *track = AliESDtrackCuts::GetTPCOnlyTrack(const_cast<AliESDEvent*>(&esd),esdTrack->GetID());
1198     if(!track) continue;
1199     
1200     if(track->Pt()>0.)
1201     {
1202       // only constrain tracks above threshold
1203       AliExternalTrackParam exParam;
1204       // take the B-field from the ESD, no 3D fieldMap available at this point
1205       Bool_t relate = false;
1206       relate = track->RelateToVertexTPC(vtxSPD,esd.GetMagneticField(),kVeryBig,&exParam);
1207       if(!relate){
1208         delete track;
1209         continue;
1210       }
1211       // fetch the track parameters at the DCA (unconstraint)
1212       if(track->GetTPCInnerParam()){
1213         track->GetTPCInnerParam()->GetPxPyPz(pDCA);
1214         track->GetTPCInnerParam()->GetXYZ(rDCA);
1215       }
1216       // get the DCA to the vertex:
1217       track->GetImpactParametersTPC(dDCA,cDCA);
1218       // set the constrained parameters to the track
1219       track->Set(exParam.GetX(),exParam.GetAlpha(),exParam.GetParameter(),exParam.GetCovariance());
1220     }
1221     
1222     track->GetPxPyPz(p);
1223
1224     Float_t pT = track->Pt();
1225     if(pT<ptMin||pT>ptMax){
1226       delete track;
1227       continue;
1228     }
1229
1230     // 
1231
1232
1233     track->GetXYZ(pos);
1234     track->GetCovarianceXYZPxPyPz(covTr);
1235     esdTrack->GetESDpid(pid);// original PID
1236     esdTrack->GetTOFLabel(tofLabel);
1237     if(fMChandler)fMChandler->SelectParticle(esdTrack->GetLabel());
1238     fUsedTrackCopy[nTrack] |= selectInfo;
1239     aodTrack = new(Tracks()[fNumberOfTracks++]) AliAODTrack((track->GetID()+1)*-1,
1240                                                             track->GetLabel(),
1241                                                             p,
1242                                                             kTRUE,
1243                                                             pos,
1244                                                             kFALSE,
1245                                                             covTr, 
1246                                                             (Short_t)track->GetSign(),
1247                                                             track->GetITSClusterMap(), 
1248                                                             pid,
1249                                                             fPrimaryVertex,
1250                                                             kTRUE, // check if this is right
1251                                                             vtx->UsesTrack(track->GetID()),
1252                                                             AliAODTrack::kPrimary, 
1253                                                             selectInfo);
1254     aodTrack->SetIsHybridTPCConstrainedGlobal(isHybridITSTPC);    
1255     aodTrack->SetTPCFitMap(track->GetTPCFitMap());
1256     aodTrack->SetTPCClusterMap(track->GetTPCClusterMap());
1257     aodTrack->SetTPCSharedMap (track->GetTPCSharedMap());
1258     aodTrack->SetIsTPCConstrained(kTRUE);    
1259     aodTrack->SetChi2perNDF(Chi2perNDF(esdTrack)); // original track
1260     // set the DCA values to the AOD track
1261     aodTrack->SetPxPyPzAtDCA(pDCA[0],pDCA[1],pDCA[2]);
1262     aodTrack->SetXYAtDCA(rDCA[0],rDCA[1]);
1263     aodTrack->SetDCA(dDCA[0],dDCA[1]);
1264
1265     aodTrack->SetFlags(track->GetStatus());
1266     aodTrack->SetTPCPointsF(track->GetTPCNclsF());
1267     aodTrack->SetTPCNCrossedRows(UShort_t(track->GetTPCCrossedRows()));
1268     aodTrack->SetIntegratedLength(track->GetIntegratedLength());
1269     aodTrack->SetTOFLabel(tofLabel);
1270     CopyCaloProps(track,aodTrack);
1271   
1272     // do not duplicate PID information 
1273     //    aodTrack->ConvertAliPIDtoAODPID();
1274     //    SetAODPID(esdTrack,aodTrack,detpid);
1275
1276     delete track;
1277   } // end of loop on tracks
1278   
1279 }
1280
1281 //______________________________________________________________________________
1282 void AliAnalysisTaskESDfilter::ConvertGlobalConstrainedTracks(const AliESDEvent& esd)
1283 {
1284
1285   // Here we have the option to store the complement from global constraint information
1286   // to tracks passing tight cuts (1) in order not to get fakes back in, one needs 
1287   // two sets of cuts one tight (1) (to throw out fakes) and one lose (2) (fakes/bad tracks would pass (2) but not (1))
1288   // using cut number (3) selects the tracks that complement (1) e.g. tracks witout ITS refit or cluster requirement
1289
1290
1291   AliCodeTimerAuto("",0);
1292   
1293   // Loop over the tracks and extract and mask out all aod tracks that pass the selections for AODt racks
1294   for(int it = 0;it < fNumberOfTracks;++it)
1295   {
1296     AliAODTrack *tr = (AliAODTrack*)(Tracks().At(it));
1297     if(!tr)continue;
1298     UInt_t map = tr->GetFilterMap();
1299     if(map&fGlobalConstrainedFilterMask){
1300       // we only reset the track select info, no deletion...
1301       // mask reset mask in case track is already taken
1302       tr->SetFilterMap(map&~fGlobalConstrainedFilterMask);
1303     }
1304     if(map&fHybridFilterMaskGCG){
1305       // this is one part of the hybrid tracks
1306       // the others not passing the selection will be the ones selected below
1307       tr->SetIsHybridGlobalConstrainedGlobal(kTRUE);
1308     }
1309   }
1310   // Loop over the ESD trcks and pick out the tracks passing the GlobalConstraint cuts
1311  
1312
1313   Double_t pos[3] = { 0. };      
1314   Double_t covTr[21]={0.};
1315   Double_t pid[10]={0.};  
1316   Double_t p[3] = { 0. };
1317
1318   Double_t pDCA[3] = { 0. }; // momentum at DCA
1319   Double_t rDCA[3] = { 0. }; // position at DCA
1320   Float_t  dDCA[2] = {0.};    // DCA to the vertex d and z
1321   Float_t  cDCA[3] = {0.};    // covariance of impact parameters
1322   Int_t    tofLabel[3] = {0};
1323
1324
1325   AliAODTrack* aodTrack(0x0);
1326   AliAODPid* detpid(0x0);
1327   const AliESDVertex *vtx = esd.GetPrimaryVertex();
1328
1329   // account for change in pT after the constraint
1330   Float_t ptMax = 1E10;
1331   Float_t ptMin = 0;
1332   for(int i = 0;i<32;i++){
1333     if(fGlobalConstrainedFilterMask&(1<<i)){
1334       AliESDtrackCuts*cuts = (AliESDtrackCuts*)fTrackFilter->GetCuts()->At(i);
1335       Float_t tmp1= 0,tmp2 = 0;
1336       cuts->GetPtRange(tmp1,tmp2);
1337       if(tmp1>ptMin)ptMin=tmp1;
1338       if(tmp2<ptMax)ptMax=tmp2;
1339     }
1340   } 
1341
1342
1343
1344  for (Int_t nTrack = 0; nTrack < esd.GetNumberOfTracks(); ++nTrack) 
1345   {
1346     AliESDtrack* esdTrack = esd.GetTrack(nTrack); //carefull do not modify it othwise  need to work with a copy 
1347     const AliExternalTrackParam * exParamGC = esdTrack->GetConstrainedParam();
1348     if(!exParamGC)continue;
1349
1350     UInt_t selectInfo = 0;
1351     Bool_t isHybridGC = false;
1352
1353     //
1354     // Track selection
1355     if (fTrackFilter) {
1356       selectInfo = fTrackFilter->IsSelected(esdTrack);
1357     }
1358
1359
1360     if(!(selectInfo&fHybridFilterMaskGCG))isHybridGC = true;
1361     if (fWriteHybridGCOnly&&!isHybridGC)continue; // write only complementary tracks
1362
1363     selectInfo &= fGlobalConstrainedFilterMask;
1364     if (!selectInfo)continue;
1365     // fetch the track parameters at the DCA (unconstrained)
1366     esdTrack->GetPxPyPz(pDCA);
1367     esdTrack->GetXYZ(rDCA);
1368     // get the DCA to the vertex:
1369     esdTrack->GetImpactParameters(dDCA,cDCA);
1370
1371     if (!esdTrack->GetConstrainedPxPyPz(p)) continue;
1372
1373
1374     Float_t pT = exParamGC->Pt();
1375     if(pT<ptMin||pT>ptMax){
1376       continue;
1377     }
1378
1379
1380     esdTrack->GetConstrainedXYZ(pos);
1381     exParamGC->GetCovarianceXYZPxPyPz(covTr);
1382     esdTrack->GetESDpid(pid);
1383     esdTrack->GetTOFLabel(tofLabel); 
1384     if(fMChandler)fMChandler->SelectParticle(esdTrack->GetLabel());
1385     fUsedTrackCopy[nTrack] |= selectInfo;
1386     aodTrack = new(Tracks()[fNumberOfTracks++]) AliAODTrack((esdTrack->GetID()+1)*-1,
1387                                                             esdTrack->GetLabel(),
1388                                                             p,
1389                                                             kTRUE,
1390                                                             pos,
1391                                                             kFALSE,
1392                                                             covTr, 
1393                                                             (Short_t)esdTrack->GetSign(),
1394                                                             esdTrack->GetITSClusterMap(), 
1395                                                             pid,
1396                                                             fPrimaryVertex,
1397                                                             kTRUE, // check if this is right
1398                                                             vtx->UsesTrack(esdTrack->GetID()),
1399                                                             AliAODTrack::kPrimary, 
1400                                                             selectInfo);
1401     aodTrack->SetIsHybridGlobalConstrainedGlobal(isHybridGC);    
1402     aodTrack->SetIsGlobalConstrained(kTRUE);    
1403     aodTrack->SetTPCFitMap(esdTrack->GetTPCFitMap());
1404     aodTrack->SetTPCClusterMap(esdTrack->GetTPCClusterMap());
1405     aodTrack->SetTPCSharedMap (esdTrack->GetTPCSharedMap());
1406     aodTrack->SetChi2perNDF(Chi2perNDF(esdTrack));
1407
1408     // set the DCA values to the AOD track
1409     aodTrack->SetPxPyPzAtDCA(pDCA[0],pDCA[1],pDCA[2]);
1410     aodTrack->SetXYAtDCA(rDCA[0],rDCA[1]);
1411     aodTrack->SetDCA(dDCA[0],dDCA[1]);
1412     aodTrack->SetFlags(esdTrack->GetStatus());
1413     aodTrack->SetTPCPointsF(esdTrack->GetTPCNclsF());
1414     aodTrack->SetTPCNCrossedRows(UShort_t(esdTrack->GetTPCCrossedRows()));
1415     aodTrack->SetIntegratedLength(esdTrack->GetIntegratedLength());
1416     aodTrack->SetTOFLabel(tofLabel);
1417     CopyCaloProps(esdTrack,aodTrack);
1418     if(isHybridGC){
1419       // only copy AOD information for hybrid, no duplicate information
1420       aodTrack->ConvertAliPIDtoAODPID();
1421       SetAODPID(esdTrack,aodTrack,detpid);
1422     }
1423   } // end of loop on tracks
1424   
1425 }
1426
1427
1428 //______________________________________________________________________________
1429 void AliAnalysisTaskESDfilter::ConvertTracks(const AliESDEvent& esd)
1430 {
1431   // Tracks (primary and orphan)
1432
1433   AliCodeTimerAuto("",0);
1434   
1435   AliDebug(1,Form("NUMBER OF ESD TRACKS %5d\n", esd.GetNumberOfTracks()));
1436   
1437   const AliESDVertex *vtx = esd.GetPrimaryVertex();
1438   Double_t p[3] = { 0. };
1439   Double_t pos[3] = { 0. };
1440   Double_t covTr[21] = { 0. };
1441   Double_t pid[10] = { 0. };
1442   Int_t    tofLabel[3] = {0};
1443   AliAODTrack* aodTrack(0x0);
1444   AliAODPid* detpid(0x0);
1445   
1446   for (Int_t nTrack = 0; nTrack < esd.GetNumberOfTracks(); ++nTrack) 
1447   {
1448     if (fUsedTrack[nTrack]) continue;
1449     
1450     AliESDtrack *esdTrack = esd.GetTrack(nTrack);
1451     UInt_t selectInfo = 0;
1452     //
1453     // Track selection
1454     if (fTrackFilter) {
1455             selectInfo = fTrackFilter->IsSelected(esdTrack);
1456             if (!selectInfo && !vtx->UsesTrack(esdTrack->GetID())) continue;
1457     }
1458     
1459     
1460     esdTrack->GetPxPyPz(p);
1461     esdTrack->GetXYZ(pos);
1462     esdTrack->GetCovarianceXYZPxPyPz(covTr);
1463     esdTrack->GetESDpid(pid);
1464     esdTrack->GetTOFLabel(tofLabel);
1465     if(fMChandler)fMChandler->SelectParticle(esdTrack->GetLabel());
1466     fUsedTrack[nTrack] = kTRUE;
1467     fPrimaryVertex->AddDaughter(aodTrack =
1468                          new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdTrack->GetID(),
1469                                                             esdTrack->GetLabel(),
1470                                                             p,
1471                                                             kTRUE,
1472                                                             pos,
1473                                                             kFALSE,
1474                                                             covTr, 
1475                                                             (Short_t)esdTrack->GetSign(),
1476                                                             esdTrack->GetITSClusterMap(), 
1477                                                             pid,
1478                                                             fPrimaryVertex,
1479                                                             kTRUE, // check if this is right
1480                                                             vtx->UsesTrack(esdTrack->GetID()),
1481                                                             AliAODTrack::kPrimary, 
1482                                                             selectInfo)
1483                          );
1484     aodTrack->SetTPCFitMap(esdTrack->GetTPCFitMap());
1485     aodTrack->SetTPCClusterMap(esdTrack->GetTPCClusterMap());
1486     aodTrack->SetTPCSharedMap (esdTrack->GetTPCSharedMap());
1487     aodTrack->SetChi2perNDF(Chi2perNDF(esdTrack));
1488     aodTrack->SetTPCPointsF(esdTrack->GetTPCNclsF());
1489     aodTrack->SetTPCNCrossedRows(UShort_t(esdTrack->GetTPCCrossedRows()));
1490     aodTrack->SetIntegratedLength(esdTrack->GetIntegratedLength());
1491     aodTrack->SetTOFLabel(tofLabel);
1492     CopyCaloProps(esdTrack,aodTrack);
1493
1494     fAODTrackRefs->AddAt(aodTrack, nTrack);
1495     
1496     if (esdTrack->GetSign() > 0) ++fNumberOfPositiveTracks;
1497     aodTrack->SetFlags(esdTrack->GetStatus());
1498     aodTrack->ConvertAliPIDtoAODPID();
1499     SetAODPID(esdTrack,aodTrack,detpid);
1500   } // end of loop on tracks
1501 }
1502
1503 //______________________________________________________________________________
1504 void AliAnalysisTaskESDfilter::ConvertPmdClusters(const AliESDEvent& esd)
1505 {
1506 // Convert PMD Clusters 
1507   AliCodeTimerAuto("",0);
1508   Int_t jPmdClusters=0;
1509   // Access to the AOD container of PMD clusters
1510   TClonesArray &pmdClusters = *(AODEvent()->GetPmdClusters());
1511   for (Int_t iPmd = 0; iPmd < esd.GetNumberOfPmdTracks(); ++iPmd) {
1512     // file pmd clusters, to be revised!
1513     AliESDPmdTrack *pmdTrack = esd.GetPmdTrack(iPmd);
1514     Int_t nLabel = 0;
1515     Int_t *label = 0x0;
1516     Double_t posPmd[3] = { pmdTrack->GetClusterX(), pmdTrack->GetClusterY(), pmdTrack->GetClusterZ()};
1517     Double_t pidPmd[13] = { 0.}; // to be revised!
1518     // type not set!
1519     // assoc cluster not set
1520     new(pmdClusters[jPmdClusters++]) AliAODPmdCluster(iPmd, nLabel, label, pmdTrack->GetClusterADC(), posPmd, pidPmd);
1521   }
1522 }
1523
1524
1525 //______________________________________________________________________________
1526 void AliAnalysisTaskESDfilter::ConvertCaloClusters(const AliESDEvent& esd)
1527 {
1528 // Convert Calorimeter Clusters
1529   AliCodeTimerAuto("",0);
1530   
1531   // Access to the AOD container of clusters
1532   TClonesArray &caloClusters = *(AODEvent()->GetCaloClusters());
1533   Int_t jClusters(0);
1534   
1535   for (Int_t iClust=0; iClust<esd.GetNumberOfCaloClusters(); ++iClust) {
1536     
1537     AliESDCaloCluster * cluster = esd.GetCaloCluster(iClust);
1538     
1539     Int_t  id        = cluster->GetID();
1540     Int_t  nLabel    = cluster->GetNLabels();
1541     Int_t *labels    = cluster->GetLabels();
1542     if(labels){ 
1543                   for(int i = 0;i < nLabel;++i){
1544                           if(fMChandler)fMChandler->SelectParticle(labels[i]);
1545                   }
1546           }             
1547     
1548     Float_t energy = cluster->E();
1549     Float_t posF[3] = { 0.};
1550     cluster->GetPosition(posF);
1551     
1552     AliAODCaloCluster *caloCluster = new(caloClusters[jClusters++]) AliAODCaloCluster(id,
1553                                                                                       nLabel,
1554                                                                                       labels,
1555                                                                                       energy,
1556                                                                                       posF,
1557                                                                                       NULL,
1558                                                                                       cluster->GetType(),0);
1559     
1560     caloCluster->SetCaloCluster(cluster->GetDistanceToBadChannel(),
1561                                 cluster->GetDispersion(),
1562                                 cluster->GetM20(), cluster->GetM02(),
1563                                 cluster->GetEmcCpvDistance(),  
1564                                 cluster->GetNExMax(),cluster->GetTOF()) ;
1565     
1566     caloCluster->SetPIDFromESD(cluster->GetPID());
1567     caloCluster->SetNCells(cluster->GetNCells());
1568     caloCluster->SetCellsAbsId(cluster->GetCellsAbsId());
1569     caloCluster->SetCellsAmplitudeFraction(cluster->GetCellsAmplitudeFraction());
1570
1571     caloCluster->SetTrackDistance(cluster->GetTrackDx(), cluster->GetTrackDz());
1572     
1573     Int_t nMatchCount = 0;
1574     TArrayI* matchedT =         cluster->GetTracksMatched();
1575     if (fNumberOfTracks>0 && matchedT && cluster->GetTrackMatchedIndex() >= 0) {        
1576       for (Int_t im = 0; im < matchedT->GetSize(); im++) {
1577         Int_t iESDtrack = matchedT->At(im);;
1578         if (fAODTrackRefs->At(iESDtrack) != 0) {
1579           caloCluster->AddTrackMatched((AliAODTrack*)fAODTrackRefs->At(iESDtrack));
1580           nMatchCount++;
1581         }
1582       }
1583     }
1584     if(nMatchCount==0)
1585       caloCluster->SetTrackDistance(-999,-999);
1586     
1587   } 
1588   caloClusters.Expand(jClusters); // resize TObjArray to 'remove' slots for pseudo clusters      
1589 }
1590
1591 //______________________________________________________________________________
1592 void AliAnalysisTaskESDfilter::ConvertCaloTrigger(TString calo, const AliESDEvent& esd)
1593 {
1594         AliCodeTimerAuto("",0);
1595                 
1596         if (calo == "PHOS") 
1597         {
1598           AliAODCaloTrigger &aodTrigger = *(AODEvent()->GetCaloTrigger(calo));
1599           AliESDCaloTrigger &esdTrigger = *(esd.GetCaloTrigger(calo));
1600
1601           aodTrigger.Allocate(esdTrigger.GetEntries());
1602           esdTrigger.Reset();
1603
1604           Float_t a;
1605           Int_t tmod,tabsId;
1606
1607           while (esdTrigger.Next()) {
1608             esdTrigger.GetPosition(tmod,tabsId);
1609             esdTrigger.GetAmplitude(a);
1610             aodTrigger.Add(tmod,tabsId,a,0.,(Int_t*)NULL,0,0,0);
1611           }
1612
1613           return;
1614         }
1615                         
1616         AliAODHandler *aodHandler = dynamic_cast<AliAODHandler*>(AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()); 
1617                         
1618         if (aodHandler)
1619         {
1620                 TTree *aodTree = aodHandler->GetTree();
1621                                         
1622                 if (aodTree)
1623                 {
1624                         Int_t *type = esd.GetCaloTriggerType();
1625                                                         
1626                         for (Int_t i = 0; i < 15; i++) 
1627                         {
1628                                 aodTree->GetUserInfo()->Add(new TParameter<int>(Form("EMCALCaloTrigger%d",i), type[i]));
1629                         }
1630                 }
1631         }
1632                                                 
1633         AliAODCaloTrigger &aodTrigger = *(AODEvent()->GetCaloTrigger(calo));
1634                                                 
1635         AliESDCaloTrigger &esdTrigger = *(esd.GetCaloTrigger(calo));
1636                                                 
1637         aodTrigger.Allocate(esdTrigger.GetEntries());
1638                                                 
1639         esdTrigger.Reset();
1640         while (esdTrigger.Next())
1641         {         
1642                 Int_t px, py, ts, nTimes, times[10], b; 
1643                 Float_t a, t;
1644                                                                 
1645                 esdTrigger.GetPosition(px, py);
1646                                                 
1647                 esdTrigger.GetAmplitude(a);
1648                 esdTrigger.GetTime(t);
1649                                                                 
1650                 esdTrigger.GetL0Times(times);
1651                 esdTrigger.GetNL0Times(nTimes);
1652                                                                 
1653                 esdTrigger.GetL1TimeSum(ts);
1654                                                                 
1655                 esdTrigger.GetTriggerBits(b);
1656                                                                 
1657                 aodTrigger.Add(px, py, a, t, times, nTimes, ts, b);
1658         }
1659                                                         
1660         for (int i = 0; i < 4; i++) aodTrigger.SetL1Threshold(i, esdTrigger.GetL1Threshold(i));
1661                                                         
1662         Int_t v0[2] = 
1663         {
1664                 esdTrigger.GetL1V0(0),
1665                 esdTrigger.GetL1V0(1)
1666         };              
1667                                                                 
1668         aodTrigger.SetL1V0(v0); 
1669         aodTrigger.SetL1FrameMask(esdTrigger.GetL1FrameMask());
1670 }
1671
1672 //______________________________________________________________________________
1673 void AliAnalysisTaskESDfilter::ConvertEMCALCells(const AliESDEvent& esd)
1674 {
1675 // Convert EMCAL Cells
1676   AliCodeTimerAuto("",0);
1677   // fill EMCAL cell info
1678   if (esd.GetEMCALCells()) { // protection against missing ESD information
1679     AliESDCaloCells &esdEMcells = *(esd.GetEMCALCells());
1680     Int_t nEMcell = esdEMcells.GetNumberOfCells() ;
1681     
1682     AliAODCaloCells &aodEMcells = *(AODEvent()->GetEMCALCells());
1683     aodEMcells.CreateContainer(nEMcell);
1684     aodEMcells.SetType(AliAODCaloCells::kEMCALCell);
1685     for (Int_t iCell = 0; iCell < nEMcell; iCell++) {      
1686       aodEMcells.SetCell(iCell,esdEMcells.GetCellNumber(iCell),esdEMcells.GetAmplitude(iCell),
1687                          esdEMcells.GetTime(iCell), esdEMcells.GetMCLabel(iCell), esdEMcells.GetEFraction(iCell));
1688     }
1689     aodEMcells.Sort();
1690   }
1691 }
1692
1693 //______________________________________________________________________________
1694 void AliAnalysisTaskESDfilter::ConvertPHOSCells(const AliESDEvent& esd)
1695 {
1696 // Convert PHOS Cells
1697   AliCodeTimerAuto("",0);
1698   // fill PHOS cell info
1699   if (esd.GetPHOSCells()) { // protection against missing ESD information
1700     AliESDCaloCells &esdPHcells = *(esd.GetPHOSCells());
1701     Int_t nPHcell = esdPHcells.GetNumberOfCells() ;
1702     
1703     AliAODCaloCells &aodPHcells = *(AODEvent()->GetPHOSCells());
1704     aodPHcells.CreateContainer(nPHcell);
1705     aodPHcells.SetType(AliAODCaloCells::kPHOSCell);
1706     for (Int_t iCell = 0; iCell < nPHcell; iCell++) {      
1707       aodPHcells.SetCell(iCell,esdPHcells.GetCellNumber(iCell),esdPHcells.GetAmplitude(iCell),
1708                          esdPHcells.GetTime(iCell), esdPHcells.GetMCLabel(iCell), esdPHcells.GetEFraction(iCell));
1709     }
1710     aodPHcells.Sort();
1711   }
1712 }
1713
1714 //______________________________________________________________________________
1715 void AliAnalysisTaskESDfilter::ConvertTracklets(const AliESDEvent& esd)
1716 {
1717   // tracklets    
1718   AliCodeTimerAuto("",0);
1719
1720   AliAODTracklets &SPDTracklets = *(AODEvent()->GetTracklets());
1721   const AliMultiplicity *mult = esd.GetMultiplicity();
1722   if (mult) {
1723     if (mult->GetNumberOfTracklets()>0) {
1724       SPDTracklets.CreateContainer(mult->GetNumberOfTracklets());
1725       
1726       for (Int_t n=0; n<mult->GetNumberOfTracklets(); n++) {
1727         if(fMChandler){
1728           fMChandler->SelectParticle(mult->GetLabel(n, 0));
1729           fMChandler->SelectParticle(mult->GetLabel(n, 1));
1730         }
1731         SPDTracklets.SetTracklet(n, mult->GetTheta(n), mult->GetPhi(n), mult->GetDeltaPhi(n), mult->GetLabel(n, 0),mult->GetLabel(n, 1));
1732       }
1733     }
1734   } else {
1735     //Printf("ERROR: AliMultiplicity could not be retrieved from ESD");
1736   }
1737 }
1738
1739 //______________________________________________________________________________
1740 void AliAnalysisTaskESDfilter::ConvertKinks(const AliESDEvent& esd)
1741 {
1742   AliCodeTimerAuto("",0);
1743   
1744   // Kinks: it is a big mess the access to the information in the kinks
1745   // The loop is on the tracks in order to find the mother and daugther of each kink
1746   
1747   Double_t covTr[21]={0.};
1748   Double_t pid[10]={0.};
1749   AliAODPid* detpid(0x0);
1750   Int_t tofLabel[3] = {0};
1751   
1752   fNumberOfKinks = esd.GetNumberOfKinks();
1753
1754   const AliESDVertex* vtx = esd.GetPrimaryVertex();
1755   
1756   for (Int_t iTrack=0; iTrack<esd.GetNumberOfTracks(); ++iTrack) 
1757   {
1758     AliESDtrack * esdTrack = esd.GetTrack(iTrack);
1759     
1760     Int_t ikink = esdTrack->GetKinkIndex(0);
1761     
1762     if (ikink && fNumberOfKinks) {
1763             // Negative kink index: mother, positive: daughter
1764             
1765             // Search for the second track of the kink
1766             
1767             for (Int_t jTrack = iTrack+1; jTrack<esd.GetNumberOfTracks(); ++jTrack) {
1768         
1769         AliESDtrack * esdTrack1 = esd.GetTrack(jTrack);
1770         
1771         Int_t jkink = esdTrack1->GetKinkIndex(0);
1772         
1773         if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
1774           
1775           // The two tracks are from the same kink
1776           
1777           if (fUsedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
1778           
1779           Int_t imother = -1;
1780           Int_t idaughter = -1;
1781           
1782           if (ikink<0 && jkink>0) {
1783             
1784             imother = iTrack;
1785             idaughter = jTrack;
1786           }
1787           else if (ikink>0 && jkink<0) {
1788             
1789             imother = jTrack;
1790             idaughter = iTrack;
1791           }
1792           else {
1793             //                  cerr << "Error: Wrong combination of kink indexes: "
1794             //                       << ikink << " " << jkink << endl;
1795             continue;
1796           }
1797           
1798           // Add the mother track if it passed primary track selection cuts
1799           
1800           AliAODTrack * mother = NULL;
1801           
1802           UInt_t selectInfo = 0;
1803           if (fTrackFilter) {
1804             selectInfo = fTrackFilter->IsSelected(esd.GetTrack(imother));
1805             if (!selectInfo) continue;
1806           }
1807           
1808           if (!fUsedTrack[imother]) {
1809             
1810             fUsedTrack[imother] = kTRUE;
1811             
1812             AliESDtrack *esdTrackM = esd.GetTrack(imother);
1813             Double_t p[3] = { 0. };
1814             Double_t pos[3] = { 0. };
1815             esdTrackM->GetPxPyPz(p);
1816             esdTrackM->GetXYZ(pos);
1817             esdTrackM->GetCovarianceXYZPxPyPz(covTr);
1818             esdTrackM->GetESDpid(pid);
1819             esdTrackM->GetTOFLabel(tofLabel);
1820             if(fMChandler)fMChandler->SelectParticle(esdTrackM->GetLabel());
1821             mother = 
1822             new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdTrackM->GetID(),
1823                                                esdTrackM->GetLabel(),
1824                                                p,
1825                                                kTRUE,
1826                                                pos,
1827                                                kFALSE,
1828                                                covTr, 
1829                                                (Short_t)esdTrackM->GetSign(),
1830                                                esdTrackM->GetITSClusterMap(), 
1831                                                pid,
1832                                                fPrimaryVertex,
1833                                                kTRUE, // check if this is right
1834                                                vtx->UsesTrack(esdTrack->GetID()),
1835                                                AliAODTrack::kPrimary,
1836                                                selectInfo);
1837             mother->SetTPCFitMap(esdTrackM->GetTPCFitMap());
1838             mother->SetTPCClusterMap(esdTrackM->GetTPCClusterMap());
1839             mother->SetTPCSharedMap (esdTrackM->GetTPCSharedMap());
1840             mother->SetChi2perNDF(Chi2perNDF(esdTrackM));
1841             mother->SetTPCPointsF(esdTrackM->GetTPCNclsF());
1842             mother->SetTPCNCrossedRows(UShort_t(esdTrackM->GetTPCCrossedRows()));
1843             mother->SetIntegratedLength(esdTrackM->GetIntegratedLength());
1844             mother->SetTOFLabel(tofLabel);
1845             CopyCaloProps(esdTrackM,mother);
1846             fAODTrackRefs->AddAt(mother, imother);
1847             
1848             if (esdTrackM->GetSign() > 0) ++fNumberOfPositiveTracks;
1849             mother->SetFlags(esdTrackM->GetStatus());
1850             mother->ConvertAliPIDtoAODPID();
1851             fPrimaryVertex->AddDaughter(mother);
1852             mother->ConvertAliPIDtoAODPID();
1853             SetAODPID(esdTrackM,mother,detpid);
1854           }
1855           else {
1856             //                  cerr << "Error: event " << esd.GetEventNumberInFile() << " kink " << TMath::Abs(ikink)-1
1857             //                       << " track " << imother << " has already been used!" << endl;
1858           }
1859           
1860           // Add the kink vertex
1861           AliESDkink * kink = esd.GetKink(TMath::Abs(ikink)-1);
1862           
1863           AliAODVertex * vkink = 
1864           new(Vertices()[fNumberOfVertices++]) AliAODVertex(kink->GetPosition(),
1865                                                   NULL,
1866                                                   0.,
1867                                                   mother,
1868                                                   esdTrack->GetID(),  // This is the track ID of the mother's track!
1869                                                   AliAODVertex::kKink);
1870           // Add the daughter track
1871           
1872           AliAODTrack * daughter = NULL;
1873           
1874           if (!fUsedTrack[idaughter]) {
1875             
1876             fUsedTrack[idaughter] = kTRUE;
1877             
1878             AliESDtrack *esdTrackD = esd.GetTrack(idaughter);
1879             Double_t p[3] = { 0. };
1880             Double_t pos[3] = { 0. };
1881
1882             esdTrackD->GetPxPyPz(p);
1883             esdTrackD->GetXYZ(pos);
1884             esdTrackD->GetCovarianceXYZPxPyPz(covTr);
1885             esdTrackD->GetESDpid(pid);
1886             esdTrackD->GetTOFLabel(tofLabel);
1887             selectInfo = 0;
1888             if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdTrackD);
1889             if(fMChandler)fMChandler->SelectParticle(esdTrackD->GetLabel());
1890             daughter = 
1891             new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdTrackD->GetID(),
1892                                                esdTrackD->GetLabel(),
1893                                                p,
1894                                                kTRUE,
1895                                                pos,
1896                                                kFALSE,
1897                                                covTr, 
1898                                                (Short_t)esdTrackD->GetSign(),
1899                                                esdTrackD->GetITSClusterMap(), 
1900                                                pid,
1901                                                vkink,
1902                                                kTRUE, // check if this is right
1903                                                vtx->UsesTrack(esdTrack->GetID()),
1904                                                AliAODTrack::kSecondary,
1905                                                selectInfo);
1906             daughter->SetTPCFitMap(esdTrackD->GetTPCFitMap());
1907             daughter->SetTPCClusterMap(esdTrackD->GetTPCClusterMap());
1908             daughter->SetTPCSharedMap (esdTrackD->GetTPCSharedMap());
1909             daughter->SetTPCPointsF(esdTrackD->GetTPCNclsF());
1910             daughter->SetTPCNCrossedRows(UShort_t(esdTrackD->GetTPCCrossedRows()));
1911             daughter->SetIntegratedLength(esdTrackD->GetIntegratedLength());
1912             daughter->SetTOFLabel(tofLabel);
1913             CopyCaloProps(esdTrackD,daughter);
1914             fAODTrackRefs->AddAt(daughter, idaughter);
1915             
1916             if (esdTrackD->GetSign() > 0) ++fNumberOfPositiveTracks;
1917             daughter->SetFlags(esdTrackD->GetStatus());
1918             daughter->ConvertAliPIDtoAODPID();
1919             vkink->AddDaughter(daughter);
1920             daughter->ConvertAliPIDtoAODPID();
1921             SetAODPID(esdTrackD,daughter,detpid);
1922           }
1923           else {
1924             //                  cerr << "Error: event " << esd.GetEventNumberInFile() << " kink " << TMath::Abs(ikink)-1
1925             //                       << " track " << idaughter << " has already been used!" << endl;
1926           }
1927         }
1928             }
1929     }      
1930   }
1931 }
1932
1933 //______________________________________________________________________________
1934 void AliAnalysisTaskESDfilter::ConvertPrimaryVertices(const AliESDEvent& esd)
1935 {
1936   AliCodeTimerAuto("",0);
1937   
1938   // Access to the AOD container of vertices
1939   fNumberOfVertices = 0;
1940   
1941   Double_t pos[3] = { 0. };
1942   Double_t covVtx[6] = { 0. };
1943
1944   // Add primary vertex. The primary tracks will be defined
1945   // after the loops on the composite objects (V0, cascades, kinks)
1946   const AliESDVertex *vtx = esd.GetPrimaryVertex();
1947   
1948   vtx->GetXYZ(pos); // position
1949   vtx->GetCovMatrix(covVtx); //covariance matrix
1950   
1951   fPrimaryVertex = new(Vertices()[fNumberOfVertices++])
1952   AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, -1, AliAODVertex::kPrimary);
1953   fPrimaryVertex->SetName(vtx->GetName());
1954   fPrimaryVertex->SetTitle(vtx->GetTitle());
1955   fPrimaryVertex->SetBC(vtx->GetBC());
1956   
1957   TString vtitle = vtx->GetTitle();
1958   if (!vtitle.Contains("VertexerTracks")) 
1959     fPrimaryVertex->SetNContributors(vtx->GetNContributors());
1960   
1961   if (fDebug > 0) fPrimaryVertex->Print();  
1962   
1963   // Add SPD "main" vertex 
1964   const AliESDVertex *vtxS = esd.GetPrimaryVertexSPD();
1965   vtxS->GetXYZ(pos); // position
1966   vtxS->GetCovMatrix(covVtx); //covariance matrix
1967   AliAODVertex * mVSPD = new(Vertices()[fNumberOfVertices++])
1968   AliAODVertex(pos, covVtx, vtxS->GetChi2toNDF(), NULL, -1, AliAODVertex::kMainSPD);
1969   mVSPD->SetName(vtxS->GetName());
1970   mVSPD->SetTitle(vtxS->GetTitle());
1971   mVSPD->SetNContributors(vtxS->GetNContributors()); 
1972   
1973   // Add SPD pileup vertices
1974   for(Int_t iV=0; iV<esd.GetNumberOfPileupVerticesSPD(); ++iV)
1975   {
1976     const AliESDVertex *vtxP = esd.GetPileupVertexSPD(iV);
1977     vtxP->GetXYZ(pos); // position
1978     vtxP->GetCovMatrix(covVtx); //covariance matrix
1979     AliAODVertex * pVSPD =  new(Vertices()[fNumberOfVertices++])
1980     AliAODVertex(pos, covVtx, vtxP->GetChi2toNDF(), NULL, -1, AliAODVertex::kPileupSPD);
1981     pVSPD->SetName(vtxP->GetName());
1982     pVSPD->SetTitle(vtxP->GetTitle());
1983     pVSPD->SetNContributors(vtxP->GetNContributors()); 
1984     pVSPD->SetBC(vtxP->GetBC());
1985   }
1986   
1987   // Add TRK pileup vertices
1988   for(Int_t iV=0; iV<esd.GetNumberOfPileupVerticesTracks(); ++iV)
1989   {
1990     const AliESDVertex *vtxP = esd.GetPileupVertexTracks(iV);
1991     vtxP->GetXYZ(pos); // position
1992     vtxP->GetCovMatrix(covVtx); //covariance matrix
1993     AliAODVertex * pVTRK = new(Vertices()[fNumberOfVertices++])
1994     AliAODVertex(pos, covVtx, vtxP->GetChi2toNDF(), NULL, -1, AliAODVertex::kPileupTracks);
1995     pVTRK->SetName(vtxP->GetName());
1996     pVTRK->SetTitle(vtxP->GetTitle());
1997     pVTRK->SetNContributors(vtxP->GetNContributors());
1998     pVTRK->SetBC(vtxP->GetBC());
1999   }
2000
2001   // Add TPC "main" vertex 
2002   const AliESDVertex *vtxT = esd.GetPrimaryVertexTPC();
2003   vtxT->GetXYZ(pos); // position
2004   vtxT->GetCovMatrix(covVtx); //covariance matrix
2005   AliAODVertex * mVTPC = new(Vertices()[fNumberOfVertices++])
2006   AliAODVertex(pos, covVtx, vtxT->GetChi2toNDF(), NULL, -1, AliAODVertex::kMainTPC);
2007   mVTPC->SetName(vtxT->GetName());
2008   mVTPC->SetTitle(vtxT->GetTitle());
2009   mVTPC->SetNContributors(vtxT->GetNContributors()); 
2010
2011
2012 }
2013
2014 //______________________________________________________________________________
2015 void AliAnalysisTaskESDfilter::ConvertVZERO(const AliESDEvent& esd)
2016 {
2017   // Convert VZERO data
2018   AliAODVZERO* vzeroData = AODEvent()->GetVZEROData();
2019   *vzeroData = *(esd.GetVZEROData());
2020 }
2021
2022 //______________________________________________________________________________
2023 void AliAnalysisTaskESDfilter::ConvertTZERO(const AliESDEvent& esd)
2024 {
2025   // Convert TZERO data
2026   const AliESDTZERO* esdTzero = esd.GetESDTZERO(); 
2027   AliAODTZERO* aodTzero = AODEvent()->GetTZEROData();
2028
2029   for (Int_t icase=0; icase<3; icase++){ 
2030     aodTzero->SetT0TOF(    icase, esdTzero->GetT0TOF(icase));
2031     aodTzero->SetT0TOFbest(icase, esdTzero->GetT0TOFbest(icase)); 
2032   }
2033   aodTzero->SetBackgroundFlag(esdTzero->GetBackgroundFlag());
2034   aodTzero->SetPileupFlag(esdTzero->GetPileupFlag());
2035   aodTzero->SetSatelliteFlag(esdTzero->GetSatellite()); 
2036
2037   Float_t rawTime[24];
2038   for(Int_t ipmt=0; ipmt<24; ipmt++)
2039     rawTime[ipmt] = esdTzero->GetTimeFull(ipmt,0);
2040    
2041   Int_t idxOfFirstPmtA = -1,       idxOfFirstPmtC = -1;
2042   Float_t timeOfFirstPmtA = 9999, timeOfFirstPmtC = 9999;
2043   for(int ipmt=0;  ipmt<12; ipmt++){
2044     if( rawTime[ipmt] > -200 && rawTime[ipmt] < timeOfFirstPmtC && rawTime[ipmt]!=0){
2045       timeOfFirstPmtC = rawTime[ipmt];
2046       idxOfFirstPmtC  = ipmt;
2047     }
2048   }
2049   for(int ipmt=12; ipmt<24; ipmt++){
2050     if( rawTime[ipmt] > -200 && rawTime[ipmt] < timeOfFirstPmtA && rawTime[ipmt]!=0 ){
2051       timeOfFirstPmtA = rawTime[ipmt];
2052       idxOfFirstPmtA  = ipmt;
2053     }
2054   }
2055
2056   if(idxOfFirstPmtA != -1 && idxOfFirstPmtC != -1){
2057     //speed of light in cm/ns   TMath::C()*1e-7 
2058     Float_t vertexraw = TMath::C()*1e-7 * (rawTime[idxOfFirstPmtA] - rawTime[idxOfFirstPmtC])/2;
2059     aodTzero->SetT0VertexRaw( vertexraw );
2060   }else{
2061     aodTzero->SetT0VertexRaw(99999);
2062   }
2063
2064   aodTzero->SetT0zVertex(esdTzero->GetT0zVertex());
2065   //amplitude
2066
2067   const Double32_t *amp=esdTzero->GetT0amplitude();
2068   for(int ipmt=0;  ipmt<24; ipmt++)
2069     aodTzero->SetAmp(ipmt, amp[ipmt]);
2070   aodTzero->SetAmp(24,esdTzero->GetMultC() );
2071   aodTzero->SetAmp(25,esdTzero->GetMultA() );
2072
2073 }
2074
2075
2076 //______________________________________________________________________________
2077 void AliAnalysisTaskESDfilter::ConvertZDC(const AliESDEvent& esd)
2078 {
2079   // Convert ZDC data
2080   AliESDZDC* esdZDC = esd.GetZDCData();
2081   
2082   const Double_t zem1Energy = esdZDC->GetZEM1Energy();
2083   const Double_t zem2Energy = esdZDC->GetZEM2Energy();
2084    
2085   const Double_t *towZNC = esdZDC->GetZNCTowerEnergy();
2086   const Double_t *towZPC = esdZDC->GetZPCTowerEnergy();
2087   const Double_t *towZNA = esdZDC->GetZNATowerEnergy();
2088   const Double_t *towZPA = esdZDC->GetZPATowerEnergy();
2089   const Double_t *towZNCLG = esdZDC->GetZNCTowerEnergyLR();
2090   const Double_t *towZNALG = esdZDC->GetZNATowerEnergyLR();
2091   
2092   AliAODZDC* zdcAOD = AODEvent()->GetZDCData();
2093
2094   zdcAOD->SetZEM1Energy(zem1Energy);
2095   zdcAOD->SetZEM2Energy(zem2Energy);
2096   zdcAOD->SetZNCTowers(towZNC, towZNCLG);
2097   zdcAOD->SetZNATowers(towZNA, towZNALG);
2098   zdcAOD->SetZPCTowers(towZPC);
2099   zdcAOD->SetZPATowers(towZPA);
2100   
2101   zdcAOD->SetZDCParticipants(esdZDC->GetZDCParticipants(), esdZDC->GetZDCPartSideA(), esdZDC->GetZDCPartSideC());
2102   zdcAOD->SetZDCImpactParameter(esdZDC->GetImpactParameter(), esdZDC->GetImpactParamSideA(), 
2103         esdZDC->GetImpactParamSideC());
2104   zdcAOD->SetZDCTDCSum(esdZDC->GetZNTDCSum(0)); 
2105   zdcAOD->SetZDCTDCDiff(esdZDC->GetZNTDCDiff(0));       
2106   if(esdZDC->IsZNChit()) zdcAOD->SetZNCTDC(esdZDC->GetZDCTDCCorrected(10,0));
2107   if(esdZDC->IsZNAhit()) zdcAOD->SetZNATDC(esdZDC->GetZDCTDCCorrected(12,0));
2108 }
2109
2110 //_______________________________________________________________________________________________________________________________________
2111 Int_t AliAnalysisTaskESDfilter::ConvertHMPID(const AliESDEvent& esd) // clm
2112 {
2113   //
2114   // Convtert ESD HMPID info to AOD and return the number of good tracks with HMPID signal.
2115   // We need to return an int since there is no signal counter in the ESD.
2116   //
2117   
2118   AliCodeTimerAuto("",0);
2119   
2120   Int_t cntHmpidGoodTracks = 0;
2121   
2122   Float_t  xMip = 0;
2123   Float_t  yMip = 0;
2124   Int_t    qMip = 0;
2125   Int_t    nphMip = 0;
2126   
2127   Float_t xTrk = 0;
2128   Float_t yTrk = 0;
2129   Float_t thetaTrk = 0;
2130   Float_t phiTrk = 0;
2131   
2132   Double_t hmpPid[5]={0};
2133   Double_t hmpMom[3]={0};
2134   
2135   TClonesArray &hmpidRings = *(AODEvent()->GetHMPIDrings());
2136   
2137  for (Int_t iTrack=0; iTrack<esd.GetNumberOfTracks(); ++iTrack) 
2138   {
2139     if(! esd.GetTrack(iTrack) ) continue;
2140       
2141     if(esd.GetTrack(iTrack)->GetHMPIDsignal() > -20 ) {                  // 
2142        
2143       (esd.GetTrack(iTrack))->GetHMPIDmip(xMip, yMip, qMip, nphMip);     // Get MIP properties
2144       (esd.GetTrack(iTrack))->GetHMPIDtrk(xTrk,yTrk,thetaTrk,phiTrk);
2145       (esd.GetTrack(iTrack))->GetHMPIDpid(hmpPid);
2146       if((esd.GetTrack(iTrack))->GetOuterHmpParam()) (esd.GetTrack(iTrack))->GetOuterHmpPxPyPz(hmpMom);
2147       
2148      if(esd.GetTrack(iTrack)->GetHMPIDsignal() == 0 && thetaTrk == 0 && qMip == 0 && nphMip ==0 ) continue;  //
2149       
2150      new(hmpidRings[cntHmpidGoodTracks++]) AliAODHMPIDrings(
2151                                                                  (esd.GetTrack(iTrack))->GetID(),             // Unique track id to attach the ring to
2152                                                                  1000000*nphMip+qMip,                         // MIP charge and number of photons
2153                                                                  (esd.GetTrack(iTrack))->GetHMPIDcluIdx(),    // 1000000*chamber id + cluster idx of the assigned MIP cluster  
2154                                                                  thetaTrk,                                    // track inclination angle theta
2155                                                                  phiTrk,                                      // track inclination angle phi
2156                                                                  (esd.GetTrack(iTrack))->GetHMPIDsignal(),    // Cherenkov angle
2157                                                                  (esd.GetTrack(iTrack))->GetHMPIDoccupancy(), // Occupancy claculated for the given chamber 
2158                                                                  (esd.GetTrack(iTrack))->GetHMPIDchi2(),      // Ring resolution squared
2159                                                                   xTrk,                                       // Track x coordinate (LORS)
2160                                                                   yTrk,                                       // Track y coordinate (LORS)
2161                                                                   xMip,                                       // MIP x coordinate (LORS)
2162                                                                   yMip,                                       // MIP y coordinate (LORS)
2163                                                                   hmpPid,                                     // PID probablities from ESD, remove later once it is in CombinedPid
2164                                                                   hmpMom                                      // Track momentum in HMPID at ring reconstruction
2165                                                                );  
2166      
2167       //  Printf(Form("+++++++++ yes/no: %d  %lf %lf %lf %lf %lf %lf ",(esd.GetTrack(iTrack))->IsHMPID(),thetaTrk, (esd.GetTrack(iTrack))->GetHMPIDchi2(),xTrk, yTrk , xMip, yMip));
2168      
2169                                                                 
2170    }// HMPID signal > -20
2171   }//___esd track loop
2172   
2173   return cntHmpidGoodTracks;
2174 }
2175
2176 void AliAnalysisTaskESDfilter::ConvertTRD(const AliESDEvent& esd)
2177 {
2178   // fill TRD on-line tracks with assiocated tracklets
2179   // as used for the TRD level-1 triggers
2180
2181   const Int_t nTrdTracks = esd.GetNumberOfTrdTracks();
2182   const Int_t nLayers = 6;
2183
2184   for (Int_t iTrdTrack = 0; iTrdTrack < nTrdTracks; ++iTrdTrack) {
2185     // copy information from ESD track to AOD track
2186     const AliESDTrdTrack *esdTrdTrk = esd.GetTrdTrack(iTrdTrack);
2187     AliAODTrdTrack &aodTrdTrk = AODEvent()->AddTrdTrack(esdTrdTrk);
2188
2189     // copy the contributing tracklets
2190     for (Int_t iTracklet = 0; iTracklet < nLayers; ++iTracklet) {
2191       if (const AliESDTrdTracklet *esdTrdTrkl = esdTrdTrk->GetTracklet(iTracklet))
2192         aodTrdTrk.AddTracklet(*esdTrdTrkl, iTracklet);
2193     }
2194
2195     // add the reference to the matched global track
2196     AliAODTrack *aodTrkMatch = 0x0;
2197     AliESDtrack *esdTrkMatch = (AliESDtrack*) esdTrdTrk->GetTrackMatch();
2198     if (esdTrkMatch) {
2199       Int_t idx = esdTrkMatch->GetID();
2200
2201       if (idx < 0)
2202         AliError("track has a matched track that was not found");
2203       else if (esdTrkMatch != esd.GetTrack(idx))
2204         AliError("wrong track found for ESD track index");
2205       else {
2206         UInt_t selectInfo = fTrackFilter ? fTrackFilter->IsSelected(esdTrkMatch) : 0;
2207
2208         if (fUsedTrack[idx]) {
2209           aodTrkMatch = (AliAODTrack*) (*fAODTrackRefs)[idx];
2210           AliDebug(2, Form("event %lld: existing track (idx %i, pt = %f) matched to TRD track (idx %i, pt = %f), cut flags: 0x%08x",
2211                            Entry(), idx, esdTrkMatch->Pt(), iTrdTrack, esdTrdTrk->Pt(),
2212                            selectInfo));
2213         }
2214         else {
2215           if (selectInfo & fUsedTrackCopy[idx]) {
2216             // mask filter bits already used in track copies
2217             selectInfo &= ~fUsedTrackCopy[idx];
2218             AliWarning(Form("event %lld: copied track (idx %i, pt = %f) matched to TRD track (idx %i, pt = %f), cut flags: 0x%08x -> 0x%08x",
2219                             Entry(), idx, esdTrkMatch->Pt(), iTrdTrack, esdTrdTrk->Pt(),
2220                             fTrackFilter->IsSelected(esdTrkMatch), selectInfo));
2221           }
2222           AliDebug(2, Form("event %lld: unused track (idx %i, pt = %f) matched to TRD track (idx %i, pt = %f), cut flags: 0x%08x -> 0x%08x",
2223                            Entry(), idx, esdTrkMatch->Pt(), iTrdTrack, esdTrdTrk->Pt(),
2224                            fTrackFilter->IsSelected(esdTrkMatch), selectInfo));
2225
2226           Double_t mom[3]={0.};
2227           Double_t pos[3]={0.};
2228           Double_t covTr[21]={0.};
2229           Double_t pid[10]={0.};
2230
2231           esdTrkMatch->GetPxPyPz(mom);
2232           esdTrkMatch->GetXYZ(pos);
2233           esdTrkMatch->GetCovarianceXYZPxPyPz(covTr);
2234           esdTrkMatch->GetESDpid(pid);
2235           const AliESDVertex* vtx = esd.GetPrimaryVertex();
2236
2237           fUsedTrack[idx] = kTRUE;
2238           if(fMChandler) fMChandler->SelectParticle(esdTrkMatch->GetLabel());
2239
2240           aodTrkMatch = new(Tracks()[fNumberOfTracks++])
2241             AliAODTrack(esdTrkMatch->GetID(),
2242                         esdTrkMatch->GetLabel(),
2243                         mom,
2244                         kTRUE,
2245                         pos,
2246                         kFALSE,
2247                         covTr,
2248                         (Short_t)esdTrkMatch->GetSign(),
2249                         esdTrkMatch->GetITSClusterMap(),
2250                         pid,
2251                         fPrimaryVertex,
2252                         kTRUE,
2253                         vtx->UsesTrack(esdTrkMatch->GetID()),
2254                         AliAODTrack::kUndef,
2255                         selectInfo);
2256
2257           aodTrkMatch->SetTPCFitMap(esdTrkMatch->GetTPCFitMap());
2258           aodTrkMatch->SetTPCClusterMap(esdTrkMatch->GetTPCClusterMap());
2259           aodTrkMatch->SetTPCSharedMap (esdTrkMatch->GetTPCSharedMap());
2260           aodTrkMatch->SetChi2perNDF(Chi2perNDF(esdTrkMatch));
2261           aodTrkMatch->SetTPCPointsF(esdTrkMatch->GetTPCNclsF());
2262           aodTrkMatch->SetTPCNCrossedRows(UShort_t(esdTrkMatch->GetTPCCrossedRows()));
2263           aodTrkMatch->SetIntegratedLength(esdTrkMatch->GetIntegratedLength());
2264           CopyCaloProps(esdTrkMatch,aodTrkMatch);
2265           fAODTrackRefs->AddAt(aodTrkMatch,idx);
2266           if (esdTrkMatch->GetSign() > 0) ++fNumberOfPositiveTracks;
2267           aodTrkMatch->ConvertAliPIDtoAODPID();
2268           aodTrkMatch->SetFlags(esdTrkMatch->GetStatus());
2269         }
2270       }
2271     }
2272     aodTrdTrk.SetTrackMatchReference(aodTrkMatch);
2273   }
2274 }
2275
2276 //______________________________________________________________________________
2277 void AliAnalysisTaskESDfilter::ConvertESDtoAOD() 
2278 {
2279   // ESD Filter analysis task executed for each event
2280   
2281   AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
2282   
2283   if(!esd)return;
2284
2285   AliCodeTimerAuto("",0);
2286
2287   if (fRefitVertexTracks) AliESDUtils::RefitESDVertexTracks(esd,fRefitVertexTracks,fRefitVertexTracksCuts);
2288   
2289   fOldESDformat = ( esd->GetAliESDOld() != 0x0 );
2290  
2291       // Reconstruct cascades and V0 here
2292   if (fIsV0CascadeRecoEnabled) {
2293     esd->ResetCascades();
2294     esd->ResetV0s();
2295
2296     AliV0vertexer lV0vtxer;
2297     AliCascadeVertexer lCascVtxer;
2298
2299     lV0vtxer.SetCuts(fV0Cuts);
2300     lCascVtxer.SetCuts(fCascadeCuts);
2301
2302
2303     lV0vtxer.Tracks2V0vertices(esd);
2304     lCascVtxer.V0sTracks2CascadeVertices(esd);
2305   }
2306
2307   // Perform progagation of tracks if needed
2308   if (fDoPropagateTrackToEMCal) {
2309     const Int_t ntrack = esd->GetNumberOfTracks();
2310     for (Int_t i=0;i<ntrack;++i) {
2311       AliESDtrack *t = esd->GetTrack(i);
2312       AliEMCALRecoUtils::ExtrapolateTrackToEMCalSurface(t,fEMCalSurfaceDistance);
2313     }
2314   }
2315  
2316   fNumberOfTracks = 0;
2317   fNumberOfPositiveTracks = 0;
2318   fNumberOfV0s = 0;
2319   fNumberOfVertices = 0;
2320   fNumberOfCascades = 0;
2321   fNumberOfKinks = 0;
2322     
2323   AliAODHeader* header = ConvertHeader(*esd);
2324
2325   if ( fIsVZEROEnabled ) ConvertVZERO(*esd);
2326   if ( fIsTZEROEnabled ) ConvertTZERO(*esd);
2327   
2328   // Fetch Stack for debuggging if available 
2329   fMChandler=0x0;
2330   if(MCEvent())
2331   {
2332     fMChandler = (AliMCEventHandler*) ((AliAnalysisManager::GetAnalysisManager())->GetMCtruthEventHandler()); 
2333   }
2334   
2335   // loop over events and fill them
2336   // Multiplicity information needed by the header (to be revised!)
2337   Int_t nTracks    = esd->GetNumberOfTracks();
2338   for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) esd->GetTrack(iTrack)->SetESDEvent(esd);
2339
2340   // Update the header
2341
2342   Int_t nV0s      = esd->GetNumberOfV0s();
2343   Int_t nCascades = esd->GetNumberOfCascades();
2344   Int_t nKinks    = esd->GetNumberOfKinks();
2345   Int_t nVertices = nV0s + nCascades /*V0 wihtin cascade already counted*/+ nKinks + 1 /* = prim. vtx*/;
2346   Int_t nPileSPDVertices=1+esd->GetNumberOfPileupVerticesSPD(); // also SPD main vertex
2347   Int_t nPileTrkVertices=esd->GetNumberOfPileupVerticesTracks();
2348   nVertices+=nPileSPDVertices;
2349   nVertices+=nPileTrkVertices;
2350   Int_t nJets     = 0;
2351   Int_t nCaloClus = esd->GetNumberOfCaloClusters();
2352   Int_t nFmdClus  = 0;
2353   Int_t nPmdClus  = esd->GetNumberOfPmdTracks();
2354   Int_t nHmpidRings = 0;  
2355     
2356   AliDebug(1,Form("   NV0=%d  NCASCADES=%d  NKINKS=%d", nV0s, nCascades, nKinks));
2357        
2358   AODEvent()->ResetStd(nTracks, nVertices, nV0s, nCascades, nJets, nCaloClus, nFmdClus, nPmdClus,nHmpidRings);
2359
2360   if (nV0s > 0) 
2361   {
2362     // RefArray to store a mapping between esd V0 number and newly created AOD-Vertex V0
2363     fAODV0VtxRefs = new TRefArray(nV0s);
2364     // RefArray to store the mapping between esd V0 number and newly created AOD-V0
2365     fAODV0Refs = new TRefArray(nV0s); 
2366     // Array to take into account the V0s already added to the AOD (V0 within cascades)
2367     fUsedV0 = new Bool_t[nV0s];
2368     for (Int_t iV0=0; iV0<nV0s; ++iV0) fUsedV0[iV0]=kFALSE;
2369   }
2370   
2371   if (nTracks>0) 
2372   {
2373     // RefArray to store the mapping between esd track number and newly created AOD-Track
2374     
2375     fAODTrackRefs = new TRefArray(nTracks);
2376
2377     // Array to take into account the tracks already added to the AOD    
2378     fUsedTrack = new Bool_t[nTracks];
2379     fUsedTrackCopy = new UInt_t[nTracks];
2380     for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
2381       fUsedTrack[iTrack]=kFALSE;
2382       fUsedTrackCopy[iTrack] = 0;
2383     }
2384   }
2385   
2386   // Array to take into account the kinks already added to the AOD
2387   if (nKinks>0) 
2388   {
2389     fUsedKink = new Bool_t[nKinks];
2390     for (Int_t iKink=0; iKink<nKinks; ++iKink) fUsedKink[iKink]=kFALSE;
2391   }
2392     
2393   ConvertPrimaryVertices(*esd);
2394
2395   //setting best TOF PID
2396   AliESDInputHandler* esdH = dynamic_cast<AliESDInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
2397   if (esdH)
2398       fESDpid = esdH->GetESDpid();
2399
2400   if (fIsPidOwner && fESDpid){
2401     delete fESDpid;
2402     fESDpid = 0;
2403   }
2404   if(!fESDpid)
2405   { //in case of no Tender attached 
2406     fESDpid = new AliESDpid;
2407     fIsPidOwner = kTRUE;
2408   }
2409   
2410   if(!esd->GetTOFHeader())
2411   { //protection in case the pass2 LHC10b,c,d have been processed without tender. 
2412     Float_t t0spread[10];
2413     Float_t intrinsicTOFres=100; //ps ok for LHC10b,c,d pass2!! 
2414     for (Int_t i=0; i<10; i++) t0spread[i] = (TMath::Sqrt(esd->GetSigma2DiamondZ()))/0.03; //0.03 to convert from cm to ps
2415     fESDpid->GetTOFResponse().SetT0resolution(t0spread);
2416     fESDpid->GetTOFResponse().SetTimeResolution(intrinsicTOFres);
2417       //    fESDpid->SetTOFResponse(esd, (AliESDpid::EStartTimeType_t)fTimeZeroType);    
2418     AliTOFHeader tmpTOFHeader(0,t0spread[0],0,NULL,NULL,NULL,intrinsicTOFres,t0spread[0]);   
2419     AODEvent()->SetTOFHeader(&tmpTOFHeader);         // write dummy TOF header in AOD
2420   } else {
2421     AODEvent()->SetTOFHeader(esd->GetTOFHeader());    // write TOF header in AOD
2422   }
2423   
2424   //  if(esd->GetTOFHeader() && fIsPidOwner) fESDpid->SetTOFResponse(esd, (AliESDpid::EStartTimeType_t)fTimeZeroType); //in case of AOD production strating form LHC10e without Tender. 
2425   
2426   if ( fAreCascadesEnabled ) ConvertCascades(*esd);
2427
2428   if ( fAreV0sEnabled ) ConvertV0s(*esd);
2429   
2430   if ( fAreKinksEnabled ) ConvertKinks(*esd);
2431   
2432   if ( fAreTracksEnabled ) ConvertTracks(*esd);
2433   
2434   // Update number of AOD tracks in header at the end of track loop (M.G.)
2435   header->SetRefMultiplicity(fNumberOfTracks);
2436   header->SetRefMultiplicityPos(fNumberOfPositiveTracks);
2437   header->SetRefMultiplicityNeg(fNumberOfTracks - fNumberOfPositiveTracks);
2438
2439   if ( fTPCConstrainedFilterMask ) ConvertTPCOnlyTracks(*esd);
2440   if( fGlobalConstrainedFilterMask) ConvertGlobalConstrainedTracks(*esd);  
2441
2442   if ( fArePmdClustersEnabled ) ConvertPmdClusters(*esd);
2443   
2444   if ( fAreCaloClustersEnabled ) ConvertCaloClusters(*esd);
2445   
2446   if ( fAreEMCALCellsEnabled )ConvertEMCALCells(*esd);
2447   
2448   if ( fArePHOSCellsEnabled )ConvertPHOSCells(*esd);
2449         
2450         if ( fAreEMCALTriggerEnabled )ConvertCaloTrigger(TString("EMCAL"), *esd);
2451
2452         if ( fArePHOSTriggerEnabled )ConvertCaloTrigger(TString("PHOS"), *esd);
2453   
2454   if ( fAreTrackletsEnabled ) ConvertTracklets(*esd);
2455   if ( fIsZDCEnabled ) ConvertZDC(*esd);
2456   
2457   if(fIsHMPIDEnabled) nHmpidRings = ConvertHMPID(*esd); 
2458
2459   if (fIsTRDEnabled) ConvertTRD(*esd);
2460
2461   delete fAODTrackRefs; fAODTrackRefs=0x0;
2462   delete fAODV0VtxRefs; fAODV0VtxRefs=0x0;
2463   delete fAODV0Refs; fAODV0Refs=0x0;
2464   
2465   delete[] fUsedTrack; fUsedTrack=0x0;
2466   delete[] fUsedTrackCopy; fUsedTrackCopy=0x0;
2467   delete[] fUsedV0; fUsedV0=0x0;
2468   delete[] fUsedKink; fUsedKink=0x0;
2469
2470   if ( fIsPidOwner){
2471     delete fESDpid;
2472     fESDpid = 0x0;
2473   }
2474
2475
2476 }
2477
2478
2479 //______________________________________________________________________________
2480 void AliAnalysisTaskESDfilter::SetAODPID(AliESDtrack *esdtrack, AliAODTrack *aodtrack, AliAODPid *detpid)
2481 {
2482   //
2483   // Setter for the raw PID detector signals
2484   //
2485
2486   // Save PID object for candidate electrons
2487     Bool_t pidSave = kFALSE;
2488     if (fTrackFilter) {
2489         Bool_t selectInfo = fTrackFilter->IsSelected((char*) "Electrons");
2490         if (selectInfo)  pidSave = kTRUE;
2491     }
2492
2493
2494     // Tracks passing pt cut 
2495     if(esdtrack->Pt()>fHighPthreshold) {
2496         pidSave = kTRUE;
2497     } else {
2498         if(fPtshape){
2499             if(esdtrack->Pt()> fPtshape->GetXmin()){
2500                 Double_t y = fPtshape->Eval(esdtrack->Pt())/fPtshape->Eval(fHighPthreshold);
2501                 if(gRandom->Rndm(0)<1./y){
2502                     pidSave = kTRUE;
2503                 }//end rndm
2504             }//end if p < pmin
2505         }//end if p function
2506     }// end else
2507
2508     if (pidSave) {
2509       if(!aodtrack->GetDetPid()){// prevent memory leak when calling SetAODPID twice for the same track
2510         detpid = new AliAODPid();
2511         SetDetectorRawSignals(detpid,esdtrack);
2512         aodtrack->SetDetPID(detpid);
2513       }
2514     }
2515 }
2516
2517 //______________________________________________________________________________
2518 void AliAnalysisTaskESDfilter::SetDetectorRawSignals(AliAODPid *aodpid, AliESDtrack *track)
2519 {
2520 //
2521 //assignment of the detector signals (AliXXXesdPID inspired)
2522 //
2523  if(!track){
2524  AliInfo("no ESD track found. .....exiting");
2525  return;
2526  }
2527  // TPC momentum
2528  aodpid->SetTPCmomentum(track->GetTPCmomentum());
2529  aodpid->SetTPCTgl(track->GetTPCTgl());
2530 //  const AliExternalTrackParam *in=track->GetInnerParam();
2531 //  if (in) {
2532 //    aodpid->SetTPCmomentum(in->GetP());
2533 //  }else{
2534 //    aodpid->SetTPCmomentum(-1.);
2535 //  }
2536
2537
2538  aodpid->SetITSsignal(track->GetITSsignal());
2539  Double_t itsdedx[4]; // dE/dx samples for individual ITS layers
2540  track->GetITSdEdxSamples(itsdedx);
2541  aodpid->SetITSdEdxSamples(itsdedx);
2542
2543  aodpid->SetTPCsignal(track->GetTPCsignal());
2544  aodpid->SetTPCsignalN(track->GetTPCsignalN());
2545  if(track->GetTPCdEdxInfo()) aodpid->SetTPCdEdxInfo(track->GetTPCdEdxInfo());
2546
2547  //n TRD planes = 6
2548  Int_t nslices = track->GetNumberOfTRDslices()*6;
2549  TArrayD trdslices(nslices);
2550  for(Int_t iSl =0; iSl < track->GetNumberOfTRDslices(); iSl++) {
2551    for(Int_t iPl =0; iPl<6; iPl++) trdslices[iPl*track->GetNumberOfTRDslices()+iSl] = track->GetTRDslice(iPl,iSl);
2552  }
2553  
2554 //TRD momentum
2555  for(Int_t iPl=0;iPl<6;iPl++){
2556    Double_t trdmom=track->GetTRDmomentum(iPl);
2557    aodpid->SetTRDmomentum(iPl,trdmom);
2558  }
2559
2560  aodpid->SetTRDslices(track->GetNumberOfTRDslices()*6,trdslices.GetArray());
2561  aodpid->SetTRDsignal(track->GetTRDsignal());
2562
2563  //TRD clusters and tracklets
2564  aodpid->SetTRDncls(track->GetTRDncls());
2565  aodpid->SetTRDntrackletsPID(track->GetTRDntrackletsPID());
2566  
2567  aodpid->SetTRDChi2(track->GetTRDchi2());
2568
2569  //TOF PID  
2570  Double_t times[AliPID::kSPECIESC]; track->GetIntegratedTimes(times);
2571  aodpid->SetIntegratedTimes(times);
2572
2573    //  Float_t tzeroTrack = fESDpid->GetTOFResponse().GetStartTime(track->P());
2574    //  aodpid->SetTOFsignal(track->GetTOFsignal()-tzeroTrack);
2575    aodpid->SetTOFsignal(track->GetTOFsignal());
2576   
2577   Double_t tofRes[5];
2578   for (Int_t iMass=0; iMass<5; iMass++){
2579     //    tofRes[iMass]=(Double_t)fESDpid->GetTOFResponse().GetExpectedSigma(track->P(), times[iMass], AliPID::ParticleMass(iMass));
2580     tofRes[iMass]=0; //backward compatibility
2581   }
2582   aodpid->SetTOFpidResolution(tofRes);
2583
2584 //  aodpid->SetHMPIDsignal(0); // set to zero for compression but it will be removed later
2585
2586 }
2587
2588 Double_t  AliAnalysisTaskESDfilter::Chi2perNDF(AliESDtrack* track)
2589 {
2590     // Calculate chi2 per ndf for track
2591     Int_t  nClustersTPC = track->GetTPCNcls();
2592
2593     if ( nClustersTPC > 5) {
2594        return (track->GetTPCchi2()/Float_t(nClustersTPC - 5));
2595     } else {
2596        return (-1.);
2597     }
2598  }
2599
2600
2601 //______________________________________________________________________________
2602 void AliAnalysisTaskESDfilter::Terminate(Option_t */*option*/)
2603 {
2604 // Terminate analysis
2605 //
2606     if (fDebug > 1) printf("AnalysisESDfilter: Terminate() \n");
2607 }
2608
2609 //______________________________________________________________________________
2610 void  AliAnalysisTaskESDfilter::PrintMCInfo(AliStack *pStack,Int_t label){
2611 // Print MC info
2612   if(!pStack)return;
2613   label = TMath::Abs(label);
2614   TParticle *part = pStack->Particle(label);
2615   Printf("########################");
2616   Printf("%s:%d %d UniqueID %d PDG %d P %3.3f",(char*)__FILE__,__LINE__,label,part->GetUniqueID(),part->GetPdgCode(),part->P());
2617   part->Print();
2618   TParticle* mother = part;
2619   Int_t imo = part->GetFirstMother();
2620   Int_t nprim = pStack->GetNprimary();
2621   //  while((imo >= nprim) && (mother->GetUniqueID() == 4)) {
2622   while((imo >= nprim)) {
2623     mother =  pStack->Particle(imo);
2624     Printf("Mother %s:%d Label %d UniqueID %d PDG %d P %3.3f",(char*)__FILE__,__LINE__,imo,mother->GetUniqueID(),mother->GetPdgCode(),mother->P());
2625     mother->Print();
2626     imo =  mother->GetFirstMother();
2627   }
2628   Printf("########################");
2629 }
2630
2631 //______________________________________________________________________________
2632 void  AliAnalysisTaskESDfilter::CopyCaloProps(AliESDtrack *tre, AliAODTrack *tra) {
2633   //Copy calo properties from ESD track to AOD track
2634
2635   tra->SetTrackPhiEtaPtOnEMCal(tre->GetTrackPhiOnEMCal(),tre->GetTrackEtaOnEMCal(),tre->GetTrackPtOnEMCal());
2636   if(tre->IsEMCAL()) tra->SetEMCALcluster(tre->GetEMCALcluster());
2637   if(tre->IsPHOS())  tra->SetPHOScluster(tre->GetPHOScluster());
2638
2639 }
2640
2641 //______________________________________________________________________________
2642 void AliAnalysisTaskESDfilter::SetRefitVertexTracks(Int_t algo, Double_t* cuts)
2643 {
2644   // request vertexTrack reprocessing from ESDtracks
2645   // if algo>=0 and cuts==0 then algo is interpreted as the algorithm ID to be run with default cuts
2646   // otherwise it is number of cuts to digest
2647   fRefitVertexTracks = algo;
2648   //
2649   if (algo>0 && cuts) {
2650     fRefitVertexTracksCuts = new Double_t[fRefitVertexTracks];
2651     for (int i=fRefitVertexTracks;i--;) fRefitVertexTracksCuts[i] = cuts[i];
2652   }
2653 }