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