Loading [MathJax]/extensions/tex2jax.js
LSST Applications g0fba68d861+05816baf74,g1ec0fe41b4+f536777771,g1fd858c14a+a9301854fb,g35bb328faa+fcb1d3bbc8,g4af146b050+a5c07d5b1d,g4d2262a081+6e5fcc2a4e,g53246c7159+fcb1d3bbc8,g56a49b3a55+9c12191793,g5a012ec0e7+3632fc3ff3,g60b5630c4e+ded28b650d,g67b6fd64d1+ed4b5058f4,g78460c75b0+2f9a1b4bcd,g786e29fd12+cf7ec2a62a,g8352419a5c+fcb1d3bbc8,g87b7deb4dc+7b42cf88bf,g8852436030+e5453db6e6,g89139ef638+ed4b5058f4,g8e3bb8577d+d38d73bdbd,g9125e01d80+fcb1d3bbc8,g94187f82dc+ded28b650d,g989de1cb63+ed4b5058f4,g9d31334357+ded28b650d,g9f33ca652e+50a8019d8c,gabe3b4be73+1e0a283bba,gabf8522325+fa80ff7197,gb1101e3267+d9fb1f8026,gb58c049af0+f03b321e39,gb665e3612d+2a0c9e9e84,gb89ab40317+ed4b5058f4,gcf25f946ba+e5453db6e6,gd6cbbdb0b4+bb83cc51f8,gdd1046aedd+ded28b650d,gde0f65d7ad+941d412827,ge278dab8ac+d65b3c2b70,ge410e46f29+ed4b5058f4,gf23fb2af72+b7cae620c0,gf5e32f922b+fcb1d3bbc8,gf67bdafdda+ed4b5058f4,w.2025.16
LSST Data Management Base Package
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
SdssCentroid.cc
Go to the documentation of this file.
1// -*- lsst-c++ -*-
2/*
3 * LSST Data Management System
4 * Copyright 2008-2013 LSST Corporation.
5 *
6 * This product includes software developed by the
7 * LSST Project (http://www.lsst.org/).
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 LSST License Statement and
20 * the GNU General Public License along with this program. If not,
21 * see <http://www.lsstcorp.org/LegalNotices/>.
22 */
23#include <iostream>
24#include <cmath>
25#include <numeric>
26#include "ndarray/eigen.h"
27#include "lsst/geom/Angle.h"
30#include "lsst/pex/exceptions.h"
35
36namespace lsst {
37namespace meas {
38namespace base {
39namespace {
40FlagDefinitionList flagDefinitions;
41} // namespace
42
43FlagDefinition const SdssCentroidAlgorithm::FAILURE = flagDefinitions.addFailureFlag();
45 flagDefinitions.add("flag_edge", "Object too close to edge; peak used.");
47 flagDefinitions.add("flag_noSecondDerivative", "Vanishing second derivative");
49 flagDefinitions.add("flag_almostNoSecondDerivative", "Almost vanishing second derivative");
51 flagDefinitions.add("flag_notAtMaximum", "Object is not at a maximum");
53 flagDefinitions.add("flag_near_edge", "Object close to edge; fallback kernel used.");
54
56
57namespace {
58
59/************************************************************************************************************/
60
61float const AMPAST4 = 1.33; // amplitude of `4th order' corr compared to theory
62
63/*
64 * Do the Gaussian quartic interpolation for the position
65 * of the maximum for three equally spaced values vm,v0,vp, assumed to be at
66 * abscissae -1,0,1; the answer is returned as *cen
67 *
68 * Return 0 is all is well, otherwise 1
69 */
70static int inter4(float vm, float v0, float vp, float *cen, bool negative = false) {
71 float const sp = v0 - vp;
72 float const sm = v0 - vm;
73 float const d2 = sp + sm;
74 float const s = 0.5 * (vp - vm);
75
76 if ((!negative && (d2 <= 0.0f || v0 <= 0.0f)) || (negative && (d2 >= 0.0f || v0 >= 0.0f))) {
77 return (1);
78 }
79
80 *cen = s / d2 * (1.0 + AMPAST4 * sp * sm / (d2 * v0));
81
82 return fabs(*cen) < 1 ? 0 : 1;
83}
84
85/*****************************************************************************/
86/*
87 * Calculate error in centroid
88 */
89float astrom_errors(float skyVar, // variance of pixels at the sky level
90 float sourceVar, // variance in peak due to excess counts over sky
91 float A, // abs(peak value in raw image)
92 float tau2, // Object is N(0,tau2)
93 float As, // abs(peak value in smoothed image)
94 float s, // slope across central pixel
95 float d, // curvature at central pixel
96 float sigma, // width of smoothing filter
97 int quarticBad) { // was quartic estimate bad?
98
99 double const k = quarticBad ? 0 : AMPAST4; /* quartic correction coeff */
100 double const sigma2 = sigma * sigma; /* == sigma^2 */
101 double sVar, dVar; /* variances of s and d */
102 double xVar; /* variance of centroid, x */
103
105 return (1e3);
106 }
107
108 if (sigma <= 0) { /* no smoothing; no covariance */
109 sVar = 0.5 * skyVar; /* due to sky */
110 dVar = 6 * skyVar;
111
112 sVar += 0.5 * sourceVar * exp(-1 / (2 * tau2));
113 dVar += sourceVar * (4 * exp(-1 / (2 * tau2)) + 2 * exp(-1 / (2 * tau2)));
114 } else { /* smoothed */
115 sVar = skyVar / (8 * geom::PI * sigma2) * (1 - exp(-1 / sigma2));
116 dVar = skyVar / (2 * geom::PI * sigma2) * (3 - 4 * exp(-1 / (4 * sigma2)) + exp(-1 / sigma2));
117
118 sVar += sourceVar / (12 * geom::PI * sigma2) * (exp(-1 / (3 * sigma2)) - exp(-1 / sigma2));
119 dVar += sourceVar / (3 * geom::PI * sigma2) * (2 - 3 * exp(-1 / (3 * sigma2)) + exp(-1 / sigma2));
120 }
121
122 xVar = sVar * pow(1 / d + k / (4 * As) * (1 - 12 * s * s / (d * d)), 2) +
123 dVar * pow(s / (d * d) - k / (4 * As) * 8 * s * s / (d * d * d), 2);
124
125 return (xVar >= 0 ? sqrt(xVar) : NAN);
126}
127
128/************************************************************************************************************/
129/*
130 * Estimate the position of an object, assuming we know that it's approximately the size of the PSF
131 */
132
133template <typename MaskedImageXy_locatorT>
134int doMeasureCentroidImpl(double *xCenter, // output; x-position of object
135 double *dxc, // output; error in xCenter
136 double *yCenter, // output; y-position of object
137 double *dyc, // output; error in yCenter
138 double *sizeX2, double *sizeY2, // output; object widths^2 in x and y directions
139 double *peakVal, // output; peak of object
140 MaskedImageXy_locatorT mim, // Locator for the pixel values
141 double smoothingSigma, // Gaussian sigma of already-applied smoothing filter
142 bool negative, FlagHandler flagHandler) {
143 /*
144 * find a first quadratic estimate
145 */
146 double const d2x = 2 * mim.image(0, 0) - mim.image(-1, 0) - mim.image(1, 0);
147 double const d2y = 2 * mim.image(0, 0) - mim.image(0, -1) - mim.image(0, 1);
148 double const sx = 0.5 * (mim.image(1, 0) - mim.image(-1, 0));
149 double const sy = 0.5 * (mim.image(0, 1) - mim.image(0, -1));
150
151 if (d2x == 0.0 || d2y == 0.0) {
153 }
154 if ((!negative && (d2x < 0.0 || d2y < 0.0)) || (negative && (d2x > 0.0 || d2y > 0.0))) {
156 }
157
158 double const dx0 = sx / d2x;
159 double const dy0 = sy / d2y; // first guess
160
161 if (fabs(dx0) > 10.0 || fabs(dy0) > 10.0) {
163 }
164
165 double vpk = mim.image(0, 0) + 0.5 * (sx * dx0 + sy * dy0); // height of peak in image
166 // if (vpk < 0) {
167 // vpk = -vpk;
168 //}
169 /*
170 * now evaluate maxima on stripes
171 */
172 float m0x = 0, m1x = 0, m2x = 0;
173 float m0y = 0, m1y = 0, m2y = 0;
174
175 int quarticBad = 0;
176 quarticBad += inter4(mim.image(-1, -1), mim.image(0, -1), mim.image(1, -1), &m0x, negative);
177 quarticBad += inter4(mim.image(-1, 0), mim.image(0, 0), mim.image(1, 0), &m1x, negative);
178 quarticBad += inter4(mim.image(-1, 1), mim.image(0, 1), mim.image(1, 1), &m2x, negative);
179
180 quarticBad += inter4(mim.image(-1, -1), mim.image(-1, 0), mim.image(-1, 1), &m0y, negative);
181 quarticBad += inter4(mim.image(0, -1), mim.image(0, 0), mim.image(0, 1), &m1y, negative);
182 quarticBad += inter4(mim.image(1, -1), mim.image(1, 0), mim.image(1, 1), &m2y, negative);
183
184 double xc, yc; // position of maximum
185 double sigmaX2, sigmaY2; // widths^2 in x and y of smoothed object
186
187 if (quarticBad) { // >= 1 quartic interpolator is bad
188 xc = dx0;
189 yc = dy0;
190 sigmaX2 = vpk / d2x; // widths^2 in x
191 sigmaY2 = vpk / d2y; // and y
192 } else {
193 double const smx = 0.5 * (m2x - m0x);
194 double const smy = 0.5 * (m2y - m0y);
195 double const dm2x = m1x - 0.5 * (m0x + m2x);
196 double const dm2y = m1y - 0.5 * (m0y + m2y);
197 double const dx = m1x + dy0 * (smx - dy0 * dm2x); // first quartic approx
198 double const dy = m1y + dx0 * (smy - dx0 * dm2y);
199 double const dx4 = m1x + dy * (smx - dy * dm2x); // second quartic approx
200 double const dy4 = m1y + dx * (smy - dx * dm2y);
201
202 xc = dx4;
203 yc = dy4;
204 sigmaX2 = vpk / d2x - (1 + 6 * dx0 * dx0) / 4; // widths^2 in x
205 sigmaY2 = vpk / d2y - (1 + 6 * dy0 * dy0) / 4; // and y
206 }
207 /*
208 * Now for the errors.
209 */
210 float tauX2 = sigmaX2; // width^2 of _un_ smoothed object
211 float tauY2 = sigmaY2;
212 tauX2 -= smoothingSigma * smoothingSigma; // correct for smoothing
213 tauY2 -= smoothingSigma * smoothingSigma;
214
215 if (tauX2 <= smoothingSigma * smoothingSigma) { // problem; sigmaX2 must be bad
216 tauX2 = smoothingSigma * smoothingSigma;
217 }
218 if (tauY2 <= smoothingSigma * smoothingSigma) { // sigmaY2 must be bad
219 tauY2 = smoothingSigma * smoothingSigma;
220 }
221
222 float const skyVar =
223 (mim.variance(-1, -1) + mim.variance(0, -1) + mim.variance(1, -1) + mim.variance(-1, 0) +
224 mim.variance(1, 0) + mim.variance(-1, 1) + mim.variance(0, 1) + mim.variance(1, 1)) /
225 8.0; // Variance in sky
226 float const sourceVar = mim.variance(0, 0); // extra variance of peak due to its photons
227 float const A = vpk * sqrt((sigmaX2 / tauX2) * (sigmaY2 / tauY2)); // peak of Unsmoothed object
228
229 *xCenter = xc;
230 *yCenter = yc;
231
232 *dxc = astrom_errors(skyVar, sourceVar, A, tauX2, vpk, sx, d2x, fabs(smoothingSigma), quarticBad);
233 *dyc = astrom_errors(skyVar, sourceVar, A, tauY2, vpk, sy, d2y, fabs(smoothingSigma), quarticBad);
234
235 *sizeX2 = tauX2; // return the estimates of the (object size)^2
236 *sizeY2 = tauY2;
237
238 *peakVal = vpk;
239 return 0;
240}
241
242template <typename MaskedImageT>
243std::tuple<MaskedImageT, double, int> smoothAndBinImage(std::shared_ptr<afw::detection::Psf const> psf, int const x,
244 const int y, MaskedImageT const &mimage, int binX, int binY,
245 FlagHandler _flagHandler) {
246 geom::Point2D const center(x + mimage.getX0(), y + mimage.getY0());
247 afw::geom::ellipses::Quadrupole const &shape = psf->computeShape(center);
248 double const smoothingSigma = shape.getDeterminantRadius();
249#if 0
250 double const nEffective = psf->computeEffectiveArea(); // not implemented yet (#2821)
251#else
252 double const nEffective = 4 * M_PI * smoothingSigma * smoothingSigma; // correct for a Gaussian
253#endif
254
255 std::shared_ptr<afw::math::Kernel const> kernel = psf->getLocalKernel(center);
256 int const kWidth = kernel->getWidth();
257 int const kHeight = kernel->getHeight();
258
259 geom::BoxI bbox(geom::Point2I(x - binX * (2 + kWidth / 2), y - binY * (2 + kHeight / 2)),
260 geom::ExtentI(binX * (3 + kWidth + 1), binY * (3 + kHeight + 1)));
261
262 // image to smooth, a shallow copy
263 std::shared_ptr<MaskedImageT> subImage;
264 if (!mimage.getBBox(afw::image::LOCAL).contains(bbox)) {
265 return std::make_tuple(mimage, 0, SdssCentroidAlgorithm::EDGE.number);
266 }
267 subImage.reset(new MaskedImageT(mimage, bbox, afw::image::LOCAL));
268 std::shared_ptr<MaskedImageT> binnedImage = afw::math::binImage(*subImage, binX, binY, afw::math::MEAN);
269 binnedImage->setXY0(subImage->getXY0());
270 // image to smooth into, a deep copy.
271 MaskedImageT smoothedImage = MaskedImageT(*binnedImage, true);
272 if(smoothedImage.getWidth() / 2 != kWidth / 2 + 2 || // assumed by the code that uses smoothedImage
273 smoothedImage.getHeight() / 2 != kHeight / 2 + 2) {
274 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError, "invalid image dimensions");
275 }
276
277 afw::math::convolve(smoothedImage, *binnedImage, *kernel, afw::math::ConvolutionControl());
278 *smoothedImage.getVariance() *= binX * binY * nEffective; // We want the per-pixel variance, so undo the
279 // effects of binning and smoothing
280
281 return std::make_tuple(smoothedImage, smoothingSigma, 0);
282}
283
284} // end anonymous namespace
285
287 afw::table::Schema &schema)
288 : _ctrl(ctrl),
289 _centroidKey(CentroidResultKey::addFields(schema, name, "centroid from Sdss Centroid algorithm",
290 SIGMA_ONLY)),
291 _flagHandler(FlagHandler::addFields(schema, name, getFlagDefinitions())),
292 _centroidExtractor(schema, name, true),
293 _centroidChecker(schema, name, ctrl.doFootprintCheck, ctrl.maxDistToPeak) {}
295 afw::image::Exposure<float> const &exposure) const {
296 // get our current best guess about the centroid: either a centroider measurement or peak.
297 geom::Point2D center = _centroidExtractor(measRecord, _flagHandler);
298 CentroidResult result;
299 result.x = center.getX();
300 result.y = center.getY();
301 measRecord.set(_centroidKey, result); // better than NaN
302
304 typedef MaskedImageT::Image ImageT;
305 typedef MaskedImageT::Variance VarianceT;
306 bool negative = false;
307 try {
308 negative = measRecord.get(measRecord.getSchema().find<afw::table::Flag>("is_negative").key);
309 } catch (pexExcept::Exception &e) {
310 }
311
312 MaskedImageT const &mimage = exposure.getMaskedImage();
313 ImageT const &image = *mimage.getImage();
314 std::shared_ptr<afw::detection::Psf const> psf = exposure.getPsf();
315
316 int const x = image.positionToIndex(center.getX(), afw::image::X).first;
317 int const y = image.positionToIndex(center.getY(), afw::image::Y).first;
318
319 if (!image.getBBox().contains(geom::Extent2I(x, y) + image.getXY0())) {
320 _flagHandler.setValue(measRecord, EDGE.number, true);
321 _flagHandler.setValue(measRecord, SdssCentroidAlgorithm::FAILURE.number, true);
322 return;
323 }
324
325 // Algorithm uses a least-squares fit (implemented via a convolution) to a symmetrized PSF model.
326 // If you don't have a Psf, you need to use another centroider, such as GaussianCentroider.
327 if (!psf) {
328 throw LSST_EXCEPT(FatalAlgorithmError, "SdssCentroid algorithm requires a Psf with every exposure");
329 }
330
331 int binX = 1;
332 int binY = 1;
333 double xc = 0., yc = 0., dxc = 0., dyc = 0.; // estimated centre and error therein
334 bool stopBinning = false;
335 for (int binsize = 1; binsize <= _ctrl.binmax; binsize *= 2) {
337 smoothAndBinImage(psf, x, y, mimage, binX, binY, _flagHandler);
338 int errorFlag = std::get<2>(smoothResult);
339 if (errorFlag == static_cast<int>(EDGE.number)) {
341 smoothResult = smoothAndBinImage(psf, x, y, mimage, binX, binY, _flagHandler);
342 stopBinning = true;
343 errorFlag = std::get<2>(smoothResult);
344 if (errorFlag == 0) {
345 errorFlag = NEAR_EDGE.number;
346 }
347 }
348 if (errorFlag > 0) {
349 _flagHandler.setValue(measRecord, errorFlag, true);
350 _flagHandler.setValue(measRecord, SdssCentroidAlgorithm::FAILURE.number, true);
351 // if NEAR_EDGE is not a fatal error we continue otherwise return
352 if (errorFlag != static_cast<int>(NEAR_EDGE.number)) {
353 return;
354 }
355 }
356 MaskedImageT const smoothedImage = std::get<0>(smoothResult);
357 double const smoothingSigma = std::get<1>(smoothResult);
358
359 MaskedImageT::xy_locator mim =
360 smoothedImage.xy_at(smoothedImage.getWidth() / 2, smoothedImage.getHeight() / 2);
361
362 double sizeX2, sizeY2; // object widths^2 in x and y directions
363 double peakVal; // peak intensity in image
364
365 errorFlag = doMeasureCentroidImpl(&xc, &dxc, &yc, &dyc, &sizeX2, &sizeY2, &peakVal, mim, smoothingSigma, negative,
366 _flagHandler);
367 if (errorFlag > 0) {
368 _flagHandler.setValue(measRecord, errorFlag, true);
369 _flagHandler.setValue(measRecord, SdssCentroidAlgorithm::FAILURE.number, true);
370 return;
371 }
372
373 if (binsize > 1) {
374 // dilate from the lower left corner of central pixel
375 xc = (xc + 0.5) * binX - 0.5;
376 dxc *= binX;
377 sizeX2 *= binX * binX;
378
379 yc = (yc + 0.5) * binY - 0.5;
380 dyc *= binY;
381 sizeY2 *= binY * binY;
382 }
383
384 xc += x; // xc, yc are measured relative to pixel (x, y)
385 yc += y;
386
387 if (stopBinning) {
388 break;
389 }
390
391 double const fac = _ctrl.wfac * (1 + smoothingSigma * smoothingSigma);
392 double const facX2 = fac * binX * binX;
393 double const facY2 = fac * binY * binY;
394
395 if (sizeX2 < facX2 && ::pow(xc - x, 2) < facX2 && sizeY2 < facY2 && ::pow(yc - y, 2) < facY2) {
396 if (binsize > 1 || _ctrl.peakMin < 0.0 || peakVal > _ctrl.peakMin) {
397 break;
398 }
399 }
400
401 if (sizeX2 >= facX2 || ::pow(xc - x, 2) >= facX2) {
402 binX *= 2;
403 }
404 if (sizeY2 >= facY2 || ::pow(yc - y, 2) >= facY2) {
405 binY *= 2;
406 }
407 }
408 result.x = afw::image::indexToPosition(xc + image.getX0());
409 result.y = afw::image::indexToPosition(yc + image.getY0());
410
411 result.xErr = sqrt(dxc * dxc);
412 result.yErr = sqrt(dyc * dyc);
413 measRecord.set(_centroidKey, result);
414 _centroidChecker(measRecord);
415}
416
418 _flagHandler.handleFailure(measRecord, error);
419}
420
423 : CentroidTransform{name, mapper} {
426 if (flag == SdssCentroidAlgorithm::FAILURE) continue;
427 if (mapper.getInputSchema().getNames().count(mapper.getInputSchema().join(name, flag.name)) == 0)
428 continue;
430 mapper.getInputSchema().find<afw::table::Flag>(name + "_" + flag.name).key;
431 mapper.addMapping(key);
432 }
433}
434
435} // namespace base
436} // namespace meas
437} // namespace lsst
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition Exception.h:48
#define M_PI
Definition ListMatch.cc:31
This implements the SdssCentroid algorithm within the meas_base measurement framework.
A class to contain the data, WCS, and other information needed to describe an image of the sky.
Definition Exposure.h:72
MaskedImage< ImageT, MaskT, VarianceT > MaskedImageT
Definition Exposure.h:74
Field< T >::Value get(Key< T > const &key) const
Return the value of a field for the given key.
Definition BaseRecord.h:151
Schema getSchema() const
Return the Schema that holds this record's fields and keys.
Definition BaseRecord.h:80
void set(Key< T > const &key, U const &value)
Set value of a field for the given key.
Definition BaseRecord.h:164
A class used as a handle to a particular field in a table.
Definition Key.h:53
Defines the fields and offsets for a table.
Definition Schema.h:51
std::string join(std::string const &a, std::string const &b) const
Join strings using the field delimiter appropriate for this Schema.
Definition Schema.cc:452
std::set< std::string > getNames(bool topOnly=false) const
Return a set of field names in the schema.
Definition Schema.cc:464
SchemaItem< T > find(std::string const &name) const
Find a SchemaItem in the Schema by name.
Definition Schema.cc:467
A mapping between the keys of two Schemas, used to copy data between them.
Key< T > addMapping(Key< T > const &inputKey, bool doReplace=false)
Add a new field to the output Schema that is a copy of a field in the input Schema.
Schema const getInputSchema() const
Return the input schema (copy-on-write).
Record class that contains measurements made on a single exposure.
Definition Source.h:78
A FunctorKey for CentroidResult.
CentroidTransform(std::string const &name, afw::table::SchemaMapper &mapper)
Exception to be thrown when a measurement algorithm experiences a fatal error.
Definition exceptions.h:76
vector-type utility class to build a collection of FlagDefinitions
Definition FlagHandler.h:60
std::size_t size() const
return the current size (number of defined elements) of the collection
Utility class for handling flag fields that indicate the failure modes of an algorithm.
Exception to be thrown when a measurement algorithm experiences a known failure mode.
Definition exceptions.h:48
static FlagDefinition const NOT_AT_MAXIMUM
virtual void fail(afw::table::SourceRecord &measRecord, MeasurementError *error=nullptr) const
Handle an exception thrown by the current algorithm by setting flags in the given record.
SdssCentroidAlgorithm(Control const &ctrl, std::string const &name, afw::table::Schema &schema)
static FlagDefinition const NO_SECOND_DERIVATIVE
SdssCentroidControl Control
A typedef to the Control object for this algorithm, defined above.
static FlagDefinition const FAILURE
static FlagDefinition const NEAR_EDGE
virtual void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const
Called to measure a single child source in an image.
static FlagDefinitionList const & getFlagDefinitions()
static FlagDefinition const ALMOST_NO_SECOND_DERIVATIVE
static FlagDefinition const EDGE
SdssCentroidTransform(Control const &ctrl, std::string const &name, afw::table::SchemaMapper &mapper)
T count(T... args)
T exp(T... args)
T fabs(T... args)
T make_shared(T... args)
T make_tuple(T... args)
T min(T... args)
double indexToPosition(double ind)
Convert image index to image position.
Definition ImageUtils.h:55
void convolve(OutImageT &convolvedImage, InImageT const &inImage, KernelT const &kernel, ConvolutionControl const &convolutionControl=ConvolutionControl())
Convolve an Image or MaskedImage with a Kernel, setting pixels of an existing output image.
@ MEAN
estimate sample mean
Definition Statistics.h:57
std::shared_ptr< ImageT > binImage(ImageT const &inImage, int const binX, int const binY, lsst::afw::math::Property const flags=lsst::afw::math::MEAN)
Definition binImage.cc:44
Extent< int, 2 > ExtentI
Definition Extent.h:396
Point< double, 2 > Point2D
Definition Point.h:324
double constexpr PI
The ratio of a circle's circumference to diameter.
Definition Angle.h:40
Extent< int, 2 > Extent2I
Definition Extent.h:397
Box2I BoxI
Definition Box.h:780
Point< int, 2 > Point2I
Definition Point.h:321
@ SIGMA_ONLY
Only the diagonal elements of the covariance matrix are provided.
Definition constants.h:45
T pow(T... args)
T reset(T... args)
T sqrt(T... args)
A reusable struct for centroid measurements.
Simple class used to define and document flags The name and doc constitute the identity of the FlagDe...
Definition FlagHandler.h:40