lsst.meas.base
ga44f29b7aa+acb932b993
Toggle main menu visibility
Loading...
Searching...
No Matches
python
lsst
meas
base
simple_forced_measurement.py
Go to the documentation of this file.
1
# This file is part of meas_base.
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__ = (
"SimpleForcedMeasurementConfig"
,
"SimpleForcedMeasurementTask"
)
23
24
import
numpy
as
np
25
26
import
lsst.afw.geom
27
import
lsst.afw.image
28
import
lsst.afw.table
29
import
lsst.daf.base
30
import
lsst.geom
31
import
lsst.pex.config
32
import
lsst.pipe.base
33
from
lsst.utils.logging
import
PeriodicLogger
34
35
from
.baseMeasurement
import
SimpleBaseMeasurementConfig, SimpleBaseMeasurementTask
36
from
.forcedMeasurement
import
ForcedPlugin
37
38
39
class
SimpleForcedMeasurementConfig
(
SimpleBaseMeasurementConfig
):
40
"""Config class for SimpleForcedMeasurementTask."""
41
plugins = ForcedPlugin.registry.makeField(
42
multi=
True
,
43
default=[
"base_PixelFlags"
,
44
"base_TransformedCentroidFromCoord"
,
45
"base_PsfFlux"
,
46
],
47
doc=
"Plugins to be run and their configuration"
48
)
49
psfFootprintScaling = lsst.pex.config.Field(
50
dtype=float,
51
doc=
"Scaling factor to apply to the PSF shape when footprintSource='psf' (ignored otherwise)."
,
52
default=3.0,
53
)
54
copyColumns = lsst.pex.config.DictField(
55
keytype=str, itemtype=str, doc=
"Mapping of reference columns to source columns"
,
56
default={
"id"
:
"objectId"
,
"parent"
:
"parentObjectId"
,
57
"coord_ra"
:
"coord_ra"
,
"coord_dec"
:
"coord_dec"
}
58
)
59
checkUnitsParseStrict = lsst.pex.config.Field(
60
doc=
"Strictness of Astropy unit compatibility check, can be 'raise', 'warn' or 'silent'"
,
61
dtype=str,
62
default=
"raise"
,
63
)
64
65
def
setDefaults
(self):
66
self.
slots
.centroid =
"base_TransformedCentroidFromCoord"
67
self.
slots
.shape =
None
68
self.
slots
.apFlux =
None
69
self.
slots
.modelFlux =
None
70
self.
slots
.psfFlux =
"base_PsfFlux"
71
self.
slots
.gaussianFlux =
None
72
self.
slots
.calibFlux =
None
73
74
75
class
SimpleForcedMeasurementTask
(
SimpleBaseMeasurementTask
):
76
"""Measure sources on an image using a simple forced measurement algorithm.
77
78
This differes from ForcedMeasurmentTask in that it uses a PSF-based
79
footprint for every source so it does not need to transform footprints.
80
81
Parameters
82
----------
83
algMetadata : `lsst.daf.base.PropertyList` or `None`
84
Will be updated in place to to record information about each
85
algorithm. An empty `~lsst.daf.base.PropertyList` will be created if
86
`None`.
87
**kwds
88
Keyword arguments are passed to the supertask constructor.
89
"""
90
ConfigClass = SimpleForcedMeasurementConfig
91
92
def
__init__
(self, refSchema, algMetadata: lsst.
daf.base.PropertyList
=
None
, **kwds):
93
super().
__init__
(algMetadata=algMetadata, **kwds)
94
self.
mapper
=
lsst.afw.table.SchemaMapper
(refSchema)
95
self.
mapper
.addMinimalSchema(
lsst.afw.table.SourceTable.makeMinimalSchema
(),
False
)
96
self.config.slots.setupSchema(self.
mapper
.editOutputSchema())
97
for
refName, targetName
in
self.config.copyColumns.items():
98
refItem = refSchema.find(refName)
99
self.
mapper
.addMapping(refItem.key, targetName)
100
self.config.slots.setupSchema(self.
mapper
.editOutputSchema())
101
self.
initializePlugins
(schemaMapper=self.
mapper
)
102
self.
addInvalidPsfFlag
(self.
mapper
.editOutputSchema())
103
self.
schema
= self.
mapper
.getOutputSchema()
104
self.
schema
.checkUnits(parse_strict=self.config.checkUnitsParseStrict)
105
106
def
run
(
107
self,
108
refCat: lsst.
afw.table.SourceCatalog
,
109
measCat:
lsst.afw.table.SourceCatalog
,
110
exposure:
lsst.afw.image.Exposure
,
111
refWcs:
lsst.afw.geom.SkyWcs
,
112
beginOrder: int |
None
=
None
,
113
endOrder: int |
None
=
None
,
114
) ->
None
:
115
"""Perform forced measurement.
116
117
Parameters
118
----------
119
refCat : `lsst.afw.table.SourceCatalog`
120
Catalog with locations and ids of sources to measure.
121
measCat : `lsst.afw.table.SourceCatalog`
122
Catalog that measurements are made on.
123
exposure : `lsst.afw.image.exposureF`
124
Image to be measured. Must have at least a `lsst.afw.geom.SkyWcs`
125
attached.
126
refWcs : `lsst.afw.geom.SkyWcs`
127
Defines the X,Y coordinate system of ``refCat``.
128
beginOrder : `int`, optional
129
Beginning execution order (inclusive). Algorithms with
130
``executionOrder`` < ``beginOrder`` are not executed. `None` for no limit.
131
endOrder : `int`, optional
132
Ending execution order (exclusive). Algorithms with
133
``executionOrder`` >= ``endOrder`` are not executed. `None` for no limit.
134
idFactory : `lsst.afw.table.IdFactory`, optional
135
Factory for creating IDs for sources.
136
"""
137
self.
_attachPsfShapeFootprints
(measCat, exposure, scaling=self.config.psfFootprintScaling)
138
self.log.info(
"Performing forced measurement on %d source%s"
, len(refCat),
139
""
if
len(refCat) == 1
else
"s"
)
140
# Wrap the task logger into a periodic logger.
141
periodicLog = PeriodicLogger(self.log)
142
143
for
index
in
range(len(refCat)):
144
measRecord = measCat[index]
145
refRecord = refCat[index]
146
if
measRecord.getFootprint()
is
None
:
147
self.log.warning(
"Skipping object with ID %s that is off the image."
, measRecord.getId())
148
self.
callMeasure
(measRecord, exposure, refRecord, refWcs,
149
beginOrder=beginOrder, endOrder=endOrder)
150
# Log a message if it has been a while since the last log.
151
periodicLog.log(
"Forced measurement complete for %d parents (and their children) out of %d"
,
152
index + 1, len(refCat))
153
154
def
_attachPsfShapeFootprints
(self, sources, exposure, scaling=3):
155
"""Attach Footprints to blank sources prior to measurement, by
156
creating elliptical Footprints from the PSF moments.
157
158
Parameters
159
----------
160
sources : `lsst.afw.table.SourceCatalog`
161
Blank catalog (with all rows and columns, but values other than
162
``coord_ra``, ``coord_dec`` unpopulated).
163
to which footprints should be attached.
164
exposure : `lsst.afw.image.Exposure`
165
Image object from which peak values and the PSF are obtained.
166
scaling : `int`, optional
167
Scaling factor to apply to the PSF second-moments ellipse in order
168
to determine the footprint boundary.
169
"""
170
psf = exposure.getPsf()
171
if
psf
is
None
:
172
raise
RuntimeError(
"Cannot construct Footprints from PSF shape without a PSF."
)
173
bbox = exposure.getBBox()
174
wcs = exposure.getWcs()
175
# This will always be coord_ra, coord_dec since we converted the
176
# astropy table into a schema and schema is always coord_ra, coord_dec.
177
x, y = wcs.skyToPixelArray(sources[
"coord_ra"
], sources[
"coord_dec"
], degrees=
False
)
178
inBBox = np.atleast_1d(
lsst.geom.Box2D
(bbox).contains(x, y))
179
for
idx, record
in
enumerate(sources):
180
localPoint =
lsst.geom.Point2D
(x[idx], y[idx])
181
localIntPoint =
lsst.geom.Point2I
(localPoint)
182
if
not
inBBox[idx]:
183
record.setFootprint(
None
)
184
continue
185
ellipse =
lsst.afw.geom.ellipses.Ellipse
(psf.computeShape(localPoint), localPoint)
186
ellipse.getCore().scale(scaling)
187
spans =
lsst.afw.geom.SpanSet.fromShape
(ellipse)
188
footprint =
lsst.afw.detection.Footprint
(spans.clippedTo(bbox), bbox)
189
footprint.addPeak(localIntPoint.getX(), localIntPoint.getY(),
190
exposure.image._get(localIntPoint, lsst.afw.image.PARENT))
191
record.setFootprint(footprint)
lsst::afw::detection::Footprint
lsst::afw::geom::SkyWcs
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::afw::geom::ellipses::Ellipse
lsst::afw::image::Exposure
lsst::afw::table::SchemaMapper
lsst::afw::table::SortedCatalogT< SourceRecord >
lsst::afw::table::SourceTable::makeMinimalSchema
static Schema makeMinimalSchema()
lsst::daf::base::PropertyList
lsst::geom::Box2D
lsst::geom::Point< double, 2 >
lsst::meas::base.baseMeasurement.SimpleBaseMeasurementConfig
Definition
baseMeasurement.py:140
lsst::meas::base.baseMeasurement.SimpleBaseMeasurementConfig.slots
slots
Definition
baseMeasurement.py:142
lsst::meas::base.baseMeasurement.SimpleBaseMeasurementTask
Definition
baseMeasurement.py:237
lsst::meas::base.baseMeasurement.SimpleBaseMeasurementTask.addInvalidPsfFlag
addInvalidPsfFlag(self, schema)
Definition
baseMeasurement.py:326
lsst::meas::base.baseMeasurement.SimpleBaseMeasurementTask.initializePlugins
initializePlugins(self, **kwds)
Definition
baseMeasurement.py:282
lsst::meas::base.baseMeasurement.SimpleBaseMeasurementTask.callMeasure
callMeasure(self, measRecord, *args, **kwds)
Definition
baseMeasurement.py:337
lsst::meas::base.simple_forced_measurement.SimpleForcedMeasurementConfig
Definition
simple_forced_measurement.py:39
lsst::meas::base.simple_forced_measurement.SimpleForcedMeasurementConfig.setDefaults
setDefaults(self)
Definition
simple_forced_measurement.py:65
lsst::meas::base.simple_forced_measurement.SimpleForcedMeasurementTask
Definition
simple_forced_measurement.py:75
lsst::meas::base.simple_forced_measurement.SimpleForcedMeasurementTask.run
None run(self, lsst.afw.table.SourceCatalog refCat, lsst.afw.table.SourceCatalog measCat, lsst.afw.image.Exposure exposure, lsst.afw.geom.SkyWcs refWcs, int|None beginOrder=None, int|None endOrder=None)
Definition
simple_forced_measurement.py:114
lsst::meas::base.simple_forced_measurement.SimpleForcedMeasurementTask.mapper
mapper
Definition
simple_forced_measurement.py:94
lsst::meas::base.simple_forced_measurement.SimpleForcedMeasurementTask._attachPsfShapeFootprints
_attachPsfShapeFootprints(self, sources, exposure, scaling=3)
Definition
simple_forced_measurement.py:154
lsst::meas::base.simple_forced_measurement.SimpleForcedMeasurementTask.schema
schema
Definition
simple_forced_measurement.py:103
lsst::meas::base.simple_forced_measurement.SimpleForcedMeasurementTask.__init__
__init__(self, refSchema, lsst.daf.base.PropertyList algMetadata=None, **kwds)
Definition
simple_forced_measurement.py:92
lsst::afw::geom
lsst::afw::image
lsst::afw::table
lsst::daf::base
lsst::geom
lsst::pex::config
lsst.pipe.base
Generated on
for lsst.meas.base by
1.17.0