LSSTApplications  17.0+11,17.0+34,17.0+56,17.0+57,17.0+59,17.0+7,17.0-1-g377950a+33,17.0.1-1-g114240f+2,17.0.1-1-g4d4fbc4+28,17.0.1-1-g55520dc+49,17.0.1-1-g5f4ed7e+52,17.0.1-1-g6dd7d69+17,17.0.1-1-g8de6c91+11,17.0.1-1-gb9095d2+7,17.0.1-1-ge9fec5e+5,17.0.1-1-gf4e0155+55,17.0.1-1-gfc65f5f+50,17.0.1-1-gfc6fb1f+20,17.0.1-10-g87f9f3f+1,17.0.1-11-ge9de802+16,17.0.1-16-ga14f7d5c+4,17.0.1-17-gc79d625+1,17.0.1-17-gdae4c4a+8,17.0.1-2-g26618f5+29,17.0.1-2-g54f2ebc+9,17.0.1-2-gf403422+1,17.0.1-20-g2ca2f74+6,17.0.1-23-gf3eadeb7+1,17.0.1-3-g7e86b59+39,17.0.1-3-gb5ca14a,17.0.1-3-gd08d533+40,17.0.1-30-g596af8797,17.0.1-4-g59d126d+4,17.0.1-4-gc69c472+5,17.0.1-6-g5afd9b9+4,17.0.1-7-g35889ee+1,17.0.1-7-gc7c8782+18,17.0.1-9-gc4bbfb2+3,w.2019.22
LSSTDataManagementBasePackage
CentroidUtilities.cc
Go to the documentation of this file.
1 /*
2  * LSST Data Management System
3  * Copyright 2008-2014 LSST Corporation.
4  *
5  * This product includes software developed by the
6  * LSST Project (http://www.lsst.org/).
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the LSST License Statement and
19  * the GNU General Public License along with this program. If not,
20  * see <http://www.lsstcorp.org/LegalNotices/>.
21  */
22 
23 #include <cmath>
24 
25 #include "lsst/geom/Angle.h"
26 #include "lsst/geom/Point.h"
29 
30 namespace lsst {
31 namespace meas {
32 namespace base {
33 
35  : x(std::numeric_limits<CentroidElement>::quiet_NaN()),
36  y(std::numeric_limits<CentroidElement>::quiet_NaN()),
37  xErr(std::numeric_limits<ErrElement>::quiet_NaN()),
38  yErr(std::numeric_limits<ErrElement>::quiet_NaN()),
39  x_y_Cov(std::numeric_limits<ErrElement>::quiet_NaN()) {}
40 
41 Centroid const CentroidResult::getCentroid() const { return Centroid(x, y); }
42 
44  x = centroid.getX();
45  y = centroid.getY();
46 }
47 
49  CentroidCov m;
50  m << xErr * xErr, x_y_Cov, x_y_Cov, yErr * yErr;
51  return m;
52 }
53 
55  xErr = std::sqrt(matrix(0, 0));
56  yErr = std::sqrt(matrix(1, 1));
57  x_y_Cov = matrix(0, 1);
58 }
59 
61  xErr = _xErr;
62  yErr = _yErr;
63  x_y_Cov = 0.0;
64 }
65 
67  std::string const &doc, UncertaintyEnum uncertainty) {
69  r._centroid = afw::table::PointKey<CentroidElement>::addFields(schema, name, doc, "pixel");
70  if (uncertainty != NO_UNCERTAINTY) {
73  sigma[0] = schema.addField<ErrElement>(schema.join(name, "xErr"), "1-sigma uncertainty on x position",
74  "pixel");
75  sigma[1] = schema.addField<ErrElement>(schema.join(name, "yErr"), "1-sigma uncertainty on y position",
76  "pixel");
77  if (uncertainty == FULL_COVARIANCE) {
78  cov.push_back(schema.addField<ErrElement>(schema.join(name, "x_y_Cov"),
79  "uncertainty covariance in x and y", "pixel^2"));
80  }
82  }
83  return r;
84 }
85 
86 namespace {
87 
88 std::vector<std::string> getNameVector() {
90  v.push_back("x");
91  v.push_back("y");
92  return v;
93 }
94 
95 } // namespace
96 
98  static std::vector<std::string> names = getNameVector(); // C++11 TODO: just use initializer list
99  try {
100  _centroidErr = afw::table::CovarianceMatrixKey<ErrElement, 2>(s, names);
101  } catch (pex::exceptions::NotFoundError &) {
102  }
103 }
104 
106  CentroidResult r;
107  r.setCentroid(record.get(_centroid));
108  if (_centroidErr.isValid()) {
109  r.setCentroidErr(record.get(_centroidErr));
110  }
111  return r;
112 }
113 
115  record.set(_centroid, value.getCentroid());
116  if (_centroidErr.isValid()) {
117  record.set(_centroidErr, value.getCentroidErr());
118  }
119 }
120 
122  : BaseTransform{name} {
123  // Map the flag through to the output
124  mapper.addMapping(mapper.getInputSchema().find<afw::table::Flag>(name + "_flag").key);
125 
126  // Add keys for the coordinates
127  auto &s = mapper.editOutputSchema();
128  _coordKey = afw::table::CoordKey::addFields(s, name, "ICRS coordinates");
129 
130  // If the centroid has an error key we also include one on the celestial
131  // coordinates; otherwise, it isn't necessary. Note that if we provide for
132  // errors in celestial coordinates, we always need the full covariance.
133  if (CentroidResultKey(mapper.getInputSchema()[name]).getCentroidErr().isValid()) {
136  sigma[0] = s.addField<ErrElement>(s.join(name, "raErr"), "1-sigma uncertainty on RA", "rad");
137  sigma[1] = s.addField<ErrElement>(s.join(name, "decErr"), "1-sigma uncertainty on dec", "rad");
138  cov[0] = s.addField<ErrElement>(s.join(name, "ra_dec_Cov"), "Uncertainty covariance in RA and dec",
139  "rad^2");
141  }
142 }
143 
145  afw::table::BaseCatalog &outputCatalog, afw::geom::SkyWcs const &wcs,
146  afw::image::PhotoCalib const &photoCalib) const {
147  checkCatalogSize(inputCatalog, outputCatalog);
148  CentroidResultKey centroidResultKey(inputCatalog.getSchema()[_name]);
149 
150  afw::table::SourceCatalog::const_iterator inSrc = inputCatalog.begin();
151  afw::table::BaseCatalog::iterator outSrc = outputCatalog.begin();
152 
153  for (; inSrc != inputCatalog.end() && outSrc != outputCatalog.end(); ++inSrc, ++outSrc) {
154  CentroidResult centroidResult = centroidResultKey.get(*inSrc);
155 
156  _coordKey.set(*outSrc, wcs.pixelToSky(centroidResult.getCentroid()));
157 
158  if (centroidResultKey.getCentroidErr().isValid()) {
159  CentroidCov centroidCov = centroidResult.getCentroidErr();
160  if (!(std::isnan(centroidCov(0, 0)) || std::isnan(centroidCov(1, 1)))) {
161  auto transform = wcs.linearizePixelToSky(centroidResult.getCentroid(), geom::radians)
162  .getLinear()
163  .getMatrix();
164  _coordErrKey.set(*outSrc, (transform * centroidResult.getCentroidErr().cast<double>() *
165  transform.transpose())
166  .cast<ErrElement>());
167  }
168  }
169  }
170 }
171 
172 // Add a key "flag_resetToPeak" if something is wrong with the centroid
173 // Save a key to this algorithm's Centroid, as well as the general failure flag
175  double maxDistFromPeak)
176  : _doFootprintCheck(doFootprintCheck), _maxDistFromPeak(maxDistFromPeak) {
177  _resetKey = schema.addField<afw::table::Flag>(schema.join(name, "flag_resetToPeak"),
178  "set if CentroidChecker reset the centroid");
179  _failureKey = schema.find<afw::table::Flag>(schema.join(name, "flag")).key;
180  _xKey = schema.find<CentroidElement>(schema.join(name, "x")).key;
181  _yKey = schema.find<CentroidElement>(schema.join(name, "y")).key;
182 }
183 
184 // Set the centroid to the first footprint if the centroid is eithe more than _maxDistFromPeak
185 // pixels from the centroid, or if it is outside the footprint.
187  CentroidElement x = record.get(_xKey);
188  CentroidElement y = record.get(_yKey);
189 
190  if (!_doFootprintCheck && _maxDistFromPeak < 0.0) {
191  return false;
192  }
194  if (!footprint) {
195  throw LSST_EXCEPT(pex::exceptions::RuntimeError, "No Footprint attached to record");
196  }
197  if (footprint->getPeaks().empty()) {
198  throw LSST_EXCEPT(pex::exceptions::RuntimeError, "Footprint has no peaks; cannot verify centroid.");
199  }
200  CentroidElement footX = footprint->getPeaks().front().getFx();
201  CentroidElement footY = footprint->getPeaks().front().getFy();
202  double distsq = (x - footX) * (x - footX) + (y - footY) * (y - footY);
203  if ((_doFootprintCheck && !footprint->contains(geom::Point2I(geom::Point2D(x, y)))) ||
204  ((_maxDistFromPeak > 0) && (distsq > _maxDistFromPeak * _maxDistFromPeak))) {
205  record.set(_xKey, footX);
206  record.set(_yKey, footY);
207  record.set(_failureKey, true);
208  record.set(_resetKey, true);
209  return true;
210  }
211  return false;
212 }
213 } // namespace base
214 } // namespace meas
215 } // namespace lsst
void set(BaseRecord &record, Eigen::Matrix< T, N, N > const &value) const override
Set a covariance matrix in the given record (uses only the lower triangle of the given matrix) ...
Definition: aggregates.cc:278
Defines the fields and offsets for a table.
Definition: Schema.h:50
ErrElement yErr
standard deviation of y
Centroid const getCentroid() const
Return a Point object containing the measured x and y.
A 2-dimensional celestial WCS that transform pixels to ICRS RA/Dec, using the LSST standard for pixel...
Definition: SkyWcs.h:117
A proxy type for name lookups in a Schema.
Definition: Schema.h:360
virtual void set(afw::table::BaseRecord &record, CentroidResult const &value) const
Set a CentroidResult in the given record.
The photometric calibration of an exposure.
Definition: PhotoCalib.h:116
UncertaintyEnum
An enum used to specify how much uncertainty information measurement algorithms provide.
Definition: constants.h:43
lsst::geom::SpherePoint pixelToSky(lsst::geom::Point2D const &pixel) const
Compute sky position(s) from pixel position(s)
Definition: SkyWcs.h:334
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:641
A mapping between the keys of two Schemas, used to copy data between them.
Definition: SchemaMapper.h:21
A coordinate class intended to represent absolute positions.
A reusable struct for centroid measurements.
bool isValid() const
Return True if the centroid key is valid.
The full covariance matrix is provided.
Definition: constants.h:46
int y
Definition: SpanSet.cc:49
std::shared_ptr< Footprint > getFootprint() const
Definition: Source.h:102
static PointKey addFields(Schema &schema, std::string const &name, std::string const &doc, std::string const &unit)
Add a pair of _x, _y fields to a Schema, and return a PointKey that points to them.
Definition: aggregates.cc:36
ErrElement xErr
standard deviation of x
STL namespace.
CentroidElement x
x (column) coordinate of the measured position
void setCentroid(Centroid const &centroid)
Set the struct fields from the given Point object.
Field< T >::Value get(Key< T > const &key) const
Return the value of a field for the given key.
Definition: BaseRecord.h:151
CentroidChecker(afw::table::Schema &schema, std::string const &name, bool inside=true, double maxDistFromPeak=-1.0)
Check source record for an centroid algorithm called name, noting if the centroid already set by the ...
AngleUnit constexpr radians
constant with units of radians
Definition: Angle.h:108
table::Key< table::Array< std::uint8_t > > wcs
Definition: SkyWcs.cc:71
float ErrElement
Definition: constants.h:55
Matrix const getMatrix() const noexcept
Return the transform as a full 3x3 matrix.
STL class.
CentroidResult()
Constructor; initializes everything to NaN.
Reports attempts to access elements using an invalid key.
Definition: Runtime.h:151
Eigen::Matrix< ErrElement, 2, 2, Eigen::DontAlign > CentroidCov
Definition: constants.h:59
T push_back(T... args)
SchemaItem< T > find(std::string const &name) const
Find a SchemaItem in the Schema by name.
Definition: Schema.cc:656
A base class for image defects.
UnitVector3d centroid(VertexIterator const begin, VertexIterator const end)
iterator end()
Iterator access.
Definition: Catalog.h:397
ErrElement x_y_Cov
x,y term in the uncertainty convariance matrix
Iterator class for CatalogT.
Definition: Catalog.h:38
lsst::geom::AffineTransform linearizePixelToSky(lsst::geom::SpherePoint const &coord, lsst::geom::AngleUnit const &skyUnit) const
Return the local linear approximation to pixelToSky at a point given in sky coordinates.
Definition: SkyWcs.cc:259
table::Schema schema
Definition: Camera.cc:161
static CentroidResultKey addFields(afw::table::Schema &schema, std::string const &name, std::string const &doc, UncertaintyEnum uncertainty)
Add the appropriate fields to a Schema, and return a CentroidResultKey that manages them...
afw::table::Key< double > sigma
Definition: GaussianPsf.cc:50
geom::Point< CentroidElement, 2 > Centroid
Definition: constants.h:58
virtual void operator()(afw::table::SourceCatalog const &inputCatalog, afw::table::BaseCatalog &outputCatalog, afw::geom::SkyWcs const &wcs, afw::image::PhotoCalib const &photoCalib) const
solver_t * s
Class to describe the properties of a detected object from an image.
Definition: Footprint.h:62
double x
bool operator()(afw::table::SourceRecord &record) const
Set the centroid to the first footprint if the centroid is either more than _dist pixels from the foo...
CentroidTransform(std::string const &name, afw::table::SchemaMapper &mapper)
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
STL class.
Base class for all records.
Definition: BaseRecord.h:31
Key< U > key
Definition: Schema.cc:281
Algorithm provides no uncertainy information at all.
Definition: constants.h:44
Abstract base class for all C++ measurement transformations.
Definition: Transform.h:86
static CoordKey addFields(afw::table::Schema &schema, std::string const &name, std::string const &doc)
Add a pair of _ra, _dec fields to a Schema, and return a CoordKey that points to them.
Definition: aggregates.cc:83
A FunctorKey for CentroidResult.
T isnan(T... args)
void set(Key< T > const &key, U const &value)
Set value of a field for the given key.
Definition: BaseRecord.h:164
CentroidElement y
y (row) coordinate of the measured position
int m
Definition: SpanSet.cc:49
#define PTR(...)
Definition: base.h:41
CentroidResultKey()
Default constructor; instance will not be usuable unless subsequently assigned to.
void checkCatalogSize(afw::table::BaseCatalog const &cat1, afw::table::BaseCatalog const &cat2) const
Ensure that catalogs have the same size.
Definition: Transform.h:102
Record class that contains measurements made on a single exposure.
Definition: Source.h:82
double CentroidElement
Definition: constants.h:56
virtual CentroidResult get(afw::table::BaseRecord const &record) const
Get a CentroidResult from the given record.
T sqrt(T... args)
void set(BaseRecord &record, lsst::geom::SpherePoint const &value) const override
Set an lsst::geom::SpherePoint in the given record.
Definition: aggregates.cc:93
CentroidCov const getCentroidErr() const
Return the 2x2 symmetric covariance matrix, with rows and columns ordered (x, y)
iterator begin()
Iterator access.
Definition: Catalog.h:396
bool isValid() const noexcept
Return True if all the constituent error Keys are valid.
Definition: aggregates.cc:294
Key< T > addField(Field< T > const &field, bool doReplace=false)
Add a new field to the Schema, and return the associated Key.
Definition: Schema.cc:668
SchemaMapper * mapper
Definition: SchemaMapper.cc:78
void setCentroidErr(CentroidCov const &matrix)
Set the struct uncertainty fields from the given matrix, with rows and columns ordered (x...
Reports errors that are due to events beyond the control of the program.
Definition: Runtime.h:104