source: trunk/Mars/melectronics/MAvalanchePhotoDiode.h@ 19942

Last change on this file since 19942 was 19130, checked in by tbretz, 6 years ago
Added a member function to return the total charge in the sensor.
File size: 6.1 KB
Line 
1#ifndef MARS_MAvalanchePhotoDiode
2#define MARS_MAvalanchePhotoDiode
3
4#ifndef ROOT_TH2
5#include <TH2.h>
6#endif
7
8#ifndef ROOT_TSortedList
9#include <TSortedList.h>
10#endif
11
12class APD : public TObject // FIXME: Derive from TH2?
13{
14 friend class Afterpulse;
15
16private:
17 TH2F fHist;
18
19 TSortedList fAfterpulses; //! List of produced afterpulses
20
21 Float_t fCrosstalkProb; // Probability that a converted photon creates another one in a neighboring cell
22 Float_t fDeadTime; // Deadtime of a single cell after a hit
23 Float_t fRecoveryTime; // Recoverytime after Deadtime (1-exp(-t/fRecoveryTime)
24 Float_t fAfterpulseProb[2]; // Afterpulse probabilities
25 Float_t fAfterpulseTau[2]; // Afterpulse time constants
26
27 Float_t fTime; // A user settable time of the system
28
29 // The implementation of the cell behaviour (crosstalk and afterpulses)
30 Float_t HitCellImp(Int_t x, Int_t y, Float_t t=0);
31
32 // Processing of afterpulses
33 void GenerateAfterpulse(UInt_t cell, Int_t idx, Double_t charge, Double_t t);
34 void ProcessAfterpulses(Float_t time, Float_t dt);
35 void DeleteAfterpulses(Float_t time);
36
37public:
38 APD(Int_t n, Float_t prob=0, Float_t dt=0, Float_t rt=0);
39
40 // --- Setter and Getter ----
41
42 // Set the afterpulse probability and time-constant of distribution 1 and 2
43 void SetAfterpulse1(Double_t p, Double_t tau) { fAfterpulseProb[0]=p; fAfterpulseTau[0]=tau; }
44 void SetAfterpulse2(Double_t p, Double_t tau) { fAfterpulseProb[1]=p; fAfterpulseTau[1]=tau; }
45
46 // Set the afterpulse probability for distribution 1 and 2
47 void SetAfterpulseProb(Double_t p1, Double_t p2) { fAfterpulseProb[0]=p1; fAfterpulseProb[1]=p2; }
48
49 // Getter functions
50 Float_t GetCellContent(Int_t x, Int_t y) const { return fHist.GetBinContent(x, y); }
51 Int_t GetNumCellsX() const { return fHist.GetNbinsX(); }
52
53 Float_t GetCrosstalkProb() const { return fCrosstalkProb; }
54 Float_t GetDeadTime() const { return fDeadTime; }
55 Float_t GetRecoveryTime() const { return fRecoveryTime; }
56 Float_t GetTime() const { return fTime; }
57
58 Float_t GetRelaxationTime(Float_t threshold=0.001) const;
59
60 Float_t GetLastHit() const { return fHist.GetMaximum(); }
61
62 TSortedList &GetListOfAfterpulses() { return fAfterpulses; }
63
64 // Functions for easy production of statistics about the cells
65 Int_t CountDeadCells(Float_t t=0) const;
66 Int_t CountRecoveringCells(Float_t t=0) const;
67 Float_t GetChargeState(Float_t t=0) const;
68
69 // --- Lower level user interface ---
70
71 // Implementation to hit a specified or random cell
72 Float_t HitCell(Int_t x, Int_t y, Float_t t=0);
73 Float_t HitRandomCell(Float_t t=0);
74
75 // Functions to produce virgin chips or just effected by constant rates
76 void FillEmpty(Float_t t=0);
77 void FillRandom(Float_t rate, Float_t t=0);
78
79 // Produce random pulses with the given rate over a time dt.
80 // Processes afterpulses until the new time and deletes previous
81 // afterpulses.
82 Float_t Evolve(Double_t freq, Double_t dt);
83
84 // Delete Afterpulses before fTime. This might be wanted after
85 // a call to Evolve or Relax to maintain memeory usage.
86 void DeleteAfterpulses() { DeleteAfterpulses(fTime); }
87
88 // --- High level user interface ---
89
90 // This fills a G-APD with a rough estimated state at a given time
91 // T=0. It then evolves the time over the ralaxation time. If the
92 // chip is not virgin (i.e. fTime<0) the random filling is omitted
93 void Init(Float_t rate) { if (fTime<0) FillRandom(rate); Relax(rate); ShiftTime(); }
94
95 // Shifts all times including fTime by dt backwards (adds -dt)
96 // This is convenient because you can set the current time (fTime) to 0
97 void ShiftTime(Double_t dt);
98 void ShiftTime() { ShiftTime(fTime); }
99
100 // Functions producing photons hitting cells. It is meant to add
101 // many photons with an arrival time t after fTime. The photons
102 // must be sorted in time first to ensure proper treatment of the
103 // afterpulses.
104 Float_t HitRandomCellRelative(Float_t t=0) { ProcessAfterpulses(fTime, t); return HitRandomCell(fTime+t); }
105
106 // Produce random pulses with a given frequency until the influence
107 // of the effects of the G-APD (relaxation time, afterpulses) are
108 // below the given threshold. (Calls Evolve())
109 // FIXME: Maybe the calculation of the relaxation time could be optimized?
110 Float_t Relax(Double_t freq, Float_t threshold=0.001) { return Evolve(freq, GetRelaxationTime(threshold)); }
111
112 // Issue afterpulses until fTime+dt and set fTime to fTime+dt
113 // This is needed to create all afterpulses from external pulses
114 // and afterpulses until the time fTime+dt. This makes mainly
115 // the list of afterpulses complete until fTime+dt
116 void IncreaseTime(Float_t dt) { ProcessAfterpulses(fTime, dt); fTime += dt; }
117
118 // TObject
119 void Draw(Option_t *o="") { fHist.Draw(o); }
120 void DrawCopy(Option_t *o="") { fHist.DrawCopy(o); }
121
122 ClassDef(APD, 1) // An object representing a Geigermode APD
123};
124
125class Afterpulse : public TObject
126{
127private:
128 UInt_t fCellIndex; // Index of G-APD cell the afterpulse belongs to
129
130 Float_t fTime; // Time at which the afterpulse avalanch broke through
131 Float_t fAmplitude; // Amplitude (crosstalk!) the pulse produced
132
133 Int_t Compare(const TObject *obj) const
134 {
135 return static_cast<const Afterpulse*>(obj)->fTime>fTime ? -1 : 1;
136 }
137
138 Bool_t IsSortable() const { return kTRUE; }
139
140public:
141 Afterpulse(UInt_t idx, Float_t t) : fCellIndex(idx), fTime(t), fAmplitude(0) { }
142
143 UInt_t GetCellIndex() const { return fCellIndex; }
144
145 Float_t GetTime() const { return fTime; }
146 Float_t GetAmplitude() const { return fAmplitude; }
147
148 Float_t Process(APD &apd)
149 {
150 // Do not process afterpulses twice (e.g. HitRelative + IncreaseTime)
151 // This should not happen anyway
152 // if (fAmplitude>0)
153 // return fAmplitude;
154
155 const UInt_t nx = apd.GetNumCellsX()+2;
156
157 const UInt_t x = fCellIndex%nx;
158 const UInt_t y = fCellIndex/nx;
159
160 fAmplitude = apd.HitCellImp(x, y, fTime);
161
162 return fAmplitude;
163 }
164 ClassDef(Afterpulse, 1) // An Afterpulse object
165};
166
167#endif
Note: See TracBrowser for help on using the repository browser.