mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
idealCoronagraph.hpp
Go to the documentation of this file.
1 /** \file idealCoronagraph.hpp
2  * \brief Declares and defines a class to describe the Ideal Coronagraph.
3  * \ingroup imaging_files
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  */
7 
8 //***********************************************************************//
9 // Copyright 2015, 2016, 2017 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 __idealCoronagraph_hpp__
28 #define __idealCoronagraph_hpp__
29 
30 #include <iostream>
31 
32 #include "fraunhoferPropagator.hpp"
33 #include "imagingUtils.hpp"
34 
35 #include "../wfp/imagingArray.hpp"
36 
37 #include "../ioutils/fits/fitsFile.hpp"
38 #include "../ioutils/fits/fitsUtils.hpp"
39 #include "../improc/imagePads.hpp"
40 
41 namespace mx
42 {
43 
44 namespace wfp
45 {
46 
47 /// The Ideal Coronagraph
48 /** A simple toy coronagraph which operates only the pupil plane, subtracting the energy-minimizing wavefront \cite cavarroc_2006. For an on-axis source with
49  * a perfectly flat wavefront this results in perfect extinction. This coronagraph is not physically realizable, but it is often useful
50  * for modeling and analysis, and it has been shown that real-world optimized coronagraphs often approach ideal performance \cite sauvage_2010 [and Males in prep].
51  *
52  * \ingroup coronagraphs
53  */
54 template<typename _realT>
56 {
57  ///The real floating point type
58  typedef _realT realT;
59 
60  ///The complex floating point type
61  typedef std::complex<realT> complexT;
62 
63  ///The wavefront complex field type
64  typedef imagingArray<std::complex<realT>, fftwAllocator<std::complex<realT> >, 0> complexFieldT;
65 
66  ///The image type
67  typedef Eigen::Array< realT, Eigen::Dynamic, Eigen::Dynamic> imageT;
68 
69  ///The directory where coronagraph files are stored
70  std::string _fileDir;
71 
72  ///The linear size of the wavefront in pixels
73  int _wfSz;
74 
75  imageT _realPupil;
76 
77  complexFieldT m_focalPlane;
78 
79  ///Fraunhofer propagator
81 
82  /// Determines how the image is centered.
83  /** If 0 (default) it is at 0.5*(wfSz-1), if true it is shifted by 0.5*m_wholePixel in each axis. This is passed to
84  * fraunhoferPropagator when it is resized.
85  */
87 
89 
90  ///Get the wavefront size in pixels
91  /**
92  * \returns the wavefront size in pixels
93  */
94  int wfSz();
95 
96  ///Set the wavefront size in pixels.
97  /**
98  */
99  void wfSz(int sz /**< [in] is the new size */);
100 
101  /// Set the real pupil mask.
102  /** The input mask does not have to be the same size as wfSz, as the stored mask will be padded.
103  *
104  * \returns 0 on success.
105  * \returns -1 on error.
106  */
107  int setPupil( imageT & pupil /**< [in] the pupil mask. */);
108 
109  /// Load the real pupil mask from a FITS file.
110  /** The input mask does not have to be the same size as wfSz, as the stored mask will be padded.
111  *
112  * \returns 0 on success.
113  * \returns -1 on error.
114  */
115  int loadPupil( const std::string & pupilFile /**< [in] the FITS file containing the pupil mask. */);
116 
117  ///Load the components of the coronagraph (just a pupil) based in its base name
118  /** Looks in _filDir for the files.
119  *
120  * \returns 0 on success.
121  * \returns -1 on error.
122  */
123  int loadCoronagraph( const std::string & cName /**< The name of the coronagraph, without directory or file extensions */);
124 
125  /// Propagate the given pupil-plane wavefront through the coronagraph to the exit pupil plane
126  int propagate( complexFieldT & pupilPlane /**< [in.out] The wavefront at the input pupil plane. It is modified by the coronagraph. */);
127 
128 
129  /// Propagate the given pupil-plane wavefront through the coronagraph to the exit pupil plane, and then to the final focal plane.
130  int propagate( imageT & fpIntensity, ///< [out] The intensity image in the focal plane. This should be pre-allocated.
131  complexFieldT & pupilPlane ///< [in.out] The wavefront at the input pupil plane. It is modified by the coronagraph.
132  );
133 
134  /// Propagate the given pupil-plane wavefront without the coronagraph.
135  /** For the ideal coronagraph nothing is done. This method is included for compliance with
136  * with the coronagraph interface.
137  */
138  int propagateNC( complexFieldT & pupilPlane /**< [in.out] The wavefront at the input pupil plane. It is un-modified. */);
139 
140  /// Propagate the given pupil-plane wavefront without the coronagraph to the exit pupil plane, and then to the final focal plane.
141  /** For the ideal coronagraph nothing is done to the input wavefront.
142  */
143  int propagateNC( imageT & fpIntensity, ///< [out] The intensity image in the focal plane. This should be pre-allocated.
144  complexFieldT & pupilPlane ///< [in.out] The wavefront at the input pupil plane. It is un-modified.
145  );
146 
147  bool apodize {false};
148  imageT apodizer;
149 
150 };
151 
152 template<typename realT>
153 idealCoronagraph<realT>::idealCoronagraph()
154 {
155  _wfSz = 0;
156 }
157 
158 template<typename realT>
160 {
161  return _wfSz;
162 }
163 
164 template<typename realT>
166 {
167  _wfSz = sz;
168 
169  m_fi.setWavefrontSizePixels(sz);
170  m_fi.wholePixel(m_wholePixel);
171  m_focalPlane.resize(sz, sz);
172 
173 }
174 
175 template<typename realT>
177 {
178  if(_wfSz <= 0)
179  {
180  mxError("idealCoronagraph", MXE_PARAMNOTSET, "Must set wavefront size (wfSz) before setting up coronagraph.");
181  return -1;
182  }
183 
184  //Create Coronagraph pupil.
185  improc::padImage(_realPupil, pupil, 0.5*(_wfSz-pupil.rows()),0);
186 
187  return 0;
188 }
189 
190 template<typename realT>
191 int idealCoronagraph<realT>::loadPupil( const std::string & pupilFile)
192 {
193 
194  imageT pupil;
195 
197 
198  ff.read(pupil, pupilFile);
199 
200  return setPupil(pupil);
201 
202  return 0;
203 }
204 
205 template<typename realT>
206 int idealCoronagraph<realT>::loadCoronagraph( const std::string & cName)
207 {
208 
209  if( _fileDir == "")
210  {
211  mxError("idealCoronagraph", MXE_PARAMNOTSET, "file directory (fileDir) not set.");
212  return -1;
213  }
214 
215  std::string pupilFile = _fileDir + "/" + cName + ".fits";
216 
217  return loadPupil(pupilFile);
218 
219 }
220 
221 template<typename realT>
223 {
224  if( pupilPlane.rows() != _realPupil.rows() || pupilPlane.cols() != _realPupil.cols())
225  {
226  mxError("idealCoronagraph", MXE_SIZEERR, "pupilPlane wavefront size does not match realPupil");
227  return -1;
228  }
229 
230  Eigen::Map<Eigen::Array<complexT,-1,-1> > eigWf(pupilPlane.data(), pupilPlane.cols(), pupilPlane.rows());
231  Eigen::Map<Eigen::Array<realT,-1,-1> > eigPup(_realPupil.data(), _realPupil.cols(), _realPupil.rows());
232 
233  eigWf = (eigWf - ((eigWf*eigPup).sum()/(eigPup*eigPup).sum()))*eigPup;
234 
235  if(apodize)
236  {
237  eigWf *= apodizer;
238  }
239 
240  return 0;
241 }
242 
243 template<typename realT>
245  complexFieldT & pupilPlane
246  )
247 {
248  propagate(pupilPlane);
249 
250  m_fi.propagatePupilToFocal(m_focalPlane, pupilPlane);
251 
252  int x0 = 0.5*(_wfSz-1) - 0.5*(fpIntensity.rows()-1);
253  int y0 = 0.5*(_wfSz-1) - 0.5*(fpIntensity.cols()-1);
254 
255  extractIntensityImage(fpIntensity,0, fpIntensity.rows(),0,fpIntensity.cols(), m_focalPlane, x0,y0);
256 
257  return 0;
258 }
259 
260 template<typename realT>
262 {
263  static_cast<void>(pupilPlane);
264  return 0;
265 }
266 
267 template<typename realT>
269  complexFieldT & pupilPlane )
270 {
271  propagateNC(pupilPlane);
272 
273  m_fi.propagatePupilToFocal(m_focalPlane, pupilPlane);
274 
275  int x0 = 0.5*(_wfSz-1) - 0.5*(fpIntensity.rows()-1);
276  int y0 = 0.5*(_wfSz-1) - 0.5*(fpIntensity.cols()-1);
277 
278  extractIntensityImage(fpIntensity,0, fpIntensity.rows(),0,fpIntensity.cols(), m_focalPlane, x0,y0);
279 
280  return 0;
281 }
282 
283 
284 } //namespace wfp
285 } //namespace mx
286 
287 #endif //__idealCoronagraph_hpp__
Class to manage interactions with a FITS file.
Definition: fitsFile.hpp:54
int read(dataT *data)
Read the contents of the FITS file into an array.
Definition: fitsFile.hpp:828
Declares and defines a class for Fraunhofer propagation of optical wavefronts.
int padImage(imOutT &imOut, imInT &imIn, unsigned int padSz, typename imOutT::Scalar value)
Pad an image with a constant value.
Definition: imagePads.hpp:57
Utilities for modeling image formation.
The mxlib c++ namespace.
Definition: mxError.hpp:107
The Ideal Coronagraph.
std::string _fileDir
The directory where coronagraph files are stored.
int _wfSz
The linear size of the wavefront in pixels.
int propagate(complexFieldT &pupilPlane)
Propagate the given pupil-plane wavefront through the coronagraph to the exit pupil plane.
Eigen::Array< realT, Eigen::Dynamic, Eigen::Dynamic > imageT
The image type.
int loadPupil(const std::string &pupilFile)
Load the real pupil mask from a FITS file.
std::complex< realT > complexT
The complex floating point type.
imagingArray< std::complex< realT >, fftwAllocator< std::complex< realT > >, 0 > complexFieldT
The wavefront complex field type.
int loadCoronagraph(const std::string &cName)
Load the components of the coronagraph (just a pupil) based in its base name.
_realT realT
The real floating point type.
realT m_wholePixel
Determines how the image is centered.
int wfSz()
Get the wavefront size in pixels.
int propagateNC(complexFieldT &pupilPlane)
Propagate the given pupil-plane wavefront without the coronagraph.
int setPupil(imageT &pupil)
Set the real pupil mask.
fraunhoferPropagator< complexFieldT > m_fi
Fraunhofer propagator.