LSST Applications g0f08755f38+82efc23009,g12f32b3c4e+e7bdf1200e,g1653933729+a8ce1bb630,g1a0ca8cf93+50eff2b06f,g28da252d5a+52db39f6a5,g2bbee38e9b+37c5a29d61,g2bc492864f+37c5a29d61,g2cdde0e794+c05ff076ad,g3156d2b45e+41e33cbcdc,g347aa1857d+37c5a29d61,g35bb328faa+a8ce1bb630,g3a166c0a6a+37c5a29d61,g3e281a1b8c+fb992f5633,g414038480c+7f03dfc1b0,g41af890bb2+11b950c980,g5fbc88fb19+17cd334064,g6b1c1869cb+12dd639c9a,g781aacb6e4+a8ce1bb630,g80478fca09+72e9651da0,g82479be7b0+04c31367b4,g858d7b2824+82efc23009,g9125e01d80+a8ce1bb630,g9726552aa6+8047e3811d,ga5288a1d22+e532dc0a0b,gae0086650b+a8ce1bb630,gb58c049af0+d64f4d3760,gc28159a63d+37c5a29d61,gcf0d15dbbd+2acd6d4d48,gd7358e8bfb+778a810b6e,gda3e153d99+82efc23009,gda6a2b7d83+2acd6d4d48,gdaeeff99f8+1711a396fd,ge2409df99d+6b12de1076,ge79ae78c31+37c5a29d61,gf0baf85859+d0a5978c5a,gf3967379c6+4954f8c433,gfb92a5be7c+82efc23009,gfec2e1e490+2aaed99252,w.2024.46
LSST Data Management Base Package
Loading...
Searching...
No Matches
genDistortedImage.py
Go to the documentation of this file.
2# LSST Data Management System
3# Copyright 2008, 2009, 2010 LSST Corporation.
4#
5# This product includes software developed by the
6# LSST Project (http://www.lsst.org/).
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the LSST License Statement and
19# the GNU General Public License along with this program. If not,
20# see <http://www.lsstcorp.org/LegalNotices/>.
21#
22
23__all__ = ["noDistort", "linearXDistort", "quadraticDistortX",
24 "cubicDistortX", "manyTermX", "crossTerms1",
25 "crossTerms2", "crossTerms3", "quadraticDistort",
26 "T2DistortX", "T2DistortX"]
27
28
29import math
30
31import lsst.afw.table as afwTable
32
33
34def noDistort(src):
35 """Do no distortion. Used for sanity checking
36
37 Parameters
38 ----------
39 src : `lsst.afw.table.SourceRecord`
40 Input record
41
42 Returns
43 -------
44 out : `lsst.afw.table.SourceRecord`
45 Copy of input record.
46 """
47
48 out = src.table.copyRecord(src)
49 return out
50
51
52def linearXDistort(src, frac=.001):
53 """Increase the x value in a Source object by frac. E.g
54 src.x = 1000 --> 1001 if frac=.001
55
56 Parameters
57 ----------
58 src : `lsst.afw.table.SourceRecord`
59 A Source object
60 frac : `float`
61 How much to change X by
62
63 Returns
64 -------
65 out : `lsst.afw.table.SourceRecord`
66 A deep copy of src, with the value of x changed
67 """
68
69 out = src.table.copyRecord(src)
70 out.set(out.table.getCentroidSlot().getMeasKey().getX(), out.getX()*(1+frac))
71 return out
72
73
74def quadraticDistortX(src, frac=1e-6):
75 """Distort image by terms with power <=2
76 i.e y, y^2, x, xy, x^2
77
78 Parameters
79 ----------
80 src : `lsst.afw.table.SourceRecord`
81 A Source object
82 frac : `float`
83 How much to change X by
84
85 Returns
86 -------
87 out : `lsst.afw.table.SourceRecord`
88 A deep copy of src, with the value of x changed
89 """
90
91 out = src.table.copyRecord(src)
92 x = out.getX()
93 y = out.getY()
94 val = x**2
95
96 out.set(out.table.getCentroidSlot().getMeasKey().getX(), x + val*frac)
97 out.set(out.table.getCentroidSlot().getMeasKey().getY(), y)
98 return out
99
100
101def cubicDistortX(src, frac=1e-9):
102 """Distort image by terms with power <=2
103 i.e y, y^2, x, xy, x^2
104
105 Parameters
106 ----------
107 src : `lsst.afw.table.SourceRecord`
108 A Source object
109 frac : `float`
110 How much to change X by
111
112 Returns
113 -------
114 out : `lsst.afw.table.SourceRecord`
115 A deep copy of src, with the value of x changed
116 """
117
118 out = src.table.copyRecord(src)
119 x = out.getX()
120 y = out.getY()
121 val = x**3
122
123 out.set(out.table.getCentroidSlot().getMeasKey().getX(), x + val*frac)
124 out.set(out.table.getCentroidSlot().getMeasKey().getY(), y)
125 return out
126
127
128def manyTermX(src, frac=1e-9):
129 """Distort image by multiple powers of x, 'x**3 - 2*x**2 + 4*x - 9'.
130
131 Parameters
132 ----------
133 src : `lsst.afw.table.SourceRecord`
134 A Source object
135 frac : `float`
136 How much to change X by
137
138 Returns
139 -------
140 out : `lsst.afw.table.SourceRecord`
141 A deep copy of src, with the value of x changed
142 """
143
144 out = src.table.copyRecord(src)
145 x = out.getX()
146 y = out.getY()
147 val = x**3 - 2*x**2 + 4*x - 9
148
149 out.set(out.table.getCentroidSlot().getMeasKey().getX(), x + val*frac)
150 out.set(out.table.getCentroidSlot().getMeasKey().getY(), y)
151 return out
152
153
154def linearYDistort(src, frac=.001):
155 """Increase the y value in a Source object by frac. E.g
156 src.x = 1000 --> 1001 if frac=.001
157
158 Parameters
159 ----------
160 src : `lsst.afw.table.SourceRecord`
161 A Source object
162 frac : `float`
163 How much to change Y by
164
165 Returns
166 -------
167 out : `lsst.afw.table.SourceRecord`
168 A deep copy of src, with the value of Y changed
169 """
170
171 out = src.table.copyRecord(src)
172 out.set(out.table.getCentroidSlot().getMeasKey().getY(), out.getY()*(1+frac))
173 return out
174
175
176def quadraticDistortY(src, frac=1e-6):
177 """Distort image by terms with power <=2
178 i.e y, y^2, x, xy, x^2
179
180 Parameters
181 ----------
182 src : `lsst.afw.table.SourceRecord`
183 A Source object
184 frac : `float`
185 How much to change Y by
186
187 Returns
188 -------
189 out : `lsst.afw.table.SourceRecord`
190 A deep copy of src, with the value of Y changed
191 """
192
193 out = src.table.copyRecord(src)
194 x = out.getX()
195 y = out.getY()
196 val = y**2
197
198 out.set(out.table.getCentroidSlot().getMeasKey().getX(), x)
199 out.set(out.table.getCentroidSlot().getMeasKey().getY(), y + val*frac)
200 return out
201
202
203def cubicDistortY(src, frac=1e-9):
204 """Distort image by terms with power <=2
205 i.e y, y^2, x, xy, x^2
206
207 Parameters
208 ----------
209 src : `lsst.afw.table.SourceRecord`
210 A Source object
211 frac : `float`
212 How much to change Y by
213
214 Returns
215 -------
216 out : `lsst.afw.table.SourceRecord`
217 A deep copy of src, with the value of Y changed
218 """
219
220 out = src.table.copyRecord(src)
221 x = out.getX()
222 y = out.getY()
223 val = x**3
224
225 out.set(out.table.getCentroidSlot().getMeasKey().getX(), x)
226 out.set(out.table.getCentroidSlot().getMeasKey().getY(), y + val*frac)
227 return out
228
229
230def manyTermY(src, frac=1e-9):
231 """Distort image by multiple terms of Y, 'y**3 - 2*y**2 + 4*y - 9'.
232
233 Parameters
234 ----------
235 src : `lsst.afw.table.SourceRecord`
236 A Source object
237 frac : `float`
238 How much to change Y by
239
240 Returns
241 -------
242 out : `lsst.afw.table.SourceRecord`
243 A deep copy of src, with the value of Y changed
244 """
245 out = src.table.copyRecord(src)
246 x = out.getX()
247 y = out.getY()
248 val = y**3 - 2*y**2 + 4*y - 9
249
250 out.set(out.table.getCentroidSlot().getMeasKey().getX(), x)
251 out.set(out.table.getCentroidSlot().getMeasKey().getY(), y + val*frac)
252 return out
253
254
255def crossTerms1(src, frac=1e-11):
256 """Distort image Y by X, leaving X unchanged, 'x**3 - 2*x**2'.
257
258 Parameters
259 ----------
260 src : `lsst.afw.table.SourceRecord`
261 A Source object
262 frac : `float`
263 How much to change Y by
264
265 Returns
266 -------
267 out : `lsst.afw.table.SourceRecord`
268 A deep copy of src, with the value of Y changed
269 """
270 out = src.table.copyRecord(src)
271 x = out.getX()
272 y = out.getY()
273 val = x**3 - 2*x**2 # + 4*x - 9
274
275 out.set(out.table.getCentroidSlot().getMeasKey().getX(), x)
276 out.set(out.table.getCentroidSlot().getMeasKey().getY(), y + val*frac)
277 return out
278
279
280def crossTerms2(src, frac=1e-11):
281 """Distort image X by Y, leaving Y unchanged, 'y**3 - 2*y**2 + 4*y - 9'.
282
283 Parameters
284 ----------
285 src : `lsst.afw.table.SourceRecord`
286 A Source object
287 frac : `float`
288 How much to change X by
289
290 Returns
291 -------
292 out : `lsst.afw.table.SourceRecord`
293 A deep copy of src, with the value of X changed
294 """
295 out = src.table.copyRecord(src)
296 x = out.getX()
297 y = out.getY()
298 val = y**3 - 2*y**2 + 4*y - 9
299
300 out.set(out.table.getCentroidSlot().getMeasKey().getX(), x + val*frac)
301 out.set(out.table.getCentroidSlot().getMeasKey().getY(), y)
302 return out
303
304
305def crossTerms3(src, frac=1e-9):
306 """Distort image X and Y , 'dx=x**3 - 2*x**2 + 4*x - 9',
307 'dy=y**3 - 2*y**2 + 4*y - 9'.
308
309 Parameters
310 ----------
311 src : `lsst.afw.table.SourceRecord`
312 A Source object
313 frac : `float`
314 How much to change X and Y by
315
316 Returns
317 -------
318 out : `lsst.afw.table.SourceRecord`
319 A deep copy of src, with the value of X and Y changed
320 """
321 out = src.table.copyRecord(src)
322 x = out.getX()
323 y = out.getY()
324 valx = x**3 - 2*x**2 + 4*x - 9
325 valy = y**3 - 2*y**2 + 4*y - 9
326
327 out.set(out.table.getCentroidSlot().getMeasKey().getX(), x + valy*frac)
328 out.set(out.table.getCentroidSlot().getMeasKey().getY(), y + valx*frac)
329 return out
330
331
332def quadraticDistort(src, frac=1e-6):
333 """Distort image by terms with power <=2
334 i.e y, y^2, x, xy, x^2
335
336 Parameters
337 ----------
338 src : `lsst.afw.table.SourceRecord`
339 A Source object
340 frac : `float`
341 How much to change X
342
343 Returns
344 -------
345 out : `lsst.afw.table.SourceRecord`
346 A deep copy of src, with the value of X
347 """
348
349 out = src.table.copyRecord(src)
350 x = out.getX()
351 y = out.getY()
352 val = y + 2*y**2
353 val += 3*x + 4*x*y
354 val += x**2
355
356 out.set(out.table.getCentroidSlot().getMeasKey().getX(), x + val*frac)
357 out.set(out.table.getCentroidSlot().getMeasKey().getY(), y)
358 return out
359
360
361def T2DistortX(src, frac=1e-6):
362 """Distort image by a 2nd order Cheby polynomial
363
364 Parameters
365 ----------
366 src : `lsst.afw.table.SourceRecord`
367 A Source object
368 frac : `float`
369 How much to change X
370
371 Returns
372 -------
373 out : `lsst.afw.table.SourceRecord`
374 A deep copy of src, with the value of X
375 """
376
377 out = src.table.copyRecord(src)
378 x = src.getX()
379 val = 2*(x**2) - 1
380 out.set(out.table.getCentroidSlot().getMeasKey().getX(), x + frac*val)
381 return out
382
383
384def distortList(srcList, function):
385 """Create a copy of srcList, and apply function to distort the
386 values of x and y.
387
388 Parameters
389 ----------
390 srcList : `list` of `lsst.afw.table.SourceRecord`
391 Input list of source to distort.
392 function : `callable`
393 A function that does a deep copy of a single Source
394
395 Returns
396 -------
397 out : `lsst.afw.table.SourceCatalog`
398 Output catalog with distorted positions.
399 """
400
401 out = afwTable.SourceCatalog(srcList.table)
402 out.reserve(len(srcList))
403
404 for src in srcList:
405 out.append(function(src))
406
407 maxDiff = 0
408 for i in range(len(srcList)):
409 s = srcList[i]
410 o = out[i]
411
412 x1, y1 = s.getX(), s.getY()
413 x2, y2 = o.getX(), o.getY()
414
415 diff = math.hypot(x1-x2, y1-y2)
416 maxDiff = max(diff, maxDiff)
417
418 print("Max deviation is %e pixels" % (maxDiff))
419
420 return out
int max