]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG4/CaloCalib/AliAnalysisTaskEMCALClusterize.cxx
Change AliEMCALGeoUtils to AliEMCALGeometry
[u/mrichter/AliRoot.git] / PWG4 / CaloCalib / AliAnalysisTaskEMCALClusterize.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 /* $Id: $ */
16
17 //_________________________________________________________________________
18 // This analysis provides a new list of clusters to be used in other analysis
19 //
20 // Author: Gustavo Conesa Balbastre,
21 //         Adapted from analysis class from Deepa Thomas
22 //
23 //
24 //_________________________________________________________________________
25
26 // --- Root ---
27 #include "TString.h"
28 #include "TRefArray.h"
29 #include "TClonesArray.h"
30 #include "TTree.h"
31 #include "TGeoManager.h"
32 #include "TROOT.h"
33 #include "TInterpreter.h"
34 #include "TFile.h"
35 //#include "string.h"
36
37 // --- AliRoot Analysis Steering
38 #include "AliAnalysisTask.h"
39 #include "AliAnalysisManager.h"
40 #include "AliESDEvent.h"
41 #include "AliGeomManager.h"
42 #include "AliVCaloCells.h"
43 #include "AliAODCaloCluster.h"
44 #include "AliCDBManager.h"
45 #include "AliCDBStorage.h"
46 #include "AliCDBEntry.h"
47 #include "AliLog.h"
48 #include "AliVEventHandler.h"
49 #include "AliAODInputHandler.h"
50
51 // --- EMCAL
52 #include "AliEMCALRecParam.h"
53 #include "AliEMCALAfterBurnerUF.h"
54 #include "AliEMCALGeometry.h"
55 #include "AliEMCALClusterizerNxN.h"
56 #include "AliEMCALClusterizerv1.h"
57 #include "AliEMCALClusterizerv2.h"
58 #include "AliEMCALRecPoint.h"
59 #include "AliEMCALDigit.h"
60 #include "AliCaloCalibPedestal.h"
61 #include "AliEMCALCalibData.h"
62 #include "AliEMCALRecoUtils.h"
63
64 #include "AliAnalysisTaskEMCALClusterize.h"
65
66 ClassImp(AliAnalysisTaskEMCALClusterize)
67
68 //________________________________________________________________________
69 AliAnalysisTaskEMCALClusterize::AliAnalysisTaskEMCALClusterize(const char *name) 
70   : AliAnalysisTaskSE(name)
71   , fGeom(0), fGeomName("EMCAL_FIRSTYEARV1"),  fGeomMatrixSet(kFALSE), fLoadGeomMatrices(kFALSE)
72   , fCalibData(0),       fPedestalData(0),     fOCDBpath("raw://"),    fAccessOCDB(kFALSE)
73   , fDigitsArr(0),       fClusterArr(0),       fCaloClusterArr(0)
74   , fRecParam(0),        fClusterizer(0),      fUnfolder(0),           fJustUnfold(kFALSE) 
75   , fOutputAODBranch(0), fOutputAODBranchName("newEMCALClusters")
76   , fFillAODFile(kTRUE), fFillAODHeader(0),    fFillAODCaloCells(0)
77   , fRun(-1),            fRecoUtils(0),        fConfigName("")
78   , fCellLabels(),       fCellSecondLabels(),  fMaxEvent(1000000000),  fDoTrackMatching(kFALSE)
79   
80   {
81   //ctor
82   for(Int_t i = 0; i < 10;    i++)  fGeomMatrix[i] =  0;
83     for(Int_t j = 0; j < 24*48*11; j++)  {
84       fCellLabels[j]       = -1;
85       fCellSecondLabels[j] = -1;
86     }  
87   fDigitsArr       = new TClonesArray("AliEMCALDigit",200);
88   fClusterArr      = new TObjArray(100);
89   fCaloClusterArr  = new TObjArray(100);
90   fRecParam        = new AliEMCALRecParam;
91   fBranchNames     = "ESD:AliESDHeader.,EMCALCells.";
92   fRecoUtils       = new AliEMCALRecoUtils();
93 }
94
95 //________________________________________________________________________
96 AliAnalysisTaskEMCALClusterize::AliAnalysisTaskEMCALClusterize() 
97   : AliAnalysisTaskSE("DefaultAnalysis_AliAnalysisTaskEMCALClusterize")
98   , fGeom(0), fGeomName("EMCAL_FIRSTYEARV1"),   fGeomMatrixSet(kFALSE), fLoadGeomMatrices(kFALSE)
99   , fCalibData(0),        fPedestalData(0),     fOCDBpath("raw://"),    fAccessOCDB(kFALSE)  
100   , fDigitsArr(0),        fClusterArr(0),       fCaloClusterArr(0)
101   , fRecParam(0),         fClusterizer(0),      fUnfolder(0),           fJustUnfold(kFALSE)
102   , fOutputAODBranch(0),  fOutputAODBranchName("newEMCALClusters")
103   , fFillAODFile(kFALSE), fFillAODHeader(0),    fFillAODCaloCells(0)
104   , fRun(-1),             fRecoUtils(0),        fConfigName("") 
105   , fCellLabels(),        fCellSecondLabels(),  fMaxEvent(1000000000),  fDoTrackMatching(kFALSE)
106 {
107   // Constructor
108   for(Int_t i = 0; i < 10;    i++)  fGeomMatrix[i] =  0;
109   for(Int_t j = 0; j < 24*48*11; j++)  {
110     fCellLabels[j]       = -1;
111     fCellSecondLabels[j] = -1;
112   }
113   fDigitsArr       = new TClonesArray("AliEMCALDigit",200);
114   fClusterArr      = new TObjArray(100);
115   fCaloClusterArr  = new TObjArray(100);
116   fRecParam        = new AliEMCALRecParam;
117   fBranchNames     = "ESD:AliESDHeader.,EMCALCells.";
118   fRecoUtils       = new AliEMCALRecoUtils();
119 }
120
121
122 //________________________________________________________________________
123 AliAnalysisTaskEMCALClusterize::~AliAnalysisTaskEMCALClusterize()
124 {
125   //dtor 
126   
127   if (fDigitsArr){
128     fDigitsArr->Clear("C");
129     delete fDigitsArr; 
130   }
131   
132   if (fClusterArr){
133     fClusterArr->Delete();
134     delete fClusterArr;
135   }
136   
137   if (fCaloClusterArr){
138     fCaloClusterArr->Delete();
139     delete fCaloClusterArr; 
140   }
141
142   if(fClusterizer) delete fClusterizer;
143   if(fUnfolder)    delete fUnfolder;   
144   if(fRecoUtils)   delete fRecoUtils;
145
146 }
147
148 //-------------------------------------------------------------------
149 void AliAnalysisTaskEMCALClusterize::Init()
150 {
151   //Init analysis with configuration macro if available
152   
153   if(gROOT->LoadMacro(fConfigName) >=0){
154     printf("Configure analysis with %s\n",fConfigName.Data());
155     AliAnalysisTaskEMCALClusterize *clus = (AliAnalysisTaskEMCALClusterize*)gInterpreter->ProcessLine("ConfigEMCALClusterize()");
156     fGeomName         = clus->fGeomName; 
157     fLoadGeomMatrices = clus->fLoadGeomMatrices;
158     fOCDBpath         = clus->fOCDBpath;   
159     fAccessOCDB       = clus->fAccessOCDB;
160     fRecParam         = clus->fRecParam;
161     fJustUnfold       = clus->fJustUnfold;
162     fFillAODFile      = clus->fFillAODFile;
163     fRecoUtils        = clus->fRecoUtils; 
164     fConfigName       = clus->fConfigName;
165     fMaxEvent         = clus->fMaxEvent;
166     fDoTrackMatching  = clus->fDoTrackMatching;
167     fOutputAODBranchName = clus->fOutputAODBranchName;
168     for(Int_t i = 0; i < 10; i++) fGeomMatrix[i] = clus->fGeomMatrix[i] ;
169
170   }
171
172 }  
173
174 //-------------------------------------------------------------------
175 void AliAnalysisTaskEMCALClusterize::UserCreateOutputObjects()
176 {
177   // Init geometry, create list of output clusters
178
179   fGeom =  AliEMCALGeometry::GetInstance(fGeomName) ;   
180   if(fOutputAODBranchName.Length()!=0){
181     fOutputAODBranch = new TClonesArray("AliAODCaloCluster", 0);
182     fOutputAODBranch->SetName(fOutputAODBranchName);
183     AddAODBranch("TClonesArray", &fOutputAODBranch);
184   }
185   else {
186     AliFatal("fOutputAODBranchName not set\n");
187   }
188 }
189
190 //________________________________________________________________________
191 void AliAnalysisTaskEMCALClusterize::FillAODCaloCells() {
192   // Put calo cells in standard branch  
193   AliVEvent * event = InputEvent();
194   AliVCaloCells &eventEMcells = *(event->GetEMCALCells());
195   Int_t nEMcell = eventEMcells.GetNumberOfCells() ;
196   
197   AliAODCaloCells &aodEMcells = *(AODEvent()->GetEMCALCells());
198   aodEMcells.CreateContainer(nEMcell);
199   aodEMcells.SetType(AliVCaloCells::kEMCALCell);
200   Double_t calibFactor = 1.;   
201   for (Int_t iCell = 0; iCell < nEMcell; iCell++) { 
202     Int_t imod = -1, iphi =-1, ieta=-1,iTower = -1, iIphi = -1, iIeta = -1; 
203     fGeom->GetCellIndex(eventEMcells.GetCellNumber(iCell),imod,iTower,iIphi,iIeta); 
204     fGeom->GetCellPhiEtaIndexInSModule(imod,iTower,iIphi, iIeta,iphi,ieta);     
205     
206     if(fRecoUtils->IsRecalibrationOn()){ 
207       calibFactor = fRecoUtils->GetEMCALChannelRecalibrationFactor(imod,ieta,iphi);
208     }
209     
210     if(!fRecoUtils->GetEMCALChannelStatus(imod, ieta, iphi)){ //Channel is not declared as bad
211       aodEMcells.SetCell(iCell,eventEMcells.GetCellNumber(iCell),eventEMcells.GetAmplitude(iCell)*calibFactor);
212       //printf("GOOD channel\n");
213     }
214     else {
215       aodEMcells.SetCell(iCell,eventEMcells.GetCellNumber(iCell),0);
216       //printf("BAD channel\n");
217     }
218   }
219   aodEMcells.Sort();
220   
221 }
222
223 //________________________________________________________________________
224 void AliAnalysisTaskEMCALClusterize::FillAODHeader() {
225   //Put event header information in standard AOD branch
226   
227   AliVEvent* event      = InputEvent();
228   AliESDEvent* esdevent = dynamic_cast<AliESDEvent*> (event);
229   AliAODEvent* aodevent = dynamic_cast<AliAODEvent*> (event);
230
231   Double_t pos[3]   ;
232   Double_t covVtx[6];
233   for (Int_t i = 0; i < 6; i++)  covVtx[i] = 0.;
234   
235   AliAODHeader* header = AODEvent()->GetHeader();
236   header->SetRunNumber(event->GetRunNumber());
237   
238   if(esdevent){
239     TTree* tree = fInputHandler->GetTree();
240     if (tree) {
241       TFile* file = tree->GetCurrentFile();
242       if (file) header->SetESDFileName(file->GetName());
243     }
244   }
245   else if (aodevent) header->SetESDFileName(aodevent->GetHeader()->GetESDFileName());
246   
247   header->SetBunchCrossNumber(event->GetBunchCrossNumber());
248   header->SetOrbitNumber(event->GetOrbitNumber());
249   header->SetPeriodNumber(event->GetPeriodNumber());
250   header->SetEventType(event->GetEventType());
251   
252   //Centrality
253   if(event->GetCentrality()){
254     header->SetCentrality(new AliCentrality(*(event->GetCentrality())));
255   }
256   else{
257     header->SetCentrality(0);
258   }
259   
260   //Trigger  
261   header->SetOfflineTrigger(fInputHandler->IsEventSelected()); // propagate the decision of the physics selection
262   if      (esdevent) header->SetFiredTriggerClasses(esdevent->GetFiredTriggerClasses());
263   else if (aodevent) header->SetFiredTriggerClasses(aodevent->GetFiredTriggerClasses());
264   header->SetTriggerMask(event->GetTriggerMask()); 
265   header->SetTriggerCluster(event->GetTriggerCluster());
266   if(esdevent){
267     header->SetL0TriggerInputs(esdevent->GetHeader()->GetL0TriggerInputs());    
268     header->SetL1TriggerInputs(esdevent->GetHeader()->GetL1TriggerInputs());    
269     header->SetL2TriggerInputs(esdevent->GetHeader()->GetL2TriggerInputs());    
270   }
271   else if (aodevent){
272     header->SetL0TriggerInputs(aodevent->GetHeader()->GetL0TriggerInputs());    
273     header->SetL1TriggerInputs(aodevent->GetHeader()->GetL1TriggerInputs());    
274     header->SetL2TriggerInputs(aodevent->GetHeader()->GetL2TriggerInputs());    
275   }
276   
277   header->SetMagneticField(event->GetMagneticField());
278   //header->SetMuonMagFieldScale(esdevent->GetCurrentDip()/6000.); 
279   
280   header->SetZDCN1Energy(event->GetZDCN1Energy());
281   header->SetZDCP1Energy(event->GetZDCP1Energy());
282   header->SetZDCN2Energy(event->GetZDCN2Energy());
283   header->SetZDCP2Energy(event->GetZDCP2Energy());
284   header->SetZDCEMEnergy(event->GetZDCEMEnergy(0),event->GetZDCEMEnergy(1));
285   
286   Float_t diamxy[2]={event->GetDiamondX(),event->GetDiamondY()};
287   Float_t diamcov[3];
288   event->GetDiamondCovXY(diamcov);
289   header->SetDiamond(diamxy,diamcov);
290   if      (esdevent) header->SetDiamondZ(esdevent->GetDiamondZ(),esdevent->GetSigma2DiamondZ());
291   else if (aodevent) header->SetDiamondZ(aodevent->GetDiamondZ(),aodevent->GetSigma2DiamondZ());
292   
293   //
294   //
295   Int_t nVertices = 1 ;/* = prim. vtx*/;
296   Int_t nCaloClus = event->GetNumberOfCaloClusters();
297   
298   AODEvent()->ResetStd(0, nVertices, 0, 0, 0, nCaloClus, 0, 0);
299   
300   // Access to the AOD container of vertices
301   TClonesArray &vertices = *(AODEvent()->GetVertices());
302   Int_t jVertices=0;
303   
304   // Add primary vertex. The primary tracks will be defined
305   // after the loops on the composite objects (V0, cascades, kinks)
306   event->GetPrimaryVertex()->GetXYZ(pos);
307   Float_t chi = 0;
308   if      (esdevent){
309     esdevent->GetPrimaryVertex()->GetCovMatrix(covVtx);
310     chi = esdevent->GetPrimaryVertex()->GetChi2toNDF();
311   }
312   else if (aodevent){
313     aodevent->GetPrimaryVertex()->GetCovMatrix(covVtx);
314     chi = aodevent->GetPrimaryVertex()->GetChi2perNDF();//Different from ESD?
315   }
316   
317   AliAODVertex * primary = new(vertices[jVertices++])
318   AliAODVertex(pos, covVtx, chi, NULL, -1, AliAODVertex::kPrimary);
319   primary->SetName(event->GetPrimaryVertex()->GetName());
320   primary->SetTitle(event->GetPrimaryVertex()->GetTitle());
321   
322 }
323
324 //________________________________________________________________________
325 void AliAnalysisTaskEMCALClusterize::UserExec(Option_t *) 
326 {
327   // Main loop
328   // Called for each event
329
330   AliAODInputHandler* aodIH = dynamic_cast<AliAODInputHandler*>((AliAnalysisManager::GetAnalysisManager())->GetInputEventHandler());
331   Int_t eventN = Entry();
332   if(aodIH) eventN = aodIH->GetReadEntry(); 
333   
334   if (eventN > fMaxEvent) return;
335   //printf("Clusterizer --- Event %d-- \n",eventN);
336
337   //Remove the contents of output list set in the previous event 
338   fOutputAODBranch->Clear("C");
339   
340 //  if(fOutputAODBranchName.Length()!=0){
341 //    //Remove the contents of output list set in the previous event 
342 //    fOutputAODBranch->Clear("C");
343 //  }
344 //  else{ 
345 //    //Reset and put new clusters in standard branch, also cells
346 //    AODEvent()->ResetStd(0, 1, 0, 0, 0, AODEvent()->GetNumberOfCaloClusters(), 0, 0);
347 //    fOutputAODBranch = AODEvent()->GetCaloClusters();// Put new clusters in standard branch
348 //  }
349   
350   //Magic line to write events to AOD file
351   AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillAOD(fFillAODFile);
352   LoadBranches();
353   
354   
355   //Init pointers, clusterizer, ocdb
356   if(fAccessOCDB) AccessOCDB();
357   InitClusterization();
358
359   //Get the event
360   AliVEvent   * event    = 0;
361   AliESDEvent * esdevent = 0;
362     
363   //Fill output event with headerø
364
365   //Check if input event are embedded events
366   //If so, take output event
367   if (aodIH && aodIH->GetMergeEvents()) {
368     //printf("AliAnalysisTaskEMCALClusterize::UserExec() - Use embedded events\n");
369     event  = AODEvent();
370     
371     if(!aodIH->GetMergeEMCALCells()) 
372       AliFatal("Events merged but not EMCAL cells, check analysis settings!");
373     
374 //    printf("InputEvent  N Clusters %d, N Cells %d\n",InputEvent()->GetNumberOfCaloClusters(),
375 //           InputEvent()->GetEMCALCells()->GetNumberOfCells());
376 //    printf("MergedEvent  N Clusters %d, N Cells %d\n",aodIH->GetEventToMerge()->GetNumberOfCaloClusters(),
377 //           aodIH->GetEventToMerge()->GetEMCALCells()->GetNumberOfCells());
378 //    for (Int_t icl=0; icl < aodIH->GetEventToMerge()->GetNumberOfCaloClusters(); icl++) {
379 //        AliAODCaloCluster *sigCluster = aodIH->GetEventToMerge()->GetCaloCluster(icl);
380 //        if(sigCluster->IsEMCAL()) printf("Signal cluster: i %d, E  %f\n",icl,sigCluster->E());
381 //    }
382 //    printf("OutputEvent N Clusters %d, N Cells %d\n", AODEvent()->GetNumberOfCaloClusters(),
383 //           AODEvent()->GetEMCALCells()->GetNumberOfCells());
384     
385   }
386   else {
387     event =  InputEvent();
388     esdevent = dynamic_cast<AliESDEvent*>(InputEvent());
389     if(fFillAODCaloCells) FillAODCaloCells();   
390     if(fFillAODHeader)    FillAODHeader();
391   }
392   
393   if (!event) {
394     Error("UserExec","Event not available");
395     return;
396   }
397
398   //-------------------------------------------------------------------------------------
399   //Set the geometry matrix, for the first event, skip the rest
400   //-------------------------------------------------------------------------------------
401   if(!fGeomMatrixSet){
402     if(fLoadGeomMatrices){
403       for(Int_t mod=0; mod < (fGeom->GetEMCGeometry())->GetNumberOfSuperModules(); mod++){
404         if(fGeomMatrix[mod]){
405           if(DebugLevel() > 1) 
406             fGeomMatrix[mod]->Print();
407           fGeom->SetMisalMatrix(fGeomMatrix[mod],mod) ;  
408         }
409         fGeomMatrixSet=kTRUE;
410       }//SM loop
411     }//Load matrices
412     else if(!gGeoManager){
413       Info("UserExec","Get geo matrices from data");
414       //Still not implemented in AOD, just a workaround to be able to work at least with ESDs   
415       if(!strcmp(event->GetName(),"AliAODEvent")) {
416         if(DebugLevel() > 1) 
417           Warning("UserExec","Use ideal geometry, values geometry matrix not kept in AODs.");
418       }//AOD
419       else {    
420         if(DebugLevel() > 1) 
421           Info("UserExec","AliAnalysisTaskEMCALClusterize Load Misaligned matrices.");
422         AliESDEvent* esd = dynamic_cast<AliESDEvent*>(event) ;
423         if(!esd) {
424           Error("UserExec","This event does not contain ESDs?");
425           return;
426         }
427         for(Int_t mod=0; mod < (fGeom->GetEMCGeometry())->GetNumberOfSuperModules(); mod++){
428           if(DebugLevel() > 1) 
429             esd->GetEMCALMatrix(mod)->Print();
430           if(esd->GetEMCALMatrix(mod)) fGeom->SetMisalMatrix(esd->GetEMCALMatrix(mod),mod) ;
431         } 
432         fGeomMatrixSet=kTRUE;
433       }//ESD
434     }//Load matrices from Data 
435     
436     //Recover time dependent corrections, put then in recalibration histograms. Do it once
437     fRecoUtils->SetTimeDependentCorrections(InputEvent()->GetRunNumber());
438
439   }//first event
440
441   //Get the list of cells needed for unfolding and reclustering
442   AliVCaloCells *cells= event->GetEMCALCells();
443   Int_t nClustersOrg = 0;
444   //-------------------------------------------
445   //---------Unfolding clusters----------------
446   //-------------------------------------------
447   if (fJustUnfold) {
448     
449     //Fill the array with the EMCAL clusters, copy them
450     for (Int_t i = 0; i < event->GetNumberOfCaloClusters(); i++)
451     {
452       AliVCluster *clus = event->GetCaloCluster(i);
453       if(clus->IsEMCAL()){        
454         //printf("Org Cluster %d, E %f\n",i, clus->E());
455         
456         //recalibrate/remove bad channels/etc if requested
457         if(fRecoUtils->ClusterContainsBadChannel(fGeom,clus->GetCellsAbsId(), clus->GetNCells())){
458           //printf("Remove cluster\n");
459           continue;
460         } 
461         
462         if(fRecoUtils->IsRecalibrationOn()){
463           //printf("Energy before %f ",clus->E());
464           fRecoUtils->RecalibrateClusterEnergy(fGeom, clus, cells);
465           //printf("; after %f\n",clus->E());
466         }
467         //Cast to ESD or AOD, needed to create the cluster array
468         AliESDCaloCluster * esdCluster = dynamic_cast<AliESDCaloCluster*> (clus);
469         AliAODCaloCluster * aodCluster = dynamic_cast<AliAODCaloCluster*> (clus);
470         if     (esdCluster){
471           fCaloClusterArr->Add( new AliESDCaloCluster(*esdCluster) );   
472         }//ESD
473         else if(aodCluster){
474           fCaloClusterArr->Add( new AliAODCaloCluster(*aodCluster) );   
475         }//AOD
476         else 
477           Warning("UserExec()"," - Wrong CaloCluster type?");
478         nClustersOrg++;
479       }
480     }
481     
482     //Do the unfolding
483     fUnfolder->UnfoldClusters(fCaloClusterArr, cells);
484     
485     //CLEAN-UP
486     fUnfolder->Clear();
487     
488     
489     //printf("nClustersOrg %d\n",nClustersOrg);
490   }
491   //-------------------------------------------
492   //---------- Recluster cells ----------------
493   //-------------------------------------------
494   
495   else{
496     //-------------------------------------------------------------------------------------
497     //Transform CaloCells into Digits
498     //-------------------------------------------------------------------------------------
499     
500     //In case of MC, first loop on the clusters and fill MC label to array
501     //.....................................................................
502     
503 //    for(Int_t j = 0; j < 24*48*11; j++)  {
504 //      if(fCellLabels[j]      !=-1) printf("Not well initialized cell %d, label1 %d\n",j,fCellLabels[j]      ) ;
505 //      if(fCellSecondLabels[j]!=-1) printf("Not well initialized cell %d, label2 %d\n",j,fCellSecondLabels[j]) ;
506 //    }
507     
508     Int_t nClusters = event->GetNumberOfCaloClusters();
509     if(aodIH && aodIH->GetEventToMerge())  //Embedding
510       nClusters = aodIH->GetEventToMerge()->GetNumberOfCaloClusters(); //Get clusters directly from embedded signal
511     for (Int_t i = 0; i < nClusters; i++)
512     {
513       AliVCluster *clus = 0;
514       if(aodIH && aodIH->GetEventToMerge()) //Embedding
515         clus = aodIH->GetEventToMerge()->GetCaloCluster(i); //Get clusters directly from embedded signal
516       else      
517         clus = event->GetCaloCluster(i);
518
519       if(!clus) {
520         printf("AliEMCALReclusterize::UserExec() - No Clusters\n");
521         return;
522       }
523       
524       if(clus->IsEMCAL()){   
525         //printf("Cluster Signal %d, energy %f\n",clus->GetID(),clus->E());
526         Int_t label = clus->GetLabel();
527         Int_t label2 = -1 ;
528         if (clus->GetNLabels()>=2) label2 = clus->GetLabelAt(1) ;
529         UShort_t * index    = clus->GetCellsAbsId() ;
530         for(Int_t icell=0; icell < clus->GetNCells(); icell++ ){
531           fCellLabels[index[icell]]      =label;
532           fCellSecondLabels[index[icell]]=label2;
533           //printf("1) absID %d, label[0] %d label[1] %d\n",index[icell], fCellLabels[index[icell]],fCellSecondLabels[index[icell]]);
534         }
535         nClustersOrg++;
536       }
537     } 
538
539     // Create digits 
540     //.................
541     Int_t idigit =  0;
542     Int_t id     = -1;
543     Float_t amp  = -1; 
544     Float_t time = -1; 
545     
546     Double_t cellAmplitude = 0;
547     Double_t cellTime      = 0;
548     Short_t  cellNumber    = 0;
549         
550     TTree *digitsTree = new TTree("digitstree","digitstree");
551     digitsTree->Branch("EMCAL","TClonesArray", &fDigitsArr, 32000);
552     
553     
554     for (Int_t icell = 0; icell < cells->GetNumberOfCells(); icell++)
555     {
556       if (cells->GetCell(icell, cellNumber, cellAmplitude, cellTime) != kTRUE)
557         break;
558       
559       time = cellTime;
560       amp  = cellAmplitude;
561       id   = cellNumber;
562       
563       Int_t imod = -1, iphi =-1, ieta=-1,iTower = -1, iIphi = -1, iIeta = -1; 
564       fGeom->GetCellIndex(id,imod,iTower,iIphi,iIeta); 
565       fGeom->GetCellPhiEtaIndexInSModule(imod,iTower,iIphi, iIeta,iphi,ieta);   
566       
567       //Do not include bad channels found in analysis?
568       if( fRecoUtils->IsBadChannelsRemovalSwitchedOn() && 
569           fRecoUtils->GetEMCALChannelStatus(imod, ieta, iphi)){
570           fCellLabels[id]      =-1; //reset the entry in the array for next event
571           fCellSecondLabels[id]=-1; //reset the entry in the array for next event
572         //printf("Remove channel %d\n",id);
573         continue;
574       }
575              
576       //Recalibrate?
577       if(fRecoUtils->IsRecalibrationOn()){ 
578         //printf("CalibFactor %f times %f for id %d\n",fRecoUtils->GetEMCALChannelRecalibrationFactor(imod,ieta,iphi),amp,id);
579         amp *=fRecoUtils->GetEMCALChannelRecalibrationFactor(imod,ieta,iphi);
580       }
581            
582       //Create the digit, put a fake primary deposited energy to trick the clusterizer when checking the most likely primary
583       new((*fDigitsArr)[idigit]) AliEMCALDigit( fCellLabels[id], fCellLabels[id],id, amp, time,AliEMCALDigit::kHG,idigit, 0, 0, 1); 
584       //if(fCellLabels[id]>=0)printf("2) Digit cell %d, label %d\n",id,fCellLabels[id]) ;
585       //else                  printf("2) Digit cell %d, no label, amp %f \n",id,amp) ;
586       fCellLabels[id]      =-1; //reset the entry in the array for next event
587
588       //AliEMCALDigit *digit = (AliEMCALDigit*) fDigitsArr->New(idigit);
589       //digit->SetId(id);
590       //digit->SetAmplitude(amp);
591       //digit->SetTime(time);
592       //digit->SetTimeR(time);
593       //digit->SetIndexInList(idigit);
594       //digit->SetType(AliEMCALDigit::kHG);
595       
596       //printf("Digit: Id %d, amp %f, time %e, index %d\n",id, amp,time,idigit);
597       idigit++;
598     }
599     
600     //Fill the tree with digits
601     digitsTree->Fill();
602     
603     //-------------------------------------------------------------------------------------
604     //Do the clusterization
605     //-------------------------------------------------------------------------------------        
606     TTree *clustersTree = new TTree("clustertree","clustertree");
607
608     fClusterizer->SetInput(digitsTree);
609     fClusterizer->SetOutput(clustersTree);
610     fClusterizer->Digits2Clusters("");
611
612     //-------------------------------------------------------------------------------------
613     //Transform the recpoints into AliVClusters
614     //-------------------------------------------------------------------------------------
615     
616     clustersTree->SetBranchStatus("*",0); //disable all branches
617     clustersTree->SetBranchStatus("EMCALECARP",1); //Enable only the branch we need
618     
619     TBranch *branch = clustersTree->GetBranch("EMCALECARP");
620     branch->SetAddress(&fClusterArr);
621     branch->GetEntry(0);
622
623     RecPoints2Clusters(fDigitsArr, fClusterArr, fCaloClusterArr);
624     
625     //Reset the array with second labels for this event
626     memset(fCellSecondLabels, -1, sizeof(fCellSecondLabels));
627     
628     //---CLEAN UP-----
629     fClusterizer->Clear();
630     fDigitsArr  ->Clear("C");
631     fClusterArr ->Delete(); // Do not Clear(), it leaks, why?
632
633     clustersTree->Delete("all");
634     digitsTree  ->Delete("all");
635   }
636   
637   //Recalculate track-matching for the new clusters, only with ESDs
638   if(fDoTrackMatching) fRecoUtils->FindMatches(event,fCaloClusterArr,fGeom);
639
640   
641   //-------------------------------------------------------------------------------------
642   //Put the new clusters in the AOD list
643   //-------------------------------------------------------------------------------------
644   
645   Int_t kNumberOfCaloClusters   = fCaloClusterArr->GetEntries();
646   //printf("New clusters %d, Org clusters %d\n",kNumberOfCaloClusters, nClustersOrg);
647   for(Int_t i = 0; i < kNumberOfCaloClusters; i++){
648     AliAODCaloCluster *newCluster = (AliAODCaloCluster *) fCaloClusterArr->At(i);
649     //if(Entry()==0) Info("UserExec","newCluster E %f\n", newCluster->E());
650     
651     //Add matched track, if any, only with ESDs
652     if(esdevent && fDoTrackMatching){
653       Int_t trackIndex = fRecoUtils->GetMatchedTrackIndex(i);
654       if(trackIndex >= 0){
655         newCluster->AddTrackMatched(event->GetTrack(trackIndex));
656         if(DebugLevel() > 1) 
657           Info("UserExec","Matched Track index %d to new cluster %d \n",trackIndex,i);
658       }
659     }
660     
661     //In case of new bad channels, recalculate distance to bad channels
662     if(fRecoUtils->IsBadChannelsRemovalSwitchedOn()){
663       //printf("DistToBad before %f ",newCluster->GetDistanceToBadChannel());
664       fRecoUtils->RecalculateClusterDistanceToBadChannel(fGeom, event->GetEMCALCells(), newCluster);
665       //printf("; after %f \n",newCluster->GetDistanceToBadChannel());
666     }
667     
668 //    if(newCluster->GetNLabels()>0){
669 //      printf("3) MC: N labels %d, label %d ; ", newCluster->GetNLabels(), newCluster->GetLabel() );
670 //      UShort_t * newindex    = newCluster->GetCellsAbsId() ;
671 //      for(Int_t icell=0; icell < newCluster->GetNCells(); icell++ ){
672 //       printf("\t absID %d\n",newindex[icell]);
673 //     }
674 //    }
675     
676 //    printf("Cluster %d, energy %f\n",newCluster->GetID(),newCluster->E());
677 //    printf("labels: ");
678 //    for(UInt_t ilab = 0; ilab < newCluster->GetNLabels(); ilab++)
679 //      printf("Label[%d]: %d ",ilab, newCluster->GetLabelAt(ilab)); 
680 //     printf("\n ");
681     
682     newCluster->SetID(i);
683     new((*fOutputAODBranch)[i])  AliAODCaloCluster(*newCluster);
684   }
685   
686   //if(fOutputAODBranchName.Length()!=0)
687   fOutputAODBranch->Expand(kNumberOfCaloClusters); // resize TObjArray to 'remove' slots
688   
689   //---CLEAN UP-----
690   fCaloClusterArr->Delete(); // Do not Clear(), it leaks, why?
691 }      
692
693 //_____________________________________________________________________
694 Bool_t AliAnalysisTaskEMCALClusterize::AccessOCDB()
695 {
696   //Access to OCDB stuff
697   
698   AliVEvent * event = InputEvent();
699   if (!event)
700   {
701     Warning("AccessOCDB","Event not available!!!");
702     return kFALSE;
703   }
704   
705   if (event->GetRunNumber()==fRun)
706     return kTRUE;
707   fRun = event->GetRunNumber();
708   
709   if(DebugLevel() > 1 )
710     Info("AccessODCD()"," Begin");
711   
712   //fGeom = AliEMCALGeometry::GetInstance(fGeomName);
713   
714   AliCDBManager *cdb = AliCDBManager::Instance();
715   
716   
717   if (fOCDBpath.Length()){
718     cdb->SetDefaultStorage(fOCDBpath.Data());
719     Info("AccessOCDB","Default storage %s",fOCDBpath.Data());
720   }
721   
722   cdb->SetRun(event->GetRunNumber());
723   
724   //
725   // EMCAL from RAW OCDB
726   if (fOCDBpath.Contains("alien:"))
727   {
728     cdb->SetSpecificStorage("EMCAL/Calib/Data","alien://Folder=/alice/data/2010/OCDB");
729     cdb->SetSpecificStorage("EMCAL/Calib/Pedestals","alien://Folder=/alice/data/2010/OCDB");
730   }
731   
732   TString path = cdb->GetDefaultStorage()->GetBaseFolder();
733   
734   // init parameters:
735   
736   //Get calibration parameters  
737   if(!fCalibData)
738   {
739     AliCDBEntry *entry = (AliCDBEntry*) 
740     AliCDBManager::Instance()->Get("EMCAL/Calib/Data");
741     
742     if (entry) fCalibData =  (AliEMCALCalibData*) entry->GetObject();
743   }
744   
745   if(!fCalibData)
746     AliFatal("Calibration parameters not found in CDB!");
747   
748   //Get calibration parameters  
749   if(!fPedestalData)
750   {
751     AliCDBEntry *entry = (AliCDBEntry*) 
752     AliCDBManager::Instance()->Get("EMCAL/Calib/Pedestals");
753     
754     if (entry) fPedestalData =  (AliCaloCalibPedestal*) entry->GetObject();
755   }
756   
757   if(!fPedestalData)
758     AliFatal("Dead map not found in CDB!");
759   
760   return kTRUE;
761 }
762
763 //________________________________________________________________________________________
764 void AliAnalysisTaskEMCALClusterize::InitClusterization()
765 {
766   //Select clusterization/unfolding algorithm and set all the needed parameters
767   
768   if (fJustUnfold){
769     // init the unfolding afterburner 
770     delete fUnfolder;
771     fUnfolder =  new AliEMCALAfterBurnerUF(fRecParam->GetW0(),fRecParam->GetLocMaxCut());
772     return;
773  }
774
775   //First init the clusterizer
776   delete fClusterizer;
777   if     (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv1)
778     fClusterizer = new AliEMCALClusterizerv1 (fGeom, fCalibData, fPedestalData);
779   else if(fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv2) 
780     fClusterizer = new AliEMCALClusterizerv2(fGeom, fCalibData, fPedestalData);
781   else if(fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerNxN) 
782     fClusterizer = new AliEMCALClusterizerNxN(fGeom, fCalibData, fPedestalData);
783   else if(fRecParam->GetClusterizerFlag() > AliEMCALRecParam::kClusterizerv2) { //FIX this other way.
784    AliEMCALClusterizerNxN *clusterizer = new AliEMCALClusterizerNxN(fGeom, fCalibData, fPedestalData);
785    clusterizer->SetNRowDiff(2);
786    clusterizer->SetNColDiff(2);
787    fClusterizer = clusterizer;
788   } else{
789     AliFatal(Form("Clusterizer < %d > not available", fRecParam->GetClusterizerFlag()));
790   }
791     
792   //Now set the parameters
793   fClusterizer->SetECAClusteringThreshold( fRecParam->GetClusteringThreshold() );
794   fClusterizer->SetECALogWeight          ( fRecParam->GetW0()                  );
795   fClusterizer->SetMinECut               ( fRecParam->GetMinECut()             );    
796   fClusterizer->SetUnfolding             ( fRecParam->GetUnfold()              );
797   fClusterizer->SetECALocalMaxCut        ( fRecParam->GetLocMaxCut()           );
798   fClusterizer->SetTimeCut               ( fRecParam->GetTimeCut()             );
799   fClusterizer->SetTimeMin               ( fRecParam->GetTimeMin()             );
800   fClusterizer->SetTimeMax               ( fRecParam->GetTimeMax()             );
801   fClusterizer->SetInputCalibrated       ( kTRUE                               );
802   fClusterizer->SetJustClusters          ( kTRUE                               );  
803   //In case of unfolding after clusterization is requested, set the corresponding parameters
804   if(fRecParam->GetUnfold()){
805     Int_t i=0;
806     for (i = 0; i < 8; i++) {
807       fClusterizer->SetSSPars(i, fRecParam->GetSSPars(i));
808     }//end of loop over parameters
809     for (i = 0; i < 3; i++) {
810       fClusterizer->SetPar5  (i, fRecParam->GetPar5(i));
811       fClusterizer->SetPar6  (i, fRecParam->GetPar6(i));
812     }//end of loop over parameters
813     
814     fClusterizer->InitClusterUnfolding();
815   }// to unfold
816 }
817
818 //________________________________________________________________________________________
819 void AliAnalysisTaskEMCALClusterize::RecPoints2Clusters(TClonesArray *digitsArr, TObjArray *recPoints, TObjArray *clusArray)
820 {
821   // Restore clusters from recPoints
822   // Cluster energy, global position, cells and their amplitude fractions are restored
823   
824   for(Int_t i = 0; i < recPoints->GetEntriesFast(); i++)
825   {
826     AliEMCALRecPoint *recPoint = (AliEMCALRecPoint*) recPoints->At(i);
827     
828     const Int_t ncells = recPoint->GetMultiplicity();
829     Int_t ncells_true = 0;
830     
831     // cells and their amplitude fractions
832     UShort_t   absIds[ncells];  
833     Double32_t ratios[ncells];
834     
835     for (Int_t c = 0; c < ncells; c++) {
836       AliEMCALDigit *digit = (AliEMCALDigit*) digitsArr->At(recPoint->GetDigitsList()[c]);
837       
838       absIds[ncells_true] = digit->GetId();
839       ratios[ncells_true] = recPoint->GetEnergiesList()[c]/digit->GetAmplitude();
840       
841       if (ratios[ncells_true] > 0.001) ncells_true++;
842     }
843     
844     if (ncells_true < 1) {
845       Warning("AliAnalysisTaskEMCALClusterize::RecPoints2Clusters", "skipping cluster with no cells");
846       continue;
847     }
848     
849     TVector3 gpos;
850     Float_t g[3];
851     
852     // calculate new cluster position
853     recPoint->EvalGlobalPosition(fRecParam->GetW0(), digitsArr);
854     recPoint->GetGlobalPosition(gpos);
855     gpos.GetXYZ(g);
856     
857     // create a new cluster
858     AliAODCaloCluster *clus = new AliAODCaloCluster();
859     clus->SetType(AliVCluster::kEMCALClusterv1);
860     clus->SetE(recPoint->GetEnergy());
861     clus->SetPosition(g);
862     clus->SetNCells(ncells_true);
863     clus->SetCellsAbsId(absIds);
864     clus->SetCellsAmplitudeFraction(ratios);
865     clus->SetDispersion(recPoint->GetDispersion());
866     clus->SetChi2(-1); //not yet implemented
867     clus->SetTOF(recPoint->GetTime()) ; //time-of-flight
868     clus->SetNExMax(recPoint->GetNExMax()); //number of local maxima
869     Float_t elipAxis[2];
870     recPoint->GetElipsAxis(elipAxis);
871     clus->SetM02(elipAxis[0]*elipAxis[0]) ;
872     clus->SetM20(elipAxis[1]*elipAxis[1]) ;
873     clus->SetDistanceToBadChannel(recPoint->GetDistanceToBadTower()); 
874     
875     //MC
876     Int_t  parentMult  = 0;
877     Int_t *parentList = recPoint->GetParents(parentMult);
878     clus->SetLabel(parentList, parentMult); 
879     
880 //    if(parentMult)printf("RecToESD: Labels %d",parentMult);
881 //    for (Int_t iii = 0; iii < parentMult; iii++) {
882 //      printf("\t label %d\n",parentList[iii]);
883 //    }
884     //Write the second major contributor to each MC cluster.
885     Int_t iNewLabel ;
886     for ( Int_t iLoopCell = 0 ; iLoopCell < clus->GetNCells() ; iLoopCell++ ){
887       
888       Int_t idCell = clus->GetCellAbsId(iLoopCell) ;
889       if(idCell>=0){
890         iNewLabel = 1 ; //iNewLabel makes sure we  don't write twice the same label.
891         for ( UInt_t iLoopLabels = 0 ; iLoopLabels < clus->GetNLabels() ; iLoopLabels++ )
892         {
893           if ( fCellSecondLabels[idCell] == -1 )  iNewLabel = 0;  // -1 is never a good second label.
894           if ( fCellSecondLabels[idCell] == clus->GetLabelAt(iLoopLabels) )  iNewLabel = 0;
895         }
896         if (iNewLabel == 1) 
897         {
898           Int_t * newLabelArray = (Int_t*)malloc((clus->GetNLabels()+1)*sizeof(Int_t)) ;
899           for ( UInt_t iLoopNewLabels = 0 ; iLoopNewLabels < clus->GetNLabels() ; iLoopNewLabels++ ){
900             newLabelArray[iLoopNewLabels] = clus->GetLabelAt(iLoopNewLabels) ;
901           }
902
903           newLabelArray[clus->GetNLabels()] = fCellSecondLabels[idCell] ;
904           //if(fCellSecondLabels[idCell]>-1)printf("\t new label %d\n",fCellSecondLabels[idCell]);
905           clus->SetLabel(newLabelArray,clus->GetNLabels()+1) ;
906           delete [] newLabelArray;
907         }
908       }//positive cell number
909     }
910     
911     clusArray->Add(clus);
912   } // recPoints loop
913 }