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