2__all__ = [
"SkyObjectsConfig",
"SkyObjectsTask",
"generateSkyObjects"]
5from lsst.pipe.base
import Task
13 """Configuration for generating sky objects"""
14 avoidMask = ListField(dtype=str, default=[
"DETECTED",
"DETECTED_NEGATIVE",
"BAD",
"NO_DATA"],
15 doc=
"Avoid pixels masked with these mask planes")
16 growMask = Field(dtype=int, default=0,
17 doc=
"Number of pixels to grow the masked pixels when adding sky objects")
18 sourceRadius = Field(dtype=float, default=8, doc=
"Radius, in pixels, of sky objects")
19 nSources = Field(dtype=int, default=100, doc=
"Try to add this many sky objects")
20 nTrialSources = Field(dtype=int, default=
None, optional=
True,
21 doc=
"Maximum number of trial sky object positions\n"
22 "(default: nSkySources*nTrialSkySourcesMultiplier)")
23 nTrialSourcesMultiplier = Field(dtype=int, default=5,
24 doc=
"Set nTrialSkySources to\n"
25 " nSkySources*nTrialSkySourcesMultiplier\n"
26 "if nTrialSkySources is None")
30 """Generate a list of Footprints of sky objects
32 Sky objects don't overlap with other objects. This is determined
33 through the provided `mask` (in which objects are typically flagged
36 The algorithm
for determining sky objects
is random trial
and error:
37 we
try up to `nTrialSkySources` random positions to find `nSources`
43 Input mask plane, which identifies pixels to avoid
for the sky
46 Random number generator seed.
47 config : `SkyObjectsConfig`
48 Configuration
for finding sky objects.
53 Footprints of sky objects. Each will have a peak at the center
56 if config.nSources <= 0:
59 skySourceRadius = config.sourceRadius
60 nSkySources = config.nSources
61 nTrialSkySources = config.nTrialSources
62 if nTrialSkySources
is None:
63 nTrialSkySources = config.nTrialSourcesMultiplier*nSkySources
66 box.grow(-(
int(skySourceRadius) + 1))
67 xMin, yMin = box.getMin()
68 xMax, yMax = box.getMax()
71 if config.growMask > 0:
72 avoid = avoid.dilated(config.growMask)
77 for _
in range(nTrialSkySources):
78 if len(skyFootprints) == nSkySources:
81 x =
int(rng.flat(xMin, xMax))
82 y =
int(rng.flat(yMin, yMax))
84 if spans.overlaps(avoid):
89 skyFootprints.append(fp)
95 """Generate a list of Footprints of sky objects.
97 ConfigClass = SkyObjectsConfig
99 def run(self, mask, seed):
100 """Generate a list of Footprints of sky objects
102 Sky objects don't overlap with other objects. This is determined
103 through the provided `mask` (in which objects are typically flagged
106 The algorithm
for determining sky objects
is random trial
and error:
107 we
try up to `nTrialSkySources` random positions to find `nSources`
113 Input mask plane, which identifies pixels to avoid
for the sky
116 Random number generator seed.
121 Footprints of sky objects. Each will have a peak at the center
125 self.log.info("Added %d of %d requested sky sources (%.0f%%)", len(skyFootprints),
126 self.config.nSources, 100*len(skyFootprints)/self.config.nSources)
static std::shared_ptr< geom::SpanSet > fromMask(image::Mask< T > const &mask, UnaryPredicate comparator=details::AnyBitSetFunctor< T >())
static std::shared_ptr< geom::SpanSet > fromShape(int r, Stencil s=Stencil::CIRCLE, lsst::geom::Point2I offset=lsst::geom::Point2I())
def run(self, mask, seed)
def generateSkyObjects(mask, seed, config)