LSST Applications g180d380827+6621f76652,g2079a07aa2+86d27d4dc4,g2305ad1205+f5a9e323a1,g2bbee38e9b+c6a8a0fb72,g337abbeb29+c6a8a0fb72,g33d1c0ed96+c6a8a0fb72,g3a166c0a6a+c6a8a0fb72,g3ddfee87b4+9a10e1fe7b,g48712c4677+c9a099281a,g487adcacf7+f2e03ea30b,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+aead732c78,g64a986408d+eddffb812c,g858d7b2824+eddffb812c,g864b0138d7+aa38e45daa,g974c55ee3d+f37bf00e57,g99cad8db69+119519a52d,g9c22b2923f+e2510deafe,g9ddcbc5298+9a081db1e4,ga1e77700b3+03d07e1c1f,gb0e22166c9+60f28cb32d,gb23b769143+eddffb812c,gba4ed39666+c2a2e4ac27,gbb8dafda3b+27317ec8e9,gbd998247f1+585e252eca,gc120e1dc64+5817c176a8,gc28159a63d+c6a8a0fb72,gc3e9b769f7+6707aea8b4,gcf0d15dbbd+9a10e1fe7b,gdaeeff99f8+f9a426f77a,ge6526c86ff+6a2e01d432,ge79ae78c31+c6a8a0fb72,gee10cc3b42+585e252eca,gff1a9f87cc+eddffb812c,v27.0.0.rc1
LSST Data Management Base Package
Loading...
Searching...
No Matches
pupil.py
Go to the documentation of this file.
1# This file is part of afw.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <https://www.gnu.org/licenses/>.
21
22__all__ = ['PupilFactory', 'Pupil']
23
24import numpy as np
25
26
27class Pupil:
28 """Pupil obscuration function.
29
30 Parameters
31 ----------
32 illuminated : `numpy.ndarray`, (Nx, Ny)
33 2D numpy array indicating which parts of the pupil plane are
34 illuminated.
35 size : `float`
36 Size of pupil plane array in meters. Note that this may be larger
37 than the actual diameter of the illuminated pupil to accommodate
38 zero-padding.
39 scale : `float`
40 Sampling interval of pupil plane array in meters.
41 """
42
43 def __init__(self, illuminated, size, scale):
44 self.illuminated = illuminated
45 self.size = size
46 self.scale = scale
47
48
50 """Pupil obscuration function factory for use with Fourier optics.
51
52 Parameters
53 ----------
54 visitInfo : `lsst.afw.image.VisitInfo`
55 Visit information for a particular exposure.
56 pupilSize : `float`
57 Size in meters of constructed Pupil array.
58 Note that this may be larger than the actual diameter of the
59 illuminated pupil to accommodate zero-padding.
60 npix : `int`
61 Constructed Pupils will be npix x npix.
62 """
63
64 def __init__(self, visitInfo, pupilSize, npix):
65 self.visitInfo = visitInfo
66 self.pupilSize = pupilSize
67 self.npix = npix
68 self.pupilScale = pupilSize/npix
69 u = (np.arange(npix, dtype=np.float64) - (npix - 1)/2) * self.pupilScale
70 self.u, self.v = np.meshgrid(u, u)
71
72 def getPupil(self, point):
73 """Calculate a Pupil at a given point in the focal plane.
74
75 Parameters
76 ----------
77 point : `lsst.geom.Point2D`
78 The focal plane coordinates.
79
80 Returns
81 -------
82 pupil : `Pupil`
83 The Pupil at ``point``.
84 """
85 raise NotImplementedError(
86 "PupilFactory not implemented for this camera")
87
88 @staticmethod
89 def _pointLineDistance(p0, p1, p2):
90 """Compute the right-angle distance between the points given by `p0`
91 and the line that passes through `p1` and `p2`.
92
93 Parameters
94 ----------
95 p0 : `tuple` of `numpy.ndarray`
96 2-tuple of numpy arrays (x, y focal plane coordinates)
97 p1 : ``pair`` of `float`
98 x,y focal plane coordinates
99 p2 : ``pair`` of `float`
100 x,y focal plane coordinates
101
102 Returns
103 -------
104 distances : `numpy.ndarray`
105 Numpy array of distances; shape congruent to p0[0].
106 """
107 x0, y0 = p0
108 x1, y1 = p1
109 x2, y2 = p2
110 dy21 = y2 - y1
111 dx21 = x2 - x1
112 return np.abs(dy21*x0 - dx21*y0 + x2*y1 - y2*x1)/np.hypot(dy21, dx21)
113
114 def _fullPupil(self):
115 """Make a fully-illuminated Pupil.
116
117 Returns
118 -------
119 pupil : `Pupil`
120 The illuminated pupil.
121 """
122 illuminated = np.ones(self.u.shape, dtype=bool)
123 return Pupil(illuminated, self.pupilSize, self.pupilScale)
124
125 def _cutCircleInterior(self, pupil, p0, r):
126 """Cut out the interior of a circular region from a Pupil.
127
128 Parameters
129 ----------
130 pupil : `Pupil`
131 Pupil to modify in place.
132 p0 : `pair`` of `float`
133 2-tuple indicating region center.
134 r : `float`
135 Circular region radius.
136 """
137 r2 = (self.u - p0[0])**2 + (self.v - p0[1])**2
138 pupil.illuminated[r2 < r**2] = False
139
140 def _cutCircleExterior(self, pupil, p0, r):
141 """Cut out the exterior of a circular region from a Pupil.
142
143 Parameters
144 ----------
145 pupil : `Pupil`
146 Pupil to modify in place
147 p0 : `pair`` of `float`
148 2-tuple indicating region center.
149 r : `float`
150 Circular region radius.
151 """
152 r2 = (self.u - p0[0])**2 + (self.v - p0[1])**2
153 pupil.illuminated[r2 > r**2] = False
154
155 def _cutRay(self, pupil, p0, angle, thickness):
156 """Cut out a ray from a Pupil.
157
158 Parameters
159 ----------
160 pupil : `Pupil`
161 Pupil to modify in place.
162 p0 : `pair`` of `float`
163 2-tuple indicating ray starting point.
164 angle : `pair` of `float`
165 Ray angle measured CCW from +x.
166 thickness : `float`
167 Thickness of cutout.
168 """
169 angleRad = angle.asRadians()
170 # the 1 is arbitrary, just need something to define another point on
171 # the line
172 p1 = (p0[0] + 1, p0[1] + np.tan(angleRad))
173 d = PupilFactory._pointLineDistance((self.u, self.v), p0, p1)
174 pupil.illuminated[(d < 0.5*thickness)
175 & ((self.u - p0[0])*np.cos(angleRad)
176 + (self.v - p0[1])*np.sin(angleRad) >= 0)] = False
177
178 def _centerPupil(self, pupil):
179 """Center the illuminated portion of the pupil in array.
180
181 Parameters
182 ----------
183 pupil : `Pupil`
184 Pupil to modify in place
185 """
186 def center(arr, axis):
187 smash = np.sum(arr, axis=axis)
188 w = np.where(smash)[0]
189 return int(0.5*(np.min(w)+np.max(w)))
190 ycenter = center(pupil.illuminated, 0)
191 xcenter = center(pupil.illuminated, 1)
192 ytarget = pupil.illuminated.shape[0]//2
193 xtarget = pupil.illuminated.shape[1]//2
194 pupil.illuminated = np.roll(np.roll(pupil.illuminated,
195 xtarget-xcenter,
196 axis=0),
197 ytarget-ycenter,
198 axis=1)
_cutRay(self, pupil, p0, angle, thickness)
Definition pupil.py:155
__init__(self, visitInfo, pupilSize, npix)
Definition pupil.py:64
_cutCircleExterior(self, pupil, p0, r)
Definition pupil.py:140
_cutCircleInterior(self, pupil, p0, r)
Definition pupil.py:125
__init__(self, illuminated, size, scale)
Definition pupil.py:43