mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
ccdDetector.hpp
Go to the documentation of this file.
1 /** \file ccdDetector.hpp
2  * \author Jared R. Males (jaredmales@gmail.com)
3  * \brief Provides a class to simulate a CCD.
4  * \ingroup mxAO_files
5  *
6  */
7 
8 #ifndef ccdDetector_hpp
9 #define ccdDetector_hpp
10 
11 
12 //#include <Eigen/Dense>
13 
14 #include "../../improc/imageTransforms.hpp"
15 #include "../../math/randomT.hpp"
16 
17 #include "wavefront.hpp"
18 
19 
20 #include <fcntl.h>
21 #include <iostream>
22 
23 namespace mx
24 {
25 namespace AO
26 {
27 namespace sim
28 {
29 
30 
31 
32 ///A simulated CCD detector
33 /** A simulated CCD detector, including an optional EMCCD noise model.
34  *
35  * \ingroup mxAOSim
36  */
37 template<typename _realT>
39 {
40 
41 public:
42 
43  typedef _realT realT;
44 
46 
47  typedef Eigen::Array<realT, Eigen::Dynamic, Eigen::Dynamic> imageT;
48 
50 
52 
53 
55 
56 
57 
58  ccdDetector();
59 
60 protected:
61 
62  norm_distT m_normVar; ///<Gets normal-distributed variates
63  poisson_distT m_poissonVar; ///<Gets Poisson distributed variates
64  gamma_distT m_gammaVar; ///<Gets gamma distributed variates
65 
66  realT m_qe {1}; ///<The quantum efficiency.
67 
68  realT m_darkCurrent {0}; ///<The dark current, per pixel per second
69  realT m_ron {0}; ///<The readout noise, electrons per pixel per read #include "mx/randomT.hpp"
70 
71  realT m_cic {0}; ///< EMCCD clock induced charge, electrons per pixel per read.
72  realT m_gain {1}; ///<Electron multiplication gain. If >1, then EMCCD is modeled.
73 
74  realT m_expTime {1}; ///<The exposure time, in seconds.
75 
76  int m_rows {0}; ///<The detector size, in rows.
77  int m_cols {0}; ///<The detector size, in columns.
78 
79  bool m_noNoise {false}; ///< If true no noise is added to the exposed image.
80 
81  //This is probably vestigial, commented out on 2018-07-23
82  //Delete after testing with an aoSim compile.
83  //long get_seed();
84 
85 public:
86 
87  /// Get the current value of qe.
88  /**
89  * \returns the current value of m_qe
90  */
91  realT qe();
92 
93  void qe(const realT & q);
94 
95  realT darkCurrent();
96 
97  void darkCurrent(const realT & dc);
98 
99  realT ron();
100 
101  void ron(const realT & r);
102 
103  realT cic();
104 
105  void cic(const realT & c);
106 
107  realT gain();
108 
109  void gain(const realT & g);
110 
111  realT expTime();
112 
113  void expTime(const realT &dt);
114 
115  int rows();
116 
117  void rows(const int & r);
118 
119  int cols();
120 
121  void cols(const int & c);
122 
123  void setSize(const int &r, const int &c);
124 
125  bool noNoise();
126 
127  void noNoise(bool nn);
128 
129  ///Rebin and add noise to the input image, placing the result in the output image.
130  /** The output image must be the same size or smaller than the input image.
131  * The output image is resized only if necessary.
132  * The input image is multiplied by expTime, so its flux should be in photons/sec.
133  * Noise is modeled as follows:
134  * -# The number of input photons for pixel (i,j) is \f$ n_{ie} = (in(i,j) + darkCurrent)*expTime + cic \f$
135  * -# The Poisson distribution with mean and variance \f$ n_{ie} \f$ is sampled.
136  * -# If gain > 1, the gamma distribution is sampled
137  * -# Read noise is applied
138  * -# Result is rounded to nearest whole integer.
139  */
140  void exposeImage( imageT & out, ///< [out] The output image, after all above steps applied.
141  imageT & in ///< [in] the input image, in photons/sec flux units.
142  );
143 
144 
145 
146 };
147 
148 
149 
150 template<typename realT>
151 ccdDetector<realT>::ccdDetector()
152 {
153  m_normVar.seed();
154  m_poissonVar.seed();
155  m_gammaVar.seed();
156 }
157 
158 
159 /*template<typename realT>
160 long ccdDetector<realT>::get_seed()
161 {
162  long int seedval;
163 
164  int fd;
165 
166  fd = open("/dev/urandom", O_RDONLY);
167 
168  int rv =read(fd, &seedval, sizeof(long int));
169 
170  close(fd);
171 
172 
173  if(rv < 0)
174  {
175  std::cerr << "read from /dev/urandom returned error\n";
176 
177  return 0;
178  }
179 
180  return seedval;
181 }
182 */
183 
184 template<typename realT>
186 {
187  return m_qe;
188 }
189 
190 template<typename realT>
191 void ccdDetector<realT>::qe(const realT & q)
192 {
193  m_qe = q;
194 }
195 
196 template<typename realT>
197 realT ccdDetector<realT>::darkCurrent()
198 {
199  return m_darkCurrent;
200 }
201 
202 template<typename realT>
203 void ccdDetector<realT>::darkCurrent(const realT & dc)
204 {
205  m_darkCurrent = dc;
206 }
207 
208 template<typename realT>
209 realT ccdDetector<realT>::ron()
210 {
211  return m_ron;
212 }
213 
214 template<typename realT>
215 void ccdDetector<realT>::ron(const realT & r)
216 {
217  m_ron = r;
218 }
219 
220 template<typename realT>
221 realT ccdDetector<realT>::cic()
222 {
223  return m_cic;
224 }
225 
226 template<typename realT>
227 void ccdDetector<realT>::cic(const realT & c)
228 {
229  m_cic = c;
230 }
231 
232 template<typename realT>
233 realT ccdDetector<realT>::gain()
234 {
235  return m_gain;
236 }
237 
238 template<typename realT>
239 void ccdDetector<realT>::gain(const realT & g)
240 {
241  m_gain = g;
242 }
243 
244 template<typename realT>
245 realT ccdDetector<realT>::expTime()
246 {
247  return m_expTime;
248 }
249 
250 template<typename realT>
251 void ccdDetector<realT>::expTime(const realT & dt)
252 {
253  m_expTime = dt;
254 }
255 
256 
257 template<typename realT>
258 int ccdDetector<realT>::rows()
259 {
260  return m_rows;
261 }
262 
263 template<typename realT>
264 void ccdDetector<realT>::rows(const int & r)
265 {
266  m_rows = r;
267 }
268 
269 template<typename realT>
270 int ccdDetector<realT>::cols()
271 {
272  return m_cols;
273 }
274 
275 template<typename realT>
276 void ccdDetector<realT>::cols(const int & c)
277 {
278  m_cols = c;
279 }
280 
281 template<typename realT>
282 void ccdDetector<realT>::setSize(const int & r, const int & c)
283 {
284  m_rows = r;
285  m_cols = c;
286 }
287 
288 
289 template<typename realT>
290 bool ccdDetector<realT>::noNoise()
291 {
292  return m_noNoise;
293 }
294 
295 template<typename realT>
296 void ccdDetector<realT>::noNoise(bool nn)
297 {
298  m_noNoise = nn;
299 }
300 
301 
302 template<typename realT>
303 void ccdDetector<realT>::exposeImage(imageT & out, imageT & in)
304 {
305 
306  using poisson_param_t = typename std::poisson_distribution<int>::param_type;
307  using gamma_param_t = typename std::gamma_distribution<realT>::param_type;
308 
309  BREAD_CRUMB
310 
311  out.resize(m_rows, m_cols);
312 
313  BREAD_CRUMB
314 
315  improc::imageDownSample(out, in);
316 
317  BREAD_CRUMB
318 
319  if(m_noNoise) return;
320 
321  for(int i=0;i<m_rows;++i)
322  {
323  for(int j=0; j<m_cols;++j)
324  {
325  realT charge = (out(i,j)*m_qe + m_darkCurrent) * m_expTime + m_cic;
326 
327  if(charge > 1000)
328  {
329  out(i,j) = charge + m_normVar*sqrt(charge);
330  }
331  else
332  {
333  m_poissonVar.distribution.param(poisson_param_t{charge});
334  out(i,j) = m_poissonVar;
335  }
336 
337  if(m_gain > 1)
338  {
339  m_gammaVar.distribution.param(gamma_param_t{out(i,j), m_gain});
340 
341 
342  out(i,j) = m_gammaVar;
343 
344  }
345 
346  out(i,j) += m_normVar*m_ron;
347 
348  if(m_gain > 1) out(i,j) /= m_gain;
349 
350  out(i,j) = round(out(i,j));
351 
352  }
353  }
354 
355 
356 
357 
358 
359 }
360 
361 } //namespace sim
362 } //namespace AO
363 } //namespace mx
364 
365 #endif //ccdDetector_hpp
A simulated CCD detector.
Definition: ccdDetector.hpp:39
realT m_ron
The readout noise, electrons per pixel per read #include "mx/randomT.hpp".
Definition: ccdDetector.hpp:69
realT m_darkCurrent
The dark current, per pixel per second.
Definition: ccdDetector.hpp:68
realT m_qe
The quantum efficiency.
Definition: ccdDetector.hpp:66
realT qe()
Get the current value of qe.
realT m_cic
EMCCD clock induced charge, electrons per pixel per read.
Definition: ccdDetector.hpp:71
int m_cols
The detector size, in columns.
Definition: ccdDetector.hpp:77
realT m_expTime
The exposure time, in seconds.
Definition: ccdDetector.hpp:74
norm_distT m_normVar
Gets normal-distributed variates.
Definition: ccdDetector.hpp:62
gamma_distT m_gammaVar
Gets gamma distributed variates.
Definition: ccdDetector.hpp:64
int m_rows
The detector size, in rows.
Definition: ccdDetector.hpp:76
poisson_distT m_poissonVar
Gets Poisson distributed variates.
Definition: ccdDetector.hpp:63
bool m_noNoise
If true no noise is added to the exposed image.
Definition: ccdDetector.hpp:79
void exposeImage(imageT &out, imageT &in)
Rebin and add noise to the input image, placing the result in the output image.
realT m_gain
Electron multiplication gain. If >1, then EMCCD is modeled.
Definition: ccdDetector.hpp:72
A random number type, which functions like any other arithmetic type.
Definition: randomT.hpp:61
constexpr units::realT c()
The speed of light.
Definition: constants.hpp:60
void imageDownSample(imageOutT &imout, const imageInT &imin)
Down-sample an image, reducing its size while conserving the total flux.
The mxlib c++ namespace.
Definition: mxError.hpp:107
Structure containing the phase and amplitude of a wavefront
Definition: wavefront.hpp:26