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