#ifndef ALIITSUSIMULATION_H
#define ALIITSUSIMULATION_H
#include <TObject.h>
#include "AliITSUSensMap.h"
#include "AliITSsegmentation.h"
#include "AliMathBase.h"
#include <TArrayS.h>
class AliITSCalibration;
class AliITSUSimuParam;
class AliITSUChip;
class TRandom;
class TSegCollection;
class AliITSUParamList;
class AliITSUSimulation : public TObject
{
public:
enum {kMaxROCycleAccept=126};
AliITSUSimulation();
AliITSUSimulation(AliITSUSimuParam* sim, AliITSUSensMap* map);
virtual ~AliITSUSimulation() {}
AliITSUSimulation(const AliITSUSimulation &source);
AliITSUSimulation& operator=(const AliITSUSimulation &source);
virtual void Init() = 0;
void UpdateMapSignal(UInt_t col,UInt_t row, Int_t trk,Int_t ht,Double_t signal, Int_t roCycle=0);
void UpdateMapNoise(UInt_t col,UInt_t row, Double_t noise, Int_t roCycle=0);
virtual void InitSimulationChip(AliITSUChip* mod, Int_t ev, AliITSsegmentation* seg, AliITSUParamList* resp);
virtual void SDigitiseChip() = 0;
virtual void FinishSDigitiseChip() = 0;
virtual Bool_t AddSDigitsToChip( TSeqCollection *pItemArray, Int_t mask );
virtual void DigitiseChip() = 0;
virtual void CreateFastRecPoints(AliITSUChip *,Int_t,TRandom *,TClonesArray* ) {}
virtual Double_t GenerateReadOutCycleOffset();
AliITSCalibration* GetCalibDead() const {return fCalibDead;}
AliITSCalibration* GetCalibNoisy() const {return fCalibNoisy;}
AliITSsegmentation* GetSegmentation() const {return fSeg;}
AliITSUSimuParam* GetSimuParam() const {return fSimuParam;}
AliITSUSensMap* GetMap() const {return fSensMap;}
AliITSUChip* GetChip() const {return fChip;}
AliITSUParamList* GetResponseParam() const {return fResponseParam;}
Int_t GetEvent() const {return fEvent;}
Bool_t GetDebug(Int_t level=1) const {return fDebug>=level;}
void SetCalibDead(AliITSCalibration *calib) {fCalibDead = calib;}
void SetCalibNoisy(AliITSCalibration *calib) {fCalibNoisy = calib;}
void SetSegmentation(AliITSsegmentation *seg) {fSeg = seg; if (seg&&fSensMap) fSensMap->SetDimensions(seg->Npz(),seg->Npx(),kMaxROCycleAccept);}
void SetSimuParam(AliITSUSimuParam *sp) {fSimuParam = sp;}
virtual void SetResponseParam(AliITSUParamList* resp) {fResponseParam = resp;}
void SetMap(AliITSUSensMap *p) {fSensMap = p;}
void SetChip(AliITSUChip* mod) {fChip=mod;}
void SetEvent(Int_t evnt) {fEvent=evnt;}
void SetDebug(Int_t level=5) {fDebug=level;}
void SetNoDebug() {fDebug=0;}
void ClearMap() {fSensMap->Clear();}
Double_t GetReadOutCycleOffset() const {return fReadOutCycleOffset;}
void SetReadOutCycleOffset(Double_t v=0) {fReadOutCycleOffset = v;}
Double_t GetReadOutCycleLength() const {return fReadOutCycleLength;}
void SetReadOutCycleLength(Double_t v=25e-6) {fReadOutCycleLength = v;}
static Int_t GenOrderedSample(UInt_t nmax,UInt_t ngen,TArrayI &vals,TArrayI &ind);
static Double_t GausInt1D(Double_t sig,Double_t a,Double_t b);
static Double_t GausInt2D(Double_t sig0,Double_t a0,Double_t b0,
Double_t sig1,Double_t a1,Double_t b1);
protected:
AliITSsegmentation *fSeg;
AliITSCalibration *fCalibDead;
AliITSCalibration *fCalibNoisy;
AliITSUSensMap *fSensMap;
AliITSUSimuParam *fSimuParam;
AliITSUParamList *fResponseParam;
AliITSUChip *fChip;
Float_t fReadOutCycleOffset;
Float_t fReadOutCycleLength;
Int_t fEvent;
Int_t fDebug;
Bool_t fCyclesID[2*kMaxROCycleAccept+1];
ClassDef(AliITSUSimulation,2)
};
inline Double_t AliITSUSimulation::GausInt1D(Double_t sig,Double_t a,Double_t b)
{
const Double_t kRoot2 = 1.414213562;
double sp = 1.0/(sig*kRoot2);
return 0.5*TMath::Abs( AliMathBase::ErfcFast(sp*a) - AliMathBase::ErfcFast(sp*b) );
}
inline Double_t AliITSUSimulation::GausInt2D(Double_t sig0,Double_t a0,Double_t b0,
Double_t sig1,Double_t a1,Double_t b1)
{
const Double_t kRoot2 = 1.414213562;
double sp0 = 1.0/(sig0*kRoot2);
double sp1 = 1.0/(sig1*kRoot2);
return 0.25*TMath::Abs( (AliMathBase::ErfcFast(sp0*a0) - AliMathBase::ErfcFast(sp0*b0)) *
(AliMathBase::ErfcFast(sp1*a1) - AliMathBase::ErfcFast(sp1*b1)));
}
#endif