drizzle 2.0.0__cp311-cp311-win_amd64.whl → 2.1.0__cp311-cp311-win_amd64.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.

@@ -5,9 +5,11 @@ import numpy as np
5
5
  import pytest
6
6
 
7
7
  from astropy import wcs
8
- from astropy.io import fits
8
+ from astropy.convolution import Gaussian2DKernel
9
9
  from drizzle import cdrizzle, resample, utils
10
10
 
11
+ from .helpers import wcs_from_file
12
+
11
13
  TEST_DIR = os.path.abspath(os.path.dirname(__file__))
12
14
  DATA_DIR = os.path.join(TEST_DIR, 'data')
13
15
 
@@ -166,20 +168,20 @@ def centroid_statistics(title, fname, image1, image2, amp, size):
166
168
  return tuple(diff)
167
169
 
168
170
 
169
- def make_point_image(input_image, point, value):
171
+ def make_point_image(shape, point, value):
170
172
  """
171
173
  Create an image with a single point set
172
174
  """
173
- output_image = np.zeros(input_image.shape, dtype=input_image.dtype)
175
+ output_image = np.zeros(shape, dtype=np.float32)
174
176
  output_image[point] = value
175
177
  return output_image
176
178
 
177
179
 
178
- def make_grid_image(input_image, spacing, value):
180
+ def make_grid_image(shape, spacing, value):
179
181
  """
180
182
  Create an image with points on a grid set
181
183
  """
182
- output_image = np.zeros(input_image.shape, dtype=input_image.dtype)
184
+ output_image = np.zeros(shape, dtype=np.float32)
183
185
 
184
186
  shape = output_image.shape
185
187
  half_space = int(spacing / 2)
@@ -190,27 +192,55 @@ def make_grid_image(input_image, spacing, value):
190
192
  return output_image
191
193
 
192
194
 
193
- def read_image(filename):
194
- """
195
- Read the image from a fits file
196
- """
197
- path = os.path.join(DATA_DIR, filename)
198
- hdu = fits.open(path)
195
+ @pytest.fixture(scope="module")
196
+ def nrcb5_stars():
197
+ full_file_name = os.path.join(DATA_DIR, "nrcb5_sip_wcs.hdr")
198
+ path = os.path.join(DATA_DIR, full_file_name)
199
199
 
200
- image = hdu[1].data
201
- hdu.close()
202
- return image
200
+ wcs, data = wcs_from_file(path, return_data=True)
201
+ dq = np.zeros(data.shape, dtype=np.int32)
202
+ wht = np.zeros(data.shape, dtype=np.float32)
203
+ np.random.seed(0)
203
204
 
205
+ patch_size = 21
206
+ p2 = patch_size // 2
207
+ # add border so that resampled partial pixels can be isolated
208
+ # in the segmentation:
209
+ border = 4
210
+ pwb = patch_size + border
204
211
 
205
- def read_wcs(filename):
206
- """
207
- Read the wcs of a fits file
208
- """
209
- path = os.path.join(DATA_DIR, filename)
210
- hdu = fits.open(path)
211
- the_wcs = wcs.WCS(hdu[1].header)
212
- hdu.close()
213
- return the_wcs
212
+ fwhm2sigma = 2.0 * math.sqrt(2.0 * math.log(2.0))
213
+
214
+ ny, nx = data.shape
215
+
216
+ stars = []
217
+
218
+ for yc in range(border + p2, ny - pwb, pwb):
219
+ for xc in range(border + p2, nx - pwb, pwb):
220
+ sl = np.s_[yc - p2:yc + p2 + 1, xc - p2:xc + p2 + 1]
221
+ flux = 1.0 + 99.0 * np.random.random()
222
+ if np.random.random() > 0.7:
223
+ # uniform image
224
+ psf = np.full((patch_size, patch_size), flux)
225
+ else:
226
+ # "star":
227
+ fwhm = 1.5 + 1.5 * np.random.random()
228
+ sigma = fwhm / fwhm2sigma
229
+
230
+ psf = flux * Gaussian2DKernel(
231
+ sigma,
232
+ x_size=patch_size,
233
+ y_size=patch_size
234
+ ).array
235
+ weight = 0.6 + 0.4 * np.random.random((patch_size, patch_size))
236
+ wflux = (psf * weight).sum()
237
+
238
+ data[sl] = psf
239
+ wht[sl] = weight
240
+ dq[sl] = 0
241
+ stars.append((xc, yc, wflux, sl))
242
+
243
+ return data, wht, dq, stars, wcs
214
244
 
