source: branches/MarsISDCBranchBasedOn17887/melectronics/MAvalanchePhotoDiode.h@ 18027

Last change on this file since 18027 was 17202, checked in by dneise, 11 years ago
in commit 17200 & 17201 I committed accidentally a lot of changes, that were totally unnecessary. So I reverted back to 17199. In this revision the svn property svn:ignore is still set, such that all the Cint.cc and Cint.h files as well as .d files are ignored. In addition I changed melectronics/MAvalanchePhotoDiode.h: I gave the Afterpulse class a ClassDef macro... and I added the link pragma into LinkDef.h file. So now one can easier write test macros for the APD class, without the need to compile the macro. Sorry for the hubbub.
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
68 // --- Lower level user interface ---
69
70 // Implementation to hit a specified or random cell
71 Float_t HitCell(Int_t x, Int_t y, Float_t t=0);
72 Float_t HitRandomCell(Float_t t=0);
73
74 // Functions to produce virgin chips or just effected by constant rates
75 void FillEmpty(Float_t t=0);
76 void FillRandom(Float_t rate, Float_t t=0);
77
78 // Produce random pulses with the given rate over a time dt.
79 // Processes afterpulses until the new time and deletes previous
80 // afterpulses.
81 Float_t Evolve(Double_t freq, Double_t dt);
82
83 // Delete Afterpulses before fTime. This might be wanted after
84 // a call to Evolve or Relax to maintain memeory usage.
85 void DeleteAfterpulses() { DeleteAfterpulses(fTime); }
86
87 // --- High level user interface ---
88
89 // This fills a G-APD with a rough estimated state at a given time
90 // T=0. It then evolves the time over the ralaxation time. If the
91 // chip is not virgin (i.e. fTime<0) the random filling is omitted
92 void Init(Float_t rate) { if (fTime<0) FillRandom(rate); Relax(rate); ShiftTime(); }
93
94 // Shifts all times including fTime by dt backwards (adds -dt)
95 // This is convenient because you can set the current time (fTime) to 0
96 void ShiftTime(Double_t dt);
97 void ShiftTime() { ShiftTime(fTime); }
98
99 // Functions producing photons hitting cells. It is meant to add
100 // many photons with an arrival time t after fTime. The photons
101 // must be sorted in time first to ensure proper treatment of the
102 // afterpulses.
103 Float_t HitRandomCellRelative(Float_t t=0) { ProcessAfterpulses(fTime, t); return HitRandomCell(fTime+t); }
104
105 // Produce random pulses with a given frequency until the influence
106 // of the effects of the G-APD (relaxation time, afterpulses) are
107 // below the given threshold. (Calls Evolve())
108 // FIXME: Maybe the calculation of the relaxation time could be optimized?
109 Float_t Relax(Double_t freq, Float_t threshold=0.001) { return Evolve(freq, GetRelaxationTime(threshold)); }
110
111 // Issue afterpulses until fTime+dt and set fTime to fTime+dt
112 // This is needed to create all afterpulses from external pulses
113 // and afterpulses until the time fTime+dt. This makes mainly
114 // the list of afterpulses complete until fTime+dt
115 void IncreaseTime(Float_t dt) { ProcessAfterpulses(fTime, dt); fTime += dt; }
116
117 // TObject
118 void Draw(Option_t *o="") { fHist.Draw(o); }
119 void DrawCopy(Option_t *o="") { fHist.DrawCopy(o); }
120
121 ClassDef(APD, 1) // An object representing a Geigermode APD
122};
123
124class Afterpulse : public TObject
125{
126private:
127 UInt_t fCellIndex; // Index of G-APD cell the afterpulse belongs to
128
129 Float_t fTime; // Time at which the afterpulse avalanch broke through
130 Float_t fAmplitude; // Amplitude (crosstalk!) the pulse produced
131
132 Int_t Compare(const TObject *obj) const
133 {
134 return static_cast<const Afterpulse*>(obj)->fTime>fTime ? -1 : 1;
135 }
136
137 Bool_t IsSortable() const { return kTRUE; }
138
139public:
140 Afterpulse(UInt_t idx, Float_t t) : fCellIndex(idx), fTime(t), fAmplitude(0) { }
141
142 UInt_t GetCellIndex() const { return fCellIndex; }
143
144 Float_t GetTime() const { return fTime; }
145 Float_t GetAmplitude() const { return fAmplitude; }
146
147 Float_t Process(APD &apd)
148 {
149 // Do not process afterpulses twice (e.g. HitRelative + IncreaseTime)
150 // This should not happen anyway
151 // if (fAmplitude>0)
152 // return fAmplitude;
153
154 const UInt_t nx = apd.GetNumCellsX()+2;
155
156 const UInt_t x = fCellIndex%nx;
157 const UInt_t y = fCellIndex/nx;
158
159 fAmplitude = apd.HitCellImp(x, y, fTime);
160
161 return fAmplitude;
162 }
163 ClassDef(Afterpulse, 1) // An Afterpulse object
164};
165
166#endif
Note: See TracBrowser for help on using the repository browser.