roman-snpit-snappl 0.5.0__tar.gz → 0.7.0__tar.gz

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 roman-snpit-snappl might be problematic. Click here for more details.

Files changed (76) hide show
  1. {roman_snpit_snappl-0.5.0/roman_snpit_snappl.egg-info → roman_snpit_snappl-0.7.0}/PKG-INFO +1 -1
  2. roman_snpit_snappl-0.7.0/changes/31.feature.rst +1 -0
  3. roman_snpit_snappl-0.7.0/changes/35.snappl.rst +1 -0
  4. roman_snpit_snappl-0.7.0/changes/36.snappl.rst +1 -0
  5. roman_snpit_snappl-0.7.0/changes/37.snappl.rst +1 -0
  6. roman_snpit_snappl-0.7.0/changes/40.snappl.rst +1 -0
  7. roman_snpit_snappl-0.7.0/experimentation/README.md +1 -0
  8. roman_snpit_snappl-0.7.0/experimentation/play_with_photutils.py +118 -0
  9. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0/roman_snpit_snappl.egg-info}/PKG-INFO +1 -1
  10. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/roman_snpit_snappl.egg-info/SOURCES.txt +8 -0
  11. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/snappl/_version.py +2 -2
  12. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/snappl/image.py +60 -0
  13. roman_snpit_snappl-0.7.0/snappl/psf.py +1401 -0
  14. roman_snpit_snappl-0.7.0/snappl/sed.py +168 -0
  15. roman_snpit_snappl-0.5.0/snappl/psf.py +0 -438
  16. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/.cruft.json +0 -0
  17. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/.github/CODEOWNERS +0 -0
  18. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md +0 -0
  19. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md +0 -0
  20. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/.github/ISSUE_TEMPLATE/PR_TEMPLATE.md +0 -0
  21. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/.github/dependabot.yml +0 -0
  22. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/.github/labeler.yml +0 -0
  23. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/.github/workflows/changelog.yml +0 -0
  24. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/.github/workflows/run_labeler.yml +0 -0
  25. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/.github/workflows/run_snappl_tests.yml +0 -0
  26. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/.github/workflows/sphinx-deploy.yml +0 -0
  27. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/.github/workflows/sub_package_update.yml +0 -0
  28. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/.gitignore +0 -0
  29. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/.pre-commit-config.yaml +0 -0
  30. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/CHANGES.rst +0 -0
  31. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/CITATION.cff +0 -0
  32. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/CODE_OF_CONDUCT.md +0 -0
  33. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/CONTRIBUTING.md +0 -0
  34. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/LICENSE +0 -0
  35. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/MANIFEST.in +0 -0
  36. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/README.rst +0 -0
  37. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/changes/.gitkeep +0 -0
  38. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/changes/10.snappl.rst +0 -0
  39. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/changes/13.bugfix.rst +0 -0
  40. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/changes/14.snappl.rst +0 -0
  41. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/changes/15.feature.rst +0 -0
  42. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/changes/16.feature.rst +0 -0
  43. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/changes/18.feature.rst +0 -0
  44. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/changes/20.bugfix.rst +0 -0
  45. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/changes/23.snappl.rst +0 -0
  46. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/changes/26.feature.rst +0 -0
  47. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/changes/3.snappl.rst +0 -0
  48. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/changes/5.snappl.rst +0 -0
  49. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/changes/8.snappl.rst +0 -0
  50. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/changes/9.snappl.rst +0 -0
  51. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/codespell-ignore.txt +0 -0
  52. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/docs/Makefile +0 -0
  53. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/docs/_static/logo_black_filled.png +0 -0
  54. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/docs/changes.rst +0 -0
  55. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/docs/conf.py +0 -0
  56. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/docs/index.rst +0 -0
  57. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/docs/installation.rst +0 -0
  58. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/docs/make.bat +0 -0
  59. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/docs/usage.rst +0 -0
  60. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/licenses/.DS_Store +0 -0
  61. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/licenses/LICENSE.rst +0 -0
  62. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/licenses/README.rst +0 -0
  63. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/licenses/TEMPLATE_LICENSE.rst +0 -0
  64. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/pyproject.toml +0 -0
  65. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/roman_snpit_snappl.egg-info/dependency_links.txt +0 -0
  66. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/roman_snpit_snappl.egg-info/not-zip-safe +0 -0
  67. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/roman_snpit_snappl.egg-info/requires.txt +0 -0
  68. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/roman_snpit_snappl.egg-info/top_level.txt +0 -0
  69. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/setup.cfg +0 -0
  70. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/setup.py +0 -0
  71. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/snappl/__init__.py +0 -0
  72. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/snappl/_dev/__init__.py +0 -0
  73. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/snappl/_dev/scm_version.py +0 -0
  74. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/snappl/data/README.rst +0 -0
  75. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/snappl/wcs.py +0 -0
  76. {roman_snpit_snappl-0.5.0 → roman_snpit_snappl-0.7.0}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: roman_snpit_snappl
