ROOT logo
/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

//-- Author: Yves Schutz (SUBATECH)  & Dmitri Peressounko (SUBATECH & Kurchatov Institute)
//--         Gustavo Conesa (LPSC-Grenoble), move common clusterizer functionalities to mother class
//////////////////////////////////////////////////////////////////////////////
//  Clusterization class. Performs clusterization (collects neighbouring active cells) and 
//  unfolds the clusters having several local maxima.  
//  Results are stored in TreeR#, branches EMCALTowerRP (EMC recPoints),
//  EMCALPreShoRP (CPV RecPoints) and AliEMCALClusterizer (Clusterizer with all 
//  parameters including input digits branch title, thresholds etc.)
//

// --- ROOT system ---

#include <TFile.h> 
#include <TMath.h> 
#include <TMinuit.h>
#include <TTree.h> 
#include <TBenchmark.h>
#include <TBrowser.h>
#include <TROOT.h>
#include <TList.h>
#include <TClonesArray.h>

// --- Standard library ---
#include <cassert>

// --- AliRoot header files ---
#include "AliLog.h"
#include "AliEMCALClusterizerv2.h"
#include "AliEMCALRecPoint.h"
#include "AliEMCALDigit.h"
#include "AliEMCALGeometry.h"
#include "AliCaloCalibPedestal.h"
#include "AliEMCALCalibData.h"
#include "AliESDCaloCluster.h"
#include "AliEMCALUnfolding.h"

ClassImp(AliEMCALClusterizerv2)

//____________________________________________________________________________
AliEMCALClusterizerv2::AliEMCALClusterizerv2() 
  : AliEMCALClusterizerv1(), fDoEnGradCut(1)
{
  // ctor with the indication of the file where header Tree and digits Tree are stored
}

//____________________________________________________________________________
AliEMCALClusterizerv2::AliEMCALClusterizerv2(AliEMCALGeometry* geometry)
  : AliEMCALClusterizerv1(geometry), fDoEnGradCut(1)
{
  // ctor with the indication of the file where header Tree and digits Tree are stored
  // use this contructor to avoid usage of Init() which uses runloader
  // change needed by HLT - MP
}

//____________________________________________________________________________
AliEMCALClusterizerv2::AliEMCALClusterizerv2(AliEMCALGeometry* geometry, AliEMCALCalibData* calib, AliCaloCalibPedestal* caloped)
  : AliEMCALClusterizerv1(geometry, calib, caloped), fDoEnGradCut(1)
{
  // ctor, geometry and calibration are initialized elsewhere.
}

//____________________________________________________________________________
AliEMCALClusterizerv2::~AliEMCALClusterizerv2()
{
  // dtor
}

//____________________________________________________________________________
Int_t AliEMCALClusterizerv2::AreNeighbours(AliEMCALDigit* d1, AliEMCALDigit* d2, Bool_t& shared) const
{ 
  // Gives the neighbourness of two digits = 0 are not neighbour; continue searching 
  //                                       = 1 are neighbour
  //                                       = 2 is in different SM; continue searching 
  // In case it is in different SM, but same phi rack, check if neigbours at eta=0
  // neighbours are defined as digits having at least a common side 
  // The order of d1 and d2 is important: first (d1) should be a digit already in a cluster 
  //                                      which is compared to a digit (d2)  not yet in a cluster  
  
  if (fDoEnGradCut) {
    if (d2->GetCalibAmp()>d1->GetCalibAmp())
      return 3; // energy of neighboring cell should be smaller in order to become a neighbor
  }
  return AliEMCALClusterizerv1::AreNeighbours(d1,d2,shared);
}

