lsst.meas.extensions.trailedSources
g1147af6e9c+35b0431be0
Toggle main menu visibility
Loading...
Searching...
No Matches
python
lsst
meas
extensions
trailedSources
VeresPlugin.py
Go to the documentation of this file.
1
#
2
# This file is part of meas_extensions_trailedSources.
3
#
4
# Developed for the LSST Data Management System.
5
# This product includes software developed by the LSST Project
6
# (http://www.lsst.org).
7
# See the COPYRIGHT file at the top-level directory of this distribution
8
# for details of code ownership.
9
#
10
# This program is free software: you can redistribute it and/or modify
11
# it under the terms of the GNU General Public License as published by
12
# the Free Software Foundation, either version 3 of the License, or
13
# (at your option) any later version.
14
#
15
# This program is distributed in the hope that it will be useful,
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
# GNU General Public License for more details.
19
#
20
# You should have received a copy of the GNU General Public License
21
# along with this program. If not, see <http://www.gnu.org/licenses/>.
22
#
23
24
import
numpy
as
np
25
import
scipy.optimize
as
sciOpt
26
27
from
lsst.pex.config
import
Field
28
29
from
lsst.meas.base.pluginRegistry
import
register
30
from
lsst.meas.base
import
SingleFramePlugin, SingleFramePluginConfig
31
from
lsst.meas.base
import
FlagHandler, FlagDefinitionList, SafeCentroidExtractor
32
33
from
._trailedSources
import
VeresModel
34
from
.NaivePlugin
import
SingleFrameNaiveTrailPlugin
35
from
.utils
import
getMeasurementCutout
36
37
__all__ = (
"SingleFrameVeresTrailConfig"
,
"SingleFrameVeresTrailPlugin"
)
38
39
40
class
SingleFrameVeresTrailConfig
(SingleFramePluginConfig):
41
"""Config class for SingleFrameVeresTrailPlugin
42
"""
43
44
optimizerMethod = Field(
45
doc=
"Optimizer method for scipy.optimize.minimize"
,
46
dtype=str,
47
default=
"L-BFGS-B"
48
)
49
50
51
@register("ext_trailedSources_Veres")
52
class
SingleFrameVeresTrailPlugin
(SingleFramePlugin):
53
"""Veres trailed source characterization plugin.
54
55
Measures the length, angle, flux, centroid, and end points of a trailed
56
source using the Veres et al. 2012 model [1]_.
57
58
Parameters
59
----------
60
config: `SingleFrameNaiveTrailConfig`
61
Plugin configuration.
62
name: `str`
63
Plugin name.
64
schema: `lsst.afw.table.Schema`
65
Schema for the output catalog.
66
metadata: `lsst.daf.base.PropertySet`
67
Metadata to be attached to output catalog.
68
69
Notes
70
-----
71
This plugin is designed to refine the measurements of trail length,
72
angle, and end points from `NaivePlugin`, and of flux and centroid from
73
previous measurement algorithms. Vereš et al. 2012 [1]_ derive a model for
74
the flux in a given image pixel by convolving an axisymmetric Gaussian with
75
a line. The model is parameterized by the total flux, trail length, angle
76
from the x-axis, and the centroid. The best estimates are computed using a
77
chi-squared minimization.
78
79
References
80
----------
81
.. [1] Vereš, P., et al. "Improved Asteroid Astrometry and Photometry with
82
Trail Fitting" PASP, vol. 124, 2012.
83
84
See also
85
--------
86
lsst.meas.base.SingleFramePlugin
87
"""
88
89
ConfigClass = SingleFrameVeresTrailConfig
90
91
@classmethod
92
def
getExecutionOrder
(cls):
93
# Needs centroids, shape, flux, and NaivePlugin measurements.
94
# Make sure this always runs after NaivePlugin.
95
return
SingleFrameNaiveTrailPlugin.getExecutionOrder() + 0.1
96
97
def
__init__
(self, config, name, schema, metadata, logName=None):
98
super().
__init__
(config, name, schema, metadata, logName=logName)
99
100
self.
keyXC
= schema.addField(
101
name +
"_centroid_x"
, type=
"D"
, doc=
"Trail centroid X coordinate."
, units=
"pixel"
)
102
self.
keyYC
= schema.addField(
103
name +
"_centroid_y"
, type=
"D"
, doc=
"Trail centroid Y coordinate."
, units=
"pixel"
)
104
self.
keyX0
= schema.addField(name +
"_x0"
, type=
"D"
, doc=
"Trail head X coordinate."
, units=
"pixel"
)
105
self.
keyY0
= schema.addField(name +
"_y0"
, type=
"D"
, doc=
"Trail head Y coordinate."
, units=
"pixel"
)
106
self.
keyX1
= schema.addField(name +
"_x1"
, type=
"D"
, doc=
"Trail tail X coordinate."
, units=
"pixel"
)
107
self.
keyY1
= schema.addField(name +
"_y1"
, type=
"D"
, doc=
"Trail tail Y coordinate."
, units=
"pixel"
)
108
self.
keyLength
= schema.addField(name +
"_length"
, type=
"D"
, doc=
"Length of trail."
, units=
"pixel"
)
109
self.
keyTheta
= schema.addField(name +
"_angle"
, type=
"D"
, doc=
"Angle of trail from +x-axis."
)
110
self.
keyFlux
= schema.addField(name +
"_flux"
, type=
"D"
, doc=
"Trailed source flux."
, units=
"count"
)
111
self.
keyRChiSq
= schema.addField(name +
"_rChiSq"
, type=
"D"
, doc=
"Reduced chi-squared of fit"
)
112
113
flagDefs =
FlagDefinitionList
()
114
self.
FAILURE
= flagDefs.addFailureFlag(
"No trailed-sources measured"
)
115
self.
NON_CONVERGE
= flagDefs.add(
"flag_nonConvergence"
,
"Optimizer did not converge"
)
116
self.
NO_NAIVE
= flagDefs.add(
"flag_noNaive"
,
"Naive measurement contains NaNs"
)
117
self.
flagHandler
= FlagHandler.addFields(schema, name, flagDefs)
118
119
self.
centroidExtractor
=
SafeCentroidExtractor
(schema, name)
120
121
def
measure
(self, measRecord, exposure):
122
"""Run the Veres trailed source measurement plugin.
123
124
Parameters
125
----------
126
measRecord : `lsst.afw.table.SourceRecord`
127
Record describing the object being measured.
128
exposure : `lsst.afw.image.Exposure`
129
Pixel data to be measured.
130
131
See also
132
--------
133
lsst.meas.base.SingleFramePlugin.measure
134
"""
135
xc, yc = self.
centroidExtractor
(measRecord, self.
flagHandler
)
136
137
# Look at measRecord for Naive measurements
138
# ASSUMES NAIVE ALREADY RAN
139
flux = measRecord.get(
"ext_trailedSources_Naive_flux"
)
140
length = measRecord.get(
"ext_trailedSources_Naive_length"
)
141
theta = measRecord.get(
"ext_trailedSources_Naive_angle"
)
142
if
not
np.isfinite(flux)
or
not
np.isfinite(length)
or
not
np.isfinite(theta):
143
self.
flagHandler
.setValue(measRecord, self.
NO_NAIVE
.number)
144
self.
flagHandler
.setValue(measRecord, self.
FAILURE
.number)
145
return
146
147
# Get exposure cutout
148
# sigma = exposure.getPsf().getSigma()
149
# cutout = getMeasurementCutout(exposure, xc, yc, length, sigma)
150
cutout = getMeasurementCutout(measRecord, exposure)
151
152
# Make VeresModel
153
model =
VeresModel
(cutout)
154
155
# Do optimization with scipy
156
params = np.array([xc, yc, flux, length, theta])
157
results = sciOpt.minimize(
158
model, params, method=self.config.optimizerMethod, jac=model.gradient)
159
160
# Check if optimizer converged
161
if
not
results.success:
162
self.
flagHandler
.setValue(measRecord, self.
NON_CONVERGE
.number)
163
self.
flagHandler
.setValue(measRecord, self.
FAILURE
.number)
164
return
165
166
# Calculate end points and reduced chi-squared
167
xc_fit, yc_fit, flux_fit, length_fit, theta_fit = results.x
168
a = length_fit/2
169
x0_fit = xc_fit - a * np.cos(theta_fit)
170
y0_fit = yc_fit - a * np.sin(theta_fit)
171
x1_fit = xc_fit + a * np.cos(theta_fit)
172
y1_fit = yc_fit + a * np.sin(theta_fit)
173
rChiSq = results.fun / (cutout.image.array.size - 6)
174
175
# Set keys
176
measRecord.set(self.
keyXC
, xc_fit)
177
measRecord.set(self.
keyYC
, yc_fit)
178
measRecord.set(self.
keyX0
, x0_fit)
179
measRecord.set(self.
keyY0
, y0_fit)
180
measRecord.set(self.
keyX1
, x1_fit)
181
measRecord.set(self.
keyY1
, y1_fit)
182
measRecord.set(self.
keyFlux
, flux_fit)
183
measRecord.set(self.
keyLength
, length_fit)
184
measRecord.set(self.
keyTheta
, theta_fit)
185
measRecord.set(self.
keyRChiSq
, rChiSq)
186
187
def
fail
(self, measRecord, error=None):
188
"""Record failure
189
190
See also
191
--------
192
lsst.meas.base.SingleFramePlugin.fail
193
"""
194
if
error
is
None
:
195
self.
flagHandler
.handleFailure(measRecord)
196
else
:
197
self.
flagHandler
.handleFailure(measRecord, error.cpp)
lsst::meas::base::FlagDefinitionList
lsst::meas::base::SafeCentroidExtractor
lsst::meas::extensions::trailedSources::VeresModel
Implementation of an axisymmetric 2D Gaussian convolved with a line – a model for a fast-moving,...
Definition
VeresModel.h:47
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailConfig
Definition
VeresPlugin.py:40
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin
Definition
VeresPlugin.py:52
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.keyRChiSq
keyRChiSq
Definition
VeresPlugin.py:111
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.centroidExtractor
centroidExtractor
Definition
VeresPlugin.py:119
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.keyX0
keyX0
Definition
VeresPlugin.py:104
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.getExecutionOrder
getExecutionOrder(cls)
Definition
VeresPlugin.py:92
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.keyX1
keyX1
Definition
VeresPlugin.py:106
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.NON_CONVERGE
NON_CONVERGE
Definition
VeresPlugin.py:115
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.keyY0
keyY0
Definition
VeresPlugin.py:105
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.NO_NAIVE
NO_NAIVE
Definition
VeresPlugin.py:116
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.keyLength
keyLength
Definition
VeresPlugin.py:108
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.keyY1
keyY1
Definition
VeresPlugin.py:107
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.flagHandler
flagHandler
Definition
VeresPlugin.py:117
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.fail
fail(self, measRecord, error=None)
Definition
VeresPlugin.py:187
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.__init__
__init__(self, config, name, schema, metadata, logName=None)
Definition
VeresPlugin.py:97
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.keyFlux
keyFlux
Definition
VeresPlugin.py:110
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.keyXC
keyXC
Definition
VeresPlugin.py:100
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.FAILURE
FAILURE
Definition
VeresPlugin.py:114
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.keyYC
keyYC
Definition
VeresPlugin.py:102
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.keyTheta
keyTheta
Definition
VeresPlugin.py:109
lsst::meas::extensions::trailedSources.VeresPlugin.SingleFrameVeresTrailPlugin.measure
measure(self, measRecord, exposure)
Definition
VeresPlugin.py:121
lsst::meas::base::pluginRegistry
lsst::meas::base
lsst::pex::config
Generated on
for lsst.meas.extensions.trailedSources by
1.17.0