]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGGA/CaloTasks/AliAnalysisTaskCaloFilter.cxx
added copy of VZERO, copy only hybrid tracks, copy only the main vertices, select...
[u/mrichter/AliRoot.git] / PWGGA / CaloTasks / AliAnalysisTaskCaloFilter.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 //////////////////////////////////////////////////////////
17 // Filter the ESDCaloClusters and ESDCaloCells of EMCAL,
18 // PHOS or both, creating the corresponing AODCaloClusters
19 // and AODCaloCells.
20 // Keep also the AODHeader information and the vertex.
21 // Keep tracks, v0s, VZERO if requested
22 // Select events containing a cluster or track avobe a given threshold
23 // Copy of AliAnalysisTaskESDfilter.
24 // Author: Gustavo Conesa Balbastre (INFN - Frascati)
25 //////////////////////////////////////////////////////////
26
27 //Root
28 #include "TGeoManager.h"
29 #include "TFile.h"
30 #include "TROOT.h"
31 #include "TInterpreter.h"
32
33 //STEER
34 #include "AliESDEvent.h"
35 #include "AliAODEvent.h"
36 #include "AliLog.h"
37 #include "AliVCluster.h"
38 #include "AliVCaloCells.h"
39 #include "AliVEventHandler.h"
40 #include "AliAnalysisManager.h"
41 #include "AliInputEventHandler.h"
42
43 //EMCAL
44 #include "AliEMCALRecoUtils.h"
45 #include "AliEMCALGeometry.h"
46
47 #include "AliAnalysisTaskCaloFilter.h"
48
49 ClassImp(AliAnalysisTaskCaloFilter)
50
51 ////////////////////////////////////////////////////////////////////////
52
53 AliAnalysisTaskCaloFilter::AliAnalysisTaskCaloFilter():
54 AliAnalysisTaskSE("CaloFilterTask"), 
55 fCaloFilter(0),           fEventSelection(), 
56 fAcceptAllMBEvent(kFALSE),  fCorrect(kFALSE), 
57 fEMCALGeo(0x0),           fEMCALGeoName("EMCAL_COMPLETE12SMV1"), 
58 fEMCALRecoUtils(new AliEMCALRecoUtils),
59 fLoadEMCALMatrices(kFALSE), //fLoadPHOSMatrices(kFALSE),
60 fGeoMatrixSet(kFALSE),
61 fConfigName(""),          fFillAODFile(kTRUE), 
62 fFillTracks(kFALSE),      fFillHybridTracks(kFALSE),
63 fFillAllVertices(kFALSE), fFillv0s(kFALSE),  
64 fFillVZERO(kFALSE),
65 fEMCALEnergyCut(0.),      fEMCALNcellsCut (0),
66 fPHOSEnergyCut(0.),       fPHOSNcellsCut (0), 
67 fTrackPtCut(-1),
68 fVzCut(100.),             fEvent(0x0),              
69 fESDEvent(0x0),           fAODEvent(0x0)
70 {
71   // Default constructor
72   
73   fEventSelection[0] = kFALSE;
74   fEventSelection[1] = kFALSE;
75   fEventSelection[2] = kFALSE;
76   
77   for(Int_t i = 0; i < 12; i++) fEMCALMatrix[i] = 0 ;
78   //for(Int_t i = 0; i < 5 ; i++) fPHOSMatrix[i]  = 0 ;
79   
80 }
81
82 //__________________________________________________
83 AliAnalysisTaskCaloFilter::AliAnalysisTaskCaloFilter(const char* name):
84 AliAnalysisTaskSE(name), 
85 fCaloFilter(0),           fEventSelection(), 
86 fAcceptAllMBEvent(kFALSE),  fCorrect(kFALSE),
87 fEMCALGeo(0x0),           fEMCALGeoName("EMCAL_COMPLETE12SMV1"), 
88 fEMCALRecoUtils(new AliEMCALRecoUtils),
89 fLoadEMCALMatrices(kFALSE), //fLoadPHOSMatrices(kFALSE),
90 fGeoMatrixSet(kFALSE),
91 fConfigName(""),          fFillAODFile(kTRUE),
92 fFillTracks(kFALSE),      fFillHybridTracks(kFALSE),
93 fFillAllVertices(kFALSE), fFillv0s(kFALSE),
94 fFillVZERO(kFALSE),
95 fEMCALEnergyCut(0.),      fEMCALNcellsCut(0), 
96 fPHOSEnergyCut(0.),       fPHOSNcellsCut(0), 
97 fTrackPtCut(-1),
98 fVzCut(100.),             fEvent(0x0),              
99 fESDEvent(0x0),           fAODEvent(0x0)
100 {
101   // Constructor
102   
103   fEventSelection[0] = kFALSE;
104   fEventSelection[1] = kFALSE;
105   fEventSelection[2] = kFALSE;  
106   
107   for(Int_t i = 0; i < 12; i++) fEMCALMatrix[i] = 0 ;
108   //for(Int_t i = 0; i < 5 ; i++) fPHOSMatrix[i]  = 0 ;
109   
110 }
111
112 //__________________________________________________
113 AliAnalysisTaskCaloFilter::~AliAnalysisTaskCaloFilter()
114 {
115   //Destructor.
116         
117   if(fEMCALGeo)        delete fEMCALGeo;        
118   if(fEMCALRecoUtils)  delete fEMCALRecoUtils;
119   
120 }
121
122 //_____________________________________________
123 Bool_t AliAnalysisTaskCaloFilter::AcceptEvent()
124 {
125   // Define conditions to accept the event to be filtered
126   
127   Bool_t eventSel = kFALSE;
128   
129   Bool_t isMB = (((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected() & AliVEvent::kMB);
130   
131   if     ( isMB && fAcceptAllMBEvent )                eventSel = kTRUE; // accept any MB event
132   
133   else if( fEventSelection[0] && AcceptEventEMCAL() ) eventSel = kTRUE; // accept event depending on EMCAL activity
134   
135   else if( fEventSelection[1] && AcceptEventPHOS () ) eventSel = kTRUE; // accept event depending on PHOS  activity
136   
137   else if( fEventSelection[2] && AcceptEventTrack() ) eventSel = kTRUE; // accept event depending on Track activity
138   
139   return eventSel ;
140   
141 }
142
143 //__________________________________________________
144 Bool_t AliAnalysisTaskCaloFilter::AcceptEventEMCAL()
145 {
146   // Accept event given there is a EMCAL cluster with enough energy, and not noisy, exotic
147   
148   if(fCaloFilter==kPHOS)   return kTRUE; // accept 
149   
150   if(fEMCALEnergyCut <= 0) return kTRUE; // accept
151   
152   Int_t           nCluster = InputEvent() -> GetNumberOfCaloClusters();
153   AliVCaloCells * caloCell = InputEvent() -> GetEMCALCells();
154   Int_t           bc       = InputEvent() -> GetBunchCrossNumber();
155   
156   for(Int_t icalo = 0; icalo < nCluster; icalo++)
157   {
158     AliVCluster *clus = (AliVCluster*) (InputEvent()->GetCaloCluster(icalo));
159     
160     if( ( clus->IsEMCAL() ) && ( clus->GetNCells() > fEMCALNcellsCut ) && ( clus->E() > fEMCALEnergyCut ) &&
161        fEMCALRecoUtils->IsGoodCluster(clus,fEMCALGeo,caloCell,bc))
162     { 
163       
164       if (fDebug > 0) printf("AliAnalysisTaskCaloFilter::AcceptEventEMCAL() - Accept :  E %2.2f > %2.2f, nCells %d > %d \n", 
165                              clus->E(), fEMCALEnergyCut, clus->GetNCells(), fEMCALNcellsCut);
166       
167       return kTRUE;
168     }
169     
170   }// loop
171   
172   if (fDebug > 0)  printf("AliAnalysisTaskCaloFilter::AcceptEventEMCAL() - Reject \n");
173   
174   return kFALSE;
175   
176 }  
177
178 //_________________________________________________
179 Bool_t AliAnalysisTaskCaloFilter::AcceptEventPHOS()
180 {
181   // Accept event given there is a PHOS cluster with enough energy and not noisy/exotic
182   
183   if(fCaloFilter==kEMCAL) return kTRUE; // accept 
184   
185   if(fPHOSEnergyCut <= 0) return kTRUE; // accept
186   
187   Int_t nCluster = InputEvent() -> GetNumberOfCaloClusters();
188   
189   for(Int_t icalo = 0; icalo < nCluster; icalo++)
190   {
191     AliVCluster *clus = (AliVCluster*) (InputEvent()->GetCaloCluster(icalo));
192     
193     if( ( clus->IsPHOS() ) && ( clus->GetNCells() > fPHOSNcellsCut ) && ( clus->E() > fPHOSEnergyCut ))
194     { 
195       
196       if (fDebug > 0) printf("AliAnalysisTaskCaloFilter::AcceptEventPHOS() - Accept :  E %2.2f > %2.2f, nCells %d > %d \n", 
197                              clus->E(), fPHOSEnergyCut, clus->GetNCells(), fPHOSNcellsCut);
198       
199       return kTRUE;
200     }
201     
202   }// loop
203   
204   if (fDebug > 0)  printf("AliAnalysisTaskCaloFilter::AcceptEventPHOS() - Reject \n");
205   
206   return kFALSE;
207   
208 }  
209
210 //__________________________________________________
211 Bool_t AliAnalysisTaskCaloFilter::AcceptEventTrack()
212 {
213   // Accept event if there is a track avobe a certain pT
214   
215   if(fTrackPtCut <= 0) return kTRUE; // accept
216   
217   Double_t pTrack[3] = {0,0,0};
218   
219   for (Int_t nTrack = 0; nTrack < fEvent->GetNumberOfTracks(); ++nTrack) 
220   {
221     AliVTrack *track = (AliVTrack*) fEvent->GetTrack(nTrack);
222     
223     // Select only hybrid tracks?
224     if(fAODEvent && fFillHybridTracks && !((AliAODTrack*)track)->IsHybridGlobalConstrainedGlobal()) continue;
225     
226     track->GetPxPyPz(pTrack) ;
227     
228     TLorentzVector momentum(pTrack[0],pTrack[1],pTrack[2],0);
229     
230     if(momentum.Pt() > fTrackPtCut) 
231     {
232       if (fDebug > 0) printf("AliAnalysisTaskCaloFilter::AcceptEventTrack() - Accept :  pT %2.2f > %2.2f \n", 
233                              momentum.Pt(), fTrackPtCut);
234
235       return kTRUE;
236     }
237     
238   } 
239   
240   if (fDebug > 0)  printf("AliAnalysisTaskCaloFilter::AcceptEventTrack() - Reject \n");
241   
242   return kFALSE;
243   
244 }  
245
246 //___________________________________________________
247 Bool_t AliAnalysisTaskCaloFilter::AcceptEventVertex()
248 {
249   // Accept event with good vertex
250   
251   Double_t v[3];
252   InputEvent()->GetPrimaryVertex()->GetXYZ(v) ;
253   
254   if(TMath::Abs(v[2]) > fVzCut) 
255   {
256     if (fDebug > 0)  printf("AliAnalysisTaskCaloFilter::AcceptEventVertex() - Vz Reject \n");
257     return kFALSE ;
258   }
259   
260   return CheckForPrimaryVertex();
261 }  
262
263 //_______________________________________________________
264 Bool_t AliAnalysisTaskCaloFilter::CheckForPrimaryVertex()
265 {
266   //Check if the vertex was well reconstructed, copy from v0Reader of conversion group
267   //It only works for ESDs
268   
269   // AODs
270   if(!fESDEvent) 
271   {
272     // Check that the vertex is not (0,0,0)
273     Double_t v[3];
274     InputEvent()->GetPrimaryVertex()->GetXYZ(v) ;
275     
276     if(TMath::Abs(v[2]) < 1e-6 && 
277        TMath::Abs(v[1]) < 1e-6 && 
278        TMath::Abs(v[0]) < 1e-6 ) 
279     {
280       if (fDebug > 0)  printf("AliAnalysisTaskCaloFilter::CheckForPrimaryVertex() - Reject \n");
281       
282       return kFALSE ;
283     }
284     
285     return kTRUE;
286   }
287   
288   // ESDs
289   if(fESDEvent->GetPrimaryVertexTracks()->GetNContributors() > 0)
290   {
291     return kTRUE;
292   }
293   
294   if(fESDEvent->GetPrimaryVertexTracks()->GetNContributors() < 1) 
295   {
296     // SPD vertex
297     if(fESDEvent->GetPrimaryVertexSPD()->GetNContributors() > 0) 
298     {
299       //cout<<"spd vertex type::"<< fESDEvent->GetPrimaryVertex()->GetName() << endl;
300       return kTRUE;
301       
302     }
303     if(fESDEvent->GetPrimaryVertexSPD()->GetNContributors() < 1) 
304     {
305       //      cout<<"bad vertex type::"<< fESDEvent->GetPrimaryVertex()->GetName() << endl;
306       if (fDebug > 0)  printf("AliAnalysisTaskCaloFilter::CheckForPrimaryVertex() - Reject \n");
307       return kFALSE;
308     }
309   }
310   
311   if (fDebug > 0)  printf("AliAnalysisTaskCaloFilter::CheckForPrimaryVertex() - Reject \n");
312   
313   return kFALSE;
314   
315 }
316
317 //__________________________________________________
318 void AliAnalysisTaskCaloFilter::CorrectionsInEMCAL()
319 {
320   //If EMCAL, and requested, correct energy, position ...
321   
322   //Need to do this in a separate loop before filling the ESDs because of the track matching recalculations
323   
324   if(fCorrect && (fCaloFilter==kEMCAL || fCaloFilter==kBoth) ) 
325   {
326     if(!fGeoMatrixSet)
327     {
328       if(fLoadEMCALMatrices)
329       {
330         printf("AliAnalysisTaskCaloFilter::UserExec() - Load user defined EMCAL geometry matrices\n");
331         for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++){
332           if(fEMCALMatrix[mod]){
333             if(DebugLevel() > 1) 
334               fEMCALMatrix[mod]->Print();
335             fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod) ;  
336           }
337           fGeoMatrixSet=kTRUE;
338         }//SM loop
339       }//Load matrices
340       else if(!gGeoManager)
341       {
342         printf("AliAnalysisTaskCaloFilter::UserExec() - Get geo matrices from data\n");
343         //Still not implemented in AOD, just a workaround to be able to work at least with ESDs 
344         if(!strcmp(InputEvent()->GetName(),"AliAODEvent")) 
345         {
346           if(DebugLevel() > 1) 
347             printf("AliAnalysisTaskCaloFilter Use ideal geometry, values geometry matrix not kept in AODs.\n");
348         }//AOD
349         else 
350         {       
351           if(DebugLevel() > 1) printf("AliAnalysisTaskCaloFilter Load Misaligned matrices. \n");
352           AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent()) ;
353           if(!esd) 
354           {
355             printf("AliAnalysisTaskCaloFilter::UserExec() - This event does not contain ESDs?");
356             return;
357           }
358           for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++)
359           {
360             //if(DebugLevel() > 1) 
361             esd->GetEMCALMatrix(mod)->Print();
362             if(esd->GetEMCALMatrix(mod)) fEMCALGeo->SetMisalMatrix(esd->GetEMCALMatrix(mod),mod) ;
363           } 
364           fGeoMatrixSet=kTRUE;
365         }//ESD
366       }//Load matrices from Data 
367       
368     }//first event
369     
370     //Cluster Loop
371     Int_t nCaloClus = InputEvent()->GetNumberOfCaloClusters();
372     
373     for (Int_t iClust=0; iClust<nCaloClus; ++iClust) 
374     {
375       AliVCluster * cluster = InputEvent()->GetCaloCluster(iClust);
376       
377       if(cluster->IsPHOS()) continue ;
378       
379       Float_t position[]={0,0,0};
380       if(DebugLevel() > 2)
381         printf("Check cluster %d for bad channels and close to border\n",cluster->GetID());
382       if(fEMCALRecoUtils->ClusterContainsBadChannel(fEMCALGeo,cluster->GetCellsAbsId(), cluster->GetNCells())) continue;        
383       
384       if(DebugLevel() > 2)
385       { 
386         printf("Filter, before  : i %d, E %f, dispersion %f, m02 %f, m20 %f, distToBad %f\n",iClust,cluster->E(),
387                cluster->GetDispersion(),cluster->GetM02(),cluster->GetM20(), cluster->GetDistanceToBadChannel());
388         cluster->GetPosition(position);
389         printf("Filter, before  : i %d, x %f, y %f, z %f\n",cluster->GetID(), position[0], position[1], position[2]);
390       }
391       
392       //Recalculate distance to bad channels, if new list of bad channels provided
393       fEMCALRecoUtils->RecalculateClusterDistanceToBadChannel(fEMCALGeo, InputEvent()->GetEMCALCells(), cluster);
394       
395       if(fEMCALRecoUtils->IsRecalibrationOn())  
396       {
397         fEMCALRecoUtils->RecalibrateClusterEnergy(fEMCALGeo, cluster, InputEvent()->GetEMCALCells());
398         fEMCALRecoUtils->RecalculateClusterShowerShapeParameters(fEMCALGeo, InputEvent()->GetEMCALCells(),cluster);
399         fEMCALRecoUtils->RecalculateClusterPID(cluster);
400       }
401       
402       fEMCALRecoUtils->RecalculateClusterPosition(fEMCALGeo, InputEvent()->GetEMCALCells(),cluster);
403       
404       if(DebugLevel() > 2)
405       { 
406         printf("Filter, after   : i %d, E %f, dispersion %f, m02 %f, m20 %f, distToBad %f\n",cluster->GetID(),cluster->E(),
407                cluster->GetDispersion(),cluster->GetM02(),cluster->GetM20(), cluster->GetDistanceToBadChannel());
408         cluster->GetPosition(position);
409         printf("Filter, after   : i %d, x %f, y %f, z %f\n",cluster->GetID(), position[0], position[1], position[2]);
410       }    
411       
412       cluster->SetE(fEMCALRecoUtils->CorrectClusterEnergyLinearity(cluster));
413       
414     }
415     
416     //Recalculate track-matching
417     fEMCALRecoUtils->FindMatches(InputEvent(),0,fEMCALGeo);
418     
419   } // corrections in EMCAL
420 }
421
422 //________________________________________________
423 void AliAnalysisTaskCaloFilter::FillAODCaloCells()
424 {  
425   // Fill EMCAL/PHOS cell info
426   
427   // EMCAL
428   if ((fCaloFilter==kBoth ||  fCaloFilter==kEMCAL) && fEvent->GetEMCALCells()) 
429   { // protection against missing ESD information
430     AliVCaloCells &eventEMcells = *(fEvent->GetEMCALCells());
431     Int_t nEMcell = eventEMcells.GetNumberOfCells() ;
432     
433     AliAODCaloCells &aodEMcells = *(AODEvent()->GetEMCALCells());
434     aodEMcells.CreateContainer(nEMcell);
435     aodEMcells.SetType(AliVCaloCells::kEMCALCell);
436     Double_t calibFactor = 1.;   
437     for (Int_t iCell = 0; iCell < nEMcell; iCell++) 
438     { 
439       Int_t imod = -1, iphi =-1, ieta=-1,iTower = -1, iIphi = -1, iIeta = -1; 
440       fEMCALGeo->GetCellIndex(eventEMcells.GetCellNumber(iCell),imod,iTower,iIphi,iIeta); 
441       fEMCALGeo->GetCellPhiEtaIndexInSModule(imod,iTower,iIphi, iIeta,iphi,ieta);       
442       
443       if(fCorrect && fEMCALRecoUtils->IsRecalibrationOn())
444       { 
445         calibFactor = fEMCALRecoUtils->GetEMCALChannelRecalibrationFactor(imod,ieta,iphi);
446       }
447       
448       if(!fEMCALRecoUtils->GetEMCALChannelStatus(imod, ieta, iphi))
449       { //Channel is not declared as bad
450         aodEMcells.SetCell(iCell,eventEMcells.GetCellNumber(iCell),eventEMcells.GetAmplitude(iCell)*calibFactor,
451                            eventEMcells.GetTime(iCell),eventEMcells.GetMCLabel(iCell),eventEMcells.GetEFraction(iCell));
452         //printf("GOOD channel\n");
453       }
454       else 
455       {
456         aodEMcells.SetCell(iCell,eventEMcells.GetCellNumber(iCell),0,-1,-1,0);
457         //printf("BAD channel\n");
458       }
459     }
460     aodEMcells.Sort();
461   }
462   
463   // PHOS 
464   if ((fCaloFilter==kBoth ||  fCaloFilter==kPHOS) && fEvent->GetPHOSCells()) 
465   { // protection against missing ESD information
466     AliVCaloCells &eventPHcells = *(fEvent->GetPHOSCells());
467     Int_t nPHcell = eventPHcells.GetNumberOfCells() ;
468     
469     AliAODCaloCells &aodPHcells = *(AODEvent()->GetPHOSCells());
470     aodPHcells.CreateContainer(nPHcell);
471     aodPHcells.SetType(AliVCaloCells::kPHOSCell);
472     
473     for (Int_t iCell = 0; iCell < nPHcell; iCell++) 
474     {      
475       aodPHcells.SetCell(iCell,eventPHcells.GetCellNumber(iCell),eventPHcells.GetAmplitude(iCell),
476                          eventPHcells.GetTime(iCell),eventPHcells.GetMCLabel(iCell),eventPHcells.GetEFraction(iCell));
477     }
478     
479     aodPHcells.Sort();
480   }
481 }
482
483
484 //___________________________________________________
485 void AliAnalysisTaskCaloFilter::FillAODCaloClusters()
486 {
487   // Fill the AOD with caloclusters
488   
489   // Access to the AOD container of clusters
490   
491   TClonesArray &caloClusters = *(AODEvent()->GetCaloClusters());
492   Int_t jClusters=0;
493   Float_t  posF[3]  ;
494   
495   Int_t nCaloClus = fEvent->GetNumberOfCaloClusters();
496   for (Int_t iClust=0; iClust<nCaloClus; ++iClust) 
497   {
498     
499     AliVCluster * cluster = fEvent->GetCaloCluster(iClust);
500     
501     //Check which calorimeter information we want to keep.
502     
503     if(fCaloFilter!=kBoth)
504     {
505       if     (fCaloFilter==kPHOS  && cluster->IsEMCAL()) continue ;
506       else if(fCaloFilter==kEMCAL && cluster->IsPHOS())  continue ;
507     }  
508     
509     // Get original residuals, in case of previous recalculation, reset them 
510     Float_t dR = cluster->GetTrackDx();
511     Float_t dZ = cluster->GetTrackDz();
512     
513     if(DebugLevel() > 2)
514       printf("Original residuals : dZ %f, dR %f\n ",dZ, dR);
515     
516     //--------------------------------------------------------------
517     //If EMCAL and corrections done, get the new matching parameters, do not copy noisy clusters
518     if(cluster->IsEMCAL() && fCorrect)
519     {
520       if(DebugLevel() > 2)
521         printf("Check cluster %d for bad channels and close to border\n",cluster->GetID());
522       
523       if(fEMCALRecoUtils->ClusterContainsBadChannel(fEMCALGeo,cluster->GetCellsAbsId(), cluster->GetNCells())) continue;        
524       
525       if(fEMCALRecoUtils->IsExoticCluster(cluster, InputEvent()->GetEMCALCells(),InputEvent()->GetBunchCrossNumber())) continue;        
526       
527       fEMCALRecoUtils->GetMatchedResiduals(cluster->GetID(),dR,dZ);
528       cluster->SetTrackDistance(dR,dZ);
529     }
530     
531     if(DebugLevel() > 2)
532     {
533       if(cluster->IsEMCAL()) printf("EMCAL Track-Cluster Residuals : dZ %f, dR %f\n ",dZ, dR);
534       if(cluster->IsPHOS())  printf("PHOS  Track-Cluster Residuals : dZ %f, dR %f\n ",dZ, dR);
535     }
536     
537     //--------------------------------------------------------------
538     
539     //Now fill AODs
540     
541     Int_t id       = cluster->GetID();
542     Float_t energy = cluster->E();
543     cluster->GetPosition(posF);
544     
545     AliAODCaloCluster *caloCluster = new(caloClusters[jClusters++]) 
546     AliAODCaloCluster(id,
547                       cluster->GetNLabels(),
548                       cluster->GetLabels(),
549                       energy,
550                       posF,
551                       NULL,
552                       cluster->GetType());
553     
554     caloCluster->SetCaloCluster(cluster->GetDistanceToBadChannel(),
555                                 cluster->GetDispersion(),
556                                 cluster->GetM20(), cluster->GetM02(),
557                                 -1,  
558                                 cluster->GetNExMax(),cluster->GetTOF()) ;
559     
560     caloCluster->SetPIDFromESD(cluster->GetPID());
561     caloCluster->SetNCells(cluster->GetNCells());
562     caloCluster->SetCellsAbsId(cluster->GetCellsAbsId());
563     caloCluster->SetCellsAmplitudeFraction(cluster->GetCellsAmplitudeFraction());
564     caloCluster->SetTrackDistance(dR, dZ);
565     
566     if(DebugLevel() > 2)
567     { 
568       printf("Filter, aod     : i %d, E %f, dispersion %f, m02 %f, m20 %f\n",caloCluster->GetID(),caloCluster->E(),
569              caloCluster->GetDispersion(),caloCluster->GetM02(),caloCluster->GetM20());
570       caloCluster->GetPosition(posF);
571       printf("Filter, aod     : i %d, x %f, y %f, z %f\n",caloCluster->GetID(), posF[0], posF[1], posF[2]);
572     }    
573     
574     //Matched tracks, just to know if there was any match, the track pointer is useless if tracks not stored
575     if(TMath::Abs(dR) < 990 && TMath::Abs(dZ) < 990) 
576     { //Default value in PHOS 999, in EMCAL 1024, why?
577       caloCluster->AddTrackMatched(new AliAODTrack); 
578     }
579     // TO DO, in case Tracks available, think how to put the matched track in AOD
580   }
581   
582   caloClusters.Expand(jClusters); // resize TObjArray to 'remove' slots  
583   
584 }
585
586 //__________________________________________________
587 void AliAnalysisTaskCaloFilter::FillAODCaloTrigger()
588 {
589   // AOD CaloTrigger copy
590   
591   AliAODCaloTrigger* triggerEM = AODEvent()->GetCaloTrigger("EMCAL");
592   AliAODCaloTrigger* triggerPH = AODEvent()->GetCaloTrigger("PHOS");
593   
594   // Copy from AODs
595   if(fAODEvent)
596   {
597     if(fCaloFilter==kBoth || fCaloFilter==kPHOS)  *triggerPH = *(fAODEvent->GetCaloTrigger("PHOS"));
598     
599     if(fCaloFilter==kBoth || fCaloFilter==kEMCAL) *triggerEM = *(fAODEvent->GetCaloTrigger("EMCAL"));
600     
601     return;
602   }
603   
604 }  
605
606 //______________________________________________
607 void AliAnalysisTaskCaloFilter::FillAODHeader()
608 {
609   // AOD header copy
610   
611   AliAODHeader* header = AODEvent()->GetHeader();
612   
613   // Copy from AODs
614   if(fAODEvent)
615   {
616     *header = *(fAODEvent->GetHeader());
617     return;
618   }
619   
620   if(!fESDEvent) return;
621   
622   // Copy from ESDs
623   
624   header->SetRunNumber(fEvent->GetRunNumber());
625   
626   TTree* tree = fInputHandler->GetTree();
627   if (tree) 
628   {
629     TFile* file = tree->GetCurrentFile();
630     if (file) header->SetESDFileName(file->GetName());
631   }
632   
633   header->SetBunchCrossNumber(fEvent->GetBunchCrossNumber());
634   header->SetOrbitNumber(fEvent->GetOrbitNumber());
635   header->SetPeriodNumber(fEvent->GetPeriodNumber());
636   header->SetEventType(fEvent->GetEventType());
637   
638   //Centrality
639   if(fEvent->GetCentrality())
640   {
641     header->SetCentrality(new AliCentrality(*(fEvent->GetCentrality())));
642   }
643   else
644   {
645     header->SetCentrality(0);
646   }
647   
648   //Trigger  
649   header->SetOfflineTrigger(fInputHandler->IsEventSelected()); // propagate the decision of the physics selection
650   header->SetFiredTriggerClasses(fESDEvent->GetFiredTriggerClasses());
651   header->SetTriggerMask(fEvent->GetTriggerMask()); 
652   header->SetTriggerCluster(fEvent->GetTriggerCluster());
653   header->SetL0TriggerInputs(fESDEvent->GetHeader()->GetL0TriggerInputs());    
654   header->SetL1TriggerInputs(fESDEvent->GetHeader()->GetL1TriggerInputs());    
655   header->SetL2TriggerInputs(fESDEvent->GetHeader()->GetL2TriggerInputs());    
656   
657   header->SetMagneticField(fEvent->GetMagneticField());
658   //header->SetMuonMagFieldScale(fESDEvent->GetCurrentDip()/6000.); 
659   
660   header->SetZDCN1Energy(fEvent->GetZDCN1Energy());
661   header->SetZDCP1Energy(fEvent->GetZDCP1Energy());
662   header->SetZDCN2Energy(fEvent->GetZDCN2Energy());
663   header->SetZDCP2Energy(fEvent->GetZDCP2Energy());
664   header->SetZDCEMEnergy(fEvent->GetZDCEMEnergy(0),fEvent->GetZDCEMEnergy(1));
665   
666   Float_t diamxy[2]={fEvent->GetDiamondX(),fEvent->GetDiamondY()};
667   Float_t diamcov[3];
668   fEvent->GetDiamondCovXY(diamcov);
669   header->SetDiamond(diamxy,diamcov);
670   header->SetDiamondZ(fESDEvent->GetDiamondZ(),fESDEvent->GetSigma2DiamondZ());
671   
672 }
673
674 //_____________________________________________
675 void AliAnalysisTaskCaloFilter::FillAODTracks()
676 {
677   // AOD track copy
678   
679   if(!fFillTracks) return;
680   
681   AliAODTrack* aodTrack(0x0);
682   
683   Double_t pos[3]   = { 0. };      
684   Double_t covTr[21]= { 0. };
685   Double_t pid[10]  = { 0. };  
686   Double_t p[3]     = { 0. };
687     
688   // Copy from AODs
689   if(fAODEvent)
690   {
691     //TClonesArray* inTracks = fAODEvent  ->GetTracks();
692     TClonesArray* ouTracks = AODEvent()->GetTracks();
693                 //new (ouTracks) TClonesArray(*inTracks);
694     
695     //printf("N tracks %d\n",fAODEvent->GetNumberOfTracks());
696     Int_t nCopyTrack = 0;
697     for (Int_t nTrack = 0; nTrack < fAODEvent->GetNumberOfTracks(); ++nTrack) 
698     {
699       AliAODTrack *track = fAODEvent->GetTrack(nTrack);
700       
701       // Select only hybrid tracks?
702       if(fFillHybridTracks && !track->IsHybridGlobalConstrainedGlobal()) continue;
703       
704       // Remove PID object to save space
705       //track->SetDetPID(0x0);
706       
707       //new((*ouTracks)[nCopyTrack++]) AliAODTrack(*track);
708       
709       track->GetPxPyPz(p);
710       Bool_t isDCA  = track->GetPosition(pos);
711       track->GetCovMatrix(covTr);
712       track->GetPID(pid);
713       
714       AliAODVertex* primVertex = (AliAODVertex*) AODEvent()->GetVertices()->At(0); // primary vertex, copied previously!!!
715
716       aodTrack = new((*ouTracks)[nCopyTrack++]) AliAODTrack(
717                                                             track->GetID(),
718                                                             track->GetLabel(),
719                                                             p,
720                                                             kTRUE,
721                                                             pos,
722                                                             isDCA,
723                                                             covTr, 
724                                                             track->Charge(),
725                                                             track->GetITSClusterMap(), 
726                                                             pid,
727                                                             primVertex,
728                                                             track->GetUsedForVtxFit(),
729                                                             track->GetUsedForPrimVtxFit(),
730                                                             (AliAODTrack::AODTrk_t) track->GetType(), 
731                                                             track->GetFilterMap(),
732                                                             track->Chi2perNDF());
733       
734       
735       aodTrack->SetIsHybridGlobalConstrainedGlobal(track->IsHybridGlobalConstrainedGlobal());   
736       aodTrack->SetIsHybridTPCConstrainedGlobal   (track->IsHybridTPCConstrainedGlobal());    
737       aodTrack->SetIsGlobalConstrained            (track->IsGlobalConstrained());  
738       aodTrack->SetIsTPCConstrained               (track->IsTPCConstrained());    
739       
740       aodTrack->SetTPCFitMap    (track->GetTPCFitMap());
741       aodTrack->SetTPCClusterMap(track->GetTPCClusterMap());
742       aodTrack->SetTPCSharedMap (track->GetTPCSharedMap());
743       
744       aodTrack->SetChi2MatchTrigger(track->GetChi2MatchTrigger());
745       
746       // set the DCA values to the AOD track
747     
748       aodTrack->SetPxPyPzAtDCA(track->PxAtDCA(),track->PyAtDCA(),track->PzAtDCA());
749       aodTrack->SetXYAtDCA    (track->XAtDCA() ,track->YAtDCA());
750       
751       aodTrack->SetFlags      (track->GetFlags());
752       aodTrack->SetTPCPointsF (track->GetTPCNclsF());
753       
754       // Calo 
755       
756       if(track->IsEMCAL()) aodTrack->SetEMCALcluster(track->GetEMCALcluster());
757       if(track->IsPHOS())  aodTrack->SetPHOScluster (track->GetPHOScluster());
758       aodTrack->SetTrackPhiEtaOnEMCal( track->GetTrackPhiOnEMCal(),  track->GetTrackPhiOnEMCal() );
759           
760     } 
761     
762     //printf("Final N tracks %d\n",nCopyTrack);
763     
764     return;
765   }
766   
767 }  
768
769 //_________________________________________
770 void AliAnalysisTaskCaloFilter::FillAODv0s()
771 {
772   // Copy v0s (use if you know what you do, use quite a lot of memory)
773   
774   if(!fFillv0s) return;
775   
776   // Copy from AODs
777   if(fAODEvent)
778   {
779     TClonesArray* inv0 = fAODEvent  ->GetV0s();
780     TClonesArray* ouv0 =  AODEvent()->GetV0s();
781     
782                 //new (ouv0s) TClonesArray(*inv0s);
783     
784     Int_t allv0s = inv0->GetEntriesFast();
785     
786     for (Int_t nv0s = 0; nv0s < allv0s; ++nv0s) 
787     {
788       AliAODv0 *v0 = (AliAODv0*)inv0->At(nv0s);
789       
790       new((*ouv0)[nv0s]) AliAODv0(*v0);
791     } 
792     
793     return;
794   }
795   
796 }  
797
798 //____________________________________________
799 void AliAnalysisTaskCaloFilter::FillAODVZERO()
800 {
801   // Copy VZERO
802   
803   if(!fFillVZERO) return;
804   
805   AliAODVZERO* vzeroData = AODEvent()->GetVZEROData();
806   
807   if(fESDEvent) *vzeroData = *(fESDEvent->GetVZEROData());
808   else          *vzeroData = *(fAODEvent->GetVZEROData());
809   
810 }  
811
812 //_______________________________________________
813 void AliAnalysisTaskCaloFilter::FillAODVertices()
814 {
815   // Copy vertices
816   
817   // set arrays and pointers
818   Double_t pos[3]   ;
819   Double_t covVtx[6];
820   for (Int_t i = 0; i < 6; i++)  covVtx[i] = 0.;
821   
822   // Copy from AODs
823   if(fAODEvent)
824   {
825     TClonesArray* inVertices = fAODEvent  ->GetVertices();
826     TClonesArray* ouVertices = AODEvent()->GetVertices();
827     
828                 //new (ouVertices) TClonesArray(*inVertices);
829     
830     //Keep only the first 3 vertices if not requested
831     Int_t allVertices = inVertices->GetEntriesFast();
832     
833     //printf("n Vertices %d\n",allVertices);
834     
835     if(!fFillAllVertices) 
836     {
837       if(allVertices >  3) allVertices = 3;
838     }
839     
840     //printf("Final n Vertices %d\n",allVertices);
841     
842     for (Int_t nVertices = 0; nVertices < allVertices; ++nVertices) 
843     {
844       AliAODVertex *vertex = (AliAODVertex*)inVertices->At(nVertices);
845       
846       new((*ouVertices)[nVertices]) AliAODVertex(*vertex);
847     } 
848     
849     return;
850   }
851   
852   if(!fESDEvent) return;
853   
854   // Copy from ESDs
855   
856   // Access to the AOD container of vertices
857   Int_t jVertices=0;
858   TClonesArray &vertices = *(AODEvent()->GetVertices());
859   
860   // Add primary vertex. The primary tracks will be defined
861   // after the loops on the composite objects (v0, cascades, kinks)
862   fEvent   ->GetPrimaryVertex()->GetXYZ(pos);
863   fESDEvent->GetPrimaryVertex()->GetCovMatrix(covVtx);
864   Float_t chi = fESDEvent->GetPrimaryVertex()->GetChi2toNDF();
865   
866   AliAODVertex * primary = new(vertices[jVertices++])
867   AliAODVertex(pos, covVtx, chi, NULL, -1, AliAODVertex::kPrimary);
868   primary->SetName(fEvent->GetPrimaryVertex()->GetName());
869   primary->SetTitle(fEvent->GetPrimaryVertex()->GetTitle());
870   
871 }
872
873 //____________________________________
874 void AliAnalysisTaskCaloFilter::Init()
875 {
876   //Init analysis with configuration macro if available
877   
878   if(gROOT->LoadMacro(fConfigName) >=0)
879   {
880     printf("Configure analysis with %s\n",fConfigName.Data());
881     
882     AliAnalysisTaskCaloFilter *filter = (AliAnalysisTaskCaloFilter*)gInterpreter->ProcessLine("ConfigCaloFilter()");
883     
884     fEMCALGeoName      = filter->fEMCALGeoName; 
885     fLoadEMCALMatrices = filter->fLoadEMCALMatrices;
886     fFillAODFile       = filter->fFillAODFile;
887     fFillTracks        = filter->fFillTracks;
888     fFillHybridTracks  = filter->fFillHybridTracks;
889     fFillv0s           = filter->fFillv0s;
890     fFillVZERO         = filter->fFillVZERO;
891     fFillAllVertices   = filter->fFillAllVertices;
892     fEMCALRecoUtils    = filter->fEMCALRecoUtils; 
893     fConfigName        = filter->fConfigName;
894     fCaloFilter        = filter->fCaloFilter;
895     fEventSelection[0] = filter->fEventSelection[0];
896     fEventSelection[1] = filter->fEventSelection[1];
897     fEventSelection[2] = filter->fEventSelection[2];
898     fAcceptAllMBEvent  = filter->fAcceptAllMBEvent;
899     fCorrect           = filter->fCorrect;
900     fEMCALEnergyCut    = filter->fEMCALEnergyCut;
901     fEMCALNcellsCut    = filter->fEMCALNcellsCut;
902     fPHOSEnergyCut     = filter->fPHOSEnergyCut;
903     fPHOSNcellsCut     = filter->fPHOSNcellsCut;
904     fTrackPtCut        = filter->fTrackPtCut;
905     fVzCut             = filter->fVzCut;
906     
907     for(Int_t i = 0; i < 12; i++) fEMCALMatrix[i] = filter->fEMCALMatrix[i] ;
908   }
909
910
911 //_________________________________________
912 void AliAnalysisTaskCaloFilter::PrintInfo()
913 {
914   //Print settings
915   
916   printf("AnalysisCaloFilter::PrintInfo() \n");
917   
918   printf("\t Not only filter, correct Clusters? %d\n",fCorrect);
919   printf("\t Calorimeter Filtering Option     ? %d\n",fCaloFilter);
920   
921   //printf("\t Use handmade geo matrices?   EMCAL %d, PHOS %d\n",fLoadEMCALMatrices, fLoadPHOSMatrices);
922   printf("\t Use handmade geo matrices?   EMCAL %d, PHOS 0\n",fLoadEMCALMatrices);
923   
924   printf("\t Fill: AOD file? %d Tracks? %d; all Vertex? %d; v0s? %d; VZERO ? %d\n", 
925          fFillAODFile,fFillTracks,fFillAllVertices, fFillv0s, fFillVZERO);
926   
927   printf("\t Event Selection based : EMCAL?  %d, PHOS?  %d Tracks? %d - Accept all MB? %d\n",
928          fEventSelection[0],fEventSelection[1],fEventSelection[2],fAcceptAllMBEvent);
929   
930   printf("\t \t EMCAL E > %2.2f, EMCAL nCells >= %d, PHOS E > %2.2f, PHOS nCells >= %d, Track pT > %2.2f, |vz| < %2.2f\n",
931          fEMCALEnergyCut,fEMCALNcellsCut,fPHOSEnergyCut,fPHOSNcellsCut, fTrackPtCut,fVzCut);
932 }
933
934 //_______________________________________________________
935 void AliAnalysisTaskCaloFilter::UserCreateOutputObjects()
936 {
937   // Init geometry 
938         
939   fEMCALGeo =  AliEMCALGeometry::GetInstance(fEMCALGeoName) ;   
940   
941 }  
942
943 //____________________________________________________________
944 void AliAnalysisTaskCaloFilter::UserExec(Option_t */*option*/)
945 {
946   // Execute analysis for current event
947   // Copy input ESD or AOD header, vertex, CaloClusters and CaloCells to output AOD
948   
949   if (fDebug > 0)  
950     printf("CaloFilter: Analysing event # %d\n", (Int_t)Entry());
951   
952   fEvent    = InputEvent();
953   fAODEvent = dynamic_cast<AliAODEvent*> (fEvent);  
954   fESDEvent = dynamic_cast<AliESDEvent*> (fEvent);
955   
956   if(!fEvent) 
957   {
958     printf("AliAnalysisTaskCaloFilter::UserExec - This event does not contain Input?");
959     return;
960   }
961   
962   // printf("Start processing : %s\n",fAODEvent->GetFiredTriggerClasses().Data());
963   
964   // Select the event
965   
966   if(!AcceptEvent()) return ;
967   
968   //Magic line to write events to file
969   
970   AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillAOD(fFillAODFile);
971   
972   // Reset output AOD
973   
974   Int_t nVertices = 0;
975   if(fFillv0s) nVertices = fEvent->GetNumberOfV0s();
976   Int_t nCaloClus = fEvent->GetNumberOfCaloClusters();
977   Int_t nTracks   = fEvent->GetNumberOfTracks();
978   
979   AODEvent()->ResetStd(nTracks, nVertices, 0, 0, 0, nCaloClus, 0, 0);
980   
981   // Copy
982   
983   FillAODHeader();
984   
985   // 
986   FillAODv0s();
987   
988   //
989   FillAODVertices(); // Do it before the track filtering to have the reference to the vertex
990   
991   // 
992   FillAODVZERO();
993   
994   //
995   FillAODTracks();
996   
997   //
998   CorrectionsInEMCAL();
999   
1000   //
1001   FillAODCaloClusters();
1002   
1003   //
1004   FillAODCaloCells();
1005   
1006   //
1007   FillAODCaloTrigger();
1008   
1009   //printf("Filtered event, end processing : %s\n",fAODEvent->GetFiredTriggerClasses().Data());
1010   
1011 }
1012