roman-snpit-snappl 0.6.0__tar.gz → 0.8.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.
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.github/workflows/run_snappl_tests.yml +12 -1
- {roman_snpit_snappl-0.6.0/roman_snpit_snappl.egg-info → roman_snpit_snappl-0.8.0}/PKG-INFO +1 -1
- roman_snpit_snappl-0.8.0/changes/35.snappl.rst +1 -0
- roman_snpit_snappl-0.8.0/changes/36.snappl.rst +1 -0
- roman_snpit_snappl-0.8.0/changes/37.snappl.rst +1 -0
- roman_snpit_snappl-0.8.0/changes/40.snappl.rst +1 -0
- roman_snpit_snappl-0.8.0/changes/41.snappl.rst +1 -0
- roman_snpit_snappl-0.8.0/changes/43.snappl.rst +1 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0/roman_snpit_snappl.egg-info}/PKG-INFO +1 -1
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/roman_snpit_snappl.egg-info/SOURCES.txt +7 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/snappl/_version.py +16 -3
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/snappl/image.py +60 -1
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/snappl/psf.py +167 -10
- roman_snpit_snappl-0.8.0/snappl/sed.py +169 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.cruft.json +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.github/CODEOWNERS +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.github/ISSUE_TEMPLATE/PR_TEMPLATE.md +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.github/dependabot.yml +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.github/labeler.yml +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.github/workflows/changelog.yml +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.github/workflows/run_labeler.yml +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.github/workflows/sphinx-deploy.yml +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.github/workflows/sub_package_update.yml +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.gitignore +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.pre-commit-config.yaml +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/CHANGES.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/CITATION.cff +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/CODE_OF_CONDUCT.md +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/CONTRIBUTING.md +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/LICENSE +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/MANIFEST.in +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/README.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/changes/.gitkeep +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/changes/10.snappl.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/changes/13.bugfix.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/changes/14.snappl.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/changes/15.feature.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/changes/16.feature.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/changes/18.feature.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/changes/20.bugfix.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/changes/23.snappl.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/changes/26.feature.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/changes/3.snappl.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/changes/31.feature.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/changes/5.snappl.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/changes/8.snappl.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/changes/9.snappl.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/codespell-ignore.txt +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/docs/Makefile +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/docs/_static/logo_black_filled.png +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/docs/changes.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/docs/conf.py +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/docs/index.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/docs/installation.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/docs/make.bat +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/docs/usage.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/experimentation/README.md +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/experimentation/play_with_photutils.py +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/licenses/.DS_Store +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/licenses/LICENSE.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/licenses/README.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/licenses/TEMPLATE_LICENSE.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/pyproject.toml +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/roman_snpit_snappl.egg-info/dependency_links.txt +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/roman_snpit_snappl.egg-info/not-zip-safe +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/roman_snpit_snappl.egg-info/requires.txt +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/roman_snpit_snappl.egg-info/top_level.txt +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/setup.cfg +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/setup.py +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/snappl/__init__.py +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/snappl/_dev/__init__.py +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/snappl/_dev/scm_version.py +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/snappl/data/README.rst +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/snappl/wcs.py +0 -0
- {roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/tox.ini +0 -0
{roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.github/workflows/run_snappl_tests.yml
RENAMED
|
@@ -20,10 +20,20 @@ jobs:
|
|
|
20
20
|
uses: jwalton/gh-docker-logs@v2
|
|
21
21
|
|
|
22
22
|
- name: checkout code
|
|
23
|
-
uses: actions/checkout@
|
|
23
|
+
uses: actions/checkout@v5
|
|
24
24
|
with:
|
|
25
|
+
path: main
|
|
25
26
|
submodules: recursive
|
|
26
27
|
|
|
28
|
+
- name: run ruff
|
|
29
|
+
uses: astral-sh/ruff-action@v3
|
|
30
|
+
|
|
31
|
+
- name: checkout photometry test data
|
|
32
|
+
uses: actions/checkout@v5
|
|
33
|
+
with:
|
|
34
|
+
repository: Roman-Supernova-PIT/photometry_test_data
|
|
35
|
+
path: photometry_test_data
|
|
36
|
+
|
|
27
37
|
- name: log into github container registry
|
|
28
38
|
uses: docker/login-action@v3
|
|
29
39
|
with:
|
|
@@ -46,4 +56,5 @@ jobs:
|
|
|
46
56
|
|
|
47
57
|
- name: run test
|
|
48
58
|
run: |
|
|
59
|
+
cd main
|
|
49
60
|
docker compose run runtests
|
|
@@ -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
|
+
Made OU24 PSFs have passable WCSs
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Update tests to use photometry_test_data, small edit to config file layout.
|
{roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/roman_snpit_snappl.egg-info/SOURCES.txt
RENAMED
|
@@ -35,6 +35,12 @@ changes/23.snappl.rst
|
|
|
35
35
|
changes/26.feature.rst
|
|
36
36
|
changes/3.snappl.rst
|
|
37
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
|
|
42
|
+
changes/41.snappl.rst
|
|
43
|
+
changes/43.snappl.rst
|
|
38
44
|
changes/5.snappl.rst
|
|
39
45
|
changes/8.snappl.rst
|
|
40
46
|
changes/9.snappl.rst
|
|
@@ -62,6 +68,7 @@ snappl/__init__.py
|
|
|
62
68
|
snappl/_version.py
|
|
63
69
|
snappl/image.py
|
|
64
70
|
snappl/psf.py
|
|
71
|
+
snappl/sed.py
|
|
65
72
|
snappl/wcs.py
|
|
66
73
|
snappl/_dev/__init__.py
|
|
67
74
|
snappl/_dev/scm_version.py
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
# file generated by setuptools-scm
|
|
2
2
|
# don't change, don't track in version control
|
|
3
3
|
|
|
4
|
-
__all__ = [
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
5
12
|
|
|
6
13
|
TYPE_CHECKING = False
|
|
7
14
|
if TYPE_CHECKING:
|
|
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
|
|
|
9
16
|
from typing import Union
|
|
10
17
|
|
|
11
18
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
12
20
|
else:
|
|
13
21
|
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
14
23
|
|
|
15
24
|
version: str
|
|
16
25
|
__version__: str
|
|
17
26
|
__version_tuple__: VERSION_TUPLE
|
|
18
27
|
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
19
30
|
|
|
20
|
-
__version__ = version = '0.
|
|
21
|
-
__version_tuple__ = version_tuple = (0,
|
|
31
|
+
__version__ = version = '0.8.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 8, 0)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = 'gfdb162af4'
|
|
@@ -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
|
|
|
@@ -422,7 +458,7 @@ class FITSImage( Numpy2DImage ):
|
|
|
422
458
|
f"pixel, you tried to pass a size of {xsize, ysize}.")
|
|
423
459
|
|
|
424
460
|
SNLogger.debug(f'Cutting out at {x , y}')
|
|
425
|
-
data, noise, flags = self.get_data( 'all'
|
|
461
|
+
data, noise, flags = self.get_data( 'all' )
|
|
426
462
|
|
|
427
463
|
wcs = self.get_wcs()
|
|
428
464
|
if ( wcs is not None ) and ( not isinstance( wcs, AstropyWCS ) ):
|
|
@@ -554,3 +590,26 @@ 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
|
|
@@ -13,6 +13,7 @@ import galsim
|
|
|
13
13
|
from roman_imsim.utils import roman_utils
|
|
14
14
|
|
|
15
15
|
# roman snpit library imports
|
|
16
|
+
from snappl.wcs import BaseWCS
|
|
16
17
|
from snpit_utils.config import Config
|
|
17
18
|
from snpit_utils.logger import SNLogger
|
|
18
19
|
|
|
@@ -1051,7 +1052,7 @@ class ou24PSF_slow( PSF ):
|
|
|
1051
1052
|
self.sed = sed
|
|
1052
1053
|
|
|
1053
1054
|
if config_file is None:
|
|
1054
|
-
config_file = Config.get().value( '
|
|
1055
|
+
config_file = Config.get().value( 'ou24.config_file' )
|
|
1055
1056
|
self.config_file = config_file
|
|
1056
1057
|
self.pointing = pointing
|
|
1057
1058
|
self.sca = sca
|
|
@@ -1067,13 +1068,17 @@ class ou24PSF_slow( PSF ):
|
|
|
1067
1068
|
return self.size
|
|
1068
1069
|
|
|
1069
1070
|
|
|
1070
|
-
def get_stamp( self, x=None, y=None, x0=None, y0=None, flux=1., seed=None ):
|
|
1071
|
+
def get_stamp( self, x=None, y=None, x0=None, y0=None, flux=1., seed=None, input_wcs=None):
|
|
1071
1072
|
"""Return a 2d numpy image of the PSF at the image resolution.
|
|
1072
1073
|
|
|
1073
1074
|
Parameters are as in PSF.get_stamp, plus:
|
|
1074
1075
|
|
|
1075
1076
|
Parameters
|
|
1076
1077
|
----------
|
|
1078
|
+
input_wcs : BaseWCS or galsim.BaseWCS
|
|
1079
|
+
WARNING: DO NOT USE. Not part of a standard interface, for testing purposes only.
|
|
1080
|
+
An alternative WCS to use for the stamp.
|
|
1081
|
+
|
|
1077
1082
|
seed : int
|
|
1078
1083
|
A random seed to pass to galsim.BaseDeviate for photonOps.
|
|
1079
1084
|
NOTE: this is not part of the base PSF interface (at least,
|
|
@@ -1103,6 +1108,7 @@ class ou24PSF_slow( PSF ):
|
|
|
1103
1108
|
raise ValueError( f"PSF would be rendered at ({stampx},{stampy}), which is too far off of the "
|
|
1104
1109
|
f"edge of a {self.stamp_size}-pixel stamp." )
|
|
1105
1110
|
|
|
1111
|
+
|
|
1106
1112
|
if (x, y, stampx, stampy) not in self._stamps:
|
|
1107
1113
|
rmutils = roman_utils( self.config_file, self.pointing, self.sca )
|
|
1108
1114
|
if seed is not None:
|
|
@@ -1111,9 +1117,20 @@ class ou24PSF_slow( PSF ):
|
|
|
1111
1117
|
# It seems that galsim.ChromaticObject.drawImage won't function without stamp having
|
|
1112
1118
|
# a wcs. Without a WCS, the stamp was coming out all zeros.
|
|
1113
1119
|
# TODO : does rmutils.getLocalWCS want 1-indexed or 0-indexed coordinates???
|
|
1114
|
-
wcs = rmutils.getLocalWCS( x+1, y+1 )
|
|
1115
|
-
|
|
1116
|
-
|
|
1120
|
+
# wcs = rmutils.getLocalWCS( x+1, y+1 )self._
|
|
1121
|
+
|
|
1122
|
+
if input_wcs is None:
|
|
1123
|
+
self._wcs = rmutils.getLocalWCS( x+1, y+1 )
|
|
1124
|
+
elif isinstance(input_wcs, BaseWCS):
|
|
1125
|
+
SNLogger.debug( "Using user-supplied wcs for ou24PSF." )
|
|
1126
|
+
self._wcs = input_wcs.get_galsim_wcs().local( image_pos = galsim.PositionD(x+1, y+1 ))
|
|
1127
|
+
elif isinstance( input_wcs, galsim.BaseWCS ):
|
|
1128
|
+
SNLogger.debug( "Using user-supplied wcs for ou24PSF." )
|
|
1129
|
+
self._wcs = input_wcs.local( image_pos = galsim.PositionD(x+1, y+1 ))
|
|
1130
|
+
else:
|
|
1131
|
+
raise TypeError( f"wcs must be a galsim.BaseWCS, not a {type(input_wcs)}" )
|
|
1132
|
+
|
|
1133
|
+
stamp = galsim.Image( self.stamp_size, self.stamp_size, wcs=self._wcs )
|
|
1117
1134
|
point = ( galsim.DeltaFunction() * self.sed ).withFlux( flux, rmutils.bpass )
|
|
1118
1135
|
# TODO : make sure that rmutils.getPSF wants 1-indexed positions (which we assume here).
|
|
1119
1136
|
# (This is not that big a deal, because the PSF is not going to vary significantly
|
|
@@ -1124,18 +1141,158 @@ class ou24PSF_slow( PSF ):
|
|
|
1124
1141
|
|
|
1125
1142
|
# Note the +1s in galsim.PositionD below; galsim uses 1-indexed pixel positions,
|
|
1126
1143
|
# whereas snappl uses 0-indexed pixel positions
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1144
|
+
center = galsim.PositionD(stampx+1, stampy+1)
|
|
1145
|
+
# Note: self.include_photonOps is a bool that states whether we are
|
|
1146
|
+
# shooting photons or not, photon_ops is the actual map (not sure
|
|
1147
|
+
# if that's the correct word) that describes where the photons
|
|
1148
|
+
# should be shot, with some randomness.
|
|
1149
|
+
if self.include_photonOps:
|
|
1150
|
+
point.drawImage(rmutils.bpass, method='phot', rng=rmutils.rng, photon_ops=photon_ops,
|
|
1151
|
+
n_photons=self.n_photons, maxN=self.n_photons, poisson_flux=False,
|
|
1152
|
+
center=center, use_true_center=True, image=stamp)
|
|
1131
1153
|
|
|
1154
|
+
else:
|
|
1155
|
+
psf = galsim.Convolve(point, photon_ops[0])
|
|
1156
|
+
psf.drawImage(rmutils.bpass, method="no_pixel", center=center,
|
|
1157
|
+
use_true_center=True, image=stamp, wcs=self._wcs)
|
|
1158
|
+
|
|
1159
|
+
self._stamps[(x, y, stampx, stampy)] = stamp.array
|
|
1132
1160
|
|
|
1133
1161
|
return self._stamps[(x, y, stampx, stampy)]
|
|
1134
1162
|
|
|
1135
1163
|
|
|
1136
1164
|
# TODO : make a ou24PSF that makes an image and caches... when things are working better
|
|
1137
1165
|
class ou24PSF( ou24PSF_slow ):
|
|
1138
|
-
|
|
1166
|
+
def __init__( self, *args, **kwargs ):
|
|
1167
|
+
super().__init__(*args, **kwargs)
|
|
1168
|
+
self._psf = None
|
|
1169
|
+
|
|
1170
|
+
def _init_psf_object( self, x0=None, y0=None, flux=1., input_wcs = None):
|
|
1171
|
+
"""Create the galsim PSF object, WCS, and galsim.chromatic.SimpleChromaticTransformation
|
|
1172
|
+
that can be reused for multiple calls to get_stamp.
|
|
1173
|
+
|
|
1174
|
+
WARNING: Do not use input_wcs. Not part of a standard interface, for testing & simulation purposes only.
|
|
1175
|
+
|
|
1176
|
+
|
|
1177
|
+
Parameters are as in PSF.get_stamp, plus:
|
|
1178
|
+
|
|
1179
|
+
Parameters
|
|
1180
|
+
----------
|
|
1181
|
+
input_wcs : BaseWCS or galsim.BaseWCS
|
|
1182
|
+
An alternative WCS to use for the stamp.
|
|
1183
|
+
|
|
1184
|
+
seed : int
|
|
1185
|
+
A random seed to pass to galsim.BaseDeviate for photonOps.
|
|
1186
|
+
NOTE: this is not part of the base PSF interface (at least,
|
|
1187
|
+
as of yet), so don't use it in production pipeline code.
|
|
1188
|
+
However, it will be useful in tests for purposes of testing
|
|
1189
|
+
reproducibility.
|
|
1190
|
+
|
|
1191
|
+
|
|
1192
|
+
"""
|
|
1193
|
+
self._rmutils = roman_utils(self.config_file, self.pointing, self.sca)
|
|
1194
|
+
self._psf = self._rmutils.getPSF(x0+1, y0+1, pupil_bin=8)
|
|
1195
|
+
# TODO : does rmutils.getLocalWCS want 1-indexed or 0-indexed coordinates???
|
|
1196
|
+
if input_wcs is None:
|
|
1197
|
+
self._wcs = self._rmutils.getLocalWCS( x0+1, y0+1 )
|
|
1198
|
+
elif isinstance(input_wcs, BaseWCS):
|
|
1199
|
+
SNLogger.debug( "Using user-supplied wcs for ou24PSF." )
|
|
1200
|
+
self._wcs = input_wcs.get_galsim_wcs().local( image_pos = galsim.PositionD(x0+1, y0+1))
|
|
1201
|
+
elif isinstance( input_wcs, galsim.BaseWCS):
|
|
1202
|
+
SNLogger.debug( "Using user-supplied wcs for ou24PSF." )
|
|
1203
|
+
self._wcs = input_wcs.local( image_pos=galsim.PositionD(x0+1, y0+1))
|
|
1204
|
+
else:
|
|
1205
|
+
raise TypeError( f"wcs must be a galsim.BaseWCS, not a {type(input_wcs)}" )
|
|
1206
|
+
SNLogger.debug( f"ou24PSF wcs fetched at: {x0, y0}" )
|
|
1207
|
+
SNLogger.debug( f"ou24PSF wcs: {self._wcs}" )
|
|
1208
|
+
self._stamp = galsim.Image( self.stamp_size, self.stamp_size, wcs=self._wcs )
|
|
1209
|
+
self._point = ( galsim.DeltaFunction() * self.sed ).withFlux( flux, self._rmutils.bpass )
|
|
1210
|
+
self._convolved_psf = galsim.Convolve(self._point, self._psf)
|
|
1211
|
+
# This is only used to ensure the user isn't trying to move the PSF around
|
|
1212
|
+
self._stored_x0 = x0
|
|
1213
|
+
self._stored_y0 = y0
|
|
1214
|
+
|
|
1215
|
+
def get_stamp(self, x=None, y=None, x0=None, y0=None, flux=1.0, seed=None, input_wcs=None):
|
|
1216
|
+
"""Return a 2d numpy image of the PSF at the image resolution.
|
|
1217
|
+
Parameters are as in PSF.get_stamp, plus:
|
|
1218
|
+
|
|
1219
|
+
Parameters
|
|
1220
|
+
----------
|
|
1221
|
+
wcs : BaseWCS or galsim.BaseWCS
|
|
1222
|
+
WARNING: DO NOT USE. Not part of a standard interface, for testing purposes only.
|
|
1223
|
+
An alternative WCS to use for the stamp.
|
|
1224
|
+
|
|
1225
|
+
seed : int
|
|
1226
|
+
A random seed to pass to galsim.BaseDeviate for photonOps.
|
|
1227
|
+
NOTE: this is not part of the base PSF interface (at least,
|
|
1228
|
+
as of yet), so don't use it in production pipeline code.
|
|
1229
|
+
However, it will be useful in tests for purposes of testing
|
|
1230
|
+
reproducibility.
|
|
1231
|
+
|
|
1232
|
+
"""
|
|
1233
|
+
|
|
1234
|
+
# If a position is not given, assume the middle of the SCA
|
|
1235
|
+
# (within 1/2 pixel; by default, we want to make x and y
|
|
1236
|
+
# centered on a pixel).
|
|
1237
|
+
|
|
1238
|
+
x = x if x is not None else float( self.sca_size // 2 )
|
|
1239
|
+
y = y if y is not None else float( self.sca_size // 2 )
|
|
1240
|
+
|
|
1241
|
+
xc = int( np.floor( x + 0.5 ) )
|
|
1242
|
+
yc = int( np.floor( y + 0.5 ) )
|
|
1243
|
+
x0 = xc if x0 is None else x0
|
|
1244
|
+
y0 = yc if y0 is None else y0
|
|
1245
|
+
|
|
1246
|
+
if ( not isinstance( x0, numbers.Integral ) ) or ( not isinstance( y0, numbers.Integral ) ):
|
|
1247
|
+
raise TypeError( f"x0 and y0 must be integers; got x0 as a {type(x0)} and y0 as a {type(y0)}" )
|
|
1248
|
+
|
|
1249
|
+
if self._psf is None:
|
|
1250
|
+
SNLogger.debug( "Initializing ou24PSF galsim PSF object." )
|
|
1251
|
+
# If we don't have a psf object, then we need to initialize it, we then re use it for multiple calls to
|
|
1252
|
+
# get_stamp.
|
|
1253
|
+
self._init_psf_object( x0=x0, y0=y0, flux=flux, input_wcs = input_wcs)
|
|
1254
|
+
else:
|
|
1255
|
+
if x0 != self._stored_x0 or y0 != self._stored_y0:
|
|
1256
|
+
raise ValueError("ou24PSF.get_stamp called with x0 or y0 that does not match the x0 or y0 used"
|
|
1257
|
+
"to initialize the PSF object. If you want to recreate the PSF object, use "
|
|
1258
|
+
"ou24PSF_slow instead.")
|
|
1259
|
+
|
|
1260
|
+
stampx = self.stamp_size // 2 + ( x - x0 )
|
|
1261
|
+
stampy = self.stamp_size // 2 + ( y - y0 )
|
|
1262
|
+
|
|
1263
|
+
if ( ( stampx < -self.stamp_size ) or ( stampx > 2.*self.stamp_size ) or
|
|
1264
|
+
( stampy < -self.stamp_size ) or ( stampy > 2.*self.stamp_size ) ):
|
|
1265
|
+
raise ValueError( f"PSF would be rendered at ({stampx},{stampy}), which is too far off of the "
|
|
1266
|
+
f"edge of a {self.stamp_size}-pixel stamp." )
|
|
1267
|
+
|
|
1268
|
+
if (x, y, stampx, stampy) not in self._stamps:
|
|
1269
|
+
|
|
1270
|
+
if seed is not None:
|
|
1271
|
+
self._rmutils.rng = galsim.BaseDeviate( seed )
|
|
1272
|
+
|
|
1273
|
+
photon_ops = [ self._psf ]
|
|
1274
|
+
if self.include_photonOps:
|
|
1275
|
+
photon_ops += self._rmutils.photon_ops
|
|
1276
|
+
|
|
1277
|
+
# Note the +1s in galsim.PositionD below; galsim uses 1-indexed pixel positions,
|
|
1278
|
+
# whereas snappl uses 0-indexed pixel positions
|
|
1279
|
+
center = galsim.PositionD(stampx+1, stampy+1)
|
|
1280
|
+
# Note: self.include_photonOps is a bool that states whether we are
|
|
1281
|
+
# shooting photons or not, photon_ops is the actual map (not sure
|
|
1282
|
+
# if that's the correct word) that describes where the photons
|
|
1283
|
+
# should be shot, with some randomness.
|
|
1284
|
+
if self.include_photonOps:
|
|
1285
|
+
self._point.drawImage(self._rmutils.bpass, method='phot', rng=self._rmutils.rng, photon_ops=photon_ops,
|
|
1286
|
+
n_photons=self.n_photons, maxN=self.n_photons, poisson_flux=False,
|
|
1287
|
+
center=center, use_true_center=True, image=self._stamp)
|
|
1288
|
+
|
|
1289
|
+
else:
|
|
1290
|
+
self._convolved_psf.drawImage(self._rmutils.bpass, method="no_pixel", center=center,
|
|
1291
|
+
use_true_center=True, image=self._stamp, wcs=self._wcs)
|
|
1292
|
+
|
|
1293
|
+
self._stamps[(x, y, stampx, stampy)] = self._stamp.array
|
|
1294
|
+
|
|
1295
|
+
return self._stamps[(x, y, stampx, stampy)]
|
|
1139
1296
|
|
|
1140
1297
|
# class ou24PSF( OversampledImagePSF ):
|
|
1141
1298
|
# """An OversampledImagePSF that renders its internally stored image from a galsim roman_imsim PSF.
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Put in necessary imports
|
|
2
|
+
import numpy as np
|
|
3
|
+
import os
|
|
4
|
+
import h5py
|
|
5
|
+
import galsim
|
|
6
|
+
import pathlib
|
|
7
|
+
import pandas as pd
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from snpit_utils.config import Config
|
|
11
|
+
from snpit_utils.logger import SNLogger
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SED_collection:
|
|
15
|
+
def __init__(self, *args, **kwargs):
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
def get_sed(self, filename=None, snid=None, mjd=None):
|
|
19
|
+
"""Return a galsim SED."""
|
|
20
|
+
raise NotImplementedError( f"{self.__class__.__name__} needs to implement get_sed" )
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Flat_SED( SED_collection ):
|
|
24
|
+
def __init__( self ):
|
|
25
|
+
self.sed = galsim.SED( galsim.LookupTable( [1000, 26000], [1, 1], interpolant='linear' ),
|
|
26
|
+
wave_type='Angstrom', flux_type='fphotons' )
|
|
27
|
+
|
|
28
|
+
def get_sed( self, **kwargs):
|
|
29
|
+
return self.sed
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Single_CSV_SED( SED_collection ):
|
|
33
|
+
def __init__( self, csv_file ):
|
|
34
|
+
# READ THE CSV FILE, make a galsim SED in self.sed
|
|
35
|
+
raise NotImplementedError( "Single_CSV_SED is not implemented yet.")
|
|
36
|
+
|
|
37
|
+
def get_sed( self, **kwargs ):
|
|
38
|
+
return self.sed
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class OU2024_Truth_SED(SED_collection):
|
|
42
|
+
def __init__(self, snid=None, isstar=False):
|
|
43
|
+
# if (snid is None) or (sn_path is None):
|
|
44
|
+
# raise ValueError("Must specify all of snid, sn_path")
|
|
45
|
+
|
|
46
|
+
self.snid = snid
|
|
47
|
+
cfg = Config.get()
|
|
48
|
+
self.sn_path = cfg.value("ou24.sn_truth_dir")
|
|
49
|
+
self.isstar = isstar
|
|
50
|
+
|
|
51
|
+
if isstar:
|
|
52
|
+
self.lam_array, self.flambda_array = \
|
|
53
|
+
self._ou24_get_star_SED()
|
|
54
|
+
else:
|
|
55
|
+
self.lam_array, self.flambda_array, self.mjd_array = \
|
|
56
|
+
self._ou24_get_SN_SED()
|
|
57
|
+
|
|
58
|
+
def get_sed(self, snid=None, mjd=None):
|
|
59
|
+
"""Return an SED for the given snid and mjd.
|
|
60
|
+
Inputs:
|
|
61
|
+
snid: the ID of the object
|
|
62
|
+
mjd: the MJD of the observation (only used if this is a SN)
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
galsim.SED: the SED for the given snid and mjd, if a supernova, for the ID if a star.
|
|
66
|
+
"""
|
|
67
|
+
assert snid == self.snid, "ID does not match the SED collection ID."
|
|
68
|
+
|
|
69
|
+
if not self.isstar:
|
|
70
|
+
# If this is a SN, we need to find the closest SED to the given MJD.
|
|
71
|
+
bestindex = np.argmin(np.abs(np.array(self.mjd_array) - mjd))
|
|
72
|
+
max_days_cutoff = 10
|
|
73
|
+
closest_days_away = np.min(np.abs(np.array(self.mjd_array) - mjd))
|
|
74
|
+
|
|
75
|
+
if closest_days_away > max_days_cutoff:
|
|
76
|
+
SNLogger.warning(f"WARNING: No SED data within {max_days_cutoff} days of "
|
|
77
|
+
+ f"date. \n The closest SED is {closest_days_away} days away.")
|
|
78
|
+
|
|
79
|
+
return galsim.SED(
|
|
80
|
+
galsim.LookupTable(np.array(self.lam_array), (self.flambda_array[bestindex]), interpolant="linear"),
|
|
81
|
+
wave_type="Angstrom",
|
|
82
|
+
flux_type="fphotons",
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
else:
|
|
86
|
+
# If this is a star, we just return the SED
|
|
87
|
+
return galsim.SED(
|
|
88
|
+
galsim.LookupTable(np.array(self.lam_array), (self.flambda_array), interpolant="linear"),
|
|
89
|
+
wave_type="Angstrom",
|
|
90
|
+
flux_type="fphotons",
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
def _ou24_open_parquet(self, parq, obj_type="SN", engine="fastparquet"):
|
|
94
|
+
"""Convenience function to open a parquet file given its number."""
|
|
95
|
+
path = self.sn_path
|
|
96
|
+
file_prefix = {"SN": "snana", "star": "pointsource"}
|
|
97
|
+
base_name = "{:s}_{}.parquet".format(file_prefix[obj_type], parq)
|
|
98
|
+
file_path = os.path.join(path, base_name)
|
|
99
|
+
df = pd.read_parquet(file_path, engine=engine)
|
|
100
|
+
return df
|
|
101
|
+
|
|
102
|
+
def _ou24_find_parquet(self, obj_type="SN"):
|
|
103
|
+
"""Find the parquet file that contains a given supernova ID."""
|
|
104
|
+
path = self.sn_path
|
|
105
|
+
ID = self.snid
|
|
106
|
+
files = os.listdir(path)
|
|
107
|
+
SNLogger.debug(f"Looking for parquet files in {path} for {obj_type} with ID {ID}")
|
|
108
|
+
file_prefix = {"SN": "snana", "star": "pointsource"}
|
|
109
|
+
files = [f for f in files if file_prefix[obj_type] in f]
|
|
110
|
+
files = [f for f in files if ".parquet" in f]
|
|
111
|
+
files = [f for f in files if "flux" not in f]
|
|
112
|
+
|
|
113
|
+
for f in files:
|
|
114
|
+
pqfile = int(f.split("_")[1].split(".")[0])
|
|
115
|
+
df = self._ou24_open_parquet(pqfile, obj_type=obj_type)
|
|
116
|
+
if ID in df.id.values or str(ID) in df.id.values:
|
|
117
|
+
return pqfile
|
|
118
|
+
|
|
119
|
+
def _ou24_get_star_SED(self):
|
|
120
|
+
"""Return the appropriate SED for the star.
|
|
121
|
+
Inputs:
|
|
122
|
+
SNID: the ID of the object
|
|
123
|
+
sn_path: the path to the supernova data
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
lam: the wavelength of the SED in Angstrom (numpy array of floats)
|
|
127
|
+
flambda: the flux of the SED units in erg/s/cm^2/Angstrom
|
|
128
|
+
(numpy array of floats)
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
filenum = self._ou24_find_parquet(obj_type="star")
|
|
132
|
+
pqfile = self._ou24_open_parquet(filenum, obj_type="star")
|
|
133
|
+
file_name = pqfile[pqfile["id"] == str(self.snid)]["sed_filepath"].values[0]
|
|
134
|
+
fullpath = pathlib.Path(Config.get().value("ou24.sims_sed_library")) / file_name
|
|
135
|
+
sed_table = pd.read_csv(fullpath, compression="gzip", sep=r"\s+", comment="#")
|
|
136
|
+
lam = sed_table.iloc[:, 0]
|
|
137
|
+
flambda = sed_table.iloc[:, 1]
|
|
138
|
+
return np.array(lam), np.array(flambda)
|
|
139
|
+
|
|
140
|
+
def _ou24_get_SN_SED(self):
|
|
141
|
+
"""Return the appropriate SED for the supernova on the given day.
|
|
142
|
+
|
|
143
|
+
Inputs:
|
|
144
|
+
SNID: the ID of the object
|
|
145
|
+
sn_path: the path to the supernova data
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
lam: the wavelength of the SED in Angstrom
|
|
149
|
+
flambda: the flux of the SED units in erg/s/cm^2/Angstrom
|
|
150
|
+
"""
|
|
151
|
+
filenum = self._ou24_find_parquet(obj_type="SN")
|
|
152
|
+
file_name = "snana" + "_" + str(filenum) + ".hdf5"
|
|
153
|
+
fullpath = os.path.join(self.sn_path, file_name)
|
|
154
|
+
# Setting locking=False on the next line becasue it seems that you can't
|
|
155
|
+
# open an h5py file unless you have write access to... something.
|
|
156
|
+
# Not sure what. The directory where it exists? We won't
|
|
157
|
+
# always have that. It's scary to set locking to false, because it
|
|
158
|
+
# subverts all kinds of safety stuff that hdf5 does. However,
|
|
159
|
+
# because these files were created once in this case, it's not actually
|
|
160
|
+
# scary, and we expect them to be static. Locking only matters if you
|
|
161
|
+
# think somebody else might change the file
|
|
162
|
+
# while you're in the middle of reading bits of it.
|
|
163
|
+
sed_table = h5py.File(fullpath, "r", locking=False)
|
|
164
|
+
sed_table = sed_table[str(self.snid)]
|
|
165
|
+
flambda = sed_table["flambda"]
|
|
166
|
+
lam = sed_table["lambda"]
|
|
167
|
+
mjd = sed_table["mjd"]
|
|
168
|
+
|
|
169
|
+
return np.array(lam), np.array(flambda), np.array(mjd)
|
|
File without changes
|
|
File without changes
|
{roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
RENAMED
|
File without changes
|
{roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/.github/workflows/sub_package_update.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/experimentation/play_with_photutils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/roman_snpit_snappl.egg-info/not-zip-safe
RENAMED
|
File without changes
|
{roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/roman_snpit_snappl.egg-info/requires.txt
RENAMED
|
File without changes
|
{roman_snpit_snappl-0.6.0 → roman_snpit_snappl-0.8.0}/roman_snpit_snappl.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|