3
- Version: 0.5.0
3
+ Version: 0.7.0
4
4
  Summary: Photometry utilities for the Roman SNPIT
5
5
  Author: Roman Supernove Project Infrastructure Team
6
6
  Maintainer-email: Roman SN PIT <raknop@lbl.gov>
@@ -0,0 +1 @@
1
+ Offcenter PSFs in get_stamp(); test for ou24PSF; photutilsImagePSF
@@ -0,0 +1 @@
1
+ photon ops now actually turns off
@@ -0,0 +1 @@
1
+ created OU24 SED Collection object
@@ -0,0 +1 @@
1
+ Added the non-slow ou24PSF class
@@ -0,0 +1 @@
1
+ Added manual fits image and test
@@ -0,0 +1 @@
1
+ This directory is for test scripts and such that aren't really part of the snappl package, but that might be useful to archive for future reference.
@@ -0,0 +1,118 @@
1
+ import numpy as np
2
+
3
+ import astropy.table
4
+ import photutils.psf
5
+
6
+
7
+ # You probably want stampsize = 2 * 5 * 2√(2ln2) * max(sigmax,sigmay)
8
+ def make_gaussian_psf( oversamp=3, sigmax=1.2, sigmay=None, stampsize=None, x0=511, y0=511 ):
9
+ if oversamp % 2 != 1:
10
+ raise ValueError( "Please use an odd oversampling factor." )
11
+
12
+ sigmay = sigmax if sigmay is None else sigmay
13
+
14
+ # Default to a stamp size of 2 * 5 FHWMs (so "radius" 5 FWHM)
15
+ if stampsize is None:
16
+ stampsize = int( np.ceil( 10 * 2.35482 * max( sigmax, sigmay ) ) )
17
+ stampsize += 1 if stampsize % 2 ==0 else 0
18
+ if stampsize % 2 != 1:
19
+ raise ValueError( "stampsize must be odd" )
20
+
21
+ oversampsize = oversamp * stampsize
22
+ ctr = oversampsize // 2
23
+ xvals = np.arange( -ctr, ctr+1 )
24
+ yvals = np.arange( -ctr, ctr+1 )
25
+ ovsigmax = oversamp * sigmax
26
+ ovsigmay = oversamp * sigmay
27
+ data = np.exp( -( xvals[np.newaxis,:]**2 / ( 2. * ovsigmax**2 ) +
28
+ yvals[:,np.newaxis]**2 / ( 2. * ovsigmay**2 ) ) )
29
+ # photutils expects an oversampled PSF to be normalized like this:
30
+ data /= data.sum() / ( oversamp**2 )
31
+
32
+ psf = photutils.psf.ImagePSF( data, flux=1, x_0=x0, y_0=y0, oversampling=oversamp )
33
+
34
+ return psf
35
+
36
+
37
+ def make_fake_image( skynoise=10., starflux=100000., nx=1024, ny=1024, x=511, y=511,
38
+ oversamp=3, sigmax=1.2, sigmay=None, stampsize=None ):
39
+ rng = np.random.default_rng()
40
+ image = rng.normal( scale=skynoise, size=(ny, nx) )
41
+
42
+ xc = int( np.floor( x + 0.5 ) )
43
+ yc = int( np.floor( y + 0.5 ) )
44
+
45
+ psf = make_gaussian_psf( oversamp=oversamp, sigmax=sigmax, sigmay=sigmay, stampsize=stampsize, x0=x, y0=y )
46
+ xmin = -( stampsize // 2 ) + xc
47
+ xmax = xmin + stampsize
48
+ ymin = -( stampsize // 2 ) + yc
49
+ ymax = ymin + stampsize
50
+ # WORRY : did I get the x, y order right?
51
+ xvals, yvals = np.meshgrid( np.arange( xmin, xmax ), np.arange( ymin, ymax ) )
52
+ # Not adding poisson noise to our PSF; deal
53
+ image[ ymin:ymax, xmin:xmax ] += psf( xvals, yvals ) * starflux
54
+
55
+ return image, psf
56
+
57
+
58
+ # **********************************************************************
59
+ # Actual experiments
60
+
61
+ # Have a plenty-sampled PSF with a sigma of 1.2, stampsize 29, oversampling by 3)
62
+ psf = make_gaussian_psf( oversamp=3, sigmax=1.2, stampsize=29, x0=511, y0=511 )
63
+ xvals = np.arange( 511 - (29//2), 511 + (29//2) + 1 )
64
+ yvals = np.arange( 511 - (29//2), 511 + (29//2) + 1 )
65
+ xvals, yvals = np.meshgrid( xvals, yvals )
66
+ print( f"1.2-sigma PSF clip sums to {psf( xvals, yvals ).sum()}" )
67
+
68
+ # Have a PSF with a 1-pixel FWHM (so σ = 1/(2√(2ln2)) = 0.42 ), stampsize 11, oversamped 5x
69
+ psf = make_gaussian_psf( oversamp=5, sigmax=0.42, stampsize=11, x0=511, y0=511 )
70
+ xvals = np.arange( 511 - (29//2), 511 + (29//2) + 1 )
71
+ yvals = np.arange( 511 - (29//2), 511 + (29//2) + 1 )
72
+ xvals, yvals = np.meshgrid( xvals, yvals )
73
+ print( f"0.42-sigma PSF clip sums to {psf( xvals, yvals ).sum()}" )
74
+
75
+
76
+ # Now let's try some PSF photometry and see how it does
77
+ # We are always going to use sky noise 10, and just not bother
78
+ # with star poisson noise for now (because we're naughty)
79
+
80
+ # First with the happy big star
81
+ image, psf = make_fake_image( oversamp=3, sigmax=1.2, stampsize=29 )
82
+ noiseim = np.full_like( image, 10. )
83
+ fit_shape = ( 15, 15 )
84
+ photor = photutils.psf.PSFPhotometry( psf, fit_shape )
85
+ phot = photor( image, error=noiseim,
86
+ init_params=astropy.table.Table( { 'x_init': [510.5], 'y_init': [513.], 'flux_init': [95000] } ) )
87
+ print( f"Fit flux of 100000-flux star for sigma = 1.2: {phot['flux_fit'][0]}; "
88
+ f"(x,y)=({phot['x_fit'][0]}, {phot['y_fit'][0]}" )
89
+
90
+ # Now with a little star
91
+ image, psf = make_fake_image( oversamp=5, sigmax=0.42, stampsize=11 )
92
+ fit_shape = ( 7, 7 )
93
+ photor = photutils.psf.PSFPhotometry( psf, fit_shape )
94
+ phot = photor( image, error=noiseim,
95
+ init_params=astropy.table.Table( { 'x_init': [511.2], 'y_init': [510.9], 'flux_init': [120000] } ) )
96
+ print( f"Fit flux of 100000-flux star for sigma = 0.42: {phot['flux_fit'][0]}; "
97
+ f"(x,y)=({phot['x_fit'][0]}, {phot['y_fit'][0]}" )
98
+
99
+
100
+ # RESULTS OF A RUN:
101
+ # root@655734bb3457:/snappl/experimentation# python play_with_photutils.py
102
+ # 1.2-sigma PSF clip sums to 1.0000000000018092
103
+ # 0.42-sigma PSF clip sums to 1.1267689222010988
104
+ # Fit flux of 100000-flux star for sigma = 1.2: 99833.32184334665; (x,y)=(511.00130567398907, 510.99895105013127
105
+ # Fit flux of 100000-flux star for sigma = 0.42: 100005.90585339173; (x,y)=(511.0002593061244, 511.0001099684552
106
+ #
107
+ # CONCLUSION:
108
+ #
109
+ # For PSFs whose FWHM is less than ~2 pixels on the original
110
+ # image, the stamps you get from the __call__ method of a photutils
111
+ # ImagePSF are not properly normalize. (Interestingly, they are too big
112
+ # by the same factor that lanczos4 interpolation gives....) However,
113
+ # photutils PSFPhotometry works in such a way that it takes this into
114
+ # account (...or just doesn't use __call__) and produces reliable results.
115
+ #
116
+ # Which is all well and good if you just want to use PSFPhotometry, but
117
+ # if you need thumbnails for other purposes (e.g. schene modelling),
118
+ # that is very sad.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: roman_snpit_snappl
3
- Version: 0.5.0
3
+ Version: 0.7.0
4
4
  Summary: Photometry utilities for the Roman SNPIT
5
5
  Author: Roman Supernove Project Infrastructure Team
6
6
  Maintainer-email: Roman SN PIT <raknop@lbl.gov>
@@ -34,6 +34,11 @@ changes/20.bugfix.rst
34
34
  changes/23.snappl.rst
35
35
  changes/26.feature.rst
36
36
  changes/3.snappl.rst
37
+ changes/31.feature.rst
38
+ changes/35.snappl.rst
39
+ changes/36.snappl.rst
40
+ changes/37.snappl.rst
41
+ changes/40.snappl.rst
37
42
  changes/5.snappl.rst
38
43
  changes/8.snappl.rst
39
44
  changes/9.snappl.rst
@@ -45,6 +50,8 @@ docs/installation.rst
45
50
  docs/make.bat
46
51
  docs/usage.rst
47
52
  docs/_static/logo_black_filled.png
53
+ experimentation/README.md
54
+ experimentation/play_with_photutils.py
48
55
  licenses/.DS_Store
49
56
  licenses/LICENSE.rst
50
57
  licenses/README.rst
@@ -59,6 +66,7 @@ snappl/__init__.py
59
66
  snappl/_version.py
60
67
  snappl/image.py
61
68
  snappl/psf.py
69
+ snappl/sed.py
62
70
  snappl/wcs.py
63
71
  snappl/_dev/__init__.py
64
72
  snappl/_dev/scm_version.py
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.5.0'
21
- __version_tuple__ = version_tuple = (0, 5, 0)
20
+ __version__ = version = '0.7.0'
21
+ __version_tuple__ = version_tuple = (0, 7, 0)
@@ -386,6 +386,42 @@ class FITSImage( Numpy2DImage ):
386
386
  self._wcs = GalsimWCS.from_header( hdr )
387
387
  return self._wcs
388
388
 
389
+ def get_data(self, which="all"):
390
+ if self._is_cutout:
391
+ raise RuntimeError(
392
+ "get_data called on a cutout image, this will return the ORIGINAL UNCUT image. Currently not supported."
393
+ )
394
+ if which not in Image.data_array_list:
395
+ raise ValueError(f"Unknown which {which}, must be all, data, noise, or flags")
396
+
397
+ if (which == "all"):
398
+ if (self._data is not None) and (self._noise is not None) and (self._flags is not None):
399
+ return [self._data, self._noise, self._flags]
400
+ else:
401
+ raise RuntimeError(
402
+ f"get_data called with which='all', but not all data arrays are set. "
403
+ f"Data: {self._data is not None}, Noise: {self._noise is not None},"
404
+ f" Flags: {self._flags is not None}"
405
+ )
406
+
407
+ if (which == "data"):
408
+ if (self._data is not None):
409
+ return [self._data]
410
+ else:
411
+ raise RuntimeError("get_data called with which='data', but data is not set.")
412
+
413
+ if (which == "noise"):
414
+ if (self._noise is not None):
415
+ return [self._noise]
416
+ else:
417
+ raise RuntimeError("get_data called with which='noise', but noise is not set.")
418
+
419
+ if (which == "flags"):
420
+ if (self._flags is not None):
421
+ return [self._flags]
422
+ else:
423
+ raise RuntimeError("get_data called with which='flags', but flags are not set.")
424
+
389
425
  def get_cutout(self, x, y, xsize, ysize=None):
390
426
  """Creates a new snappl image object that is a cutout of the original image, at a location in pixel-space.
391
427
 
@@ -554,3 +590,27 @@ class OpenUniverse2024FITSImage( FITSImage ):
554
590
  def _get_zeropoint( self ):
555
591
  header = self._get_header()
556
592
  return galsim.roman.getBandpasses()[self.band].zeropoint + header['ZPTMAG']
593
+
594
+
595
+ class ManualFITSImage(FITSImage):
596
+ def __init__(self, header, data, noise=None, flags=None, path = None, exposure = None, sca = None, *args, **kwargs):
597
+
598
+ self._data = data
599
+ self._noise = noise
600
+ self._flags = flags
601
+ self._header = header
602
+ self._wcs = None
603
+ self._is_cutout = False
604
+ self._image_shape = None
605
+
606
+ self.inputs = types.SimpleNamespace()
607
+ self.inputs.path = None
608
+ self.inputs.exposure = None
609
+ self.inputs.sca = None
610
+
611
+ def _get_header(self):
612
+ """Get the header of the image."""
613
+ if self._header is None:
614
+ raise RuntimeError("Header is not set for ManualFITSImage.")
615
+ return self._header
616
+