215
245
 
216
246
  def test_drizzle_defaults():
@@ -256,52 +286,86 @@ def test_drizzle_defaults():
256
286
  assert driz.out_img[1, 2] == 1
257
287
  assert (driz.out_img[2, 1] - 2.0) < 1.0e-14
258
288
 
259
-
260
- def test_square_with_point(tmpdir):
289
+ @pytest.mark.parametrize(
290
+ 'kernel,test_image_type,max_diff_atol',
291
+ [
292
+ ("square", "point", 1.0e-5),
293
+ ("square", "grid", 1.0e-5),
294
+ ('point', "grid", 1.0e-5),
295
+ ("turbo", "grid", 1.0e-5),
296
+ ('lanczos3', "grid", 1.0e-5),
297
+ ("gaussian", "grid", 2.0e-5),
298
+ ],
299
+ )
300
+ def test_resample_kernel(tmpdir, kernel, test_image_type, max_diff_atol):
261
301
  """
262
302
  Test do_driz square kernel with point
263
303
  """
264
- output_difference = str(tmpdir.join('difference_square_point.txt'))
265
-
266
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
267
- output_template = os.path.join(DATA_DIR, 'reference_square_point.fits')
304
+ output_difference = str(
305
+ tmpdir.join(f"difference_{kernel}_{test_image_type}.txt")
306
+ )
268
307
 
269
- insci = read_image(input_file)
270
- inwcs = read_wcs(input_file)
271
- insci = make_point_image(insci, (500, 200), 100.0)
272
- inwht = np.ones(insci.shape, dtype=insci.dtype)
273
- output_wcs = read_wcs(output_template)
308
+ inwcs = wcs_from_file("j8bt06nyq_flt.fits", ext=1)
309
+ if test_image_type == "point":
310
+ insci = make_point_image(inwcs.array_shape, (500, 200), 100.0)
311
+ else:
312
+ insci = make_grid_image(inwcs.array_shape, 64, 100.0)
313
+ inwht = np.ones_like(insci)
314
+ output_wcs, template_data = wcs_from_file(
315
+ f"reference_{kernel}_{test_image_type}.fits",
316
+ ext=1,
317
+ return_data=True
318
+ )
274
319
 
275
320
  pixmap = utils.calc_pixmap(
276
321
  inwcs,
277
322
  output_wcs,
278
323
  )
279
324
 
280
- # ignore previous pscale and compute it the old way (only to make
281
- # tests work with old truth files and thus to show that new API gives
282
- # same results when equal definitions of the pixel scale is used):
283
- pscale = np.sqrt(
284
- np.sum(output_wcs.wcs.pc**2, axis=0)[0] /
285
- np.sum(inwcs.wcs.cd**2, axis=0)[0]
286
- )
325
+ if kernel == "point":
326
+ pscale_ratio = 1.0
327
+ else:
328
+ pscale_ratio = utils.estimate_pixel_scale_ratio(
329
+ inwcs,
330
+ output_wcs,
331
+ refpix_from=inwcs.wcs.crpix,
332
+ refpix_to=output_wcs.wcs.crpix,
333
+ )
334
+
335
+ # ignore previous pscale and compute it the old way (only to make
336
+ # tests work with old truth files and thus to show that new API gives
337
+ # same results when equal definitions of the pixel scale is used):
338
+ pscale_ratio = np.sqrt(
339
+ np.sum(output_wcs.wcs.pc**2, axis=0)[0] /
340
+ np.sum(inwcs.wcs.cd**2, axis=0)[0]
341
+ )
287
342
 
288
343
  driz = resample.Drizzle(
289
- kernel='square',
344
+ kernel=kernel,
290
345
  out_shape=output_wcs.array_shape,
291
346
  fillval=0.0,
292
347
  )
293
- driz.add_image(
294
- insci,
295
- exptime=1.0,
296
- pixmap=pixmap,
297
- weight_map=inwht,
298
- scale=pscale,
299
- )
300
348
 
