LSST Applications 26.0.0,g0265f82a02+6660c170cc,g07994bdeae+30b05a742e,g0a0026dc87+17526d298f,g0a60f58ba1+17526d298f,g0e4bf8285c+96dd2c2ea9,g0ecae5effc+c266a536c8,g1e7d6db67d+6f7cb1f4bb,g26482f50c6+6346c0633c,g2bbee38e9b+6660c170cc,g2cc88a2952+0a4e78cd49,g3273194fdb+f6908454ef,g337abbeb29+6660c170cc,g337c41fc51+9a8f8f0815,g37c6e7c3d5+7bbafe9d37,g44018dc512+6660c170cc,g4a941329ef+4f7594a38e,g4c90b7bd52+5145c320d2,g58be5f913a+bea990ba40,g635b316a6c+8d6b3a3e56,g67924a670a+bfead8c487,g6ae5381d9b+81bc2a20b4,g93c4d6e787+26b17396bd,g98cecbdb62+ed2cb6d659,g98ffbb4407+81bc2a20b4,g9ddcbc5298+7f7571301f,ga1e77700b3+99e9273977,gae46bcf261+6660c170cc,gb2715bf1a1+17526d298f,gc86a011abf+17526d298f,gcf0d15dbbd+96dd2c2ea9,gdaeeff99f8+0d8dbea60f,gdb4ec4c597+6660c170cc,ge23793e450+96dd2c2ea9,gf041782ebf+171108ac67
LSST Data Management Base Package
Loading...
Searching...
No Matches
skyObjects.py
Go to the documentation of this file.
2__all__ = ["SkyObjectsConfig", "SkyObjectsTask", "generateSkyObjects"]
3
4from scipy.stats import qmc
5
6from lsst.pex.config import Config, Field, ListField
7from lsst.pipe.base import Task
8
10import lsst.afw.geom
11import lsst.afw.math
12
13
15 """Configuration for generating sky objects"""
16 avoidMask = ListField(dtype=str, default=["DETECTED", "DETECTED_NEGATIVE", "BAD", "NO_DATA"],
17 doc="Avoid pixels masked with these mask planes")
18 growMask = Field(dtype=int, default=0,
19 doc="Number of pixels to grow the masked pixels when adding sky objects")
20 sourceRadius = Field(dtype=float, default=8, doc="Radius, in pixels, of sky objects")
21 nSources = Field(dtype=int, default=100, doc="Try to add this many sky objects")
22 nTrialSources = Field(dtype=int, default=None, optional=True,
23 doc="Maximum number of trial sky object positions "
24 "(default: nSkySources*nTrialSkySourcesMultiplier)")
25 nTrialSourcesMultiplier = Field(dtype=int, default=5,
26 doc="Set nTrialSkySources to "
27 "nSkySources*nTrialSkySourcesMultiplier "
28 "if nTrialSkySources is None")
29
30
31def generateSkyObjects(mask, seed, config):
32 """Generate a list of Footprints of sky objects
33
34 Sky objects don't overlap with other objects. This is determined
35 through the provided `mask` (in which objects are typically flagged
36 as `DETECTED`).
37
38 Sky objects are positioned using a quasi-random Halton sequence number
39 generator. This is a deterministic sequence that mimics a random trial and
40 error approach whilst acting to minimize clustering of points for a given
41 field of view. Up to `nTrialSources` points are generated, returning the
42 first `nSources` that do not overlap with the mask.
43
44 Parameters
45 ----------
46 mask : `lsst.afw.image.Mask`
47 Input mask plane, which identifies pixels to avoid for the sky
48 objects.
49 seed : `int`
50 Random number generator seed.
51 config : `SkyObjectsConfig`
52 Configuration for finding sky objects.
53
54 Returns
55 -------
56 skyFootprints : `list` of `lsst.afw.detection.Footprint`
57 Footprints of sky objects. Each will have a peak at the center
58 of the sky object.
59 """
60 if config.nSources <= 0:
61 return []
62
63 skySourceRadius = config.sourceRadius
64 nSkySources = config.nSources
65 nTrialSkySources = config.nTrialSources
66 if nTrialSkySources is None:
67 nTrialSkySources = config.nTrialSourcesMultiplier*nSkySources
68
69 box = mask.getBBox()
70 box.grow(-(int(skySourceRadius) + 1)) # Avoid objects partially off the image
71 xMin, yMin = box.getMin()
72 xMax, yMax = box.getMax()
73
74 avoid = lsst.afw.geom.SpanSet.fromMask(mask, mask.getPlaneBitMask(config.avoidMask))
75 if config.growMask > 0:
76 avoid = avoid.dilated(config.growMask)
77
78 sampler = qmc.Halton(d=2, seed=seed).random(nTrialSkySources)
79 sample = qmc.scale(sampler, [xMin, yMin], [xMax, yMax])
80
81 skyFootprints = []
82 for x, y in zip(sample[:, 0].astype(int), sample[:, 1].astype(int)):
83 if len(skyFootprints) == nSkySources:
84 break
85
86 spans = lsst.afw.geom.SpanSet.fromShape(int(skySourceRadius), offset=(x, y))
87 if spans.overlaps(avoid):
88 continue
89
90 fp = lsst.afw.detection.Footprint(spans, mask.getBBox())
91 fp.addPeak(x, y, 0)
92 skyFootprints.append(fp)
93
94 # Add doubled-in-size sky object spanSet to the avoid mask.
95 avoid = avoid.union(spans.dilated(int(skySourceRadius)))
96
97 return skyFootprints
98
99
100class SkyObjectsTask(Task):
101 """Generate a list of Footprints of sky objects.
102 """
103 ConfigClass = SkyObjectsConfig
104
105 def run(self, mask, seed):
106 """Generate a list of Footprints of sky objects
107
108 Sky objects don't overlap with other objects. This is determined
109 through the provided `mask` (in which objects are typically flagged
110 as `DETECTED`).
111
112 Sky objects are positioned using a quasi-random Halton sequence
113 number generator. This is a deterministic sequence that mimics a random
114 trial and error approach whilst acting to minimize clustering of points
115 for a given field of view. Up to `nTrialSources` points are generated,
116 returning the first `nSources` that do not overlap with the mask.
117
118 Parameters
119 ----------
120 mask : `lsst.afw.image.Mask`
121 Input mask plane, which identifies pixels to avoid for the sky
122 objects.
123 seed : `int`
124 Random number generator seed.
125
126 Returns
127 -------
128 skyFootprints : `list` of `lsst.afw.detection.Footprint`
129 Footprints of sky objects. Each will have a peak at the center
130 of the sky object.
131 """
132 skyFootprints = generateSkyObjects(mask, seed, self.config)
133 self.log.info("Added %d of %d requested sky sources (%.0f%%)", len(skyFootprints),
134 self.config.nSources, 100*len(skyFootprints)/self.config.nSources)
135 return skyFootprints
Class to describe the properties of a detected object from an image.
Definition Footprint.h:63
static std::shared_ptr< geom::SpanSet > fromMask(image::Mask< T > const &mask, UnaryPredicate comparator=details::AnyBitSetFunctor< T >())
Create a SpanSet from a mask.
Definition SpanSet.h:644
static std::shared_ptr< geom::SpanSet > fromShape(int r, Stencil s=Stencil::CIRCLE, lsst::geom::Point2I offset=lsst::geom::Point2I())
Factory function for creating SpanSets from a Stencil.
Definition SpanSet.cc:688
Represent a 2-dimensional array of bitmask pixels.
Definition Mask.h:77
generateSkyObjects(mask, seed, config)
Definition skyObjects.py:31