//____________________________________________________________________________
void AliEMCALClusterizerv2::MakeClusters()
{
  // Make list of clusters. Start from highest energy cell.
  
  if (fGeom==0) 
    AliFatal("Did not get geometry from EMCALLoader");
  
  fRecPoints->Delete();

  // set up TObjArray with pointers to digits to work on, calibrate digits 
  TObjArray digitsC;
  Double_t ehs = 0.0;
  AliEMCALDigit *digit = 0;
  TIter nextdigit(fDigitsArr);
  while ( (digit = static_cast<AliEMCALDigit*>(nextdigit())) ) {
    Float_t dEnergyCalibrated = digit->GetAmplitude();
    Float_t time              = digit->GetTime();
    Calibrate(dEnergyCalibrated, time ,digit->GetId());
    digit->SetCalibAmp(dEnergyCalibrated);
    digit->SetTime(time);
    if (dEnergyCalibrated < fMinECut || time > fTimeMax || time < fTimeMin) 
      continue;
    if (!fGeom->CheckAbsCellId(digit->GetId()))
      continue;
    ehs += dEnergyCalibrated;
    digitsC.AddLast(digit);
  }

  AliDebug(1,Form("MakeClusters: Number of digits %d  -> ehs %f (minE %f)\n",
                  fDigitsArr->GetEntries(),ehs,fMinECut));

  TIter nextdigitC(&digitsC);
  while (1) {
    Int_t   iMaxEnergyDigit = -1;
    Float_t dMaxEnergyDigit = -1;
    AliEMCALDigit *pMaxEnergyDigit = 0;
    nextdigitC.Reset();
    while ( (digit = static_cast<AliEMCALDigit *>(nextdigitC())) ) { 
      Float_t dEnergyCalibrated = digit->GetCalibAmp();
      if (dEnergyCalibrated>fECAClusteringThreshold && dEnergyCalibrated>dMaxEnergyDigit) {
        dMaxEnergyDigit = dEnergyCalibrated;
        iMaxEnergyDigit = digit->GetId();
        pMaxEnergyDigit = digit;
      }
    }
    if (iMaxEnergyDigit<0 || digitsC.GetEntries() <= 0) {
      break;
    }

    if (fNumberOfECAClusters>=fRecPoints->GetSize()) 
      fRecPoints->Expand(2*fNumberOfECAClusters+1);

    AliEMCALRecPoint *recPoint = new  AliEMCALRecPoint(""); 
    recPoint->SetClusterType(AliVCluster::kEMCALClusterv1);
    recPoint->AddDigit(*pMaxEnergyDigit, pMaxEnergyDigit->GetCalibAmp(), kFALSE);
    fRecPoints->AddAt(recPoint, fNumberOfECAClusters++);
    digitsC.Remove(pMaxEnergyDigit); 
    TObjArray clusterDigits;
    clusterDigits.AddLast(pMaxEnergyDigit);	
    TIter nextClusterDigit(&clusterDigits);
    Float_t time = pMaxEnergyDigit->GetTime(); 

    AliDebug(1,Form("MakeClusters: Max digit found id = %d, ene = %f , clus.th. = %f \n", 
                    iMaxEnergyDigit, dMaxEnergyDigit, fECAClusteringThreshold));

    while ( (digit = static_cast<AliEMCALDigit*>(nextClusterDigit())) ) { // scan over digits in cluster 
      TIter nextdigitN(&digitsC); 
      AliEMCALDigit *digitN = 0; // digi neighbor
      while ( (digitN = static_cast<AliEMCALDigit*>(nextdigitN())) ) { // scan over all digits to look for neighbours
        //Do not add digits with too different time 
        if (TMath::Abs(time - digitN->GetTime()) > fTimeCut ) 
          continue;
        Bool_t shared = kFALSE; //cluster shared by 2 SuperModules?
        if (AreNeighbours(digit, digitN, shared)==1) {
          recPoint->AddDigit(*digitN, digitN->GetCalibAmp(), shared);
          clusterDigits.AddLast(digitN); 
          digitsC.Remove(digitN); 
        } 
      }
    }
    AliDebug(2,Form("MakeClusters: %d digitd, energy %f \n", clusterDigits.GetEntries(), recPoint->GetEnergy())); 
  }
  AliDebug(1,Form("total no of clusters %d from %d digits",fNumberOfECAClusters,fDigitsArr->GetEntriesFast())); 
}

 AliEMCALClusterizerv2.cxx:1
 AliEMCALClusterizerv2.cxx:2
 AliEMCALClusterizerv2.cxx:3
 AliEMCALClusterizerv2.cxx:4
 AliEMCALClusterizerv2.cxx:5
 AliEMCALClusterizerv2.cxx:6
 AliEMCALClusterizerv2.cxx:7
 AliEMCALClusterizerv2.cxx:8
 AliEMCALClusterizerv2.cxx:9
 AliEMCALClusterizerv2.cxx:10
 AliEMCALClusterizerv2.cxx:11
 AliEMCALClusterizerv2.cxx:12
 AliEMCALClusterizerv2.cxx:13
 AliEMCALClusterizerv2.cxx:14
 AliEMCALClusterizerv2.cxx:15
 AliEMCALClusterizerv2.cxx:16
 AliEMCALClusterizerv2.cxx:17
 AliEMCALClusterizerv2.cxx:18
 AliEMCALClusterizerv2.cxx:19
 AliEMCALClusterizerv2.cxx:20
 AliEMCALClusterizerv2.cxx:21
 AliEMCALClusterizerv2.cxx:22
 AliEMCALClusterizerv2.cxx:23
 AliEMCALClusterizerv2.cxx:24
 AliEMCALClusterizerv2.cxx:25
 AliEMCALClusterizerv2.cxx:26
 AliEMCALClusterizerv2.cxx:27
 AliEMCALClusterizerv2.cxx:28
 AliEMCALClusterizerv2.cxx:29
 AliEMCALClusterizerv2.cxx:30
 AliEMCALClusterizerv2.cxx:31
 AliEMCALClusterizerv2.cxx:32
 AliEMCALClusterizerv2.cxx:33
 AliEMCALClusterizerv2.cxx:34
 AliEMCALClusterizerv2.cxx:35
 AliEMCALClusterizerv2.cxx:36
 AliEMCALClusterizerv2.cxx:37
 AliEMCALClusterizerv2.cxx:38
 AliEMCALClusterizerv2.cxx:39
 AliEMCALClusterizerv2.cxx:40
 AliEMCALClusterizerv2.cxx:41
 AliEMCALClusterizerv2.cxx:42
 AliEMCALClusterizerv2.cxx:43
 AliEMCALClusterizerv2.cxx:44
 AliEMCALClusterizerv2.cxx:45
 AliEMCALClusterizerv2.cxx:46
 AliEMCALClusterizerv2.cxx:47
 AliEMCALClusterizerv2.cxx:48
 AliEMCALClusterizerv2.cxx:49
 AliEMCALClusterizerv2.cxx:50
 AliEMCALClusterizerv2.cxx:51
 AliEMCALClusterizerv2.cxx:52
 AliEMCALClusterizerv2.cxx:53
 AliEMCALClusterizerv2.cxx:54
 AliEMCALClusterizerv2.cxx:55
 AliEMCALClusterizerv2.cxx:56
 AliEMCALClusterizerv2.cxx:57
 AliEMCALClusterizerv2.cxx:58
 AliEMCALClusterizerv2.cxx:59
 AliEMCALClusterizerv2.cxx:60
 AliEMCALClusterizerv2.cxx:61
 AliEMCALClusterizerv2.cxx:62
 AliEMCALClusterizerv2.cxx:63
 AliEMCALClusterizerv2.cxx:64
 AliEMCALClusterizerv2.cxx:65
 AliEMCALClusterizerv2.cxx:66
 AliEMCALClusterizerv2.cxx:67
 AliEMCALClusterizerv2.cxx:68
 AliEMCALClusterizerv2.cxx:69
 AliEMCALClusterizerv2.cxx:70
 AliEMCALClusterizerv2.cxx:71
 AliEMCALClusterizerv2.cxx:72
 AliEMCALClusterizerv2.cxx:73
 AliEMCALClusterizerv2.cxx:74
 AliEMCALClusterizerv2.cxx:75
 AliEMCALClusterizerv2.cxx:76
 AliEMCALClusterizerv2.cxx:77
 AliEMCALClusterizerv2.cxx:78
 AliEMCALClusterizerv2.cxx:79
 AliEMCALClusterizerv2.cxx:80
 AliEMCALClusterizerv2.cxx:81
 AliEMCALClusterizerv2.cxx:82
 AliEMCALClusterizerv2.cxx:83
 AliEMCALClusterizerv2.cxx:84
 AliEMCALClusterizerv2.cxx:85
 AliEMCALClusterizerv2.cxx:86
 AliEMCALClusterizerv2.cxx:87
 AliEMCALClusterizerv2.cxx:88
 AliEMCALClusterizerv2.cxx:89
 AliEMCALClusterizerv2.cxx:90
 AliEMCALClusterizerv2.cxx:91
 AliEMCALClusterizerv2.cxx:92
 AliEMCALClusterizerv2.cxx:93
 AliEMCALClusterizerv2.cxx:94
 AliEMCALClusterizerv2.cxx:95
 AliEMCALClusterizerv2.cxx:96
 AliEMCALClusterizerv2.cxx:97
 AliEMCALClusterizerv2.cxx:98
 AliEMCALClusterizerv2.cxx:99
 AliEMCALClusterizerv2.cxx:100
 AliEMCALClusterizerv2.cxx:101
 AliEMCALClusterizerv2.cxx:102
 AliEMCALClusterizerv2.cxx:103
 AliEMCALClusterizerv2.cxx:104
 AliEMCALClusterizerv2.cxx:105
 AliEMCALClusterizerv2.cxx:106
 AliEMCALClusterizerv2.cxx:107
 AliEMCALClusterizerv2.cxx:108
 AliEMCALClusterizerv2.cxx:109
 AliEMCALClusterizerv2.cxx:110
 AliEMCALClusterizerv2.cxx:111
 AliEMCALClusterizerv2.cxx:112
 AliEMCALClusterizerv2.cxx:113
 AliEMCALClusterizerv2.cxx:114
 AliEMCALClusterizerv2.cxx:115
 AliEMCALClusterizerv2.cxx:116
 AliEMCALClusterizerv2.cxx:117
 AliEMCALClusterizerv2.cxx:118
 AliEMCALClusterizerv2.cxx:119
 AliEMCALClusterizerv2.cxx:120
 AliEMCALClusterizerv2.cxx:121
 AliEMCALClusterizerv2.cxx:122
 AliEMCALClusterizerv2.cxx:123
 AliEMCALClusterizerv2.cxx:124
 AliEMCALClusterizerv2.cxx:125
 AliEMCALClusterizerv2.cxx:126
 AliEMCALClusterizerv2.cxx:127
 AliEMCALClusterizerv2.cxx:128
 AliEMCALClusterizerv2.cxx:129
 AliEMCALClusterizerv2.cxx:130
 AliEMCALClusterizerv2.cxx:131
 AliEMCALClusterizerv2.cxx:132
 AliEMCALClusterizerv2.cxx:133
 AliEMCALClusterizerv2.cxx:134
 AliEMCALClusterizerv2.cxx:135
 AliEMCALClusterizerv2.cxx:136
 AliEMCALClusterizerv2.cxx:137
 AliEMCALClusterizerv2.cxx:138
 AliEMCALClusterizerv2.cxx:139
 AliEMCALClusterizerv2.cxx:140
 AliEMCALClusterizerv2.cxx:141
 AliEMCALClusterizerv2.cxx:142
 AliEMCALClusterizerv2.cxx:143
 AliEMCALClusterizerv2.cxx:144
 AliEMCALClusterizerv2.cxx:145
 AliEMCALClusterizerv2.cxx:146
 AliEMCALClusterizerv2.cxx:147
 AliEMCALClusterizerv2.cxx:148
 AliEMCALClusterizerv2.cxx:149
 AliEMCALClusterizerv2.cxx:150
 AliEMCALClusterizerv2.cxx:151
 AliEMCALClusterizerv2.cxx:152
 AliEMCALClusterizerv2.cxx:153
 AliEMCALClusterizerv2.cxx:154
 AliEMCALClusterizerv2.cxx:155
 AliEMCALClusterizerv2.cxx:156
 AliEMCALClusterizerv2.cxx:157
 AliEMCALClusterizerv2.cxx:158
 AliEMCALClusterizerv2.cxx:159
 AliEMCALClusterizerv2.cxx:160
 AliEMCALClusterizerv2.cxx:161
 AliEMCALClusterizerv2.cxx:162
 AliEMCALClusterizerv2.cxx:163
 AliEMCALClusterizerv2.cxx:164
 AliEMCALClusterizerv2.cxx:165
 AliEMCALClusterizerv2.cxx:166
 AliEMCALClusterizerv2.cxx:167
 AliEMCALClusterizerv2.cxx:168
 AliEMCALClusterizerv2.cxx:169
 AliEMCALClusterizerv2.cxx:170
 AliEMCALClusterizerv2.cxx:171
 AliEMCALClusterizerv2.cxx:172
 AliEMCALClusterizerv2.cxx:173
 AliEMCALClusterizerv2.cxx:174
 AliEMCALClusterizerv2.cxx:175
 AliEMCALClusterizerv2.cxx:176
 AliEMCALClusterizerv2.cxx:177
 AliEMCALClusterizerv2.cxx:178
 AliEMCALClusterizerv2.cxx:179
 AliEMCALClusterizerv2.cxx:180
 AliEMCALClusterizerv2.cxx:181
 AliEMCALClusterizerv2.cxx:182
 AliEMCALClusterizerv2.cxx:183
 AliEMCALClusterizerv2.cxx:184
 AliEMCALClusterizerv2.cxx:185
 AliEMCALClusterizerv2.cxx:186
 AliEMCALClusterizerv2.cxx:187
 AliEMCALClusterizerv2.cxx:188