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