301
- template_data = read_image(output_template)
349
+ if kernel in ["square", "turbo", "point"]:
350
+ driz.add_image(
351
+ insci,
352
+ exptime=1.0,
353
+ pixmap=pixmap,
354
+ weight_map=inwht,
355
+ scale=pscale_ratio,
356
+ )
357
+ else:
358
+ with pytest.warns(Warning):
359
+ driz.add_image(
360
+ insci,
361
+ exptime=1.0,
362
+ pixmap=pixmap,
363
+ weight_map=inwht,
364
+ scale=pscale_ratio,
365
+ )
302
366
 
303
367
  _, med_diff, max_diff = centroid_statistics(
304
- "square with point",
368
+ f"{kernel} with {test_image_type}",
305
369
  output_difference,
306
370
  driz.out_img,
307
371
  template_data,
@@ -310,7 +374,66 @@ def test_square_with_point(tmpdir):
310
374
  )
311
375
 
312
376
  assert med_diff < 1.0e-6
313
- assert max_diff < 1.0e-5
377
+ assert max_diff < max_diff_atol
378
+
379
+
380
+ @pytest.mark.parametrize(
381
+ 'kernel,max_diff_atol',
382
+ [
383
+ ("square", 1.0e-5),
384
+ ("turbo", 1.0e-5),
385
+ ],
386
+ )
387
+ def test_resample_kernel_image(tmpdir, kernel, max_diff_atol):
388
+ """
389
+ Test do_driz square kernel with point
390
+ """
391
+ inwcs, insci = wcs_from_file(
392
+ "j8bt06nyq_flt.fits",
393
+ ext=1,
394
+ return_data=True
395
+ )
396
+ inwht = np.ones_like(insci)
397
+
398
+ outwcs, ref_sci, ref_ctx, ref_wht = wcs_from_file(
399
+ f"reference_{kernel}_image.fits",
400
+ ext=1,
401
+ return_data=["SCI", "CTX", "WHT"]
402
+ )
403
+ ref_ctx = np.array(ref_ctx, dtype=np.int32)
404
+
405
+ pixmap = utils.calc_pixmap(
406
+ inwcs,
407
+ outwcs,
408
+ )
409
+
410
+ pscale_ratio = np.sqrt(
411
+ np.sum(outwcs.wcs.cd**2, axis=0)[0] /
412
+ np.sum(inwcs.wcs.cd**2, axis=0)[0]
413
+ )
414
+
415
+ driz = resample.Drizzle(
416
+ kernel=kernel,
417
+ out_shape=ref_sci.shape,
418
+ fillval=0.0,
419
+ )
420
+
421
+ driz.add_image(
422
+ insci,
423
+ exptime=1.0,
424
+ pixmap=pixmap,
425
+ weight_map=inwht,
426
+ scale=pscale_ratio,
427
+ )
428
+ outctx = driz.out_ctx[0]
429
+
430
+ # in order to avoid small differences in the staircase in the outline
431
+ # of the input image in the output grid, select a subset:
432
+ sl = np.s_[125: -125, 5: -5]
433
+
434
+ assert np.allclose(driz.out_img[sl], ref_sci[sl], atol=0, rtol=1.0e-6)
435
+ assert np.allclose(driz.out_wht[sl], ref_wht[sl], atol=0, rtol=1.0e-6)
436
+ assert np.all(outctx[sl] == ref_ctx[sl])
314
437
 
315
438
 
