ROOT logo
#ifndef ALIMUONCLUSTERFINDERMLEM_H
#define ALIMUONCLUSTERFINDERMLEM_H
/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 * See cxx source for full Copyright notice                               */

/* $Id$ */

/// \ingroup rec
/// \class AliMUONClusterFinderMLEM
/// \brief Cluster finder in MUON arm of ALICE
///
//  Author Alexander Zinchenko, JINR Dubna; Laurent Aphecetche, SUBATECH
//

class TH2D;
class TMinuit;

#ifndef ROOT_TObjArray
#  include "TObjArray.h"
#endif
#ifndef ROOT_TVector2
#  include "TVector2.h"
#endif

class AliMUONPad;

#include "AliMUONVClusterFinder.h"

class AliMUONClusterSplitterMLEM;

class AliMUONClusterFinderMLEM : public AliMUONVClusterFinder
{
public:
  AliMUONClusterFinderMLEM(Bool_t plot, AliMUONVClusterFinder* clusterFinder); // Constructor
  virtual ~AliMUONClusterFinderMLEM(); // Destructor

  virtual Bool_t NeedSegmentation() const { return kTRUE; }
  
  using AliMUONVClusterFinder::Prepare;

  virtual Bool_t Prepare(Int_t detElemId,
                         TObjArray* pads[2],
                         const AliMpArea& area,
                         const AliMpVSegmentation* segmentations[2]);
  
  virtual AliMUONCluster* NextCluster();
  
  virtual void SetChargeHints(Double_t lowestPadCharge, Double_t lowestClusterCharge);
  
  virtual void Print(Option_t* opt="") const;

  virtual void Paint(Option_t* opt="");

  // Status flags for pads

               /// Return pad "basic" state flag
  static Int_t GetZeroFlag()       { return fgkZero; }
               /// Return do not kill flag
  static Int_t GetMustKeepFlag()   { return fgkMustKeep; }
               /// Return should be used for fit flag
  static Int_t GetUseForFitFlag()  { return fgkUseForFit; }
               /// Return processing is over flag
  static Int_t GetOverFlag()       { return fgkOver; }
               /// Return modified pad charge flag
  static Int_t GetModifiedFlag()   { return fgkModified; }
               /// Return coupled pad flag
  static Int_t GetCoupledFlag()    { return fgkCoupled; }
  
private:
  /// Not implemented
  AliMUONClusterFinderMLEM(const AliMUONClusterFinderMLEM& rhs);
  /// Not implemented
  AliMUONClusterFinderMLEM& operator=(const AliMUONClusterFinderMLEM& rhs);

  Bool_t WorkOnPreCluster();

  /// Check precluster to simplify it (if possible), and return the simplified cluster
  AliMUONCluster* CheckPrecluster(const AliMUONCluster& cluster); 
  AliMUONCluster* CheckPreclusterTwoCathodes(AliMUONCluster* cluster); 
  
  /// Checks whether a pad and a pixel have an overlapping area.
  Bool_t Overlap(const AliMUONPad& pad, const AliMUONPad& pixel); 
  
  /// build array of pixels
  void BuildPixArray(AliMUONCluster& cluster); 
  void BuildPixArrayOneCathode(AliMUONCluster& cluster); 
  void PadOverHist(Int_t idir, Int_t ix0, Int_t iy0, AliMUONPad *pad,
		   TH2D *hist1, TH2D *hist2);

  void RemovePixel(Int_t i);
  
  AliMUONPad* Pixel(Int_t i) const;
  
  Bool_t MainLoop(AliMUONCluster& cluster, Int_t iSimple); // repeat MLEM algorithm until pixels become sufficiently small
  
  void   Mlem(AliMUONCluster& cluster, const Double_t *coef, Double_t *probi, Int_t nIter); // use MLEM for cluster finding
  
  void   FindCOG(Double_t *xyc); // find COG position around maximum bin
  Int_t  FindNearest(const AliMUONPad *pixPtr0); // find nearest neighbouring pixel to the given one

  Int_t FindLocalMaxima(TObjArray *pixArray, Int_t *localMax, Double_t *maxVal); // find local maxima 
  void  FlagLocalMax(TH2D *hist, Int_t i, Int_t j, Int_t *isLocalMax); // flag local max
  void  FindCluster(AliMUONCluster& cluster, const Int_t *localMax, Int_t iMax); // find cluster around local max
  void  AddVirtualPad(AliMUONCluster& cluster); // add virtual pads for some clusters (if necessary)
  
  void  PadsInXandY(AliMUONCluster& cluster, Int_t &nInX, Int_t &nInY) const; // get number of pads in X and Y

  /// Process simple cluster
  void Simple(AliMUONCluster& cluster); 
  
  void Plot(const char* outputfile);
    
  void ComputeCoefficients(AliMUONCluster& cluster, 
                           Double_t* coef, Double_t* probi);
  
  void CheckOverlaps();
  void AddBinSimple(TH2D *mlem, Int_t ic, Int_t jc);
  void MaskPeaks(Int_t mask);

private:
  // Status flags for pads
  static const Int_t fgkZero; ///< pad "basic" state
  static const Int_t fgkMustKeep; ///< do not kill (for pixels)
  static const Int_t fgkUseForFit; ///< should be used for fit
  static const Int_t fgkOver; ///< processing is over
  static const Int_t fgkModified; ///< modified pad charge 
  static const Int_t fgkCoupled; ///< coupled pad  
      
  // Some constants
  static const Double_t fgkDistancePrecision; ///< used to check overlaps and so on
  static const TVector2 fgkIncreaseSize; ///< idem
  static const TVector2 fgkDecreaseSize; ///< idem
  
  AliMUONVClusterFinder* fPreClusterFinder; //!< the pre-clustering worker
  AliMUONCluster* fPreCluster; //!< current pre-cluster
  TObjArray fClusterList; //!< clusters corresponding to the current pre-cluster
  
  Int_t fEventNumber; //!< current event being processed
  Int_t fDetElemId; //!< current DE being processed
  Int_t fClusterNumber; //!< current cluster number
  
  const AliMpVSegmentation *fkSegmentation[2]; //!< new segmentation
  
  //Int_t fCathBeg;               //!< starting cathode (for combined cluster / track reco)
  //Int_t fPadBeg[2];             //!< starting pads (for combined cluster / track reco)
  
  //static     TMinuit* fgMinuit; //!< Fitter
  TH2D *fHistMlem; //!< histogram for MLEM procedure
  TH2D *fHistAnode; //!< histogram for local maxima search
  
  TObjArray* fPixArray; //!< collection of pixels
  Int_t fDebug; //!< debug level
  Bool_t fPlot; //!< whether we should plot thing (for debug only, quite slow!)
  
  AliMUONClusterSplitterMLEM* fSplitter; //!< helper class to go from pixel arrays to clusters
  Int_t fNClusters; //!< total number of clusters
  Int_t fNAddVirtualPads; //!< number of clusters for which we added virtual pads
  
  Double_t fLowestPixelCharge; //!< see AliMUONRecoParam
  Double_t fLowestPadCharge; //!< see AliMUONRecoParam
  Double_t fLowestClusterCharge; //!< see AliMUONRecoParam
  
  ClassDef(AliMUONClusterFinderMLEM,0) // cluster finder in MUON arm of ALICE
};

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