public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/python-photutils] epel10: Added numpy 1.14 fix https://github.com/astropy/photutils/pull/639
@ 2026-06-26 3:41 Christian Dersch
0 siblings, 0 replies; only message in thread
From: Christian Dersch @ 2026-06-26 3:41 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/python-photutils
Branch : epel10
Commit : 6b7e29dcb1f4d188fbd6d126f30cd01eb34e50b0
Author : Christian Dersch <lupinix@mailbox.org>
Date : 2018-02-14T04:02:45+01:00
Stats : +1705/-1 in 2 file(s)
URL : https://src.fedoraproject.org/rpms/python-photutils/c/6b7e29dcb1f4d188fbd6d126f30cd01eb34e50b0?branch=epel10
Log:
Added numpy 1.14 fix https://github.com/astropy/photutils/pull/639
---
diff --git a/python-photutils-fixes-for-numpy-1.14.patch b/python-photutils-fixes-for-numpy-1.14.patch
new file mode 100644
index 0000000..afe2abd
--- /dev/null
+++ b/python-photutils-fixes-for-numpy-1.14.patch
@@ -0,0 +1,1701 @@
+diff -Naur photutils-0.4/docs/aperture.rst photutils-0.4.fixed/docs/aperture.rst
+--- photutils-0.4/docs/aperture.rst 2017-10-30 15:38:18.000000000 +0100
++++ photutils-0.4.fixed/docs/aperture.rst 2018-02-14 03:56:07.064522634 +0100
+@@ -122,12 +122,13 @@
+ >>> from photutils import aperture_photometry
+ >>> data = np.ones((100, 100))
+ >>> phot_table = aperture_photometry(data, apertures)
+- >>> print(phot_table) # doctest: +SKIP
+- id xcenter ycenter aperture_sum
++ >>> phot_table['aperture_sum'].info.format = '%.8g' # for consistent table output
++ >>> print(phot_table)
++ id xcenter ycenter aperture_sum
+ pix pix
+- --- ------- ------- -------------
+- 1 30.0 30.0 28.2743338823
+- 2 40.0 40.0 28.2743338823
++ --- ------- ------- ------------
++ 1 30.0 30.0 28.274334
++ 2 40.0 40.0 28.274334
+
+ This function returns the results of the photometry in an Astropy
+ `~astropy.table.QTable`. In this example, the table has four columns,
+@@ -159,7 +160,7 @@
+
+ >>> phot_table = aperture_photometry(data, apertures, method='subpixel',
+ ... subpixels=5)
+- >>> print(phot_table) # doctest: +SKIP
++ >>> print(phot_table)
+ id xcenter ycenter aperture_sum
+ pix pix
+ --- ------- ------- ------------
+@@ -192,12 +193,14 @@
+ >>> radii = [3., 4., 5.]
+ >>> apertures = [CircularAperture(positions, r=r) for r in radii]
+ >>> phot_table = aperture_photometry(data, apertures)
+- >>> print(phot_table) # doctest: +SKIP
++ >>> for col in phot_table.colnames:
++ ... phot_table[col].info.format = '%.8g' # for consistent table output
++ >>> print(phot_table)
+ id xcenter ycenter aperture_sum_0 aperture_sum_1 aperture_sum_2
+ pix pix
+ --- ------- ------- -------------- -------------- --------------
+- 1 30.0 30.0 28.2743338823 50.2654824574 78.5398163397
+- 2 40.0 40.0 28.2743338823 50.2654824574 78.5398163397
++ 1 30 30 28.274334 50.265482 78.539816
++ 2 40 40 28.274334 50.265482 78.539816
+
+ For multiple apertures, the output table column names are appended
+ with the ``positions`` index.
+@@ -212,12 +215,14 @@
+ >>> theta = np.pi / 4.
+ >>> apertures = EllipticalAperture(positions, a, b, theta)
+ >>> phot_table = aperture_photometry(data, apertures)
+- >>> print(phot_table) # doctest: +SKIP
+- id xcenter ycenter aperture_sum
++ >>> for col in phot_table.colnames:
++ ... phot_table[col].info.format = '%.8g' # for consistent table output
++ >>> print(phot_table)
++ id xcenter ycenter aperture_sum
+ pix pix
+- --- ------- ------- -------------
+- 1 30.0 30.0 47.1238898038
+- 2 40.0 40.0 47.1238898038
++ --- ------- ------- ------------
++ 1 30 30 47.12389
++ 2 40 40 47.12389
+
+ Again, for multiple apertures one should input a list of aperture
+ objects, each with identical positions::
+@@ -228,12 +233,14 @@
+ >>> apertures = [EllipticalAperture(positions, a=ai, b=bi, theta=theta)
+ ... for (ai, bi) in zip(a, b)]
+ >>> phot_table = aperture_photometry(data, apertures)
+- >>> print(phot_table) # doctest: +SKIP
++ >>> for col in phot_table.colnames:
++ ... phot_table[col].info.format = '%.8g' # for consistent table output
++ >>> print(phot_table)
+ id xcenter ycenter aperture_sum_0 aperture_sum_1 aperture_sum_2
+ pix pix
+ --- ------- ------- -------------- -------------- --------------
+- 1 30.0 30.0 47.1238898038 75.3982236862 109.955742876
+- 2 40.0 40.0 47.1238898038 75.3982236862 109.955742876
++ 1 30 30 47.12389 75.398224 109.95574
++ 2 40 40 47.12389 75.398224 109.95574
+
+
+ Background Subtraction
+@@ -267,12 +274,14 @@
+
+ >>> apers = [apertures, annulus_apertures]
+ >>> phot_table = aperture_photometry(data, apers)
+- >>> print(phot_table) # doctest: +SKIP
++ >>> for col in phot_table.colnames:
++ ... phot_table[col].info.format = '%.8g' # for consistent table output
++ >>> print(phot_table)
+ id xcenter ycenter aperture_sum_0 aperture_sum_1
+ pix pix
+ --- ------- ------- -------------- --------------
+- 1 30.0 30.0 28.2743338823 87.9645943005
+- 2 40.0 40.0 28.2743338823 87.9645943005
++ 1 30 30 28.274334 87.964594
++ 2 40 40 28.274334 87.964594
+
+ Note that we cannot simply subtract the aperture sums because the
+ apertures have different areas.
+@@ -289,11 +298,12 @@
+ >>> bkg_sum = bkg_mean * apertures.area()
+ >>> final_sum = phot_table['aperture_sum_0'] - bkg_sum
+ >>> phot_table['residual_aperture_sum'] = final_sum
+- >>> print(phot_table['residual_aperture_sum']) # doctest: +FLOAT_CMP
++ >>> phot_table['residual_aperture_sum'].info.format = '%.8g' # for consistent table output
++ >>> print(phot_table['residual_aperture_sum'])
+ residual_aperture_sum
+ ---------------------
+- -7.1054273576e-15
+- -7.1054273576e-15
++ -7.1054274e-15
++ -7.1054274e-15
+
+ The result here should be zero because all of the data values are 1.0
+ (the tiny difference from 0.0 is due to numerical precision).
+@@ -316,12 +326,14 @@
+
+ >>> error = 0.1 * data
+ >>> phot_table = aperture_photometry(data, apertures, error=error)
+- >>> print(phot_table) # doctest: +SKIP
+- id xcenter ycenter aperture_sum aperture_sum_err
++ >>> for col in phot_table.colnames:
++ ... phot_table[col].info.format = '%.8g' # for consistent table output
++ >>> print(phot_table)
++ id xcenter ycenter aperture_sum aperture_sum_err
+ pix pix
+- --- ------- ------- ------------- ----------------
+- 1 30.0 30.0 28.2743338823 0.531736155272
+- 2 40.0 40.0 28.2743338823 0.531736155272
++ --- ------- ------- ------------ ----------------
++ 1 30 30 28.274334 0.53173616
++ 2 40 40 28.274334 0.53173616
+
+ ``'aperture_sum_err'`` values are given by:
+
+@@ -363,18 +375,20 @@
+ >>> data[2, 2] = 100. # bad pixel
+ >>> mask[2, 2] = True
+ >>> t1 = aperture_photometry(data, aperture, mask=mask)
+- >>> print(t1['aperture_sum']) # doctest: +FLOAT_CMP
+- aperture_sum
+- -------------
+- 11.5663706144
++ >>> t1['aperture_sum'].info.format = '%.8g' # for consistent table output
++ >>> print(t1['aperture_sum'])
++ aperture_sum
++ ------------
++ 11.566371
+
+ The result is very different if a ``mask`` image is not provided::
+
+ >>> t2 = aperture_photometry(data, aperture)
+- >>> print(t2['aperture_sum']) # doctest: +FLOAT_CMP
++ >>> t2['aperture_sum'].info.format = '%.8g' # for consistent table output
++ >>> print(t2['aperture_sum'])
+ aperture_sum
+- -------------
+- 111.566370614
++ ------------
++ 111.56637
+
+
+ Aperture Photometry Using Sky Coordinates
+diff -Naur photutils-0.4/docs/background.rst photutils-0.4.fixed/docs/background.rst
+--- photutils-0.4/docs/background.rst 2017-10-30 15:38:18.000000000 +0100
++++ photutils-0.4.fixed/docs/background.rst 2018-02-14 03:56:07.064522634 +0100
+@@ -76,18 +76,18 @@
+
+ >>> import numpy as np
+ >>> from astropy.stats import biweight_location
+- >>> print(np.median(data))
+- 5.2255295184
+- >>> print(biweight_location(data))
+- 5.1867597555
++ >>> print(np.median(data)) # doctest: +FLOAT_CMP
++ 5.225529518399048
++ >>> print(biweight_location(data)) # doctest: +FLOAT_CMP
++ 5.186759755495727
+
+ Similarly, using the median absolute deviation to estimate the
+ background noise level gives a value that is larger than the true
+ value of 2::
+
+ >>> from astropy.stats import mad_std
+- >>> print(mad_std(data)) # doctest: +FLOAT_CMP
+- 2.1443728009
++ >>> print(mad_std(data)) # doctest: +FLOAT_CMP
++ 2.1443760096598914
+
+
+ Sigma Clipping Sources
+@@ -103,8 +103,8 @@
+
+ >>> from astropy.stats import sigma_clipped_stats
+ >>> mean, median, std = sigma_clipped_stats(data, sigma=3.0, iters=5)
+- >>> print((mean, median, std)) # doctest: +FLOAT_CMP
+- (5.1991386516217908, 5.1555874333582912, 2.0942752121329691)
++ >>> print((mean, median, std)) # doctest: +FLOAT_CMP
++ (5.199138651621793, 5.155587433358291, 2.094275212132969)
+
+
+ Masking Sources
+@@ -132,8 +132,8 @@
+ >>> from photutils import make_source_mask
+ >>> mask = make_source_mask(data, snr=2, npixels=5, dilate_size=11)
+ >>> mean, median, std = sigma_clipped_stats(data, sigma=3.0, mask=mask)
+- >>> print((mean, median, std)) # doctest: +FLOAT_CMP
+- (5.0010134754755695, 5.0005849056043763, 1.970887100626572)
++ >>> print((mean, median, std)) # doctest: +FLOAT_CMP
++ (5.001013475475569, 5.000584905604376, 1.970887100626572)
+
+ Of course, the source detection and masking procedure can be iterated
+ further. Even with one iteration we are within 0.02% of the true
+@@ -229,7 +229,7 @@
+ >>> y, x = np.mgrid[:ny, :nx]
+ >>> gradient = x * y / 5000.
+ >>> data2 = data + gradient
+- >>> plt.imshow(data2, norm=norm, origin='lower', cmap='Greys_r') # doctest: +SKIP
++ >>> plt.imshow(data2, norm=norm, origin='lower', cmap='Greys_r') # doctest: +SKIP
+
+ .. plot::
+
+@@ -271,10 +271,10 @@
+
+ .. doctest-requires:: scipy
+
+- >>> print(bkg.background_median)
+- 10.8219978626
+- >>> print(bkg.background_rms_median)
+- 2.29882053968
++ >>> print(bkg.background_median) # doctest: +FLOAT_CMP
++ 10.821997862561792
++ >>> print(bkg.background_rms_median) # doctest: +FLOAT_CMP
++ 2.298820539683762
+
+ Let's plot the background image:
+
+@@ -348,8 +348,8 @@
+
+ >>> from scipy.ndimage import rotate
+ >>> data3 = rotate(data2, -45.)
+- >>> norm = ImageNormalize(stretch=SqrtStretch()) # doctest: +SKIP
+- >>> plt.imshow(data3, origin='lower', cmap='Greys_r', norm=norm) # doctest: +SKIP
++ >>> norm = ImageNormalize(stretch=SqrtStretch()) # doctest: +SKIP
++ >>> plt.imshow(data3, origin='lower', cmap='Greys_r', norm=norm) # doctest: +SKIP
+
+ .. plot::
+
+@@ -386,8 +386,8 @@
+ .. doctest-requires:: scipy
+
+ >>> back3 = bkg3.background * ~mask
+- >>> norm = ImageNormalize(stretch=SqrtStretch()) # doctest: +SKIP
+- >>> plt.imshow(back3, origin='lower', cmap='Greys_r', norm=norm) # doctest: +SKIP
++ >>> norm = ImageNormalize(stretch=SqrtStretch()) # doctest: +SKIP
++ >>> plt.imshow(back3, origin='lower', cmap='Greys_r', norm=norm) # doctest: +SKIP
+
+ .. plot::
+
+diff -Naur photutils-0.4/docs/detection.rst photutils-0.4.fixed/docs/detection.rst
+--- photutils-0.4/docs/detection.rst 2017-10-30 15:38:18.000000000 +0100
++++ photutils-0.4.fixed/docs/detection.rst 2018-02-14 03:56:07.065522650 +0100
+@@ -62,20 +62,23 @@
+ >>> from photutils import DAOStarFinder
+ >>> daofind = DAOStarFinder(fwhm=3.0, threshold=5.*std) # doctest: +REMOTE_DATA
+ >>> sources = daofind(data - median) # doctest: +REMOTE_DATA
++ >>> for col in sources.colnames: # doctest: +REMOTE_DATA
++ ... sources[col].info.format = '%.8g' # for consistent table output
+ >>> print(sources) # doctest: +REMOTE_DATA
+- id xcentroid ycentroid ... peak flux mag
+- --- ------------- ------------- ... ------ ------------- ---------------
+- 1 144.247567164 6.37979042704 ... 6903.0 5.70143033038 -1.88995955438
+- 2 208.669068628 6.82058053777 ... 7896.0 6.72306730455 -2.06891864748
+- 3 216.926136655 6.5775933198 ... 2195.0 1.66737467591 -0.555083002864
+- 4 351.625190383 8.5459013233 ... 6977.0 5.90092548147 -1.92730032571
+- 5 377.519909958 12.0655009987 ... 1260.0 1.11856203781 -0.121650189969
+- ... ... ... ... ... ... ...
+- 281 268.049236979 397.925371446 ... 9299.0 6.22022587541 -1.98451538884
+- 282 268.475068392 398.020998272 ... 8754.0 6.05079160593 -1.95453048936
+- 283 299.80943822 398.027911813 ... 8890.0 6.11853416663 -1.96661847383
+- 284 315.689448343 398.70251891 ... 6485.0 5.55471107793 -1.86165368631
+- 285 360.437243037 398.698539555 ... 8079.0 5.26549321379 -1.80359764345
++ id xcentroid ycentroid sharpness ... sky peak flux mag
++ --- --------- --------- ---------- ... --- ---- --------- ------------
++ 1 144.24757 6.3797904 0.58156257 ... 0 6903 5.7014303 -1.8899596
++ 2 208.66907 6.8205805 0.48348966 ... 0 7896 6.7230673 -2.0689186
++ 3 216.92614 6.5775933 0.69359525 ... 0 2195 1.6673747 -0.555083
++ 4 351.62519 8.5459013 0.48577834 ... 0 6977 5.9009255 -1.9273003
++ 5 377.51991 12.065501 0.52038488 ... 0 1260 1.118562 -0.12165019
++ ... ... ... ... ... ... ... ... ...
++ 280 345.59306 395.38222 0.384078 ... 0 9350 5.0559084 -1.759498
++ 281 268.04924 397.92537 0.29650715 ... 0 9299 6.2202259 -1.9845154
++ 282 268.47507 398.021 0.28325741 ... 0 8754 6.0507916 -1.9545305
++ 283 299.80944 398.02791 0.32011339 ... 0 8890 6.1185342 -1.9666185
++ 284 315.68945 398.70252 0.29502138 ... 0 6485 5.5547111 -1.8616537
++ 285 360.43724 398.69854 0.81147144 ... 0 8079 5.2654932 -1.8035976
+ Length = 285 rows
+
+ Let's plot the image and mark the location of detected sources:
+@@ -143,19 +146,20 @@
+ >>> mean, median, std = sigma_clipped_stats(data, sigma=3.0)
+ >>> threshold = median + (10.0 * std)
+ >>> tbl = find_peaks(data, threshold, box_size=5)
++ >>> tbl['peak_value'].info.format = '%.8g' # for consistent table output
+ >>> print(tbl[:10]) # print only the first 10 peaks
+- x_peak y_peak peak_value
+- ------ ------ -------------
+- 233 0 27.4778521972
+- 236 1 27.339519624
+- 289 22 35.8532759965
+- 442 31 30.2399941373
+- 1 40 35.5482863002
+- 89 59 41.2190469279
+- 7 70 33.2880647048
+- 258 75 26.5624808518
+- 463 80 28.7588206692
+- 182 93 38.0885687202
++ x_peak y_peak peak_value
++ ------ ------ ----------
++ 233 0 27.477852
++ 236 1 27.33952
++ 289 22 35.853276
++ 442 31 30.239994
++ 1 40 35.548286
++ 89 59 41.219047
++ 7 70 33.288065
++ 258 75 26.562481
++ 463 80 28.758821
++ 182 93 38.088569
+
+ And let's plot the location of the detected peaks in the image:
+
+diff -Naur photutils-0.4/docs/getting_started.rst photutils-0.4.fixed/docs/getting_started.rst
+--- photutils-0.4/docs/getting_started.rst 2017-10-30 15:38:18.000000000 +0100
++++ photutils-0.4.fixed/docs/getting_started.rst 2018-02-14 03:56:07.065522650 +0100
+@@ -31,20 +31,23 @@
+ >>> bkg_sigma = mad_std(image) # doctest: +REMOTE_DATA
+ >>> daofind = DAOStarFinder(fwhm=4., threshold=3.*bkg_sigma) # doctest: +REMOTE_DATA
+ >>> sources = daofind(image) # doctest: +REMOTE_DATA
++ >>> for col in sources.colnames: # doctest: +REMOTE_DATA
++ ... sources[col].info.format = '%.8g' # for consistent table output
+ >>> print(sources) # doctest: +REMOTE_DATA
+- id xcentroid ycentroid ... peak flux mag
+- --- ------------- -------------- ... ------ ------------- ---------------
+- 1 182.838658938 0.167670190537 ... 3824.0 2.80283459469 -1.11899367311
+- 2 189.204308134 0.260813525338 ... 4913.0 3.87291850311 -1.47009589582
+- 3 5.79464911433 2.61254240807 ... 7752.0 4.1029107294 -1.53273016937
+- 4 36.8470627804 1.32202279582 ... 8739.0 7.43158178793 -2.17770315441
+- 5 3.2565602452 5.41895201748 ... 6935.0 3.81262984074 -1.45306160673
+- ... ... ... ... ... ... ...
+- 148 124.313272579 188.305229159 ... 6702.0 6.63585429303 -2.05474210356
+- 149 24.2572074962 194.714942814 ... 8342.0 3.2671036996 -1.28540729858
+- 150 116.449998422 195.059233325 ... 3299.0 2.87752205766 -1.1475466535
+- 151 18.9580860645 196.342065132 ... 3854.0 2.38352961224 -0.943051379595
+- 152 111.525751196 195.731917995 ... 8109.0 7.9278607401 -2.24789003194
++ id xcentroid ycentroid sharpness ... sky peak flux mag
++ --- --------- ---------- ---------- ... --- ---- --------- -----------
++ 1 182.83866 0.16767019 0.85099873 ... 0 3824 2.8028346 -1.1189937
++ 2 189.20431 0.26081353 0.7400477 ... 0 4913 3.8729185 -1.4700959
++ 3 5.7946491 2.6125424 0.39589731 ... 0 7752 4.1029107 -1.5327302
++ 4 36.847063 1.3220228 0.29594528 ... 0 8739 7.4315818 -2.1777032
++ 5 3.2565602 5.418952 0.35985495 ... 0 6935 3.8126298 -1.4530616
++ ... ... ... ... ... ... ... ... ...
++ 147 197.24864 186.16647 0.31211532 ... 0 8302 7.5814629 -2.1993825
++ 148 124.31327 188.30523 0.5362742 ... 0 6702 6.6358543 -2.0547421
++ 149 24.257207 194.71494 0.44169546 ... 0 8342 3.2671037 -1.2854073
++ 150 116.45 195.05923 0.67080547 ... 0 3299 2.8775221 -1.1475467
++ 151 18.958086 196.34207 0.56502139 ... 0 3854 2.3835296 -0.94305138
++ 152 111.52575 195.73192 0.45827852 ... 0 8109 7.9278607 -2.24789
+ Length = 152 rows
+
+ Using the list of source locations (``xcentroid`` and ``ycentroid``),
+@@ -59,21 +62,23 @@
+ >>> positions = (sources['xcentroid'], sources['ycentroid']) # doctest: +REMOTE_DATA
+ >>> apertures = CircularAperture(positions, r=4.) # doctest: +REMOTE_DATA
+ >>> phot_table = aperture_photometry(image, apertures) # doctest: +REMOTE_DATA
+- >>> print(phot_table) # doctest: +SKIP
+- id xcenter ycenter aperture_sum
+- pix pix
+- --- ------------------ ------------------- -------------
+- 1 182.8386589381308 0.16767019053693752 18121.7594837
+- 2 189.20430813403388 0.26081352533766516 29836.5152158
+- 3 5.794649114329246 2.612542408073547 331979.819037
+- 4 36.84706278043582 1.3220227958153257 183705.093284
+- 5 3.2565602452007325 5.418952017476508 349468.978627
+- ... ... ... ...
+- 148 124.3132725793939 188.30522915858668 45084.8737867
+- 149 24.257207496209027 194.71494281419265 355778.007298
+- 150 116.44999842177826 195.05923332483115 31232.9117818
+- 151 18.958086064485013 196.3420651316401 162076.262752
+- 152 111.52575119605933 195.73191799469373 82795.7145661
++ >>> for col in phot_table.colnames: # doctest: +REMOTE_DATA
++ ... phot_table[col].info.format = '%.8g' # for consistent table output
++ >>> print(phot_table) # doctest: +REMOTE_DATA
++ id xcenter ycenter aperture_sum
++ pix pix
++ --- --------- ---------- ------------
++ 1 182.83866 0.16767019 18121.759
++ 2 189.20431 0.26081353 29836.515
++ 3 5.7946491 2.6125424 331979.82
++ 4 36.847063 1.3220228 183705.09
++ 5 3.2565602 5.418952 349468.98
++ ... ... ... ...
++ 148 124.31327 188.30523 45084.874
++ 149 24.257207 194.71494 355778.01
++ 150 116.45 195.05923 31232.912
++ 151 18.958086 196.34207 162076.26
++ 152 111.52575 195.73192 82795.715
+ Length = 152 rows
+
+ The sum of the pixel values within the apertures are given in the
+diff -Naur photutils-0.4/photutils/aperture/tests/test_aperture_photometry.py photutils-0.4.fixed/photutils/aperture/tests/test_aperture_photometry.py
+--- photutils-0.4/photutils/aperture/tests/test_aperture_photometry.py 2017-10-30 15:38:18.000000000 +0100
++++ photutils-0.4.fixed/photutils/aperture/tests/test_aperture_photometry.py 2018-02-14 03:56:07.063522619 +0100
+@@ -19,8 +19,10 @@
+ from astropy.table import Table
+ from astropy.tests.helper import remote_data
+ import astropy.units as u
++from astropy.utils.compat import NUMPY_LT_1_14
+ from astropy.wcs.utils import pixel_to_skycoord
+
++
+ from ..core import aperture_photometry
+ from ..circle import (CircularAperture, CircularAnnulus, SkyCircularAperture,
+ SkyCircularAnnulus)
+@@ -664,64 +666,119 @@
+ s = SkyCoord([1, 2], [3, 4], unit='deg')
+
+ aper = SkyCircularAperture(s, r=3*u.pix)
+- a_repr = ('<SkyCircularAperture(<SkyCoord (ICRS): (ra, dec) in deg\n'
+- ' [( 1., 3.), ( 2., 4.)]>, r=3.0 pix)>')
+- a_str = ('Aperture: SkyCircularAperture\npositions: <SkyCoord '
+- '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
+- 'r: 3.0 pix')
++ if NUMPY_LT_1_14:
++ a_repr = ('<SkyCircularAperture(<SkyCoord (ICRS): (ra, dec) in deg\n'
++ ' [( 1., 3.), ( 2., 4.)]>, r=3.0 pix)>')
++ a_str = ('Aperture: SkyCircularAperture\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
++ 'r: 3.0 pix')
++ else:
++ a_repr = ('<SkyCircularAperture(<SkyCoord (ICRS): (ra, dec) in deg\n'
++ ' [(1., 3.), (2., 4.)]>, r=3.0 pix)>')
++ a_str = ('Aperture: SkyCircularAperture\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [(1., 3.), (2., 4.)]>\n'
++ 'r: 3.0 pix')
++
+ assert repr(aper) == a_repr
+ assert str(aper) == a_str
+
+ aper = SkyCircularAnnulus(s, r_in=3.*u.pix, r_out=5*u.pix)
+- a_repr = ('<SkyCircularAnnulus(<SkyCoord (ICRS): (ra, dec) in deg\n'
+- ' [( 1., 3.), ( 2., 4.)]>, r_in=3.0 pix, r_out=5.0 pix)>')
+- a_str = ('Aperture: SkyCircularAnnulus\npositions: <SkyCoord '
+- '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
+- 'r_in: 3.0 pix\nr_out: 5.0 pix')
++ if NUMPY_LT_1_14:
++ a_repr = ('<SkyCircularAnnulus(<SkyCoord (ICRS): (ra, dec) in deg\n'
++ ' [( 1., 3.), ( 2., 4.)]>, r_in=3.0 pix, '
++ 'r_out=5.0 pix)>')
++ a_str = ('Aperture: SkyCircularAnnulus\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
++ 'r_in: 3.0 pix\nr_out: 5.0 pix')
++ else:
++ a_repr = ('<SkyCircularAnnulus(<SkyCoord (ICRS): (ra, dec) in deg\n'
++ ' [(1., 3.), (2., 4.)]>, r_in=3.0 pix, r_out=5.0 pix)>')
++ a_str = ('Aperture: SkyCircularAnnulus\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [(1., 3.), (2., 4.)]>\n'
++ 'r_in: 3.0 pix\nr_out: 5.0 pix')
++
+ assert repr(aper) == a_repr
+ assert str(aper) == a_str
+
+ aper = SkyEllipticalAperture(s, a=3*u.pix, b=5*u.pix, theta=15*u.deg)
+- a_repr = ('<SkyEllipticalAperture(<SkyCoord (ICRS): (ra, dec) in '
+- 'deg\n [( 1., 3.), ( 2., 4.)]>, a=3.0 pix, b=5.0 pix,'
+- ' theta=15.0 deg)>')
+- a_str = ('Aperture: SkyEllipticalAperture\npositions: <SkyCoord '
+- '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
+- 'a: 3.0 pix\nb: 5.0 pix\ntheta: 15.0 deg')
++ if NUMPY_LT_1_14:
++ a_repr = ('<SkyEllipticalAperture(<SkyCoord (ICRS): (ra, dec) in '
++ 'deg\n [( 1., 3.), ( 2., 4.)]>, a=3.0 pix, b=5.0 pix,'
++ ' theta=15.0 deg)>')
++ a_str = ('Aperture: SkyEllipticalAperture\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
++ 'a: 3.0 pix\nb: 5.0 pix\ntheta: 15.0 deg')
++ else:
++ a_repr = ('<SkyEllipticalAperture(<SkyCoord (ICRS): (ra, dec) in '
++ 'deg\n [(1., 3.), (2., 4.)]>, a=3.0 pix, b=5.0 pix,'
++ ' theta=15.0 deg)>')
++ a_str = ('Aperture: SkyEllipticalAperture\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [(1., 3.), (2., 4.)]>\n'
++ 'a: 3.0 pix\nb: 5.0 pix\ntheta: 15.0 deg')
++
+ assert repr(aper) == a_repr
+ assert str(aper) == a_str
+
+ aper = SkyEllipticalAnnulus(s, a_in=3*u.pix, a_out=5*u.pix, b_out=3*u.pix,
+ theta=15*u.deg)
+- a_repr = ('<SkyEllipticalAnnulus(<SkyCoord (ICRS): (ra, dec) in '
+- 'deg\n [( 1., 3.), ( 2., 4.)]>, a_in=3.0 pix, '
+- 'a_out=5.0 pix, b_out=3.0 pix, theta=15.0 deg)>')
+- a_str = ('Aperture: SkyEllipticalAnnulus\npositions: <SkyCoord '
+- '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
+- 'a_in: 3.0 pix\na_out: 5.0 pix\nb_out: 3.0 pix\n'
+- 'theta: 15.0 deg')
++ if NUMPY_LT_1_14:
++ a_repr = ('<SkyEllipticalAnnulus(<SkyCoord (ICRS): (ra, dec) in '
++ 'deg\n [( 1., 3.), ( 2., 4.)]>, a_in=3.0 pix, '
++ 'a_out=5.0 pix, b_out=3.0 pix, theta=15.0 deg)>')
++ a_str = ('Aperture: SkyEllipticalAnnulus\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
++ 'a_in: 3.0 pix\na_out: 5.0 pix\nb_out: 3.0 pix\n'
++ 'theta: 15.0 deg')
++ else:
++ a_repr = ('<SkyEllipticalAnnulus(<SkyCoord (ICRS): (ra, dec) in '
++ 'deg\n [(1., 3.), (2., 4.)]>, a_in=3.0 pix, '
++ 'a_out=5.0 pix, b_out=3.0 pix, theta=15.0 deg)>')
++ a_str = ('Aperture: SkyEllipticalAnnulus\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [(1., 3.), (2., 4.)]>\n'
++ 'a_in: 3.0 pix\na_out: 5.0 pix\nb_out: 3.0 pix\n'
++ 'theta: 15.0 deg')
++
+ assert repr(aper) == a_repr
+ assert str(aper) == a_str
+
+ aper = SkyRectangularAperture(s, w=3*u.pix, h=5*u.pix, theta=15*u.deg)
+- a_repr = ('<SkyRectangularAperture(<SkyCoord (ICRS): (ra, dec) in '
+- 'deg\n [( 1., 3.), ( 2., 4.)]>, w=3.0 pix, h=5.0 pix'
+- ', theta=15.0 deg)>')
+- a_str = ('Aperture: SkyRectangularAperture\npositions: <SkyCoord '
+- '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
+- 'w: 3.0 pix\nh: 5.0 pix\ntheta: 15.0 deg')
++ if NUMPY_LT_1_14:
++ a_repr = ('<SkyRectangularAperture(<SkyCoord (ICRS): (ra, dec) in '
++ 'deg\n [( 1., 3.), ( 2., 4.)]>, w=3.0 pix, h=5.0 pix'
++ ', theta=15.0 deg)>')
++ a_str = ('Aperture: SkyRectangularAperture\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
++ 'w: 3.0 pix\nh: 5.0 pix\ntheta: 15.0 deg')
++ else:
++ a_repr = ('<SkyRectangularAperture(<SkyCoord (ICRS): (ra, dec) in '
++ 'deg\n [(1., 3.), (2., 4.)]>, w=3.0 pix, h=5.0 pix'
++ ', theta=15.0 deg)>')
++ a_str = ('Aperture: SkyRectangularAperture\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [(1., 3.), (2., 4.)]>\n'
++ 'w: 3.0 pix\nh: 5.0 pix\ntheta: 15.0 deg')
++
+ assert repr(aper) == a_repr
+ assert str(aper) == a_str
+
+ aper = SkyRectangularAnnulus(s, w_in=3*u.pix, w_out=3.4*u.pix,
+ h_out=5*u.pix, theta=15*u.deg)
+- a_repr = ('<SkyRectangularAnnulus(<SkyCoord (ICRS): (ra, dec) in deg'
+- '\n [( 1., 3.), ( 2., 4.)]>, w_in=3.0 pix, '
+- 'w_out=3.4 pix, h_out=5.0 pix, theta=15.0 deg)>')
+- a_str = ('Aperture: SkyRectangularAnnulus\npositions: <SkyCoord '
+- '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
+- 'w_in: 3.0 pix\nw_out: 3.4 pix\nh_out: 5.0 pix\n'
+- 'theta: 15.0 deg')
++ if NUMPY_LT_1_14:
++ a_repr = ('<SkyRectangularAnnulus(<SkyCoord (ICRS): (ra, dec) in deg'
++ '\n [( 1., 3.), ( 2., 4.)]>, w_in=3.0 pix, '
++ 'w_out=3.4 pix, h_out=5.0 pix, theta=15.0 deg)>')
++ a_str = ('Aperture: SkyRectangularAnnulus\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
++ 'w_in: 3.0 pix\nw_out: 3.4 pix\nh_out: 5.0 pix\n'
++ 'theta: 15.0 deg')
++ else:
++ a_repr = ('<SkyRectangularAnnulus(<SkyCoord (ICRS): (ra, dec) in deg'
++ '\n [(1., 3.), (2., 4.)]>, w_in=3.0 pix, '
++ 'w_out=3.4 pix, h_out=5.0 pix, theta=15.0 deg)>')
++ a_str = ('Aperture: SkyRectangularAnnulus\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [(1., 3.), (2., 4.)]>\n'
++ 'w_in: 3.0 pix\nw_out: 3.4 pix\nh_out: 5.0 pix\n'
++ 'theta: 15.0 deg')
++
+ assert repr(aper) == a_repr
+ assert str(aper) == a_str
+
+diff -Naur photutils-0.4/photutils/aperture/tests/test_aperture_photometry.py.orig photutils-0.4.fixed/photutils/aperture/tests/test_aperture_photometry.py.orig
+--- photutils-0.4/photutils/aperture/tests/test_aperture_photometry.py.orig 1970-01-01 01:00:00.000000000 +0100
++++ photutils-0.4.fixed/photutils/aperture/tests/test_aperture_photometry.py.orig 2017-10-30 15:38:18.000000000 +0100
+@@ -0,0 +1,830 @@
++# Licensed under a 3-clause BSD style license - see LICENSE.rst
++"""
++The tests in this file test the accuracy of the photometric results.
++Here we test directly with aperture objects since we are checking the
++algorithms in aperture_photometry, not in the wrappers.
++"""
++
++from __future__ import (absolute_import, division, print_function,
++ unicode_literals)
++
++import pytest
++import numpy as np
++from numpy.testing import (assert_allclose, assert_array_equal,
++ assert_array_less)
++
++from astropy.coordinates import SkyCoord
++from astropy.io import fits
++from astropy.nddata import NDData
++from astropy.table import Table
++from astropy.tests.helper import remote_data
++import astropy.units as u
++from astropy.wcs.utils import pixel_to_skycoord
++
++from ..core import aperture_photometry
++from ..circle import (CircularAperture, CircularAnnulus, SkyCircularAperture,
++ SkyCircularAnnulus)
++from ..ellipse import (EllipticalAperture, EllipticalAnnulus,
++ SkyEllipticalAperture, SkyEllipticalAnnulus)
++from ..rectangle import (RectangularAperture, RectangularAnnulus,
++ SkyRectangularAperture, SkyRectangularAnnulus)
++from ...datasets import (get_path, make_4gaussians_image, make_wcs,
++ make_imagehdu)
++
++try:
++ import matplotlib # noqa
++ HAS_MATPLOTLIB = True
++except ImportError:
++ HAS_MATPLOTLIB = False
++
++
++APERTURE_CL = [CircularAperture,
++ CircularAnnulus,
++ EllipticalAperture,
++ EllipticalAnnulus,
++ RectangularAperture,
++ RectangularAnnulus]
++
++
++TEST_APERTURES = list(zip(APERTURE_CL, ((3.,), (3., 5.),
++ (3., 5., 1.), (3., 5., 4., 1.),
++ (5, 8, np.pi / 4),
++ (8, 12, 8, np.pi / 8))))
++
++
++@pytest.mark.parametrize(('aperture_class', 'params'), TEST_APERTURES)
++def test_outside_array(aperture_class, params):
++ data = np.ones((10, 10), dtype=np.float)
++ aperture = aperture_class((-60, 60), *params)
++ fluxtable = aperture_photometry(data, aperture)
++ # aperture is fully outside array:
++ assert np.isnan(fluxtable['aperture_sum'])
++
++
++@pytest.mark.parametrize(('aperture_class', 'params'), TEST_APERTURES)
++def test_inside_array_simple(aperture_class, params):
++ data = np.ones((40, 40), dtype=np.float)
++ aperture = aperture_class((20., 20.), *params)
++ table1 = aperture_photometry(data, aperture, method='center', subpixels=10)
++ table2 = aperture_photometry(data, aperture, method='subpixel',
++ subpixels=10)
++ table3 = aperture_photometry(data, aperture, method='exact', subpixels=10)
++ true_flux = aperture.area()
++
++ if not isinstance(aperture, (RectangularAperture, RectangularAnnulus)):
++ assert_allclose(table3['aperture_sum'], true_flux)
++ assert_allclose(table2['aperture_sum'], table3['aperture_sum'],
++ atol=0.1)
++ assert table1['aperture_sum'] < table3['aperture_sum']
++
++
++@pytest.mark.skipif('not HAS_MATPLOTLIB')
++@pytest.mark.parametrize(('aperture_class', 'params'), TEST_APERTURES)
++def test_aperture_plots(aperture_class, params):
++ # This test should run without any errors, and there is no return
++ # value.
++ # TODO: check the content of the plot
++ aperture = aperture_class((20., 20.), *params)
++ aperture.plot()
++
++
++def test_aperture_pixel_positions():
++ pos1 = (10, 20)
++ pos2 = u.Quantity((10, 20), unit=u.pixel)
++ pos3 = ((10, 20, 30), (10, 20, 30))
++ pos3_pairs = ((10, 10), (20, 20), (30, 30))
++
++ r = 3
++ ap1 = CircularAperture(pos1, r)
++ ap2 = CircularAperture(pos2, r)
++ ap3 = CircularAperture(pos3, r)
++
++ assert_allclose(np.atleast_2d(pos1), ap1.positions)
++ assert_allclose(np.atleast_2d(pos2.value), ap2.positions)
++ assert_allclose(pos3_pairs, ap3.positions)
++
++
++class BaseTestAperturePhotometry(object):
++
++ def test_scalar_error(self):
++ # Scalar error
++ error = 1.
++ if not hasattr(self, 'mask'):
++ mask = None
++ true_error = np.sqrt(self.area)
++ else:
++ mask = self.mask
++ # 1 masked pixel
++ true_error = np.sqrt(self.area - 1)
++
++ table1 = aperture_photometry(self.data,
++ self.aperture, method='center',
++ mask=mask, error=error)
++ table2 = aperture_photometry(self.data,
++ self.aperture,
++ method='subpixel', subpixels=12,
++ mask=mask, error=error)
++ table3 = aperture_photometry(self.data,
++ self.aperture, method='exact',
++ mask=mask, error=error)
++
++ if not isinstance(self.aperture, (RectangularAperture,
++ RectangularAnnulus)):
++ assert_allclose(table3['aperture_sum'], self.true_flux)
++ assert_allclose(table2['aperture_sum'], table3['aperture_sum'],
++ atol=0.1)
++ assert np.all(table1['aperture_sum'] < table3['aperture_sum'])
++
++ if not isinstance(self.aperture, (RectangularAperture,
++ RectangularAnnulus)):
++ assert_allclose(table3['aperture_sum_err'], true_error)
++ assert_allclose(table2['aperture_sum'], table3['aperture_sum'],
++ atol=0.1)
++ assert np.all(table1['aperture_sum_err'] < table3['aperture_sum_err'])
++
++ def test_array_error(self):
++ # Array error
++ error = np.ones(self.data.shape, dtype=np.float)
++ if not hasattr(self, 'mask'):
++ mask = None
++ true_error = np.sqrt(self.area)
++ else:
++ mask = self.mask
++ # 1 masked pixel
++ true_error = np.sqrt(self.area - 1)
++
++ table1 = aperture_photometry(self.data,
++ self.aperture, method='center',
++ mask=mask, error=error)
++ table2 = aperture_photometry(self.data,
++ self.aperture,
++ method='subpixel', subpixels=12,
++ mask=mask, error=error)
++ table3 = aperture_photometry(self.data,
++ self.aperture, method='exact',
++ mask=mask, error=error)
++
++ if not isinstance(self.aperture, (RectangularAperture,
++ RectangularAnnulus)):
++ assert_allclose(table3['aperture_sum'], self.true_flux)
++ assert_allclose(table2['aperture_sum'], table3['aperture_sum'],
++ atol=0.1)
++ assert np.all(table1['aperture_sum'] < table3['aperture_sum'])
++
++ if not isinstance(self.aperture, (RectangularAperture,
++ RectangularAnnulus)):
++ assert_allclose(table3['aperture_sum_err'], true_error)
++ assert_allclose(table2['aperture_sum_err'],
++ table3['aperture_sum_err'], atol=0.1)
++ assert np.all(table1['aperture_sum_err'] < table3['aperture_sum_err'])
++
++
++class TestCircular(BaseTestAperturePhotometry):
++
++ def setup_class(self):
++ self.data = np.ones((40, 40), dtype=np.float)
++ position = (20., 20.)
++ r = 10.
++ self.aperture = CircularAperture(position, r)
++ self.area = np.pi * r * r
++ self.true_flux = self.area
++
++
++class TestCircularArray(BaseTestAperturePhotometry):
++
++ def setup_class(self):
++ self.data = np.ones((40, 40), dtype=np.float)
++ position = ((20., 20.), (25., 25.))
++ r = 10.
++ self.aperture = CircularAperture(position, r)
++ self.area = np.pi * r * r
++ self.area = np.array((self.area, ) * 2)
++ self.true_flux = self.area
++
++
++class TestCircularAnnulus(BaseTestAperturePhotometry):
++
++ def setup_class(self):
++ self.data = np.ones((40, 40), dtype=np.float)
++ position = (20., 20.)
++ r_in = 8.
++ r_out = 10.
++ self.aperture = CircularAnnulus(position, r_in, r_out)
++ self.area = np.pi * (r_out * r_out - r_in * r_in)
++ self.true_flux = self.area
++
++
++class TestCircularAnnulusArray(BaseTestAperturePhotometry):
++
++ def setup_class(self):
++ self.data = np.ones((40, 40), dtype=np.float)
++ position = ((20., 20.), (25., 25.))
++ r_in = 8.
++ r_out = 10.
++ self.aperture = CircularAnnulus(position, r_in, r_out)
++ self.area = np.pi * (r_out * r_out - r_in * r_in)
++ self.area = np.array((self.area, ) * 2)
++ self.true_flux = self.area
++
++
++class TestElliptical(BaseTestAperturePhotometry):
++
++ def setup_class(self):
++ self.data = np.ones((40, 40), dtype=np.float)
++ position = (20., 20.)
++ a = 10.
++ b = 5.
++ theta = -np.pi / 4.
++ self.aperture = EllipticalAperture(position, a, b, theta)
++ self.area = np.pi * a * b
++ self.true_flux = self.area
++
++
++class TestEllipticalAnnulus(BaseTestAperturePhotometry):
++
++ def setup_class(self):
++ self.data = np.ones((40, 40), dtype=np.float)
++ position = (20., 20.)
++ a_in = 5.
++ a_out = 8.
++ b_out = 5.
++ theta = -np.pi / 4.
++ self.aperture = EllipticalAnnulus(position, a_in, a_out, b_out, theta)
++ self.area = (np.pi * (a_out * b_out) -
++ np.pi * (a_in * b_out * a_in / a_out))
++ self.true_flux = self.area
++
++
++class TestRectangularAperture(BaseTestAperturePhotometry):
++
++ def setup_class(self):
++ self.data = np.ones((40, 40), dtype=np.float)
++ position = (20., 20.)
++ h = 5.
++ w = 8.
++ theta = np.pi / 4.
++ self.aperture = RectangularAperture(position, w, h, theta)
++ self.area = h * w
++ self.true_flux = self.area
++
++
++class TestRectangularAnnulus(BaseTestAperturePhotometry):
++
++ def setup_class(self):
++ self.data = np.ones((40, 40), dtype=np.float)
++ position = (20., 20.)
++ h_out = 8.
++ w_in = 8.
++ w_out = 12.
++ h_in = w_in * h_out / w_out
++ theta = np.pi / 8.
++ self.aperture = RectangularAnnulus(position, w_in, w_out, h_out, theta)
++ self.area = h_out * w_out - h_in * w_in
++ self.true_flux = self.area
++
++
++class TestMaskedSkipCircular(BaseTestAperturePhotometry):
++
++ def setup_class(self):
++ self.data = np.ones((40, 40), dtype=np.float)
++ self.mask = np.zeros((40, 40), dtype=bool)
++ self.mask[20, 20] = True
++ position = (20., 20.)
++ r = 10.
++ self.aperture = CircularAperture(position, r)
++ self.area = np.pi * r * r
++ self.true_flux = self.area - 1
++
++
++class BaseTestDifferentData(object):
++
++ def test_basic_circular_aperture_photometry(self):
++ aperture = CircularAperture(self.position, self.radius)
++ table = aperture_photometry(self.data, aperture,
++ method='exact', unit='adu')
++
++ assert_allclose(table['aperture_sum'].value, self.true_flux)
++ assert table['aperture_sum'].unit, self.fluxunit
++
++ assert np.all(table['xcenter'].value ==
++ np.transpose(self.position)[0])
++ assert np.all(table['ycenter'].value ==
++ np.transpose(self.position)[1])
++
++
++class TestInputPrimaryHDU(BaseTestDifferentData):
++
++ def setup_class(self):
++ data = np.ones((40, 40), dtype=np.float)
++ self.data = fits.ImageHDU(data=data)
++ self.data.header['BUNIT'] = 'adu'
++ self.radius = 3
++ self.position = (20, 20)
++ self.true_flux = np.pi * self.radius * self.radius
++ self.fluxunit = u.adu
++
++
++class TestInputHDUList(BaseTestDifferentData):
++
++ def setup_class(self):
++ data0 = np.ones((40, 40), dtype=np.float)
++ data1 = np.empty((40, 40), dtype=np.float)
++ data1.fill(2)
++ self.data = fits.HDUList([fits.ImageHDU(data=data0),
++ fits.ImageHDU(data=data1)])
++ self.radius = 3
++ self.position = (20, 20)
++ # It should stop at the first extension
++ self.true_flux = np.pi * self.radius * self.radius
++
++
++class TestInputHDUDifferentBUNIT(BaseTestDifferentData):
++
++ def setup_class(self):
++ data = np.ones((40, 40), dtype=np.float)
++ self.data = fits.ImageHDU(data=data)
++ self.data.header['BUNIT'] = 'Jy'
++ self.radius = 3
++ self.position = (20, 20)
++ self.true_flux = np.pi * self.radius * self.radius
++ self.fluxunit = u.adu
++
++
++class TestInputNDData(BaseTestDifferentData):
++
++ def setup_class(self):
++ data = np.ones((40, 40), dtype=np.float)
++ self.data = NDData(data, unit=u.adu)
++ self.radius = 3
++ self.position = [(20, 20), (30, 30)]
++ self.true_flux = np.pi * self.radius * self.radius
++ self.fluxunit = u.adu
++
++
++@remote_data
++def test_wcs_based_photometry_to_catalogue():
++ pathcat = get_path('spitzer_example_catalog.xml', location='remote')
++ pathhdu = get_path('spitzer_example_image.fits', location='remote')
++ hdu = fits.open(pathhdu)
++ scale = hdu[0].header['PIXSCAL1']
++
++ catalog = Table.read(pathcat)
++
++ pos_skycoord = SkyCoord(catalog['l'], catalog['b'], frame='galactic')
++
++ photometry_skycoord = aperture_photometry(
++ hdu, SkyCircularAperture(pos_skycoord, 4 * u.arcsec))
++
++ photometry_skycoord_pix = aperture_photometry(
++ hdu, SkyCircularAperture(pos_skycoord, 4. / scale * u.pixel))
++
++ assert_allclose(photometry_skycoord['aperture_sum'],
++ photometry_skycoord_pix['aperture_sum'])
++
++ # Photometric unit conversion is needed to match the catalogue
++ factor = (1.2 * u.arcsec) ** 2 / u.pixel
++ converted_aperture_sum = (photometry_skycoord['aperture_sum'] *
++ factor).to(u.mJy / u.pixel)
++
++ fluxes_catalog = catalog['f4_5'].filled()
++
++ # There shouldn't be large outliers, but some differences is OK, as
++ # fluxes_catalog is based on PSF photometry, etc.
++ assert_allclose(fluxes_catalog, converted_aperture_sum.value, rtol=1e0)
++
++ assert(np.mean(np.fabs(((fluxes_catalog - converted_aperture_sum.value) /
++ fluxes_catalog))) < 0.1)
++
++
++def test_wcs_based_photometry():
++ data = make_4gaussians_image()
++ wcs = make_wcs(data.shape)
++ hdu = make_imagehdu(data, wcs=wcs)
++
++ # hard wired positions in make_4gaussian_image
++ pos_orig_pixel = u.Quantity(([160., 25., 150., 90.],
++ [70., 40., 25., 60.]), unit=u.pixel)
++
++ pos_skycoord = pixel_to_skycoord(pos_orig_pixel[0], pos_orig_pixel[1], wcs)
++
++ pos_skycoord_s = pos_skycoord[2]
++
++ photometry_skycoord_circ = aperture_photometry(
++ hdu, SkyCircularAperture(pos_skycoord, 3 * u.arcsec))
++ photometry_skycoord_circ_2 = aperture_photometry(
++ hdu, SkyCircularAperture(pos_skycoord, 2 * u.arcsec))
++ photometry_skycoord_circ_s = aperture_photometry(
++ hdu, SkyCircularAperture(pos_skycoord_s, 3 * u.arcsec))
++
++ assert_allclose(photometry_skycoord_circ['aperture_sum'][2],
++ photometry_skycoord_circ_s['aperture_sum'])
++
++ photometry_skycoord_circ_ann = aperture_photometry(
++ hdu, SkyCircularAnnulus(pos_skycoord, 2 * u.arcsec, 3 * u.arcsec))
++ photometry_skycoord_circ_ann_s = aperture_photometry(
++ hdu, SkyCircularAnnulus(pos_skycoord_s, 2 * u.arcsec, 3 * u.arcsec))
++
++ assert_allclose(photometry_skycoord_circ_ann['aperture_sum'][2],
++ photometry_skycoord_circ_ann_s['aperture_sum'])
++
++ assert_allclose(photometry_skycoord_circ_ann['aperture_sum'],
++ photometry_skycoord_circ['aperture_sum'] -
++ photometry_skycoord_circ_2['aperture_sum'])
++
++ photometry_skycoord_ell = aperture_photometry(
++ hdu, SkyEllipticalAperture(pos_skycoord, 3 * u.arcsec,
++ 3.0001 * u.arcsec, 45 * u.arcsec))
++ photometry_skycoord_ell_2 = aperture_photometry(
++ hdu, SkyEllipticalAperture(pos_skycoord, 2 * u.arcsec,
++ 2.0001 * u.arcsec, 45 * u.arcsec))
++ photometry_skycoord_ell_s = aperture_photometry(
++ hdu, SkyEllipticalAperture(pos_skycoord_s, 3 * u.arcsec,
++ 3.0001 * u.arcsec, 45 * u.arcsec))
++ photometry_skycoord_ell_ann = aperture_photometry(
++ hdu, SkyEllipticalAnnulus(pos_skycoord, 2 * u.arcsec, 3 * u.arcsec,
++ 3.0001 * u.arcsec, 45 * u.arcsec))
++ photometry_skycoord_ell_ann_s = aperture_photometry(
++ hdu, SkyEllipticalAnnulus(pos_skycoord_s, 2 * u.arcsec, 3 * u.arcsec,
++ 3.0001 * u.arcsec, 45 * u.arcsec))
++
++ assert_allclose(photometry_skycoord_ell['aperture_sum'][2],
++ photometry_skycoord_ell_s['aperture_sum'])
++
++ assert_allclose(photometry_skycoord_ell_ann['aperture_sum'][2],
++ photometry_skycoord_ell_ann_s['aperture_sum'])
++
++ assert_allclose(photometry_skycoord_ell['aperture_sum'],
++ photometry_skycoord_circ['aperture_sum'], rtol=5e-3)
++
++ assert_allclose(photometry_skycoord_ell_ann['aperture_sum'],
++ photometry_skycoord_ell['aperture_sum'] -
++ photometry_skycoord_ell_2['aperture_sum'], rtol=1e-4)
++
++ photometry_skycoord_rec = aperture_photometry(
++ hdu, SkyRectangularAperture(pos_skycoord,
++ 6 * u.arcsec, 6 * u.arcsec,
++ 0 * u.arcsec),
++ method='subpixel', subpixels=20)
++ photometry_skycoord_rec_4 = aperture_photometry(
++ hdu, SkyRectangularAperture(pos_skycoord,
++ 4 * u.arcsec, 4 * u.arcsec,
++ 0 * u.arcsec),
++ method='subpixel', subpixels=20)
++ photometry_skycoord_rec_s = aperture_photometry(
++ hdu, SkyRectangularAperture(pos_skycoord_s,
++ 6 * u.arcsec, 6 * u.arcsec,
++ 0 * u.arcsec),
++ method='subpixel', subpixels=20)
++ photometry_skycoord_rec_ann = aperture_photometry(
++ hdu, SkyRectangularAnnulus(pos_skycoord, 4 * u.arcsec, 6 * u.arcsec,
++ 6 * u.arcsec, 0 * u.arcsec),
++ method='subpixel', subpixels=20)
++ photometry_skycoord_rec_ann_s = aperture_photometry(
++ hdu, SkyRectangularAnnulus(pos_skycoord_s, 4 * u.arcsec, 6 * u.arcsec,
++ 6 * u.arcsec, 0 * u.arcsec),
++ method='subpixel', subpixels=20)
++
++ assert_allclose(photometry_skycoord_rec['aperture_sum'][2],
++ photometry_skycoord_rec_s['aperture_sum'])
++
++ assert np.all(photometry_skycoord_rec['aperture_sum'] >
++ photometry_skycoord_circ['aperture_sum'])
++
++ assert_allclose(photometry_skycoord_rec_ann['aperture_sum'][2],
++ photometry_skycoord_rec_ann_s['aperture_sum'])
++
++ assert_allclose(photometry_skycoord_rec_ann['aperture_sum'],
++ photometry_skycoord_rec['aperture_sum'] -
++ photometry_skycoord_rec_4['aperture_sum'], rtol=1e-4)
++
++
++def test_basic_circular_aperture_photometry_unit():
++ data1 = np.ones((40, 40), dtype=np.float)
++ data2 = u.Quantity(data1, unit=u.adu)
++
++ radius = 3
++ position = (20, 20)
++ true_flux = np.pi * radius * radius
++ unit = u.adu
++
++ table1 = aperture_photometry(data1, CircularAperture(position, radius),
++ unit=unit)
++ table2 = aperture_photometry(data2, CircularAperture(position, radius),
++ unit=unit)
++
++ assert_allclose(table1['aperture_sum'].value, true_flux)
++ assert_allclose(table2['aperture_sum'].value, true_flux)
++ assert table1['aperture_sum'].unit == unit
++ assert table2['aperture_sum'].unit == data2.unit == unit
++
++
++def test_aperture_photometry_with_error_units():
++ """Test aperture_photometry when error has units (see #176)."""
++
++ data1 = np.ones((40, 40), dtype=np.float)
++ data2 = u.Quantity(data1, unit=u.adu)
++ error = u.Quantity(data1, unit=u.adu)
++ radius = 3
++ true_flux = np.pi * radius * radius
++ unit = u.adu
++ position = (20, 20)
++ table1 = aperture_photometry(data2, CircularAperture(position, radius),
++ error=error)
++ assert_allclose(table1['aperture_sum'].value, true_flux)
++ assert_allclose(table1['aperture_sum_err'].value, np.sqrt(true_flux))
++ assert table1['aperture_sum'].unit == unit
++ assert table1['aperture_sum_err'].unit == unit
++
++
++def test_aperture_photometry_inputs_with_mask():
++ """
++ Test that aperture_photometry does not modify the input
++ data or error array when a mask is input.
++ """
++
++ data = np.ones((5, 5))
++ aperture = CircularAperture((2, 2), 2.)
++ mask = np.zeros_like(data, dtype=bool)
++ data[2, 2] = 100. # bad pixel
++ mask[2, 2] = True
++ error = np.sqrt(data)
++ data_in = data.copy()
++ error_in = error.copy()
++ t1 = aperture_photometry(data, aperture, error=error, mask=mask)
++ assert_array_equal(data, data_in)
++ assert_array_equal(error, error_in)
++ assert_allclose(t1['aperture_sum'][0], 11.5663706144)
++ t2 = aperture_photometry(data, aperture)
++ assert_allclose(t2['aperture_sum'][0], 111.566370614)
++
++
++TEST_ELLIPSE_EXACT_APERTURES = [(3.469906, 3.923861394, 3.),
++ (0.3834415188257778, 0.3834415188257778, 0.3)]
++
++
++@pytest.mark.parametrize('x,y,r', TEST_ELLIPSE_EXACT_APERTURES)
++def test_ellipse_exact_grid(x, y, r):
++ """
++ Test elliptical exact aperture photometry on a grid of pixel positions.
++
++ This is a regression test for the bug discovered in this issue:
++ https://github.com/astropy/photutils/issues/198
++ """
++
++ data = np.ones((10, 10))
++
++ aperture = EllipticalAperture((x, y), r, r, 0.)
++ t = aperture_photometry(data, aperture, method='exact')
++ actual = t['aperture_sum'][0] / (np.pi * r ** 2)
++ assert_allclose(actual, 1)
++
++
++@pytest.mark.parametrize('value', [np.nan, np.inf])
++def test_nan_inf_mask(value):
++ """Test that nans and infs are properly masked [267]."""
++
++ data = np.ones((9, 9))
++ mask = np.zeros_like(data, dtype=bool)
++ data[4, 4] = value
++ mask[4, 4] = True
++ radius = 2.
++ aper = CircularAperture((4, 4), radius)
++ tbl = aperture_photometry(data, aper, mask=mask)
++ desired = (np.pi * radius**2) - 1
++ assert_allclose(tbl['aperture_sum'], desired)
++
++
++def test_aperture_partial_overlap():
++ data = np.ones((20, 20))
++ error = np.ones((20, 20))
++ xypos = [(10, 10), (0, 0), (0, 19), (19, 0), (19, 19)]
++ r = 5.
++ aper = CircularAperture(xypos, r=r)
++ tbl = aperture_photometry(data, aper, error=error)
++ assert_allclose(tbl['aperture_sum'][0], np.pi * r ** 2)
++ assert_array_less(tbl['aperture_sum'][1:], np.pi * r ** 2)
++
++ unit = u.MJy / u.sr
++ tbl = aperture_photometry(data * unit, aper, error=error * unit)
++ assert_allclose(tbl['aperture_sum'][0].value, np.pi * r ** 2)
++ assert_array_less(tbl['aperture_sum'][1:].value, np.pi * r ** 2)
++ assert_array_less(tbl['aperture_sum_err'][1:].value, np.pi * r ** 2)
++ assert tbl['aperture_sum'].unit == unit
++ assert tbl['aperture_sum_err'].unit == unit
++
++
++def test_pixel_aperture_repr():
++ aper = CircularAperture((10, 20), r=3.0)
++ a_repr = '<CircularAperture([[10, 20]], r=3.0)>'
++ a_str = 'Aperture: CircularAperture\npositions: [[10, 20]]\nr: 3.0'
++ assert repr(aper) == a_repr
++ assert str(aper) == a_str
++
++ aper = CircularAnnulus((10, 20), r_in=3.0, r_out=5.0)
++ a_repr = '<CircularAnnulus([[10, 20]], r_in=3.0, r_out=5.0)>'
++ a_str = ('Aperture: CircularAnnulus\npositions: [[10, 20]]\nr_in: 3.0\n'
++ 'r_out: 5.0')
++ assert repr(aper) == a_repr
++ assert str(aper) == a_str
++
++ aper = EllipticalAperture((10, 20), a=5.0, b=3.0, theta=15.0)
++ a_repr = '<EllipticalAperture([[10, 20]], a=5.0, b=3.0, theta=15.0)>'
++ a_str = ('Aperture: EllipticalAperture\npositions: [[10, 20]]\n'
++ 'a: 5.0\nb: 3.0\ntheta: 15.0')
++ assert repr(aper) == a_repr
++ assert str(aper) == a_str
++
++ aper = EllipticalAnnulus((10, 20), a_in=4.0, a_out=8.0, b_out=4.0,
++ theta=15.0)
++ a_repr = ('<EllipticalAnnulus([[10, 20]], a_in=4.0, a_out=8.0, b_out='
++ '4.0, theta=15.0)>')
++ a_str = ('Aperture: EllipticalAnnulus\npositions: [[10, 20]]\na_in: '
++ '4.0\na_out: 8.0\nb_out: 4.0\ntheta: 15.0')
++ assert repr(aper) == a_repr
++ assert str(aper) == a_str
++
++ aper = RectangularAperture((10, 20), w=5.0, h=3.0, theta=15.0)
++ a_repr = '<RectangularAperture([[10, 20]], w=5.0, h=3.0, theta=15.0)>'
++ a_str = ('Aperture: RectangularAperture\npositions: [[10, 20]]\n'
++ 'w: 5.0\nh: 3.0\ntheta: 15.0')
++ assert repr(aper) == a_repr
++ assert str(aper) == a_str
++
++ aper = RectangularAnnulus((10, 20), w_in=4.0, w_out=8.0, h_out=4.0,
++ theta=15.0)
++ a_repr = ('<RectangularAnnulus([[10, 20]], w_in=4.0, w_out=8.0, '
++ 'h_out=4.0, theta=15.0)>')
++ a_str = ('Aperture: RectangularAnnulus\npositions: [[10, 20]]\n'
++ 'w_in: 4.0\nw_out: 8.0\nh_out: 4.0\ntheta: 15.0')
++ assert repr(aper) == a_repr
++ assert str(aper) == a_str
++
++
++def test_sky_aperture_repr():
++ s = SkyCoord([1, 2], [3, 4], unit='deg')
++
++ aper = SkyCircularAperture(s, r=3*u.pix)
++ a_repr = ('<SkyCircularAperture(<SkyCoord (ICRS): (ra, dec) in deg\n'
++ ' [( 1., 3.), ( 2., 4.)]>, r=3.0 pix)>')
++ a_str = ('Aperture: SkyCircularAperture\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
++ 'r: 3.0 pix')
++ assert repr(aper) == a_repr
++ assert str(aper) == a_str
++
++ aper = SkyCircularAnnulus(s, r_in=3.*u.pix, r_out=5*u.pix)
++ a_repr = ('<SkyCircularAnnulus(<SkyCoord (ICRS): (ra, dec) in deg\n'
++ ' [( 1., 3.), ( 2., 4.)]>, r_in=3.0 pix, r_out=5.0 pix)>')
++ a_str = ('Aperture: SkyCircularAnnulus\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
++ 'r_in: 3.0 pix\nr_out: 5.0 pix')
++ assert repr(aper) == a_repr
++ assert str(aper) == a_str
++
++ aper = SkyEllipticalAperture(s, a=3*u.pix, b=5*u.pix, theta=15*u.deg)
++ a_repr = ('<SkyEllipticalAperture(<SkyCoord (ICRS): (ra, dec) in '
++ 'deg\n [( 1., 3.), ( 2., 4.)]>, a=3.0 pix, b=5.0 pix,'
++ ' theta=15.0 deg)>')
++ a_str = ('Aperture: SkyEllipticalAperture\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
++ 'a: 3.0 pix\nb: 5.0 pix\ntheta: 15.0 deg')
++ assert repr(aper) == a_repr
++ assert str(aper) == a_str
++
++ aper = SkyEllipticalAnnulus(s, a_in=3*u.pix, a_out=5*u.pix, b_out=3*u.pix,
++ theta=15*u.deg)
++ a_repr = ('<SkyEllipticalAnnulus(<SkyCoord (ICRS): (ra, dec) in '
++ 'deg\n [( 1., 3.), ( 2., 4.)]>, a_in=3.0 pix, '
++ 'a_out=5.0 pix, b_out=3.0 pix, theta=15.0 deg)>')
++ a_str = ('Aperture: SkyEllipticalAnnulus\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
++ 'a_in: 3.0 pix\na_out: 5.0 pix\nb_out: 3.0 pix\n'
++ 'theta: 15.0 deg')
++ assert repr(aper) == a_repr
++ assert str(aper) == a_str
++
++ aper = SkyRectangularAperture(s, w=3*u.pix, h=5*u.pix, theta=15*u.deg)
++ a_repr = ('<SkyRectangularAperture(<SkyCoord (ICRS): (ra, dec) in '
++ 'deg\n [( 1., 3.), ( 2., 4.)]>, w=3.0 pix, h=5.0 pix'
++ ', theta=15.0 deg)>')
++ a_str = ('Aperture: SkyRectangularAperture\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
++ 'w: 3.0 pix\nh: 5.0 pix\ntheta: 15.0 deg')
++ assert repr(aper) == a_repr
++ assert str(aper) == a_str
++
++ aper = SkyRectangularAnnulus(s, w_in=3*u.pix, w_out=3.4*u.pix,
++ h_out=5*u.pix, theta=15*u.deg)
++ a_repr = ('<SkyRectangularAnnulus(<SkyCoord (ICRS): (ra, dec) in deg'
++ '\n [( 1., 3.), ( 2., 4.)]>, w_in=3.0 pix, '
++ 'w_out=3.4 pix, h_out=5.0 pix, theta=15.0 deg)>')
++ a_str = ('Aperture: SkyRectangularAnnulus\npositions: <SkyCoord '
++ '(ICRS): (ra, dec) in deg\n [( 1., 3.), ( 2., 4.)]>\n'
++ 'w_in: 3.0 pix\nw_out: 3.4 pix\nh_out: 5.0 pix\n'
++ 'theta: 15.0 deg')
++ assert repr(aper) == a_repr
++ assert str(aper) == a_str
++
++
++def test_rectangular_bbox():
++ # odd sizes
++ width = 7
++ height = 3
++ a = RectangularAperture((50, 50), w=width, h=height, theta=0)
++ assert a.bounding_boxes[0].shape == (height, width)
++
++ a = RectangularAperture((50.5, 50.5), w=width, h=height, theta=0)
++ assert a.bounding_boxes[0].shape == (height + 1, width + 1)
++
++ a = RectangularAperture((50, 50), w=width, h=height, theta=90.*np.pi/180.)
++ assert a.bounding_boxes[0].shape == (width, height)
++
++ # even sizes
++ width = 8
++ height = 4
++ a = RectangularAperture((50, 50), w=width, h=height, theta=0)
++ assert a.bounding_boxes[0].shape == (height + 1, width + 1)
++
++ a = RectangularAperture((50.5, 50.5), w=width, h=height, theta=0)
++ assert a.bounding_boxes[0].shape == (height, width)
++
++ a = RectangularAperture((50.5, 50.5), w=width, h=height,
++ theta=90.*np.pi/180.)
++ assert a.bounding_boxes[0].shape == (width, height)
++
++
++def test_elliptical_bbox():
++ # integer axes
++ a = 7
++ b = 3
++ ap = EllipticalAperture((50, 50), a=a, b=b, theta=0)
++ assert ap.bounding_boxes[0].shape == (2*b + 1, 2*a + 1)
++
++ ap = EllipticalAperture((50.5, 50.5), a=a, b=b, theta=0)
++ assert ap.bounding_boxes[0].shape == (2*b, 2*a)
++
++ ap = EllipticalAperture((50, 50), a=a, b=b, theta=90.*np.pi/180.)
++ assert ap.bounding_boxes[0].shape == (2*a + 1, 2*b + 1)
++
++ # fractional axes
++ a = 7.5
++ b = 4.5
++ ap = EllipticalAperture((50, 50), a=a, b=b, theta=0)
++ assert ap.bounding_boxes[0].shape == (2*b, 2*a)
++
++ ap = EllipticalAperture((50.5, 50.5), a=a, b=b, theta=0)
++ assert ap.bounding_boxes[0].shape == (2*b + 1, 2*a + 1)
++
++ ap = EllipticalAperture((50, 50), a=a, b=b, theta=90.*np.pi/180.)
++ assert ap.bounding_boxes[0].shape == (2*a, 2*b)
++
++
++def test_to_sky_pixel():
++ data = make_4gaussians_image()
++ wcs = make_wcs(data.shape)
++
++ ap = CircularAperture(((12.3, 15.7), (48.19, 98.14)), r=3.14)
++ ap2 = ap.to_sky(wcs).to_pixel(wcs)
++ assert_allclose(ap.positions, ap2.positions)
++ assert_allclose(ap.r, ap2.r)
++
++ ap = CircularAnnulus(((12.3, 15.7), (48.19, 98.14)), r_in=3.14,
++ r_out=5.32)
++ ap2 = ap.to_sky(wcs).to_pixel(wcs)
++ assert_allclose(ap.positions, ap2.positions)
++ assert_allclose(ap.r_in, ap2.r_in)
++ assert_allclose(ap.r_out, ap2.r_out)
++
++ ap = EllipticalAperture(((12.3, 15.7), (48.19, 98.14)), a=3.14, b=5.32,
++ theta=103.*np.pi/180.)
++ ap2 = ap.to_sky(wcs).to_pixel(wcs)
++ assert_allclose(ap.positions, ap2.positions)
++ assert_allclose(ap.a, ap2.a)
++ assert_allclose(ap.b, ap2.b)
++ assert_allclose(ap.theta, ap2.theta)
++
++ ap = EllipticalAnnulus(((12.3, 15.7), (48.19, 98.14)), a_in=3.14,
++ a_out=15.32, b_out=4.89, theta=103.*np.pi/180.)
++ ap2 = ap.to_sky(wcs).to_pixel(wcs)
++ assert_allclose(ap.positions, ap2.positions)
++ assert_allclose(ap.a_in, ap2.a_in)
++ assert_allclose(ap.a_out, ap2.a_out)
++ assert_allclose(ap.b_out, ap2.b_out)
++ assert_allclose(ap.theta, ap2.theta)
++
++ ap = RectangularAperture(((12.3, 15.7), (48.19, 98.14)), w=3.14, h=5.32,
++ theta=103.*np.pi/180.)
++ ap2 = ap.to_sky(wcs).to_pixel(wcs)
++ assert_allclose(ap.positions, ap2.positions)
++ assert_allclose(ap.w, ap2.w)
++ assert_allclose(ap.h, ap2.h)
++ assert_allclose(ap.theta, ap2.theta)
++
++ ap = RectangularAnnulus(((12.3, 15.7), (48.19, 98.14)), w_in=3.14,
++ w_out=15.32, h_out=4.89, theta=103.*np.pi/180.)
++ ap2 = ap.to_sky(wcs).to_pixel(wcs)
++ assert_allclose(ap.positions, ap2.positions)
++ assert_allclose(ap.w_in, ap2.w_in)
++ assert_allclose(ap.w_out, ap2.w_out)
++ assert_allclose(ap.h_out, ap2.h_out)
++ assert_allclose(ap.theta, ap2.theta)
+diff -Naur photutils-0.4/photutils/background/core.py photutils-0.4.fixed/photutils/background/core.py
+--- photutils-0.4/photutils/background/core.py 2017-10-30 15:38:18.000000000 +0100
++++ photutils-0.4.fixed/photutils/background/core.py 2018-02-14 03:56:07.063522619 +0100
+@@ -477,14 +477,14 @@
+
+ >>> bkgrms_value = bkgrms.calc_background_rms(data)
+ >>> print(bkgrms_value) # doctest: +FLOAT_CMP
+- 28.866070047722118
++ 28.86607004772212
+
+ Alternatively, the background RMS value can be calculated by calling
+ the class instance as a function, e.g.:
+
+ >>> bkgrms_value = bkgrms(data)
+ >>> print(bkgrms_value) # doctest: +FLOAT_CMP
+- 28.866070047722118
++ 28.86607004772212
+ """
+
+ def calc_background_rms(self, data, axis=None):
+@@ -531,14 +531,14 @@
+
+ >>> bkgrms_value = bkgrms.calc_background_rms(data)
+ >>> print(bkgrms_value) # doctest: +FLOAT_CMP
+- 37.065055462640053
++ 37.06505546264005
+
+ Alternatively, the background RMS value can be calculated by calling
+ the class instance as a function, e.g.:
+
+ >>> bkgrms_value = bkgrms(data)
+ >>> print(bkgrms_value) # doctest: +FLOAT_CMP
+- 37.065055462640053
++ 37.06505546264005
+ """
+
+ def calc_background_rms(self, data, axis=None):
+@@ -580,14 +580,14 @@
+
+ >>> bkgrms_value = bkgrms.calc_background_rms(data)
+ >>> print(bkgrms_value) # doctest: +FLOAT_CMP
+- 30.094338485893392
++ 30.09433848589339
+
+ Alternatively, the background RMS value can be calculated by calling
+ the class instance as a function, e.g.:
+
+ >>> bkgrms_value = bkgrms(data)
+ >>> print(bkgrms_value) # doctest: +FLOAT_CMP
+- 30.094338485893392
++ 30.09433848589339
+ """
+
+ def __init__(self, c=9.0, M=None, **kwargs):
+diff -Naur photutils-0.4/photutils/datasets/make.py photutils-0.4.fixed/photutils/datasets/make.py
+--- photutils-0.4/photutils/datasets/make.py 2017-10-30 15:38:18.000000000 +0100
++++ photutils-0.4.fixed/photutils/datasets/make.py 2018-02-14 03:56:07.063522619 +0100
+@@ -214,14 +214,16 @@
+ >>> param_ranges = OrderedDict(param_ranges)
+ >>> sources = make_random_models_table(n_sources, param_ranges,
+ ... random_state=12345)
++ >>> for col in sources.colnames:
++ ... sources[col].info.format = '%.8g' # for consistent table output
+ >>> print(sources)
+- amplitude x_mean y_mean ... y_stddev theta
+- ------------- ------------- ------------- ... ------------- --------------
+- 964.808046409 297.77235149 224.314442781 ... 3.56990131158 2.29238586176
+- 658.187777291 482.257259868 288.392020822 ... 3.86981448325 3.12278892062
+- 591.959405839 326.588548436 2.51648938247 ... 2.87039602888 2.12646148032
+- 602.280139277 374.453318767 31.9333130093 ... 2.30233871016 2.48444221236
+- 783.862514541 326.784935426 89.6111141308 ... 2.75857842354 0.536942976674
++ amplitude x_mean y_mean x_stddev y_stddev theta
++ --------- --------- --------- --------- --------- ----------
++ 964.80805 297.77235 224.31444 3.6256447 3.5699013 2.2923859
++ 658.18778 482.25726 288.39202 4.2392502 3.8698145 3.1227889
++ 591.95941 326.58855 2.5164894 4.4887037 2.870396 2.1264615
++ 602.28014 374.45332 31.933313 4.8585904 2.3023387 2.4844422
++ 783.86251 326.78494 89.611114 3.8947414 2.7585784 0.53694298
+ """
+
+ prng = check_random_state(random_state)
+@@ -302,14 +304,16 @@
+ >>> param_ranges = OrderedDict(param_ranges)
+ >>> sources = make_random_gaussians_table(n_sources, param_ranges,
+ ... random_state=12345)
++ >>> for col in sources.colnames:
++ ... sources[col].info.format = '%.8g' # for consistent table output
+ >>> print(sources)
+- amplitude x_mean y_mean ... y_stddev theta
+- ------------- ------------- ------------- ... ------------- --------------
+- 964.808046409 297.77235149 224.314442781 ... 3.56990131158 2.29238586176
+- 658.187777291 482.257259868 288.392020822 ... 3.86981448325 3.12278892062
+- 591.959405839 326.588548436 2.51648938247 ... 2.87039602888 2.12646148032
+- 602.280139277 374.453318767 31.9333130093 ... 2.30233871016 2.48444221236
+- 783.862514541 326.784935426 89.6111141308 ... 2.75857842354 0.536942976674
++ amplitude x_mean y_mean x_stddev y_stddev theta
++ --------- --------- --------- --------- --------- ----------
++ 964.80805 297.77235 224.31444 3.6256447 3.5699013 2.2923859
++ 658.18778 482.25726 288.39202 4.2392502 3.8698145 3.1227889
++ 591.95941 326.58855 2.5164894 4.4887037 2.870396 2.1264615
++ 602.28014 374.45332 31.933313 4.8585904 2.3023387 2.4844422
++ 783.86251 326.78494 89.611114 3.8947414 2.7585784 0.53694298
+
+ To specifying the flux range instead of the amplitude range:
+
+@@ -322,14 +326,16 @@
+ >>> param_ranges = OrderedDict(param_ranges)
+ >>> sources = make_random_gaussians_table(n_sources, param_ranges,
+ ... random_state=12345)
++ >>> for col in sources.colnames:
++ ... sources[col].info.format = '%.8g' # for consistent table output
+ >>> print(sources)
+- flux x_mean y_mean ... theta amplitude
+- ------------- ------------- ------------- ... -------------- -------------
+- 964.808046409 297.77235149 224.314442781 ... 2.29238586176 11.8636845806
+- 658.187777291 482.257259868 288.392020822 ... 3.12278892062 6.38543882684
+- 591.959405839 326.588548436 2.51648938247 ... 2.12646148032 7.31222089567
+- 602.280139277 374.453318767 31.9333130093 ... 2.48444221236 8.56917814506
+- 783.862514541 326.784935426 89.6111141308 ... 0.536942976674 11.6117069638
++ flux x_mean y_mean x_stddev y_stddev theta amplitude
++ --------- --------- --------- --------- --------- ---------- ---------
++ 964.80805 297.77235 224.31444 3.6256447 3.5699013 2.2923859 11.863685
++ 658.18778 482.25726 288.39202 4.2392502 3.8698145 3.1227889 6.3854388
++ 591.95941 326.58855 2.5164894 4.4887037 2.870396 2.1264615 7.3122209
++ 602.28014 374.45332 31.933313 4.8585904 2.3023387 2.4844422 8.5691781
++ 783.86251 326.78494 89.611114 3.8947414 2.7585784 0.53694298 11.611707
+
+ Note that in this case the output table contains both a flux and
+ amplitude column. The flux column will be ignored when generating
+@@ -694,10 +700,10 @@
+ >>> from photutils.datasets import make_wcs
+ >>> shape = (100, 100)
+ >>> wcs = make_wcs(shape)
+- >>> print(wcs.wcs.crpix)
+- [ 50. 50.]
+- >>> print(wcs.wcs.crval)
+- [ 197.8925 -1.36555556]
++ >>> print(wcs.wcs.crpix) # doctest: +FLOAT_CMP
++ [50. 50.]
++ >>> print(wcs.wcs.crval) # doctest: +FLOAT_CMP
++ [197.8925 -1.36555556]
+ """
+
+ wcs = WCS(naxis=2)
+diff -Naur photutils-0.4/photutils/detection/tests/test_findstars.py photutils-0.4.fixed/photutils/detection/tests/test_findstars.py
+--- photutils-0.4/photutils/detection/tests/test_findstars.py 2017-10-30 15:38:18.000000000 +0100
++++ photutils-0.4.fixed/photutils/detection/tests/test_findstars.py 2018-02-14 03:56:07.061522588 +0100
+@@ -46,8 +46,10 @@
+ '.txt'.format(threshold, fwhm))
+ datafn = op.join(op.dirname(op.abspath(__file__)), 'data', datafn)
+ t_ref = Table.read(datafn, format='ascii')
+- assert_allclose(np.array(t).astype(np.float),
+- np.array(t_ref).astype(np.float))
++
++ assert t.colnames == t_ref.colnames
++ for col in t.colnames:
++ assert_allclose(t[col], t_ref[col])
+
+ def test_daofind_include_border(self):
+ starfinder = DAOStarFinder(threshold=10, fwhm=2, sigma_radius=1.5,
+@@ -100,8 +102,10 @@
+ '.txt'.format(threshold, fwhm))
+ datafn = op.join(op.dirname(op.abspath(__file__)), 'data', datafn)
+ t_ref = Table.read(datafn, format='ascii')
+- assert_allclose(np.array(t).astype(np.float),
+- np.array(t_ref).astype(np.float))
++
++ assert t.colnames == t_ref.colnames
++ for col in t.colnames:
++ assert_allclose(t[col], t_ref[col])
+
+ def test_irafstarfind_nosources(self):
+ data = np.ones((3, 3))
+diff -Naur photutils-0.4/photutils/segmentation/properties.py photutils-0.4.fixed/photutils/segmentation/properties.py
+--- photutils-0.4/photutils/segmentation/properties.py 2017-10-30 15:38:18.000000000 +0100
++++ photutils-0.4.fixed/photutils/segmentation/properties.py 2018-02-14 03:56:07.062522603 +0100
+@@ -1162,11 +1162,11 @@
+ >>> import numpy as np
+ >>> from photutils import SegmentationImage, source_properties
+ >>> image = np.arange(16.).reshape(4, 4)
+- >>> print(image)
+- [[ 0. 1. 2. 3.]
+- [ 4. 5. 6. 7.]
+- [ 8. 9. 10. 11.]
+- [ 12. 13. 14. 15.]]
++ >>> print(image) # doctest: +SKIP
++ [[ 0. 1. 2. 3.]
++ [ 4. 5. 6. 7.]
++ [ 8. 9. 10. 11.]
++ [12. 13. 14. 15.]]
+ >>> segm = SegmentationImage([[1, 1, 0, 0],
+ ... [1, 0, 0, 2],
+ ... [0, 0, 2, 2],
+@@ -1179,11 +1179,11 @@
+ >>> props[0].id # id corresponds to segment label number
+ 1
+ >>> props[0].centroid # doctest: +FLOAT_CMP
+- <Quantity [ 0.8, 0.2] pix>
++ <Quantity [0.8, 0.2] pix>
+ >>> props[0].source_sum # doctest: +FLOAT_CMP
+ 5.0
+ >>> props[0].area # doctest: +FLOAT_CMP
+- <Quantity 3.0 pix2>
++ <Quantity 3. pix2>
+ >>> props[0].max_value # doctest: +FLOAT_CMP
+ 4.0
+
+@@ -1193,11 +1193,11 @@
+ >>> props[1].id # id corresponds to segment label number
+ 2
+ >>> props[1].centroid # doctest: +FLOAT_CMP
+- <Quantity [ 2.36363636, 2.09090909] pix>
++ <Quantity [2.36363636, 2.09090909] pix>
+ >>> props[1].perimeter # doctest: +FLOAT_CMP
+- <Quantity 5.414213562373095 pix>
++ <Quantity 5.41421356 pix>
+ >>> props[1].orientation # doctest: +FLOAT_CMP
+- <Quantity -0.7417593069227176 rad>
++ <Quantity -0.74175931 rad>
+ """
+
+ if not isinstance(segment_img, SegmentationImage):
+@@ -1412,11 +1412,11 @@
+ >>> import numpy as np
+ >>> from photutils import source_properties
+ >>> image = np.arange(16.).reshape(4, 4)
+- >>> print(image)
+- [[ 0. 1. 2. 3.]
+- [ 4. 5. 6. 7.]
+- [ 8. 9. 10. 11.]
+- [ 12. 13. 14. 15.]]
++ >>> print(image) # doctest: +SKIP
++ [[ 0. 1. 2. 3.]
++ [ 4. 5. 6. 7.]
++ [ 8. 9. 10. 11.]
++ [12. 13. 14. 15.]]
+ >>> segm = SegmentationImage([[1, 1, 0, 0],
+ ... [1, 0, 0, 2],
+ ... [0, 0, 2, 2],
+diff -Naur photutils-0.4/photutils/utils/interpolation.py photutils-0.4.fixed/photutils/utils/interpolation.py
+--- photutils-0.4/photutils/utils/interpolation.py 2017-10-30 17:14:28.000000000 +0100
++++ photutils-0.4.fixed/photutils/utils/interpolation.py 2018-02-14 03:56:07.062522603 +0100
+@@ -95,15 +95,15 @@
+ >>> f(0.4) # doctest: +FLOAT_CMP
+ 0.38862424043228855
+ >>> np.sin(0.4) # doctest: +FLOAT_CMP
+- 0.38941834230865052
++ 0.3894183423086505
+
+ >>> xi = np.random.random(4)
+- >>> xi
+- array([ 0.51312815, 0.66662455, 0.10590849, 0.13089495])
+- >>> f(xi) # doctest: +FLOAT_CMP
+- array([ 0.49086423, 0.62647862, 0.1056854 , 0.13048335])
+- >>> np.sin(xi)
+- array([ 0.49090493, 0.6183367 , 0.10571061, 0.13052149])
++ >>> xi # doctest: +FLOAT_CMP
++ array([0.51312815, 0.66662455, 0.10590849, 0.13089495])
++ >>> f(xi) # doctest: +FLOAT_CMP
++ array([0.49086423, 0.62647862, 0.1056854 , 0.13048335])
++ >>> np.sin(xi) # doctest: +FLOAT_CMP
++ array([0.49090493, 0.6183367 , 0.10571061, 0.13052149])
+
+ NOTE: In the last example, ``xi`` may be a ``Nx1`` array instead of
+ a 1D vector.
+@@ -113,10 +113,10 @@
+ >>> pos = np.random.rand(1000, 2)
+ >>> val = np.sin(pos[:, 0] + pos[:, 1])
+ >>> f = idw(pos, val)
+- >>> f([0.5, 0.6]) # doctest: +FLOAT_CMP
+- 0.89312649587405657
+- >>> np.sin(0.5 + 0.6)
+- 0.89120736006143542
++ >>> f([0.5, 0.6]) # doctest: +FLOAT_CMP
++ 0.8931264958740567
++ >>> np.sin(0.5 + 0.6) # doctest: +FLOAT_CMP
++ 0.8912073600614354
+ """
+
+ def __init__(self, coordinates, values, weights=None, leafsize=10):
diff --git a/python-photutils.spec b/python-photutils.spec
index 134523f..adffc2f 100644
--- a/python-photutils.spec
+++ b/python-photutils.spec
@@ -12,6 +12,9 @@ Source0: https://pypi.io/packages/source/p/photutils/%{srcname}-%{version}.tar.g
# Use system copy of astropy-helpers
Patch0: python-photutils-Use-astropy_helpers-provided-by-the-system.patch
+# Fixes for numpy 1.14, rebased version of https://github.com/astropy/photutils/pull/639
+Patch1: python-photutils-fixes-for-numpy-1.14.patch
+
BuildRequires: python2-devel python3-devel
%description
@@ -128,7 +131,7 @@ popd
%changelog
* Wed Feb 14 2018 Christian Dersch <lupinix@mailbox.org> - 0.4-3
-- rebuilt
+- Added numpy 1.14 fix https://github.com/astropy/photutils/pull/639
* Fri Feb 09 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.4-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-06-26 3:41 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-26 3:41 [rpms/python-photutils] epel10: Added numpy 1.14 fix https://github.com/astropy/photutils/pull/639 Christian Dersch
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox