mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
airyPattern.hpp
Go to the documentation of this file.
1 /** \file airyPattern.hpp
2  * \author Jared R. Males
3  * \brief Utilities related to the Airy pattern point spread function.
4  * \ingroup gen_math_files
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 math_func_airyPattern_hpp
28 #define math_func_airyPattern_hpp
29 
30 
31 #include <gsl/gsl_integration.h>
32 #include <gsl/gsl_errno.h>
33 
34 #include "../constants.hpp"
35 #include "bessel.hpp"
36 #include "jinc.hpp"
37 
38 
39 namespace mx
40 {
41 
42 namespace math
43 {
44 
45 namespace func
46 {
47 
48 ///The classical Airy pattern
49 /** Returns the intensity distribution of the Airy pattern at a given \f$ \lambda/D \f$
50  *
51  * References: \cite born_and_wolf, \cite mahajan_1986, https://en.wikipedia.org/wiki/Airy_disk.
52  *
53  * \tparam realT is the floating point type used for arithmetic.
54  *
55  * \ingroup psfs
56  * \ingroup gen_math_airy_pattern
57  */
58 template<typename realT>
59 realT airyPattern( realT x /**< [in] is the separation in units of \f$ \lambda/D \f$. */)
60 {
61  return pow(2*jinc(pi<realT>()*x),2);
62 }
63 
64 ///The centrally obscured Airy pattern
65 /** Returns the intensity distribution of the centrally obscured Airy pattern at a given \f$ \lambda/D \f$
66  *
67  * References: \cite born_and_wolf, \cite mahajan_1986, https://en.wikipedia.org/wiki/Airy_disk.
68  *
69  * \tparam realT is the floating point type used for arithmetic.
70  *
71  * \ingroup psfs
72  * \ingroup gen_math_airy_pattern
73  */
74 template<typename realT>
75 realT airyPattern( realT x, ///< [in] is the separation in units of \f$ \lambda/D \f$.
76  realT eps ///< [in] is the ratio of the circular central obscuration diameter to the diameter.
77  )
78 {
79  return (1./pow(1.-eps*eps,2))*pow(2.*jinc( pi<realT>()*x)-eps*eps*2.*jinc(eps*pi<realT>()*x),2);
80 }
81 
82 
83 ///The general centrally obscured Airy pattern, with arbitrary center and platescale.
84 /** Returns the intensity distribution of the centrally obscured Airy pattern at a given \f$ \lambda/D \f$. This version allows
85  * for an arbitrary center, scaling, and platescale.
86  *
87  * References: \cite born_and_wolf, \cite mahajan_1986, https://en.wikipedia.org/wiki/Airy_disk.
88  *
89  * \tparam realT is the floating point type used for arithmetic.
90  *
91  * \ingroup psfs
92  * \ingroup gen_math_airy_pattern
93  */
94 template<typename realT>
95 realT airyPattern( realT x, ///< [in] is the x-coordinate in units of pixels
96  realT y, ///< [in] is the y-coordinate in units of pixels
97  realT A0, ///< [in] constant value added to the Airy pattern
98  realT A, ///< [in] peak scale of the Airy pattern.
99  realT x0, ///< [in] is the x-center in units of pixels
100  realT y0, ///< [in] is the y-center in units of pixels
101  realT ps, ///< [in] the platescale in \f$ (\lambda/D)/pixel \f$
102  realT eps ///< [in] is the ratio of the circular central obscuration diameter to the diameter.
103  )
104 {
105  realT r = sqrt( pow(x-x0,2) + pow(y-y0,2)) * ps;
106 
107  return A0 + A*airyPattern(r, eps);
108 }
109 
110 /// Fill in an array with the 2D arbitrarily-centered classical Airy pattern
111 /**
112  * At each pixel (x,y) of the array this computes:
113  *
114  * \f$ f(x,y) = A_0 + A\times Airy(\sqrt(x^2+y^2) \f$
115  *
116  * \tparam realT is the type to use for arithmetic
117  *
118  * \ingroup gen_math_airy_pattern
119  */
120 template<typename realT>
121 void airyPattern2D( realT * arr, ///< [out] is the allocated array to fill in
122  size_t nx, ///< [in] is the size of the x dimension of the array (rows)
123  size_t ny, ///< [in] is the size of the y dimension of the array (columns)
124  const realT A0, ///< [in] is the constant to add to the Gaussian
125  const realT A, ///< [in] is the scaling factor (peak height = A-A0)
126  const realT x0, ///< [in] is the x-coordinate of the center
127  const realT y0, ///< [in] is the y-coordinate of the center
128  realT ps ///< [in] the platescale in \f$ (\lambda/D)/pixel \f$
129  )
130 {
131  size_t idx;
132 
133  for(size_t j=0;j<ny; ++j)
134  {
135  for(size_t i=0;i<nx; ++i)
136  {
137  idx = i + j*nx;
138 
139  realT rad = sqrt( pow(i-x0,2) + pow(j-y0,2) ) * ps;
140 
141  arr[idx] = A0 + A* airyPattern(rad);
142  }
143  }
144 }
145 
146 ///Seeing Halo Profile
147 /** A Moffat profile due to Roddier (1981)\cite roddier_1981, see also Racine et al (1999)\cite racine_1999, which
148  * can be used to describe the seeing limited point-spread function of a telescope imaging through turbulence, or the halo in partially corrected imaging.
149  *
150  * \returns the value of the profile at x, in units of fractional flux per unit area.
151  *
152  * \ingroup psfs
153  * \ingroup gen_math_airy_pattern
154  */
155 template<typename realT>
156 realT seeingHalo( realT x, ///< [in] the separation in the same units as fwhm.
157  realT fwhm ///< [in] the fwhm in arbitrary units. Note that this defines the area units of the density.
158  )
159 {
160  return (0.488/(fwhm*fwhm))*pow(1. + (11./6.)*pow(x/fwhm,2), -11./6.);
161 }
162 
163 /// Calculate the fraction of enclosed power at a given radius for the unobscured Airy Pattern
164 /** See Mahajan (1986) \cite mahajan_1986 and https://en.wikipedia.org/wiki/Airy_disk.
165  *
166  * \returns the fraction of enclosed power at radius x
167  *
168  * \ingroup psfs
169  * \ingroup gen_math_airy_pattern
170  */
171 template<typename realT>
172 realT airyPatternEnclosed( realT x /**< [in] the radius */)
173 {
174  realT x1 = x*pi<realT>();
175 
176  realT b0 = bessel_j<realT>(0,x1);
177  b0=b0*b0;
178 
179  realT b1 = bessel_j<realT>(1,x1);
180  b1=b1*b1;
181 
182  realT encp = static_cast<realT>(1) - b0 - b1;
183 
184  return encp;
185 }
186 
187 template<typename realT>
188 realT apeInt( realT x,
189  void * params
190  )
191 {
192  realT eps = *static_cast<realT*>(params);
193 
194  return bessel_j<realT>(1,x)*bessel_j<realT>(1,eps*x)/x;
195 }
196 
197 /// Calculate the fraction of enclosed power at a given radius for the centrally obscured Airy Pattern
198 /** See Mahajan (1986) \cite mahajan_1986 and https://en.wikipedia.org/wiki/Airy_disk.
199  * If eps = 0, this calls the unobscured version.
200  *
201  * \returns the fraction of enclosed power at radius x
202  *
203  * \ingroup psfs
204  * \ingroup gen_math_airy_pattern
205  */
206 template<typename realT>
207 realT airyPatternEnclosed( realT x, ///< [in] the radius
208  realT eps ///< [in] the central obscuration fraction
209  )
210 {
211  if(eps == 0) return airyPatternEnclosed(x);
212 
213  gsl_function func;
214  func.function = apeInt<realT>;
215  func.params = &eps;
216 
217  realT jint;
218  realT abserr;
219  size_t neval;
220 
221  realT x1 = x*pi<realT>();
222 
223  gsl_set_error_handler_off();
224  gsl_integration_qng( &func, 0, x1, 1e-7, 1e-7, &jint,&abserr, &neval);
225 
226  realT b0 = bessel_j<realT>(0,x1);
227  b0=b0*b0;
228  realT b1 = bessel_j<realT>(1,x1);
229  b1=b1*b1;
230 
231  realT b0e = bessel_j<realT>(0,eps*x1);
232  b0e=b0e*b0e;
233  realT b1e = bessel_j<realT>(1,eps*x1);
234  b1e=b1e*b1e;
235 
236  realT eps2 = pow(eps,2);
237 
238  realT encp = static_cast<realT>(1) - b0 - b1 + eps2*(static_cast<realT>(1) - b0e - b1e);
239 
240  encp = encp - 4*eps*jint;
241  encp = encp/(static_cast<realT>(1)-eps2);
242 
243  return encp;
244 }
245 
246 } //namespace func
247 }//namespace math
248 }//namespace mx
249 
250 #endif //math_func_airyPattern_hpp
251 
Declares and defines Bessel functions of the first kind.
realT airyPatternEnclosed(realT x, realT eps)
Calculate the fraction of enclosed power at a given radius for the centrally obscured Airy Pattern.
realT seeingHalo(realT x, realT fwhm)
Seeing Halo Profile.
realT airyPattern(realT x, realT y, realT A0, realT A, realT x0, realT y0, realT ps, realT eps)
The general centrally obscured Airy pattern, with arbitrary center and platescale.
Definition: airyPattern.hpp:95
void airyPattern2D(realT *arr, size_t nx, size_t ny, const realT A0, const realT A, const realT x0, const realT y0, realT ps)
Fill in an array with the 2D arbitrarily-centered classical Airy pattern.
T jinc(const T &x)
The Jinc function.
Definition: jinc.hpp:64
Declares and defines the Jinc and Jinc2 functions.
The mxlib c++ namespace.
Definition: mxError.hpp:107