// LCDFMCCalRecon.h
// Apr  19,2001 Toshi      Copied from LCDCalRecon (just change class name)
// 
#ifndef LCDFMCCALRECON_H
#define LCDFMCCALRECON_H

#include "TRandom.h"

#include "LCDRecModule.h"  
#include "LCDGetParameters.h"
#include "LCDMcPart.h"
#include "LCDDetectorVolume.h"
#include "LCDSwimTraj.h"
#include "LCDCluster.h"

//=========================================================
class LCDFMCCalRecon : public LCDRecModule {
public:
  LCDFMCCalRecon();
  LCDFMCCalRecon(Int_t iseed);
  LCDFMCCalRecon(LCDGetParameters* getparam);
  LCDFMCCalRecon(LCDGetParameters* getparam, Int_t iseed);
  ~LCDFMCCalRecon(){}
  
  void Cleanup(LCDEvent* event);//clean up
  void Doit(LCDEvent* event);
  
  void SetDetectorParameters(LCDGetParameters* getparam);
  void Smear(Double_t epart,LCDSwimTraj* traj,
	     Bool_t hadron, LCDCluster* kal);
  void DoMerge();
  void AddCluster(LCDCluster* kal1, LCDCluster* kal2);
  
  void SetMergeSizeEM(Double_t a)   { merge_siz_EM    = a; }
  void SetMergeSizeHAD(Double_t a)  { merge_siz_HAD   = a; }
  void SetMergeAngleEM(Double_t a)  { merge_angle_EM  = a; }
  void SetMergeAngleHAD(Double_t a) { merge_angle_HAD = a; }
  
  void SetNoClusterMerge() { m_cluster_merge = kFALSE; }
  void SetClusterMerge()   { m_cluster_merge = kTRUE;  }
  
private:
  TClonesArray*  ClsList;       // "Clusters" 
  
  Double_t RanExpDecay(Double_t mean = 1.0) {
    return -TMath::Log(m_rand.Rndm())*mean;
  }
  
  TRandom m_rand;  // Use Root for randoms, gaussian or uniform  
  
  Int_t   Swim(LCDSwimTraj* pTraj, Bool_t hadron);
  
  LCDGetParameters*  gp;  
  
  Int_t  Smearable(LCDMcPart*);
  
  // Assume all relevant volumes are either barrels or endcaps, in any
  // case cylinders
  
  LCDDetectorVolume* pVolumes;       // Array of detector volumes
  LCDDetectorVolume* pInnerVolume;   // Innermost volume about IP
  Int_t        nVolumes;       // Number of detector volumes in array
  
  Double_t  merge_siz_EM   ; // Cut Value for merging. by cm (0.8 cm).
  Double_t  merge_siz_HAD  ; // Default value = 1.3 cm.
  Double_t  merge_angle_EM ; // Cut Value for merging. by radian (0.0200 rad)
  Double_t  merge_angle_HAD; // Default value = 0.0600 rad
  
  Bool_t m_cluster_merge; 
  // =1 With cluster merging (default) 
  // =0 Without cluster merging 
  
  void Init();
  
public:
  ClassDef(LCDFMCCalRecon,1)    // Manager class for FastMC clustering
};

// energy smearing is done according to the formula
//   sigma = E-perfect * sqrt(a**2/E-perfect + b**2)
// Magnitude of transverse position smear is
//   sigma_x = sqrt(a**2/E-perfect + b**2)
//   phi (with axis = momentum angle) is uniformly distributed in (0, 2pi)
#endif
