lsst.meas.algorithms
g4a7591d645+ff8a1bd350
Toggle main menu visibility
Loading...
Searching...
No Matches
python
lsst
meas
algorithms
skyObjects.py
Go to the documentation of this file.
1
# This file is part of meas_algorithms.
2
#
3
# Developed for the LSST Data Management System.
4
# This product includes software developed by the LSST Project
5
# (https://www.lsst.org).
6
# See the COPYRIGHT file at the top-level directory of this distribution
7
# for details of code ownership.
8
#
9
# This program is free software: you can redistribute it and/or modify
10
# it under the terms of the GNU General Public License as published by
11
# the Free Software Foundation, either version 3 of the License, or
12
# (at your option) any later version.
13
#
14
# This program is distributed in the hope that it will be useful,
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
# GNU General Public License for more details.
18
#
19
# You should have received a copy of the GNU General Public License
20
# along with this program. If not, see <https://www.gnu.org/licenses/>.
21
22
__all__ = [
"SkyObjectsConfig"
,
"SkyObjectsTask"
,
"generateSkyObjects"
]
23
24
from
scipy.stats
import
qmc
25
26
from
lsst.pex.config
import
Config, Field, ListField
27
from
lsst.pipe.base
import
Task
28
29
import
lsst.afw.detection
30
import
lsst.afw.geom
31
import
lsst.afw.math
32
33
34
class
SkyObjectsConfig
(Config):
35
"""Configuration for generating sky objects"""
36
avoidMask = ListField(
37
dtype=str,
38
default=[
"DETECTED"
,
"DETECTED_NEGATIVE"
,
"BAD"
,
"NO_DATA"
],
39
doc=
"Avoid pixels masked with these mask planes."
40
)
41
growMask = Field(
42
dtype=int,
43
default=0,
44
doc=
"Number of pixels to grow the masked pixels when adding sky sources."
45
)
46
sourceRadius = Field(
47
dtype=float,
48
default=8,
49
doc=
"Radius, in pixels, of sky sources."
50
)
51
nSources = Field(
52
dtype=int,
53
default=100,
54
doc=
"Try to add this many sky sources."
55
)
56
nTrialSources = Field(
57
dtype=int,
58
default=
None
,
59
optional=
True
,
60
doc=
"Maximum number of trial sky object positions "
61
"(default: nSkySources*nTrialSkySourcesMultiplier)."
62
)
63
nTrialSourcesMultiplier = Field(
64
dtype=int,
65
default=5,
66
doc=
"Set nTrialSkySources to nSkySources*nTrialSkySourcesMultiplier "
67
"if nTrialSkySources is None."
68
)
69
70
71
def
generateSkyObjects
(mask, seed, config):
72
"""Generate a list of Footprints of sky objects
73
74
Sky objects don't overlap with other objects. This is determined
75
through the provided `mask` (in which objects are typically flagged
76
as `DETECTED`).
77
78
Sky objects are positioned using a quasi-random Halton sequence number
79
generator. This is a deterministic sequence that mimics a random trial and
80
error approach whilst acting to minimize clustering of points for a given
81
field of view. Up to `nTrialSources` points are generated, returning the
82
first `nSources` that do not overlap with the mask.
83
84
Parameters
85
----------
86
mask : `lsst.afw.image.Mask`
87
Input mask plane, which identifies pixels to avoid for the sky
88
objects.
89
seed : `int`
90
Random number generator seed.
91
config : `SkyObjectsConfig`
92
Configuration for finding sky objects.
93
94
Returns
95
-------
96
skyFootprints : `list` of `lsst.afw.detection.Footprint`
97
Footprints of sky objects. Each will have a peak at the center
98
of the sky object.
99
"""
100
if
config.nSources <= 0:
101
return
[]
102
103
skySourceRadius = config.sourceRadius
104
nSkySources = config.nSources
105
nTrialSkySources = config.nTrialSources
106
if
nTrialSkySources
is
None
:
107
nTrialSkySources = config.nTrialSourcesMultiplier*nSkySources
108
109
box = mask.getBBox()
110
box.grow(-(int(skySourceRadius) + 1))
# Avoid objects partially off the image
111
xMin, yMin = box.getMin()
112
xMax, yMax = box.getMax()
113
114
avoid =
lsst.afw.geom.SpanSet.fromMask
(mask, mask.getPlaneBitMask(config.avoidMask))
115
if
config.growMask > 0:
116
avoid = avoid.dilated(config.growMask)
117
118
sampler = qmc.Halton(d=2, seed=seed).random(nTrialSkySources)
119
sample = qmc.scale(sampler, [xMin, yMin], [xMax, yMax])
120
121
skyFootprints = []
122
for
x, y
in
zip(sample[:, 0].astype(int), sample[:, 1].astype(int)):
123
if
len(skyFootprints) == nSkySources:
124
break
125
126
spans =
lsst.afw.geom.SpanSet.fromShape
(int(skySourceRadius), offset=(x, y))
127
if
spans.overlaps(avoid):
128
continue
129
130
fp =
lsst.afw.detection.Footprint
(spans, mask.getBBox())
131
fp.addPeak(x, y, 0)
132
skyFootprints.append(fp)
133
134
# Add doubled-in-size sky object spanSet to the avoid mask.
135
avoid = avoid.union(spans.dilated(int(skySourceRadius)))
136
137
return
skyFootprints
138
139
140
class
SkyObjectsTask
(Task):
141
"""Generate a list of Footprints of sky sources/objects (regions on the
142
sky that do not otherwise have detections).
143
144
Parameters
145
----------
146
schema : `lsst.afw.table.Schema`
147
Schema used to create the output `~lsst.afw.table.SourceCatalog`,
148
updated with fields that will be written by this task.
149
150
"""
151
ConfigClass = SkyObjectsConfig
152
153
def
__init__
(self, schema=None, **kwargs):
154
super().
__init__
(**kwargs)
155
if
schema
is
not
None
:
156
self.
skySourceKey
= schema.addField(
"sky_source"
, type=
"Flag"
,
157
doc=
"Region on image with no detections."
)
158
else
:
159
self.
skySourceKey
=
None
160
161
def
run
(self, mask, seed, catalog=None):
162
"""Generate a list of Footprints of sky sources/objects.
163
164
Sky objects don't overlap with other objects. This is determined
165
through the provided `mask` (in which objects are typically flagged
166
as `DETECTED`).
167
168
Sky objects are positioned using a quasi-random Halton sequence
169
number generator. This is a deterministic sequence that mimics a random
170
trial and error approach whilst acting to minimize clustering of points
171
for a given field of view. Up to `nTrialSources` points are generated,
172
returning the first `nSources` that do not overlap with the mask.
173
174
Parameters
175
----------
176
mask : `lsst.afw.image.Mask`
177
Input mask plane, which identifies pixels to avoid for the sky
178
objects.
179
seed : `int`
180
Random number generator seed.
181
catalog : `lsst.afw.table.SourceCatalog`, optional
182
Catalog to add detected footprints to; modified in-place if any
183
sky source/object footprints are created.
184
185
Returns
186
-------
187
skyFootprints : `list` of `lsst.afw.detection.Footprint`
188
Footprints of sky objects. Each will have a peak at the center
189
of the sky object.
190
"""
191
skyFootprints =
generateSkyObjects
(mask, seed, self.config)
192
self.log.info(
"Added %d of %d requested sky sources (%.0f%%)"
, len(skyFootprints),
193
self.config.nSources, 100*len(skyFootprints)/self.config.nSources)
194
self.metadata[
"sky_footprint_count"
] = len(skyFootprints)
195
196
if
skyFootprints
and
self.
skySourceKey
is
not
None
and
catalog
is
not
None
:
197
for
footprint
in
skyFootprints:
198
record = catalog.addNew()
199
record.setFootprint(footprint)
200
record.set(self.
skySourceKey
,
True
)
201
202
return
skyFootprints
lsst::afw::detection::Footprint
lsst::afw::geom::SpanSet::fromMask
static std::shared_ptr< geom::SpanSet > fromMask(image::Mask< T > const &mask, UnaryPredicate comparator=details::AnyBitSetFunctor< T >())
lsst::afw::geom::SpanSet::fromShape
static std::shared_ptr< geom::SpanSet > fromShape(int r, Stencil s=Stencil::CIRCLE, lsst::geom::Point2I offset=lsst::geom::Point2I())
lsst::meas::algorithms.skyObjects.SkyObjectsConfig
Definition
skyObjects.py:34
lsst::meas::algorithms.skyObjects.SkyObjectsTask
Definition
skyObjects.py:140
lsst::meas::algorithms.skyObjects.SkyObjectsTask.__init__
__init__(self, schema=None, **kwargs)
Definition
skyObjects.py:153
lsst::meas::algorithms.skyObjects.SkyObjectsTask.skySourceKey
skySourceKey
Definition
skyObjects.py:156
lsst::meas::algorithms.skyObjects.SkyObjectsTask.run
run(self, mask, seed, catalog=None)
Definition
skyObjects.py:161
lsst::afw::detection
lsst::afw::geom
lsst::afw::math
lsst::meas::algorithms.skyObjects.generateSkyObjects
generateSkyObjects(mask, seed, config)
Definition
skyObjects.py:71
lsst::pex::config
lsst.pipe.base
Generated on
for lsst.meas.algorithms by
1.17.0