Skip to content

Commit 94fe0b0

Browse files
authored
Merge pull request #25 from des-science/coadd_mixed_scene
ENH add coadd mixed scene stamp type
2 parents 1c8775a + 09c7bbc commit 94fe0b0

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed

montara/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
# package is not installed
1010
pass
1111

12+
from . import coadd_mixed_scene # noqa
1213
from . import des_tile # noqa
1314
from . import input_desstar # noqa
1415
from . import catalogsampler # noqa

montara/coadd_mixed_scene.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import coord
2+
import galsim
3+
4+
5+
class CoaddMixedSceneBuilder(galsim.config.StampBuilder):
6+
"""
7+
This class reproduces https://github.com/esheldon/galsim_extra/blob/master/galsim_extra/mixed_scene.py
8+
with a patch for using the coadd WCS of a DES tile (rather than the SE WCS)
9+
"""
10+
11+
def setup(self, config, base, xsize, ysize, ignore, logger):
12+
if 'objects' not in config:
13+
raise AttributeError('objets field is required for CoaddMixedScene stamp type')
14+
objects = config['objects']
15+
16+
# Propagate any stamp rng_num or index_key into the various object fields:
17+
objects.pop('rng_num', None) # Also remove them from here if necessary.
18+
objects.pop('index_key', None)
19+
if not config.get('_propagated_rng_index', False):
20+
config['_propagated_rng_index'] = True
21+
rng_num = config.get('rng_num', None)
22+
index_key = config.get('index_key', None)
23+
for key in objects.keys():
24+
galsim.config.PropagateIndexKeyRNGNum(base[key], index_key, rng_num)
25+
26+
rng = galsim.config.GetRNG(config, base)
27+
ud = galsim.UniformDeviate(rng)
28+
p = ud() # A random number between 0 and 1.
29+
30+
# If the user is careful, this will be 1, but if not, renormalize for them.
31+
norm = float(sum(objects.values()))
32+
33+
if 'obj_type' in config:
34+
obj_type = galsim.config.ParseValue(config, 'obj_type', base, str)[0]
35+
obj_type_index = list(objects.keys()).index(obj_type)
36+
else:
37+
# Figure out which object field to use
38+
obj_type = None # So we can check that it was set to something.
39+
obj_type_index = 0
40+
for key, value in objects.items():
41+
p1 = value / norm
42+
if p < p1:
43+
# Use this object
44+
obj_type = key
45+
break
46+
else:
47+
p -= p1
48+
obj_type_index += 1
49+
if obj_type is None:
50+
# This shouldn't happen, but maybe possible from rounding errors. Use the last one.
51+
obj_type = list(objects.keys())[-1]
52+
obj_type_index -= 1
53+
logger.error("Error in CoaddMixedScene. Didn't pick an object to use. Using %s", obj_type)
54+
55+
# Save this in the dict so it can be used by e.g. the truth catalog or to do something
56+
# different depending on which kind of object we have.
57+
base['current_obj_type'] = obj_type
58+
base['current_obj_type_index'] = obj_type_index
59+
base['current_obj'] = None
60+
61+
# Add objects field to the ignore list
62+
# Also ignore magnify and shear, which we allow here for convenience to act on whichever
63+
# object ends up being chosen.
64+
ignore = ignore + ['objects', 'magnify', 'shear', 'obj_type', 'shear_scene']
65+
66+
stamp_xsize, stamp_ysize, image_pos, world_pos = super(
67+
CoaddMixedSceneBuilder,
68+
self
69+
).setup(config, base, xsize, ysize, ignore, logger)
70+
71+
if 'shear_scene' in config:
72+
shear_scene = galsim.config.ParseValue(config, 'shear_scene', base, bool)[0]
73+
else:
74+
shear_scene = False
75+
76+
# option to shear the full scene.
77+
if shear_scene:
78+
shear = galsim.config.ParseValue(config, 'shear', base, galsim.Shear)[0]
79+
# Find the center (tangent point) of the scene in RA, DEC.
80+
scene_center = base["coadd_wcs"].center
81+
wcs = base['wcs']
82+
# world_pos might not be defined yet, so if necessary get it from image_pos.
83+
if image_pos is not None and world_pos is None:
84+
world_pos = wcs.toWorld(image_pos)
85+
if wcs.isCelestial():
86+
u, v = scene_center.project(world_pos, projection='gnomonic')
87+
pos = galsim.PositionD(u.rad, v.rad)
88+
sheared_pos = pos.shear(shear)
89+
u2 = sheared_pos.x * coord.radians
90+
v2 = sheared_pos.y * coord.radians
91+
world_pos = scene_center.deproject(u2, v2, projection='gnomonic')
92+
else:
93+
world_pos = (world_pos - scene_center).shear(shear) + scene_center
94+
image_pos = wcs.toImage(world_pos)
95+
96+
# Now go on and do the rest of the normal setup.
97+
return stamp_xsize, stamp_ysize, image_pos, world_pos
98+
99+
def buildProfile(self, config, base, psf, gsparams, logger):
100+
obj_type = base['current_obj_type']
101+
102+
# Make the appropriate object using the obj_type field
103+
obj = galsim.config.BuildGSObject(base, obj_type, gsparams=gsparams, logger=logger)[0]
104+
# Also save this in case useful for some calculation.
105+
base['current_obj'] = obj
106+
107+
# Only shear and magnify are allowed, but this general TransformObject function will
108+
# work to implement those.
109+
obj, safe = galsim.config.TransformObject(obj, config, base, logger)
110+
111+
if psf:
112+
if obj:
113+
return galsim.Convolve(obj, psf)
114+
else:
115+
return psf
116+
else:
117+
if obj:
118+
return obj
119+
else:
120+
return None
121+
122+
123+
galsim.config.stamp.RegisterStampType('CoaddMixedScene', CoaddMixedSceneBuilder())

0 commit comments

Comments
 (0)