LSSTApplications  11.0-13-gbb96280,12.1+18,12.1+7,12.1-1-g14f38d3+72,12.1-1-g16c0db7+5,12.1-1-g5961e7a+84,12.1-1-ge22e12b+23,12.1-11-g06625e2+4,12.1-11-g0d7f63b+4,12.1-19-gd507bfc,12.1-2-g7dda0ab+38,12.1-2-gc0bc6ab+81,12.1-21-g6ffe579+2,12.1-21-gbdb6c2a+4,12.1-24-g941c398+5,12.1-3-g57f6835+7,12.1-3-gf0736f3,12.1-37-g3ddd237,12.1-4-gf46015e+5,12.1-5-g06c326c+20,12.1-5-g648ee80+3,12.1-5-gc2189d7+4,12.1-6-ga608fc0+1,12.1-7-g3349e2a+5,12.1-7-gfd75620+9,12.1-9-g577b946+5,12.1-9-gc4df26a+10
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>
26 
27 namespace lsst { namespace meas { namespace base {
28 
30  x(std::numeric_limits<CentroidElement>::quiet_NaN()),
31  y(std::numeric_limits<CentroidElement>::quiet_NaN()),
32  xSigma(std::numeric_limits<ErrElement>::quiet_NaN()),
33  ySigma(std::numeric_limits<ErrElement>::quiet_NaN()),
34  x_y_Cov(std::numeric_limits<ErrElement>::quiet_NaN())
35 {}
36 
37 Centroid const CentroidResult::getCentroid() const { return Centroid(x, y); }
38 
40  x = centroid.getX();
41  y = centroid.getY();
42 }
43 
45  CentroidCov m;
46  m <<
49  return m;
50 }
51 
53  xSigma = std::sqrt(matrix(0, 0));
54  ySigma = std::sqrt(matrix(1, 1));
55  x_y_Cov = matrix(0, 1);
56 }
57 
59  xSigma = _xSigma;
60  ySigma = _ySigma;
61  x_y_Cov = 0.0;
62 }
63 
66  std::string const & name,
67  std::string const & doc,
68  UncertaintyEnum uncertainty
69 ) {
72  schema,
73  name,
74  doc,
75  "pixel"
76  );
77  if (uncertainty != NO_UNCERTAINTY) {
78  std::vector< afw::table::Key<ErrElement> > sigma(2);
79  std::vector< afw::table::Key<ErrElement> > cov;
80  sigma[0] = schema.addField<ErrElement>(
81  schema.join(name, "xSigma"), "1-sigma uncertainty on x position", "pixel"
82  );
83  sigma[1] = schema.addField<ErrElement>(
84  schema.join(name, "ySigma"), "1-sigma uncertainty on y position", "pixel"
85  );
86  if (uncertainty == FULL_COVARIANCE) {
87  cov.push_back(
88  schema.addField<ErrElement>(
89  schema.join(name, "x_y_Cov"), "uncertainty covariance in x and y", "pixel^2"
90  )
91  );
92  }
94  }
95  return r;
96 }
97 
98 namespace {
99 
100 std::vector<std::string> getNameVector() {
101  std::vector<std::string> v;
102  v.push_back("x");
103  v.push_back("y");
104  return v;
105 }
106 
107 } // anonymous
108 
110  _centroid(s)
111 {
112  static std::vector<std::string> names = getNameVector(); // C++11 TODO: just use initializer list
113  try {
115  } catch (pex::exceptions::NotFoundError &) {}
116 }
117 
119  CentroidResult r;
120  r.setCentroid(record.get(_centroid));
121  if (_centroidErr.isValid()) {
122  r.setCentroidErr(record.get(_centroidErr));
123  }
124  return r;
125 }
126 
127 void CentroidResultKey::set(afw::table::BaseRecord & record, CentroidResult const & value) const {
128  record.set(_centroid, value.getCentroid());
129  if (_centroidErr.isValid()) {
130  record.set(_centroidErr, value.getCentroidErr());
131  }
132 }
133 
135  std::string const & name,
136  afw::table::SchemaMapper & mapper
137 ) :
138  BaseTransform{name}
139 {
140  // Map the flag through to the output
141  mapper.addMapping(mapper.getInputSchema().find<afw::table::Flag>(name + "_flag").key);
142 
143  // Add keys for the coordinates
144  auto & s = mapper.editOutputSchema();
145  _coordKey = afw::table::CoordKey::addFields(s, name, "ICRS coordinates");
146 
147  // If the centroid has an error key we also include one on the celestial
148  // coordinates; otherwise, it isn't necessary. Note that if we provide for
149  // errors in celestial coordinates, we always need the full covariance.
150  if (CentroidResultKey(mapper.getInputSchema()[name]).getCentroidErr().isValid()) {
151  std::vector< afw::table::Key<ErrElement> > sigma(2);
152  std::vector< afw::table::Key<ErrElement> > cov(1);
153  sigma[0] = s.addField<ErrElement>(s.join(name, "raSigma"), "Uncertainty on RA", "rad");
154  sigma[1] = s.addField<ErrElement>(s.join(name, "decSigma"), "Uncertainty on dec", "rad");
155  cov[0] = s.addField<ErrElement>(s.join(name, "ra_dec_Cov"),
156  "Uncertainty covariance in RA and dec", "rad^2");
158  }
159 
160 }
161 
163  afw::table::SourceCatalog const & inputCatalog,
164  afw::table::BaseCatalog & outputCatalog,
165  afw::image::Wcs const & wcs,
166  afw::image::Calib const & calib
167 ) const {
168  checkCatalogSize(inputCatalog, outputCatalog);
169  CentroidResultKey centroidResultKey(inputCatalog.getSchema()[_name]);
170 
171  afw::table::SourceCatalog::const_iterator inSrc = inputCatalog.begin();
172  afw::table::BaseCatalog::iterator outSrc = outputCatalog.begin();
173 
174  for (; inSrc != inputCatalog.end() && outSrc != outputCatalog.end(); ++inSrc, ++outSrc) {
175  CentroidResult centroidResult = centroidResultKey.get(*inSrc);
176 
177  _coordKey.set(*outSrc, *wcs.pixelToSky(centroidResult.getCentroid()));
178 
179  if (centroidResultKey.getCentroidErr().isValid()) {
180  CentroidCov centroidCov = centroidResult.getCentroidErr();
181  if (!(std::isnan(centroidCov(0,0)) || std::isnan(centroidCov(1,1)))) {
182  auto transform = wcs.linearizePixelToSky(centroidResult.getCentroid(),
183  afw::geom::radians).getLinear().getMatrix();
184  _coordErrKey.set(*outSrc, (transform * centroidResult.getCentroidErr().cast<double>() *
185  transform.transpose()).cast<ErrElement>());
186  }
187  }
188  }
189 }
190 
191 // Add a key "flag_resetToPeak" if something is wrong with the centroid
192 // Save a key to this algorithm's Centroid, as well as the general failure flag
195  std::string const & name,
196  bool doFootprintCheck,
197  double maxDistFromPeak
198 ) : _doFootprintCheck(doFootprintCheck), _maxDistFromPeak(maxDistFromPeak)
199 {
200  _resetKey = schema.addField<afw::table::Flag>(schema.join(name, "flag_resetToPeak"),
201  "set if CentroidChecker reset the centroid");
202  _failureKey = schema.find<lsst::afw::table::Flag>(schema.join(name, "flag")).key;
203  _xKey = schema.find<CentroidElement>(schema.join(name, "x")).key;
204  _yKey = schema.find<CentroidElement>(schema.join(name, "y")).key;
205 }
206 
207 // Set the centroid to the first footprint if the centroid is eithe more than _maxDistFromPeak
208 // pixels from the centroid, or if it is outside the footprint.
210  afw::table::SourceRecord & record
211 ) const {
212  CentroidElement x = record.get(_xKey);
213  CentroidElement y = record.get(_yKey);
214 
215  if (!_doFootprintCheck && _maxDistFromPeak < 0.0) {
216  return false;
217  }
218  PTR(afw::detection::Footprint) footprint = record.getFootprint();
219  if (!footprint) {
220  throw LSST_EXCEPT(
221  pex::exceptions::RuntimeError,
222  "No Footprint attached to record");
223  }
224  if (footprint->getPeaks().empty()) {
225  throw LSST_EXCEPT(
226  pex::exceptions::RuntimeError,
227  "Footprint has no peaks; cannot verify centroid."
228  );
229  }
230  CentroidElement footX = footprint->getPeaks().front().getFx();
231  CentroidElement footY = footprint->getPeaks().front().getFy();
232  double distsq = (x - footX) * (x - footX) + (y - footY) * (y - footY);
233  if ((_doFootprintCheck && !footprint->contains(lsst::afw::geom::Point2I(lsst::afw::geom::Point2D(x, y)))) ||
234  ((_maxDistFromPeak > 0) && (distsq > _maxDistFromPeak*_maxDistFromPeak))) {
235  record.set(_xKey, footX);
236  record.set(_yKey, footY);
237  record.set(_failureKey, true);
238  record.set(_resetKey, true);
239  return true;
240  }
241  return false;
242 }
243 }}} // lsst::meas::base
int y
virtual void set(BaseRecord &record, Eigen::Matrix< T, N, N > const &value) const
Set a covariance matrix in the given record (uses only the lower triangle of the given matrix) ...
Defines the fields and offsets for a table.
Definition: Schema.h:44
A proxy type for name lookups in a Schema.
Definition: Schema.h:340
ErrElement ySigma
1-Sigma uncertainty on y (sqrt of variance)
table::Key< std::string > name
Definition: ApCorrMap.cc:71
geom::AffineTransform linearizePixelToSky(coord::Coord const &coord, geom::AngleUnit skyUnit=geom::degrees) const
Return the local linear approximation to Wcs::pixelToSky at a point given in sky coordinates.
Definition: Wcs.cc:929
AngleUnit const radians
constant with units of radians
Definition: Angle.h:90
UncertaintyEnum
An enum used to specify how much uncertainty information measurement algorithms provide.
Definition: constants.h:41
A custom container class for records, based on std::vector.
Definition: Catalog.h:95
void checkCatalogSize(afw::table::BaseCatalog const &cat1, afw::table::BaseCatalog const &cat2) const
Ensure that catalogs have the same size.
Definition: Transform.h:101
afw::table::Schema schema
Definition: GaussianPsf.cc:41
A mapping between the keys of two Schemas, used to copy data between them.
Definition: SchemaMapper.h:19
A reusable struct for centroid measurements.
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...
Centroid const getCentroid() const
Return a Point object containing the measured x and y.
ErrElement xSigma
1-Sigma uncertainty on x (sqrt of variance)
The full covariance matrix is provided.
Definition: constants.h:44
CentroidElement x
x (column) coordinate of the measured position
tbl::Key< int > wcs
afw::table::Key< CentroidElement > _yKey
Implementation of the WCS standard for a any projection.
Definition: Wcs.h:107
bool isValid() const
Return True if the centroid key is valid.
std::string join(std::string const &a, std::string const &b) const
Join strings using the field delimiter appropriate for this Schema.
boost::shared_ptr< coord::Coord > pixelToSky(double pix1, double pix2) const
Convert from pixel position to sky coordinates (e.g.
Definition: Wcs.cc:886
void setCentroid(Centroid const &centroid)
Set the struct fields from the given Point object.
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.
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 ...
void set(Key< T > const &key, U const &value)
Set value of a field for the given key.
Definition: BaseRecord.h:145
Describe an exposure&#39;s calibration.
Definition: Calib.h:82
float ErrElement
Definition: constants.h:53
A coordinate class intended to represent absolute positions.
afw::table::Key< double > sigma
Definition: GaussianPsf.cc:43
CentroidResult()
Constructor; initializes everything to NaN.
afw::table::Key< CentroidElement > _xKey
afw::table::Key< afw::table::Flag > _resetKey
iterator begin()
Iterator access.
Definition: Catalog.h:392
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.
Custom catalog class for record/table subclasses that are guaranteed to have an ID, and should generally be sorted by that ID.
Definition: fwd.h:55
virtual void set(BaseRecord &record, coord::IcrsCoord const &value) const
Set an IcrsCoord in the given record.
ErrElement x_y_Cov
x,y term in the uncertainty convariance matrix
Iterator class for CatalogT.
Definition: Catalog.h:35
virtual CentroidResult get(afw::table::BaseRecord const &record) const
Get a CentroidResult from the given record.
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...
Schema getSchema() const
Return the schema associated with the catalog&#39;s table.
Definition: Catalog.h:115
double x
Field< T >::Value get(Key< T > const &key) const
Return the value of a field for the given key.
Definition: BaseRecord.h:132
bool isValid() const
Return True if all the constituent sigma Keys are valid.
A set of pixels in an Image.
Definition: Footprint.h:62
virtual void operator()(afw::table::SourceCatalog const &inputCatalog, afw::table::BaseCatalog &outputCatalog, afw::image::Wcs const &wcs, afw::image::Calib const &calib) const
afw::table::CovarianceMatrixKey< ErrElement, 2 > _coordErrKey
CentroidTransform(std::string const &name, afw::table::SchemaMapper &mapper)
afw::table::Key< afw::table::Flag > _failureKey
#define LSST_EXCEPT(type,...)
Create an exception with a given type and message and optionally other arguments (dependent on the ty...
Definition: Exception.h:46
virtual void set(afw::table::BaseRecord &record, CentroidResult const &value) const
Set a CentroidResult in the given record.
Base class for all records.
Definition: BaseRecord.h:27
tuple m
Definition: lsstimport.py:48
#define PTR(...)
Definition: base.h:41
Algorithm provides no uncertainy information at all.
Definition: constants.h:42
iterator end()
Iterator access.
Definition: Catalog.h:393
Abstract base class for all C++ measurement transformations.
Definition: Transform.h:82
CentroidCov const getCentroidErr() const
Return the 2x2 symmetric covariance matrix, with rows and columns ordered (x, y)
A FunctorKey for CentroidResult.
CentroidElement y
y (row) coordinate of the measured position
Eigen::Matrix< ErrElement, 2, 2, Eigen::DontAlign > CentroidCov
Definition: constants.h:57
afw::geom::Point< CentroidElement, 2 > Centroid
Definition: constants.h:56
afw::table::PointKey< CentroidElement > _centroid
Key< T > addField(Field< T > const &field, bool doReplace=false)
Add a new field to the Schema, and return the associated Key.
CentroidResultKey()
Default constructor; instance will not be usuable unless subsequently assigned to.
SchemaItem< T > find(std::string const &name) const
Find a SchemaItem in the Schema by name.
Record class that contains measurements made on a single exposure.
Definition: Source.h:80
double CentroidElement
Definition: constants.h:54
Matrix const getMatrix() const
afw::table::CovarianceMatrixKey< ErrElement, 2 > _centroidErr
boost::shared_ptr< Footprint > getFootprint() const
Definition: Source.h:88
void setCentroidErr(CentroidCov const &matrix)
Set the struct uncertainty fields from the given matrix, with rows and columns ordered (x...