mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
fraunhoferPropagator.hpp
Go to the documentation of this file.
1 /** \file fraunhoferPropagator.hpp
2  * \brief Declares and defines a class for Fraunhofer propagation of optical wavefronts
3  * \ingroup imaging
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  */
7 
8 //***********************************************************************//
9 // Copyright 2015-2020 Jared R. Males (jaredmales@gmail.com)
10 //
11 // This file is part of mxlib.
12 //
13 // mxlib is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // mxlib is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
25 //***********************************************************************//
26 
27 #ifndef wfp_fraunhoferPropagator_hpp
28 #define wfp_fraunhoferPropagator_hpp
29 
30 #include "../math/constants.hpp"
31 #include "imagingArray.hpp"
32 #include "imagingUtils.hpp"
33 
34 #include "../math/fft/fft.hpp"
35 
36 namespace mx
37 {
38 
39 namespace wfp
40 {
41 
42 /// Class to perform Fraunhofer propagation between pupil and focal planes
43 /** This class uses the FFT to propagate between planes, and normalizes so that flux
44  * is conserved. For propagation from pupil to focal plane, the pupil wavefront is tilted so that
45  * the focal-plane image is centered at the geometric center of the array. After propagation from
46  * focal plane to pupil plane, the pupil plane wavefront is un-tilted to restore the
47  * pupil to its original position.
48  *
49  * \tparam _wavefrontT is an Eigen::Array-like type, with std::complex values.
50  *
51  * \todo check if we should reverse the FFT orders to be proper
52  *
53  * \ingroup imaging
54  */
55 template<typename _wavefrontT>
57 {
58 
59 public:
60 
61  ///The wavefront data type
62  typedef _wavefrontT wavefrontT;
63 
64  ///The complex data type
65  typedef typename wavefrontT::Scalar complexT;
66 
67  ///The real data type
68  typedef typename wavefrontT::Scalar::value_type realT;
69 
70 protected:
71 
72  ///The size of the wavefront in pixels
74 
75  realT m_xcen {0}; ///<x-coordinate of focal plane center, in pixels
76  realT m_ycen {0}; ///<x-coordinate of focal plane center, in pixels
77 
78  /// Determines how the image is centered.
79  /** If 0 (default) it is at 0.5*(wfSz-1), if true it is shifted by 0.5*m_wholePixel in each axis.
80  */
82 
83  ///Phase screen for tilting the pupil plane so that the focal plane image is centered.
85 
86  ///Phase screen for un-tilting the pupil plane after propagating from a centered focal plane.
88 
89  ///FFT object for forward FFTs
90  math::fft::fftT<complexT, complexT,2,0> m_fft_fwd;
91 
92  ///FFT object for backward FFTs
93  math::fft::fftT<complexT, complexT,2,0> m_fft_back;
94 
95  ///Initialize members
96  void initialize();
97 
98 
99 public:
100 
101  ///Constructor
103 
104  ///Destructor
106 
107  /// Get the value of the wholePixel parameter
108  /** The wholePixel parameter determines how the image is centered. If 0 (default) it is at 0.5*(wfSz-1), if true it is shifted by 0.5*m_wholePixel in each axis.
109  *
110  * \returns the value of m_wholePixel
111  */
112  int wholePixel();
113 
114  /// Set the value of the wholePixel parameter
115  /** The wholePixel parameter determines how the image is centered. If 0 (default) it is at 0.5*(wfSz-1), if true it is shifted by 0.5*m_wholePixel in each axis.
116  */
117  void wholePixel(realT wp /**< [in] the new wholePixel value */);
118 
119  ///Apply the shift to a pupil wavefront which will center the resultant focal plane image, and apply the normalization.
120  /** You must have allocated the shift screens first, by calling propagatePupilToFocal, propagateFocalToPupil, or setWavefrontSizePixels.
121  */
122  void shiftPupil( wavefrontT & complexPupil /**< [in.out] the complex pupil plane wavefront to shift*/);
123 
124  ///Apply the shift to a pupil wavefront which will restore it to a centered pupil image, with correct flux.
125  /** You must have allocated the shift screens first, by calling propagatePupilToFocal, propagateFocalToPupil, or setWavefrontSizePixels.
126  */
127  void unshiftPupil( wavefrontT & complexPupil /**< [in.out] the complex pupil plane wavefront to shift*/);
128 
129  ///Propagate the wavefront from the pupil plane to the focal plane
130  /** The pupil plane wavefront (complexPupil) is multiplied by a tilt to place the
131  * image in the geometric center of the focal plane. This can be prevented by
132  * setting doCenter to false.
133  *
134  */
135  void propagatePupilToFocal( wavefrontT & complexFocal, ///< [out] the focal plane wavefront. Must be pre-allocated to same size as complexPupil.
136  wavefrontT & complexPupil, ///< [in] the pupil plane wavefront. Modified due to application of centering tilt.
137  bool doCenter = true ///< [in] [optional] set to false to not apply the centering shift
138  );
139 
140  ///Propagate the wavefront from Focal plane to Pupil plane
141  /** After the fourier transform, the output pupil plane wavefront is de-tilted, restoring it
142  * to the state prior to calling \ref propagatePupilToFocal. This can be prevented by
143  * setting doCenter to false.
144  *
145  */
146  void propagateFocalToPupil( wavefrontT & complexPupil, ///< [out] the pupil plane wavefront. Must be pre-allocated to same size as complexFocal.
147  wavefrontT & complexFocal, ///< [in] the focal plane wavefront.
148  bool doCenter = true ///< [in] [optional] set to false to not apply the centering shift
149  );
150 
151  ///Set the size of the wavefront, in pixels
152  /** Checks if the size changes, does nothing if no change. Otherwise, calls
153  * \ref makeShiftPhase to pre-calculate the tilt arrays and plans the FFTs.
154  *
155  */
156  void setWavefrontSizePixels( int wfsPix /**< [in] the desired new size of the wavefront */ );
157 
158 protected:
159 
160  ///Calculate the complex tilt arrays for centering and normalizing the wavefronts
161  /**
162  */
164 
165 };//class fraunhoferPropagator
166 
167 template<typename wavefrontT>
169 {
170  m_wavefrontSizePixels = 0;
171 
172  m_xcen = 0;
173  m_ycen = 0;
174 }
175 
176 template<typename wavefrontT>
178 {
179 }
180 
181 template<typename wavefrontT>
183 {
184 }
185 
186 template<typename wavefrontT>
188 {
189  return m_wholePixel;
190 }
191 
192 template<typename wavefrontT>
194 {
195  m_wholePixel = wp;
196 
197  //Re-make the shift phase if size already set.
198  if(m_wavefrontSizePixels > 0) makeShiftPhase();
199 }
200 
201 
202 template<typename wavefrontT>
204 {
205  complexPupil *= m_centerFocal;
206 }
207 
208 template<typename wavefrontT>
210 {
211  complexPupil *= m_centerPupil;
212 }
213 
214 template<typename wavefrontT>
216  wavefrontT & complexPupil,
217  bool doCenter /*default = true*/
218  )
219 {
220  //First setup the tilt screens (does nothing if there's no change in size)
221  setWavefrontSizePixels(complexPupil.rows());
222 
223  //Apply the centering shift -- this adjusts by 0.5 pixels and normalizes
224  if(doCenter) shiftPupil(complexPupil);
225 
226  //fft_fwd.fft(complexPupil.data(), complexFocal.data() );
227  m_fft_fwd( complexFocal.data(), complexPupil.data() );
228 }
229 
230 template<typename wavefrontT>
232  wavefrontT & complexFocal,
233  bool doCenter /*default = true*/
234  )
235 {
236  //First setup the tilt screens (does nothing if there's no change in size)
237  setWavefrontSizePixels(complexPupil.rows());
238 
239  //fft_back.fft( complexFocal.data(), complexPupil.data());
240  m_fft_back( complexPupil.data(), complexFocal.data() );
241 
242  //Unshift the wavefront and normalize
243  if(doCenter) unshiftPupil(complexPupil);
244 }
245 
246 template<typename wavefrontT>
248 {
249  //If no change in size, do nothing
250  if(wfsPix == m_centerFocal.rows()) return;
251 
252  m_wavefrontSizePixels = wfsPix;
253 
254  m_xcen = 0.5*(wfsPix - 1.0);
255  m_ycen = 0.5*(wfsPix - 1.0);
256 
257  makeShiftPhase();
258 
259  m_fft_fwd.plan(wfsPix, wfsPix);
260 
261  m_fft_back.plan(wfsPix, wfsPix, MXFFT_BACKWARD);
262 }
263 
264 template<typename wavefrontT>
266 {
267  constexpr realT pi = math::pi<realT>();
268 
269  //The normalization is included in the tilt.
270  realT norm = 1./(m_wavefrontSizePixels*sqrt(2));
271  complexT cnorm = complexT(norm, norm);
272 
273  //Resize the center phases
274  m_centerFocal.resize(m_wavefrontSizePixels, m_wavefrontSizePixels);
275  m_centerPupil.resize(m_wavefrontSizePixels, m_wavefrontSizePixels);
276 
277  //Shift by 0.5 pixels
278  realT arg = -2.0*pi*0.5*(m_wavefrontSizePixels-m_wholePixel)/(m_wavefrontSizePixels-1);
279 
280  for(int ii=0; ii < m_wavefrontSizePixels; ++ii)
281  {
282  for(int jj=0; jj < m_wavefrontSizePixels; ++jj)
283  {
284  m_centerFocal(ii,jj) = cnorm*exp(complexT(0.,arg*((ii-m_xcen)+(jj-m_ycen))));
285  m_centerPupil(ii,jj) = cnorm*exp(complexT(0., 0.5*pi - arg*((ii-m_xcen)+(jj-m_ycen))));
286  }
287  }
288 }
289 
290 } //namespace wfp
291 } //namespace mx
292 
293 #endif //wfp_fraunhoferPropagator_hpp
Class to perform Fraunhofer propagation between pupil and focal planes.
realT m_xcen
x-coordinate of focal plane center, in pixels
void unshiftPupil(wavefrontT &complexPupil)
Apply the shift to a pupil wavefront which will restore it to a centered pupil image,...
wavefrontT::Scalar::value_type realT
The real data type.
wavefrontT m_centerPupil
Phase screen for un-tilting the pupil plane after propagating from a centered focal plane.
void makeShiftPhase()
Calculate the complex tilt arrays for centering and normalizing the wavefronts.
math::fft::fftT< complexT, complexT, 2, 0 > m_fft_fwd
FFT object for forward FFTs.
int wholePixel()
Get the value of the wholePixel parameter.
void setWavefrontSizePixels(int wfsPix)
Set the size of the wavefront, in pixels.
realT m_ycen
x-coordinate of focal plane center, in pixels
void wholePixel(realT wp)
Set the value of the wholePixel parameter.
realT m_wholePixel
Determines how the image is centered.
int m_wavefrontSizePixels
The size of the wavefront in pixels.
wavefrontT m_centerFocal
Phase screen for tilting the pupil plane so that the focal plane image is centered.
math::fft::fftT< complexT, complexT, 2, 0 > m_fft_back
FFT object for backward FFTs.
void shiftPupil(wavefrontT &complexPupil)
Apply the shift to a pupil wavefront which will center the resultant focal plane image,...
wavefrontT::Scalar complexT
The complex data type.
void propagatePupilToFocal(wavefrontT &complexFocal, wavefrontT &complexPupil, bool doCenter=true)
Propagate the wavefront from the pupil plane to the focal plane.
void initialize()
Initialize members.
_wavefrontT wavefrontT
The wavefront data type.
void propagateFocalToPupil(wavefrontT &complexPupil, wavefrontT &complexFocal, bool doCenter=true)
Propagate the wavefront from Focal plane to Pupil plane.
constexpr T pi()
Get the value of pi.
Definition: constants.hpp:52
Declares and defines a class for managing images.
Utilities for modeling image formation.
The mxlib c++ namespace.
Definition: mxError.hpp:107