drizzle 1.15.3__cp312-cp312-win32.whl → 2.0.0__cp312-cp312-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of drizzle might be problematic. Click here for more details.

@@ -1,834 +0,0 @@
1
- import math
2
- import os
3
- import pytest
4
-
5
- import numpy as np
6
- from astropy import wcs
7
- from astropy.io import fits
8
-
9
- from drizzle import drizzle, cdrizzle
10
-
11
- TEST_DIR = os.path.abspath(os.path.dirname(__file__))
12
- DATA_DIR = os.path.join(TEST_DIR, 'data')
13
- ok = False
14
-
15
-
16
- def bound_image(image):
17
- """
18
- Compute region where image is non-zero
19
- """
20
- coords = np.nonzero(image)
21
- ymin = coords[0].min()
22
- ymax = coords[0].max()
23
- xmin = coords[1].min()
24
- xmax = coords[1].max()
25
- return (ymin, ymax, xmin, xmax)
26
-
27
-
28
- def centroid(image, size, center):
29
- """
30
- Compute the centroid of a rectangular area
31
- """
32
- ylo = int(center[0] - size / 2)
33
- yhi = min(ylo + size, image.shape[0])
34
- xlo = int(center[1] - size / 2)
35
- xhi = min(xlo + size, image.shape[1])
36
-
37
- yx1 = np.mgrid[ylo:yhi, xlo:xhi, 1:2]
38
- center = (yx1[..., 0] * image[ylo:yhi, xlo:xhi]).sum(
39
- axis=(1, 2),
40
- dtype=np.float64,
41
- )
42
-
43
- if center[2] == 0.0:
44
- return None
45
-
46
- center[0] /= center[2]
47
- center[1] /= center[2]
48
- return center
49
-
50
-
51
- def centroid_close(list_of_centroids, size, point):
52
- """
53
- Find if any centroid is close to a point
54
- """
55
- for i in range(len(list_of_centroids) - 1, -1, -1):
56
- if (abs(list_of_centroids[i][0] - point[0]) < int(size / 2) and
57
- abs(list_of_centroids[i][1] - point[1]) < int(size / 2)):
58
- return 1
59
-
60
- return 0
61
-
62
-
63
- def centroid_compare(centroid):
64
- return centroid[1]
65
-
66
-
67
- def centroid_distances(image1, image2, amp, size):
68
- """
69
- Compute a list of centroids and the distances between them in two images
70
- """
71
- distances = []
72
- list_of_centroids = centroid_list(image2, amp, size)
73
- for center2 in list_of_centroids:
74
- center1 = centroid(image1, size, center2)
75
- if center1 is None:
76
- continue
77
-
78
- disty = center2[0] - center1[0]
79
- distx = center2[1] - center1[1]
80
- dist = math.sqrt(disty * disty + distx * distx)
81
- dflux = abs(center2[2] - center1[2])
82
- distances.append([dist, dflux, center1, center2])
83
-
84
- distances.sort(key=centroid_compare)
85
- return distances
86
-
87
-
88
- def centroid_list(image, amp, size):
89
- """
90
- Find the next centroid
91
- """
92
- list_of_centroids = []
93
- points = np.transpose(np.nonzero(image > amp))
94
- for point in points:
95
- if not centroid_close(list_of_centroids, size, point):
96
- center = centroid(image, size, point)
97
- list_of_centroids.append(center)
98
-
99
- return list_of_centroids
100
-
101
-
102
- def centroid_statistics(title, fname, image1, image2, amp, size):
103
- """
104
- write centroid statistics to compare differences btw two images
105
- """
106
- stats = ("minimum", "median", "maximum")
107
- images = (None, None, image1, image2)
108
- im_type = ("", "", "test", "reference")
109
-
110
- diff = []
111
- distances = centroid_distances(image1, image2, amp, size)
112
- indexes = (0, int(len(distances) / 2), len(distances) - 1)
113
- fd = open(fname, 'w')
114
- fd.write("*** %s ***\n" % title)
115
-
116
- if len(distances) == 0:
117
- diff = [0.0, 0.0, 0.0]
118
- fd.write("No matches!!\n")
119
-
120
- elif len(distances) == 1:
121
- diff = [distances[0][0], distances[0][0], distances[0][0]]
122
-
123
- fd.write("1 match\n")
124
- fd.write("distance = %f flux difference = %f\n" %
125
- (distances[0][0], distances[0][1]))
126
-
127
- for j in range(2, 4):
128
- ylo = int(distances[0][j][0]) - 1
129
- yhi = int(distances[0][j][0]) + 2
130
- xlo = int(distances[0][j][1]) - 1
131
- xhi = int(distances[0][j][1]) + 2
132
- subimage = images[j][ylo:yhi,xlo:xhi]
133
- fd.write("\n%s image centroid = (%f,%f) image flux = %f\n" %
134
- (im_type[j], distances[0][j][0], distances[0][j][1],
135
- distances[0][j][2]))
136
- fd.write(str(subimage) + "\n")
137
-
138
- else:
139
- fd.write("%d matches\n" % len(distances))
140
-
141
- for k in range(0,3):
142
- i = indexes[k]
143
- diff.append(distances[i][0])
144
- fd.write("\n%s distance = %f flux difference = %f\n" %
145
- (stats[k],distances[i][0], distances[i][1]))
146
-
147
- for j in range(2, 4):
148
- ylo = int(distances[i][j][0]) - 1
149
- yhi = int(distances[i][j][0]) + 2
150
- xlo = int(distances[i][j][1]) - 1
151
- xhi = int(distances[i][j][1]) + 2
152
- subimage = images[j][ylo:yhi,xlo:xhi]
153
- fd.write("\n%s %s image centroid = (%f,%f) image flux = %f\n" %
154
- (stats[k], im_type[j], distances[i][j][0],
155
- distances[i][j][1], distances[i][j][2]))
156
- fd.write(str(subimage) + "\n")
157
-
158
- fd.close()
159
- return tuple(diff)
160
-
161
-
162
- def make_point_image(input_image, point, value):
163
- """
164
- Create an image with a single point set
165
- """
166
- output_image = np.zeros(input_image.shape, dtype=input_image.dtype)
167
- output_image[point] = value
168
- return output_image
169
-
170
-
171
- def make_grid_image(input_image, spacing, value):
172
- """
173
- Create an image with points on a grid set
174
- """
175
- output_image = np.zeros(input_image.shape, dtype=input_image.dtype)
176
-
177
- shape = output_image.shape
178
- half_space = int(spacing / 2)
179
- for y in range(half_space, shape[0], spacing):
180
- for x in range(half_space, shape[1], spacing):
181
- output_image[y,x] = value
182
-
183
- return output_image
184
-
185
-
186
- def print_wcs(title, wcs):
187
- """
188
- Print the wcs header cards
189
- """
190
- print("=== %s ===" % title)
191
- print(wcs.to_header_string())
192
-
193
-
194
- def read_image(filename):
195
- """
196
- Read the image from a fits file
197
- """
198
- path = os.path.join(DATA_DIR, filename)
199
- hdu = fits.open(path)
200
-
201
- image = hdu[1].data
202
- hdu.close()
203
- return image
204
-
205
-
206
- def read_wcs(filename):
207
- """
208
- Read the wcs of a fits file
209
- """
210
- path = os.path.join(DATA_DIR, filename)
211
- hdu = fits.open(path)
212
- the_wcs = wcs.WCS(hdu[1].header)
213
- hdu.close()
214
- return the_wcs
215
-
216
-
217
- def test_square_with_point(tmpdir):
218
- """
219
- Test do_driz square kernel with point
220
- """
221
- output = str(tmpdir.join('output_square_point.fits'))
222
- output_difference = str(tmpdir.join('difference_square_point.txt'))
223
-
224
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
225
- output_template = os.path.join(DATA_DIR, 'reference_square_point.fits')
226
-
227
- insci = read_image(input_file)
228
- inwcs = read_wcs(input_file)
229
- insci = make_point_image(insci, (500, 200), 100.0)
230
- inwht = np.ones(insci.shape,dtype=insci.dtype)
231
- output_wcs = read_wcs(output_template)
232
-
233
- driz = drizzle.Drizzle(outwcs=output_wcs, wt_scl="")
234
- driz.add_image(insci, inwcs, inwht=inwht)
235
-
236
- if ok:
237
- driz.write(output_template)
238
- else:
239
- driz.write(output)
240
- template_data = read_image(output_template)
241
-
242
- min_diff, med_diff, max_diff = centroid_statistics("square with point",
243
- output_difference,
244
- driz.outsci,
245
- template_data, 20.0, 8)
246
-
247
- assert med_diff < 1.0e-6
248
- assert max_diff < 1.0e-5
249
-
250
-
251
- @pytest.mark.parametrize(
252
- 'kernel', ['square', 'point', 'turbo', 'gaussian', 'lanczos3'],
253
- )
254
- def test_zero_input_weight(kernel):
255
- """
256
- Test do_driz square kernel with grid
257
- """
258
- # initialize input:
259
- insci = np.ones((200, 400), dtype=np.float32)
260
- inwht = np.ones((200, 400), dtype=np.float32)
261
- inwht[:, 150:155] = 0
262
-
263
- # initialize output:
264
- outsci = np.zeros((210, 410), dtype=np.float32)
265
- outwht = np.zeros((210, 410), dtype=np.float32)
266
- outctx = np.zeros((210, 410), dtype=np.int32)
267
-
268
- # define coordinate mapping:
269
- pixmap = np.moveaxis(np.mgrid[1:201, 1:401][::-1], 0, -1)
270
-
271
- # resample:
272
- cdrizzle.tdriz(
273
- insci, inwht, pixmap,
274
- outsci, outwht, outctx,
275
- uniqid=1,
276
- xmin=0, xmax=400,
277
- ymin=0, ymax=200,
278
- pixfrac=1,
279
- kernel=kernel,
280
- in_units='cps',
281
- expscale=1,
282
- wtscale=1,
283
- fillstr='INDEF',
284
- )
285
-
286
- # check that no pixel with 0 weight has any counts:
287
- assert np.sum(np.abs(outsci[(outwht == 0)])) == 0.0
288
-
289
-
290
- def test_square_with_grid(tmpdir):
291
- """
292
- Test do_driz square kernel with grid
293
- """
294
- output = str(tmpdir.join('output_square_grid.fits'))
295
- output_difference = str(tmpdir.join('difference_square_grid.txt'))
296
-
297
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
298
- output_template = os.path.join(DATA_DIR, 'reference_square_grid.fits')
299
-
300
- insci = read_image(input_file)
301
- inwcs = read_wcs(input_file)
302
- insci = make_grid_image(insci, 64, 100.0)
303
-
304
- inwht = np.ones(insci.shape,dtype=insci.dtype)
305
- output_wcs = read_wcs(output_template)
306
-
307
- driz = drizzle.Drizzle(outwcs=output_wcs, wt_scl="")
308
- driz.add_image(insci, inwcs, inwht=inwht)
309
-
310
- if ok:
311
- driz.write(output_template)
312
- else:
313
- driz.write(output)
314
- template_data = read_image(output_template)
315
-
316
- min_diff, med_diff, max_diff = centroid_statistics("square with grid",
317
- output_difference,
318
- driz.outsci,
319
- template_data, 20.0, 8)
320
- assert med_diff < 1.0e-6
321
- assert max_diff < 1.0e-5
322
-
323
-
324
- def test_turbo_with_grid(tmpdir):
325
- """
326
- Test do_driz turbo kernel with grid
327
- """
328
- output = str(tmpdir.join('output_turbo_grid.fits'))
329
- output_difference = str(tmpdir.join('difference_turbo_grid.txt'))
330
-
331
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
332
- output_template = os.path.join(DATA_DIR, 'reference_turbo_grid.fits')
333
-
334
- insci = read_image(input_file)
335
- inwcs = read_wcs(input_file)
336
- insci = make_grid_image(insci, 64, 100.0)
337
- inwht = np.ones(insci.shape,dtype=insci.dtype)
338
- output_wcs = read_wcs(output_template)
339
-
340
- driz = drizzle.Drizzle(outwcs=output_wcs, wt_scl="", kernel='turbo')
341
- driz.add_image(insci, inwcs, inwht=inwht)
342
-
343
- if ok:
344
- driz.write(output_template)
345
- else:
346
- driz.write(output)
347
- template_data = read_image(output_template)
348
-
349
- min_diff, med_diff, max_diff = centroid_statistics("turbo with grid",
350
- output_difference,
351
- driz.outsci,
352
- template_data, 20.0, 8)
353
-
354
- assert med_diff < 1.0e-6
355
- assert max_diff < 1.0e-5
356
-
357
-
358
- def test_gaussian_with_grid(tmpdir):
359
- """
360
- Test do_driz gaussian kernel with grid
361
- """
362
- output = str(tmpdir.join('output_gaussian_grid.fits'))
363
- output_difference = str(tmpdir.join('difference_gaussian_grid.txt'))
364
-
365
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
366
- output_template = os.path.join(DATA_DIR, 'reference_gaussian_grid.fits')
367
-
368
- insci = read_image(input_file)
369
- inwcs = read_wcs(input_file)
370
- insci = make_grid_image(insci, 64, 100.0)
371
- inwht = np.ones(insci.shape,dtype=insci.dtype)
372
- output_wcs = read_wcs(output_template)
373
-
374
- driz = drizzle.Drizzle(outwcs=output_wcs, wt_scl="", kernel='gaussian')
375
- driz.add_image(insci, inwcs, inwht=inwht)
376
-
377
- if ok:
378
- driz.write(output_template)
379
- else:
380
- driz.write(output)
381
- template_data = read_image(output_template)
382
-
383
- min_diff, med_diff, max_diff = centroid_statistics("gaussian with grid",
384
- output_difference,
385
- driz.outsci,
386
- template_data, 20.0, 8)
387
-
388
- assert med_diff < 1.0e-6
389
- assert max_diff < 2.0e-5
390
-
391
-
392
- def test_lanczos_with_grid(tmpdir):
393
- """
394
- Test do_driz lanczos kernel with grid
395
- """
396
- output = str(tmpdir.join('output_lanczos_grid.fits'))
397
- output_difference = str(tmpdir.join('difference_lanczos_grid.txt'))
398
-
399
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
400
- output_template = os.path.join(DATA_DIR, 'reference_lanczos_grid.fits')
401
-
402
- insci = read_image(input_file)
403
- inwcs = read_wcs(input_file)
404
- insci = make_grid_image(insci, 64, 100.0)
405
- inwht = np.ones(insci.shape,dtype=insci.dtype)
406
- output_wcs = read_wcs(output_template)
407
-
408
- driz = drizzle.Drizzle(outwcs=output_wcs, wt_scl="", kernel='lanczos3')
409
- driz.add_image(insci, inwcs, inwht=inwht)
410
-
411
- if ok:
412
- driz.write(output_template)
413
- else:
414
- driz.write(output)
415
- template_data = read_image(output_template)
416
-
417
- min_diff, med_diff, max_diff = centroid_statistics("lanczos with grid",
418
- output_difference,
419
- driz.outsci,
420
- template_data, 20.0, 8)
421
- assert med_diff < 1.0e-6
422
- assert max_diff < 1.0e-5
423
-
424
-
425
- def test_tophat_with_grid(tmpdir):
426
- """
427
- Test do_driz tophat kernel with grid
428
- """
429
- output = str(tmpdir.join('output_tophat_grid.fits'))
430
- output_difference = str(tmpdir.join('difference_tophat_grid.txt'))
431
-
432
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
433
- output_template = os.path.join(DATA_DIR, 'reference_tophat_grid.fits')
434
-
435
- insci = read_image(input_file)
436
- inwcs = read_wcs(input_file)
437
- insci = make_grid_image(insci, 64, 100.0)
438
- inwht = np.ones(insci.shape,dtype=insci.dtype)
439
- output_wcs = read_wcs(output_template)
440
-
441
- driz = drizzle.Drizzle(outwcs=output_wcs, wt_scl="", kernel='tophat')
442
- driz.add_image(insci, inwcs, inwht=inwht)
443
-
444
- if ok:
445
- driz.write(output_template)
446
- else:
447
- driz.write(output)
448
- template_data = read_image(output_template)
449
-
450
- min_diff, med_diff, max_diff = centroid_statistics("tophat with grid",
451
- output_difference,
452
- driz.outsci,
453
- template_data, 20.0, 8)
454
- assert med_diff < 1.0e-6
455
- assert max_diff < 1.0e-5
456
-
457
-
458
- def test_point_with_grid(tmpdir):
459
- """
460
- Test do_driz point kernel with grid
461
- """
462
- output = str(tmpdir.join('output_point_grid.fits'))
463
- output_difference = str(tmpdir.join('difference_point_grid.txt'))
464
-
465
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
466
- output_template = os.path.join(DATA_DIR, 'reference_point_grid.fits')
467
-
468
- insci = read_image(input_file)
469
- inwcs = read_wcs(input_file)
470
- insci = make_grid_image(insci, 64, 100.0)
471
- inwht = np.ones(insci.shape,dtype=insci.dtype)
472
- output_wcs = read_wcs(output_template)
473
-
474
- driz = drizzle.Drizzle(outwcs=output_wcs, wt_scl="", kernel='point')
475
- driz.add_image(insci, inwcs, inwht=inwht)
476
-
477
- if ok:
478
- driz.write(output_template)
479
- else:
480
- driz.write(output)
481
- template_data = read_image(output_template)
482
-
483
- min_diff, med_diff, max_diff = centroid_statistics("point with grid",
484
- output_difference,
485
- driz.outsci,
486
- template_data, 20.0, 8)
487
- assert med_diff < 1.0e-6
488
- assert max_diff < 1.0e-5
489
-
490
-
491
- def test_blot_with_point(tmpdir):
492
- """
493
- Test do_blot with point image
494
- """
495
- output = str(tmpdir.join('output_blot_point.fits'))
496
- output_difference = str(tmpdir.join('difference_blot_point.txt'))
497
-
498
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
499
- output_template = os.path.join(DATA_DIR, 'reference_blot_point.fits')
500
-
501
- outsci = read_image(input_file)
502
- outwcs = read_wcs(input_file)
503
- outsci = make_point_image(outsci, (500, 200), 40.0)
504
- inwcs = read_wcs(output_template)
505
-
506
- driz = drizzle.Drizzle(outwcs=outwcs)
507
- driz.outsci = outsci
508
-
509
- driz.blot_image(inwcs)
510
-
511
- if ok:
512
- driz.write(output_template)
513
- else:
514
- driz.write(output)
515
- template_data = read_image(output_template)
516
-
517
- min_diff, med_diff, max_diff = centroid_statistics("blot with point",
518
- output_difference,
519
- driz.outsci,
520
- template_data, 20.0, 16)
521
- assert med_diff < 1.0e-6
522
- assert max_diff < 1.0e-5
523
-
524
-
525
- def test_blot_with_default(tmpdir):
526
- """
527
- Test do_blot with default grid image
528
- """
529
- output = str(tmpdir.join('output_blot_default.fits'))
530
- output_difference = str(tmpdir.join('difference_blot_default.txt'))
531
-
532
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
533
- output_template = os.path.join(DATA_DIR, 'reference_blot_default.fits')
534
-
535
- outsci = read_image(input_file)
536
- outsci = make_grid_image(outsci, 64, 100.0)
537
- outwcs = read_wcs(input_file)
538
- inwcs = read_wcs(output_template)
539
-
540
- driz = drizzle.Drizzle(outwcs=outwcs)
541
- driz.outsci = outsci
542
-
543
- driz.blot_image(inwcs)
544
-
545
- if ok:
546
- driz.write(output_template)
547
- else:
548
- driz.write(output)
549
- template_data = read_image(output_template)
550
-
551
- min_diff, med_diff, max_diff = centroid_statistics("blot with defaults",
552
- output_difference,
553
- driz.outsci,
554
- template_data, 20.0, 16)
555
-
556
- assert med_diff < 1.0e-6
557
- assert max_diff < 1.0e-5
558
-
559
-
560
- def test_blot_with_lan3(tmpdir):
561
- """
562
- Test do_blot with lan3 grid image
563
- """
564
- output = str(tmpdir.join('output_blot_lan3.fits'))
565
- output_difference = str(tmpdir.join('difference_blot_lan3.txt'))
566
-
567
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
568
- output_template = os.path.join(DATA_DIR, 'reference_blot_lan3.fits')
569
-
570
- outsci = read_image(input_file)
571
- outsci = make_grid_image(outsci, 64, 100.0)
572
- outwcs = read_wcs(input_file)
573
- inwcs = read_wcs(output_template)
574
-
575
- driz = drizzle.Drizzle(outwcs=outwcs)
576
- driz.outsci = outsci
577
-
578
- driz.blot_image(inwcs, interp="lan3")
579
-
580
- if ok:
581
- driz.write(output_template)
582
- else:
583
- driz.write(output)
584
- template_data = read_image(output_template)
585
-
586
- min_diff, med_diff, max_diff = centroid_statistics("blot with lan3",
587
- output_difference,
588
- driz.outsci,
589
- template_data, 20.0, 16)
590
- assert med_diff < 1.0e-6
591
- assert max_diff < 1.0e-5
592
-
593
-
594
- def test_blot_with_lan5(tmpdir):
595
- """
596
- Test do_blot with lan5 grid image
597
- """
598
- output = str(tmpdir.join('output_blot_lan5.fits'))
599
- output_difference = str(tmpdir.join('difference_blot_lan5.txt'))
600
-
601
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
602
- output_template = os.path.join(DATA_DIR, 'reference_blot_lan5.fits')
603
-
604
- outsci = read_image(input_file)
605
- outsci = make_grid_image(outsci, 64, 100.0)
606
- outwcs = read_wcs(input_file)
607
- inwcs = read_wcs(output_template)
608
-
609
- driz = drizzle.Drizzle(outwcs=outwcs)
610
- driz.outsci = outsci
611
-
612
- driz.blot_image(inwcs, interp="lan5")
613
-
614
- if ok:
615
- driz.write(output_template)
616
- else:
617
- driz.write(output)
618
- template_data = read_image(output_template)
619
-
620
- min_diff, med_diff, max_diff = centroid_statistics("blot with lan5",
621
- output_difference,
622
- driz.outsci,
623
- template_data, 20.0, 16)
624
- assert med_diff < 1.0e-6
625
- assert max_diff < 1.0e-5
626
-
627
-
628
- def test_context_planes():
629
- """Reproduce error seen in issue #50"""
630
- shape = [10, 10]
631
- outwcs = wcs.WCS()
632
- outwcs.pixel_shape = shape
633
- driz = drizzle.Drizzle(outwcs=outwcs)
634
-
635
- image = np.ones(shape)
636
- inwcs = wcs.WCS()
637
- inwcs.pixel_shape = shape
638
-
639
- for i in range(32):
640
- driz.add_image(image, inwcs)
641
- assert driz.outcon.shape == (1, 10, 10)
642
-
643
- driz.add_image(image, inwcs)
644
- assert driz.outcon.shape == (2, 10, 10)
645
-
646
-
647
- @pytest.mark.parametrize(
648
- 'kernel',
649
- [
650
- 'square',
651
- 'point',
652
- 'turbo',
653
- pytest.param(
654
- 'lanczos2',
655
- marks=pytest.mark.xfail(reason='Not a flux-conserving kernel'),
656
- ),
657
- pytest.param(
658
- 'lanczos3',
659
- marks=pytest.mark.xfail(reason='Not a flux-conserving kernel'),
660
- ),
661
- pytest.param(
662
- 'gaussian',
663
- marks=pytest.mark.xfail(reason='Not a flux-conserving kernel'),
664
- ),
665
- ],
666
- )
667
- def test_flux_conservation_nondistorted(kernel):
668
- n = 200
669
- in_shape = (n, n)
670
-
671
- # input coordinate grid:
672
- y, x = np.indices(in_shape, dtype=np.float64)
673
-
674
- # simulate a gaussian "star":
675
- fwhm = 2.9
676
- x0 = 50.0
677
- y0 = 68.0
678
- sig = fwhm / (2.0 * np.sqrt(2.0 * np.log(2.0 * fwhm)))
679
- sig2 = sig * sig
680
- star = np.exp(-0.5 / sig2 * ((x.astype(np.float32) - x0)**2 + (y.astype(np.float32) - y0)**2))
681
- in_sci = (star / np.sum(star)).astype(np.float32) # normalize to 1
682
- in_wht = np.ones(in_shape, dtype=np.float32)
683
-
684
- # linear shift:
685
- xp = x + 0.5
686
- yp = y + 0.2
687
-
688
- pixmap = np.dstack([xp, yp])
689
-
690
- out_shape = (int(yp.max()) + 1, int(xp.max()) + 1)
691
- # make sure distorion is not moving flux out of the image towards negative
692
- # coordinates (just because of the simple way of how we account for output
693
- # image size)
694
- assert np.min(xp) > -0.5 and np.min(yp) > -0.5
695
-
696
- out_sci = np.zeros(out_shape, dtype=np.float32)
697
- out_ctx = np.zeros(out_shape, dtype=np.int32)
698
- out_wht = np.zeros(out_shape, dtype=np.float32)
699
-
700
- cdrizzle.tdriz(
701
- in_sci,
702
- in_wht,
703
- pixmap,
704
- out_sci,
705
- out_wht,
706
- out_ctx,
707
- pixfrac=1.0,
708
- scale=1.0,
709
- kernel=kernel,
710
- in_units="cps",
711
- expscale=1.0,
712
- wtscale=1.0,
713
- )
714
-
715
- assert np.allclose(
716
- np.sum(out_sci * out_wht),
717
- np.sum(in_sci),
718
- atol=0.0,
719
- rtol=0.0001,
720
- )
721
-
722
- @pytest.mark.parametrize(
723
- 'kernel',
724
- [
725
- 'square',
726
- 'point',
727
- 'turbo',
728
- pytest.param(
729
- 'lanczos2',
730
- marks=pytest.mark.xfail(reason='Not a flux-conserving kernel'),
731
- ),
732
- pytest.param(
733
- 'lanczos3',
734
- marks=pytest.mark.xfail(reason='Not a flux-conserving kernel'),
735
- ),
736
- pytest.param(
737
- 'gaussian',
738
- marks=pytest.mark.xfail(reason='Not a flux-conserving kernel'),
739
- ),
740
- ],
741
- )
742
- def test_flux_conservation_distorted(kernel):
743
- n = 200
744
- in_shape = (n, n)
745
-
746
- # input coordinate grid:
747
- y, x = np.indices(in_shape, dtype=np.float64)
748
-
749
- # simulate a gaussian "star":
750
- fwhm = 2.9
751
- x0 = 50.0
752
- y0 = 68.0
753
- sig = fwhm / (2.0 * np.sqrt(2.0 * np.log(2.0 * fwhm)))
754
- sig2 = sig * sig
755
- star = np.exp(-0.5 / sig2 * ((x.astype(np.float32) - x0)**2 + (y.astype(np.float32) - y0)**2))
756
- in_sci = (star / np.sum(star)).astype(np.float32) # normalize to 1
757
- in_wht = np.ones(in_shape, dtype=np.float32)
758
-
759
- # linear shift:
760
- xp = x + 0.5
761
- yp = y + 0.2
762
- # add distortion:
763
- xp += 1e-4 * x**2 + 1e-5 * x * y
764
- yp += 1e-3 * y**2 - 2e-5 * x * y
765
-
766
- pixmap = np.dstack([xp, yp])
767
-
768
- out_shape = (int(yp.max()) + 1, int(xp.max()) + 1)
769
- # make sure distorion is not moving (pixels with) flux out of the image
770
- # towards negative coordinates (just because of the simple way of how we
771
- # account for output image size):
772
- assert np.min(xp) > -0.5 and np.min(yp) > -0.5
773
-
774
- out_sci = np.zeros(out_shape, dtype=np.float32)
775
- out_ctx = np.zeros(out_shape, dtype=np.int32)
776
- out_wht = np.zeros(out_shape, dtype=np.float32)
777
-
778
- cdrizzle.tdriz(
779
- in_sci,
780
- in_wht,
781
- pixmap,
782
- out_sci,
783
- out_wht,
784
- out_ctx,
785
- pixfrac=1.0,
786
- scale=1.0,
787
- kernel=kernel,
788
- in_units="cps",
789
- expscale=1.0,
790
- wtscale=1.0,
791
- )
792
-
793
- assert np.allclose(
794
- np.sum(out_sci * out_wht),
795
- np.sum(in_sci),
796
- atol=0.0,
797
- rtol=0.0001,
798
- )
799
-
800
-
801
- def test_no_context_array():
802
- """
803
- Test that providing None for "outctx" is supported.
804
- """
805
- # initialize input:
806
- insci = np.ones((200, 400), dtype=np.float32)
807
- inwht = np.ones((200, 400), dtype=np.float32)
808
- inwht[:, 150:155] = 0
809
-
810
- # initialize output:
811
- outsci = np.zeros((210, 410), dtype=np.float32)
812
- outwht = np.zeros((210, 410), dtype=np.float32)
813
- outctx = None
814
-
815
- # define coordinate mapping:
816
- pixmap = np.moveaxis(np.mgrid[1:201, 1:401][::-1], 0, -1)
817
-
818
- # resample:
819
- cdrizzle.tdriz(
820
- insci, inwht, pixmap,
821
- outsci, outwht, outctx,
822
- uniqid=1,
823
- xmin=0, xmax=400,
824
- ymin=0, ymax=200,
825
- pixfrac=1,
826
- kernel='square',
827
- in_units='cps',
828
- expscale=1,
829
- wtscale=1,
830
- fillstr='INDEF',
831
- )
832
-
833
- # check that no pixel with 0 weight has any counts:
834
- assert np.sum(np.abs(outsci[(outwht == 0)])) == 0.0