316
439
  @pytest.mark.parametrize(
@@ -389,472 +512,64 @@ def test_zero_input_weight(kernel, fc):
389
512
  assert np.sum(np.abs(outsci[(outwht == 0)])) == 0.0
390
513
 
391
514
 
392
- def test_square_with_grid(tmpdir):
393
- """
394
- Test do_driz square kernel with grid
395
- """
396
- output_difference = str(tmpdir.join('difference_square_grid.txt'))
397
-
398
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
399
- output_template = os.path.join(DATA_DIR, 'reference_square_grid.fits')
400
-
401
- insci = read_image(input_file)
402
- inwcs = read_wcs(input_file)
403
- insci = make_grid_image(insci, 64, 100.0)
404
-
405
- inwht = np.ones(insci.shape, dtype=insci.dtype)
406
- output_wcs = read_wcs(output_template)
407
-
408
- pixmap = utils.calc_pixmap(
409
- inwcs,
410
- output_wcs,
411
- )
412
- pscale = utils.estimate_pixel_scale_ratio(
413
- inwcs,
414
- output_wcs,
415
- refpix_from=inwcs.wcs.crpix,
416
- refpix_to=output_wcs.wcs.crpix,
417
- )
418
- # ignore previous pscale and compute it the old way (only to make
419
- # tests work with old truth files and thus to show that new API gives
420
- # same results when equal definitions of the pixel scale is used):
421
- pscale = np.sqrt(
422
- np.sum(output_wcs.wcs.pc**2, axis=0)[0] /
423
- np.sum(inwcs.wcs.cd**2, axis=0)[0]
424
- )
425
-
426
- driz = resample.Drizzle(
427
- kernel='square',
428
- out_shape=output_wcs.array_shape,
429
- fillval=0.0,
430
- )
431
- driz.add_image(
432
- insci,
433
- exptime=1.0,
434
- pixmap=pixmap,
435
- weight_map=inwht,
436
- scale=pscale,
437
- )
438
- template_data = read_image(output_template)
439
-
440
- _, med_diff, max_diff = centroid_statistics(
441
- "square with grid",
442
- output_difference,
443
- driz.out_img,
444
- template_data,
445
- 20.0,
446
- 8,
447
- )
448
- assert med_diff < 1.0e-6
449
- assert max_diff < 1.0e-5
450
-
451
-
452
- def test_turbo_with_grid(tmpdir):
453
- """
454
- Test do_driz turbo kernel with grid
455
- """
456
- output_difference = str(tmpdir.join('difference_turbo_grid.txt'))
457
-
458
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
459
- output_template = os.path.join(DATA_DIR, 'reference_turbo_grid.fits')
460
-
461
- insci = read_image(input_file)
462
- inwcs = read_wcs(input_file)
463
- insci = make_grid_image(insci, 64, 100.0)
464
- inwht = np.ones(insci.shape, dtype=insci.dtype)
465
- output_wcs = read_wcs(output_template)
466
-
467
- pixmap = utils.calc_pixmap(
468
- inwcs,
469
- output_wcs,
470
- )
471
- pscale = utils.estimate_pixel_scale_ratio(
472
- inwcs,
473
- output_wcs,
474
- refpix_from=inwcs.wcs.crpix,
475
- refpix_to=output_wcs.wcs.crpix,
476
- )
477
-
478
- # ignore previous pscale and compute it the old way (only to make
479
- # tests work with old truth files and thus to show that new API gives
480
- # same results when equal definitions of the pixel scale is used):
481
- pscale = np.sqrt(
482
- np.sum(output_wcs.wcs.pc**2, axis=0)[0] /
483
- np.sum(inwcs.wcs.cd**2, axis=0)[0]
484
- )
485
-
486
- driz = resample.Drizzle(
487
- kernel='turbo',
488
- out_shape=output_wcs.array_shape,
489
- fillval=0.0,
490
- )
491
- driz.add_image(
492
- insci,
493
- exptime=1.0,
494
- pixmap=pixmap,
495
- weight_map=inwht,
496
- scale=pscale,
497
- )
498
-
499
- template_data = read_image(output_template)
500
-
501
- _, med_diff, max_diff = centroid_statistics(
502
- "turbo with grid",
503
- output_difference,
504
- driz.out_img,
505
- template_data,
506
- 20.0,
507
- 8,
508
- )
509
-
510
- assert med_diff < 1.0e-6
511
- assert max_diff < 1.0e-5
512
-
513
-
514
- def test_gaussian_with_grid(tmpdir):
515
- """
516
- Test do_driz gaussian kernel with grid
517
- """
518
- output_difference = str(tmpdir.join('difference_gaussian_grid.txt'))
519
-
520
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
521
- output_template = os.path.join(DATA_DIR, 'reference_gaussian_grid.fits')
522
-
523
- insci = read_image(input_file)
524
- inwcs = read_wcs(input_file)
525
- insci = make_grid_image(insci, 64, 100.0)
526
- inwht = np.ones(insci.shape, dtype=insci.dtype)
527
- output_wcs = read_wcs(output_template)
528
-
529
- pixmap = utils.calc_pixmap(
530
- inwcs,
531
- output_wcs,
532
- )
533
- pscale = utils.estimate_pixel_scale_ratio(
534
- inwcs,
535
- output_wcs,
536
- refpix_from=inwcs.wcs.crpix,
537
- refpix_to=output_wcs.wcs.crpix,
538
- )
539
-
540
- # ignore previous pscale and compute it the old way (only to make
541
- # tests work with old truth files and thus to show that new API gives
542
- # same results when equal definitions of the pixel scale is used):
543
- pscale = np.sqrt(
544
- np.sum(output_wcs.wcs.pc**2, axis=0)[0] /
545
- np.sum(inwcs.wcs.cd**2, axis=0)[0]
546
- )
547
-
548
- driz = resample.Drizzle(
549
- kernel='gaussian',
550
- out_shape=output_wcs.array_shape,
551
- fillval=0.0,
552
- )
553
- with pytest.warns(Warning):
554
- driz.add_image(
555
- insci,
556
- exptime=1.0,
557
- pixmap=pixmap,
558
- weight_map=inwht,
559
- scale=pscale,
560
- )
561
-
562
- template_data = read_image(output_template)
563
-
564
- _, med_diff, max_diff = centroid_statistics(
565
- "gaussian with grid",
566
- output_difference,
567
- driz.out_img,
568
- template_data,
569
- 20.0,
570
- 8,
571
- )
572
-
573
- assert med_diff < 1.0e-6
574
- assert max_diff < 2.0e-5
575
-
576
-
577
- def test_lanczos_with_grid(tmpdir):
578
- """
579
- Test do_driz lanczos kernel with grid
580
- """
581
- output_difference = str(tmpdir.join('difference_lanczos_grid.txt'))
582
-
583
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
584
- output_template = os.path.join(DATA_DIR, 'reference_lanczos_grid.fits')
585
-
586
- insci = read_image(input_file)
587
- inwcs = read_wcs(input_file)
588
- insci = make_grid_image(insci, 64, 100.0)
589
- inwht = np.ones(insci.shape, dtype=insci.dtype)
590
- output_wcs = read_wcs(output_template)
591
-
592
- pixmap = utils.calc_pixmap(
593
- inwcs,
594
- output_wcs,
595
- )
596
- pscale = utils.estimate_pixel_scale_ratio(
597
- inwcs,
598
- output_wcs,
599
- refpix_from=inwcs.wcs.crpix,
600
- refpix_to=output_wcs.wcs.crpix,
601
- )
602
-
603
- # ignore previous pscale and compute it the old way (only to make
604
- # tests work with old truth files and thus to show that new API gives
605
- # same results when equal definitions of the pixel scale is used):
606
- pscale = np.sqrt(
607
- np.sum(output_wcs.wcs.pc**2, axis=0)[0] /
608
- np.sum(inwcs.wcs.cd**2, axis=0)[0]
609
- )
610
-
611
- driz = resample.Drizzle(
612
- kernel='lanczos3',
613
- out_shape=output_wcs.array_shape,
614
- fillval=0.0,
615
- )
616
- with pytest.warns(Warning):
617
- driz.add_image(
618
- insci,
619
- exptime=1.0,
620
- pixmap=pixmap,
621
- weight_map=inwht,
622
- scale=pscale,
623
- )
624
-
625
- template_data = read_image(output_template)
626
-
627
- _, med_diff, max_diff = centroid_statistics(
628
- "lanczos with grid",
629
- output_difference,
630
- driz.out_img,
631
- template_data,
632
- 20.0,
633
- 8,
634
- )
635
- assert med_diff < 1.0e-6
636
- assert max_diff < 1.0e-5
637
-
638
-
639
- def test_point_with_grid(tmpdir):
640
- """
641
- Test do_driz point kernel with grid
642
- """
643
- output_difference = str(tmpdir.join('difference_point_grid.txt'))
644
-
645
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
646
- output_template = os.path.join(DATA_DIR, 'reference_point_grid.fits')
647
-
648
- insci = read_image(input_file)
649
- inwcs = read_wcs(input_file)
650
- insci = make_grid_image(insci, 64, 100.0)
651
- inwht = np.ones(insci.shape, dtype=insci.dtype)
652
- output_wcs = read_wcs(output_template)
653
-
654
- pixmap = utils.calc_pixmap(inwcs, output_wcs)
655
-
656
- driz = resample.Drizzle(kernel='point', out_shape=output_wcs.array_shape, fillval=0.0)
657
- driz.add_image(insci, exptime=1.0, pixmap=pixmap, weight_map=inwht)
658
-
659
- template_data = read_image(output_template)
660
-
661
- _, med_diff, max_diff = centroid_statistics(
662
- "point with grid",
663
- output_difference,
664
- driz.out_img,
665
- template_data,
666
- 20.0,
667
- 8,
668
- )
669
- assert med_diff < 1.0e-6
670
- assert max_diff < 1.0e-5
671
-
672
-
673
- def test_blot_with_point(tmpdir):
515
+ @pytest.mark.parametrize(
516
+ 'interpolator,test_image_type',
517
+ [
518
+ ("poly5", "point"),
519
+ ("default", "grid"),
520
+ ('lan3', "grid"),
521
+ ("lan5", "grid"),
522
+ ],
523
+ )
524
+ def test_blot_interpolation(tmpdir, interpolator, test_image_type):
674
525
  """
675
- Test do_blot with point image
526
+ Test do_driz square kernel with point
676
527
  """
677
- output_difference = str(tmpdir.join('difference_blot_point.txt'))
678
-
679
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
680
- output_template = os.path.join(DATA_DIR, 'reference_blot_point.fits')
681
-
682
- outsci = read_image(input_file)
683
- outwcs = read_wcs(input_file)
684
- outsci = make_point_image(outsci, (500, 200), 40.0)
685
- inwcs = read_wcs(output_template)
686
-
687
- pixmap = utils.calc_pixmap(inwcs, outwcs)
688
-
689
- # compute pscale the old way (only to make
690
- # tests work with old truth files and thus to show that new API gives
691
- # same results when equal definitions of the pixel scale is used):
692
- pscale = np.sqrt(
693
- np.sum(inwcs.wcs.pc**2, axis=0)[0] /
694
- np.sum(outwcs.wcs.cd**2, axis=0)[0]
695
- )
696
-
697
- blotted_image = resample.blot_image(
698
- outsci,
699
- pixmap=pixmap,
700
- pix_ratio=pscale,
701
- exptime=1.0,
702
- output_pixel_shape=inwcs.pixel_shape,
528
+ output_difference = str(
529
+ tmpdir.join(f"difference_blot_{interpolator}_{test_image_type}.txt")
703
530
  )
704
531
 
705
- template_data = read_image(output_template)
706
-
707
- _, med_diff, max_diff = centroid_statistics(
708
- "blot with point",
709
- output_difference,
710
- blotted_image,
711
- template_data,
712
- 20.0,
713
- 16,
714
- )
715
- assert med_diff < 1.0e-6
716
- assert max_diff < 1.0e-5
717
-
718
-
719
- def test_blot_with_default(tmpdir):
720
- """
721
- Test do_blot with default grid image
722
- """
723
- output_difference = str(tmpdir.join('difference_blot_default.txt'))
724
-
725
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
726
- output_template = os.path.join(DATA_DIR, 'reference_blot_default.fits')
727
-
728
- outsci = read_image(input_file)
729
- outsci = make_grid_image(outsci, 64, 100.0)
730
- outwcs = read_wcs(input_file)
731
- inwcs = read_wcs(output_template)
732
-
733
- pixmap = utils.calc_pixmap(inwcs, outwcs)
734
-
735
- # compute pscale the old way (only to make
736
- # tests work with old truth files and thus to show that new API gives
737
- # same results when equal definitions of the pixel scale is used):
738
- pscale = np.sqrt(
739
- np.sum(inwcs.wcs.pc**2, axis=0)[0] /
740
- np.sum(outwcs.wcs.cd**2, axis=0)[0]
741
- )
742
-
743
- blotted_image = resample.blot_image(
744
- outsci,
745
- pixmap=pixmap,
746
- pix_ratio=pscale,
747
- exptime=1.0,
748
- output_pixel_shape=inwcs.pixel_shape,
749
- )
750
-
751
- template_data = read_image(output_template)
752
-
753
- _, med_diff, max_diff = centroid_statistics(
754
- "blot with defaults",
755
- output_difference,
756
- blotted_image,
757
- template_data,
758
- 20.0,
759
- 16,
760
- )
761
-
762
- assert med_diff < 1.0e-6
763
- assert max_diff < 1.0e-5
764
-
765
-
766
- def test_blot_with_lan3(tmpdir):
767
- """
768
- Test do_blot with lan3 grid image
769
- """
770
- output_difference = str(tmpdir.join('difference_blot_lan3.txt'))
771
-
772
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
773
- output_template = os.path.join(DATA_DIR, 'reference_blot_lan3.fits')
774
-
775
- outsci = read_image(input_file)
776
- outsci = make_grid_image(outsci, 64, 100.0)
777
- outwcs = read_wcs(input_file)
778
- inwcs = read_wcs(output_template)
532
+ outwcs = wcs_from_file("j8bt06nyq_flt.fits", ext=1)
533
+ if test_image_type == "point":
534
+ outsci = make_point_image(outwcs.array_shape, (500, 200), 40.0)
535
+ ref_fname = "reference_blot_point.fits"
536
+ else:
537
+ outsci = make_grid_image(outwcs.array_shape, 64, 100.0)
538
+ ref_fname = f"reference_blot_{interpolator}.fits"
539
+ inwcs, template_data = wcs_from_file(ref_fname, ext=1, return_data=True)
779
540
 
780
541
  pixmap = utils.calc_pixmap(inwcs, outwcs)
781
542
 
782
543
  # compute pscale the old way (only to make
783
544
  # tests work with old truth files and thus to show that new API gives
784
545
  # same results when equal definitions of the pixel scale is used):
785
- pscale = np.sqrt(
546
+ pscale_ratio = np.sqrt(
786
547
  np.sum(inwcs.wcs.pc**2, axis=0)[0] /
787
548
  np.sum(outwcs.wcs.cd**2, axis=0)[0]
788
549
  )
789
550
 
790
- blotted_image = resample.blot_image(
791
- outsci,
792
- pixmap=pixmap,
793
- pix_ratio=pscale,
794
- exptime=1.0,
795
- output_pixel_shape=inwcs.pixel_shape,
796
- interp="lan3",
797
- )
798
-
799
- template_data = read_image(output_template)
800
-
801
- _, med_diff, max_diff = centroid_statistics(
802
- "blot with lan3",
803
- output_difference,
804
- blotted_image,
805
- template_data,
806
- 20.0,
807
- 16,
808
- )
809
-
810
- assert med_diff < 1.0e-6
811
- assert max_diff < 1.0e-5
812
-
813
-
814
- def test_blot_with_lan5(tmpdir):
815
- """
816
- Test do_blot with lan5 grid image
817
- """
818
- output_difference = str(tmpdir.join('difference_blot_lan5.txt'))
819
-
820
- input_file = os.path.join(DATA_DIR, 'j8bt06nyq_flt.fits')
821
- output_template = os.path.join(DATA_DIR, 'reference_blot_lan5.fits')
822
-
823
- outsci = read_image(input_file)
824
- outsci = make_grid_image(outsci, 64, 100.0)
825
- outwcs = read_wcs(input_file)
826
- inwcs = read_wcs(output_template)
827
-
828
- pixmap = utils.calc_pixmap(inwcs, outwcs)
829
-
830
- # compute pscale the old way (only to make
831
- # tests work with old truth files and thus to show that new API gives
832
- # same results when equal definitions of the pixel scale is used):
833
- pscale = np.sqrt(
834
- np.sum(inwcs.wcs.pc**2, axis=0)[0] /
835
- np.sum(outwcs.wcs.cd**2, axis=0)[0]
836
- )
551
+ if interpolator == "default":
552
+ kwargs = {}
553
+ else:
554
+ kwargs = {"interp": interpolator}
837
555
 
838
556
  blotted_image = resample.blot_image(
839
557
  outsci,
840
558
  pixmap=pixmap,
841
- pix_ratio=pscale,
559
+ pix_ratio=pscale_ratio,
842
560
  exptime=1.0,
843
561
  output_pixel_shape=inwcs.pixel_shape,
844
- interp="lan5",
562
+ **kwargs
845
563
  )
846
564
 
847
- template_data = read_image(output_template)
848
-
849
565
  _, med_diff, max_diff = centroid_statistics(
850
- "blot with lan5",
566
+ "blot with '{interpolator}' and '{test_image_type}'",
851
567
  output_difference,
852
568
  blotted_image,
853
569
  template_data,
854
570
  20.0,
855
571
  16,
856
572
  )
857
-
858
573
  assert med_diff < 1.0e-6
859
574
  assert max_diff < 1.0e-5
860
575
 
@@ -1158,6 +873,50 @@ def test_flux_conservation_distorted(kernel, fc):
1158
873
  )
1159
874
 
1160
875
 
876
+ @pytest.mark.parametrize("kernel", ["square", "turbo", "point"])
877
+ @pytest.mark.parametrize("pscale_ratio", [0.55, 1.0, 1.2])
878
+ def test_flux_conservation_distorted_distributed_sources(nrcb5_stars, kernel, pscale_ratio):
879
+ """ test aperture photometry """
880
+ insci, inwht, dq, stars, wcs = nrcb5_stars
881
+
882
+ suffix = f"{pscale_ratio}".replace(".", "p")
883
+ output_wcs = wcs_from_file(f"nrcb5_output_wcs_psr_{suffix}.hdr")
884
+
885
+ pixmap = utils.calc_pixmap(
886
+ wcs,
887
+ output_wcs,
888
+ wcs.array_shape,
889
+ )
890
+
891
+ driz = resample.Drizzle(
892
+ kernel=kernel,
893
+ out_shape=output_wcs.array_shape,
894
+ fillval=0.0,
895
+ )
896
+ driz.add_image(
897
+ insci,
898
+ exptime=1.0,
899
+ pixmap=pixmap,
900
+ weight_map=inwht,
901
+ scale=1,
902
+ )
903
+
904
+ # for efficiency, instead of doing this patch-by-patch,
905
+ # multiply resampled data by resampled image weight
906
+ out_data = driz.out_img * driz.out_wht
907
+
908
+ dim3 = (slice(None, None, None), )
909
+ for _, _, fin, sl in stars:
910
+ xyout = pixmap[sl + dim3]
911
+ xmin = int(np.floor(xyout[:, :, 0].min() - 0.5))
912
+ xmax = int(np.ceil(xyout[:, :, 0].max() + 1.5))
913
+ ymin = int(np.floor(xyout[:, :, 1].min() - 0.5))
914
+ ymax = int(np.ceil(xyout[:, :, 1].max() + 1.5))
915
+ fout = np.nansum(out_data[ymin:ymax, xmin:xmax])
916
+
917
+ assert np.allclose(fin, fout, rtol=1.0e-6, atol=0.0)
918
+
919
+
1161
920
  def test_drizzle_exptime():
1162
921
  n = 200
1163
922
  in_shape = (n, n)
@@ -1435,3 +1194,32 @@ def test_resample_inconsistent_output():
1435
1194
  out_wht=out_wht,
1436
1195
  )
1437
1196
  assert str(err_info.value).startswith("Inconsistent data shapes specified")
1197
+
1198
+
1199
+ def test_resample_disable_ctx():
1200
+ n = 20
1201
+ in_shape = (n, n)
1202
+
1203
+ pixmap = np.dstack(np.indices(in_shape, dtype=np.float64)[::-1])
1204
+
1205
+ # simulate constant data:
1206
+ in_sci = np.ones(in_shape, dtype=np.float32)
1207
+
1208
+ driz = resample.Drizzle(
1209
+ disable_ctx=True,
1210
+ )
1211
+
1212
+ driz.add_image(in_sci, exptime=1.0, pixmap=pixmap)
1213
+
1214
+
1215
+ @pytest.mark.parametrize(
1216
+ "fillval", ["NaN", "INDEF", "", None]
1217
+ )
1218
+ def test_nan_fillval(fillval):
1219
+ driz = resample.Drizzle(
1220
+ kernel='square',
1221
+ fillval=fillval,
1222
+ out_shape=(20, 20)
1223
+ )
1224
+
1225
+ assert np.all(np.isnan(driz.out_img))