lsst.meas.algorithms  14.0-13-g68269a9e
CoaddBoundedField.cc
Go to the documentation of this file.
1 // -*- LSST-C++ -*-
2 /*
3  * LSST Data Management System
4  * Copyright 2008-2014, 2010 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 
30 
31 namespace lsst { namespace meas { namespace algorithms {
32 
33 
35  afw::geom::Box2I const & bbox,
37  ElementVector const & elements
38 ) :
39  afw::math::BoundedField(bbox),
40  _throwOnMissing(true),
41  _default(0.0), // unused
42  _coaddWcs(coaddWcs),
43  _elements(elements)
44 {}
45 
47  afw::geom::Box2I const & bbox,
49  ElementVector const & elements,
50  double default_
51 ) :
52  afw::math::BoundedField(bbox),
53  _throwOnMissing(false),
54  _default(default_),
55  _coaddWcs(coaddWcs),
56  _elements(elements)
57 {}
58 
59 double CoaddBoundedField::evaluate(afw::geom::Point2D const & position) const {
60  PTR(afw::coord::Coord) coord = _coaddWcs->pixelToSky(position);
61  double sum = 0.0;
62  double wSum = 0.0;
63  for (ElementVector::const_iterator i = _elements.begin(); i != _elements.end(); ++i) {
64  afw::geom::Point2D transformedPosition = i->wcs->skyToPixel(*coord);
65  bool inValidArea = i->validPolygon ? i->validPolygon->contains(transformedPosition) : true;
66  if (afw::geom::Box2D(i->field->getBBox()).contains(transformedPosition) && inValidArea) {
67  sum += i->weight * i->field->evaluate(transformedPosition);
68  wSum += i->weight;
69  }
70  }
71  if (wSum == 0.0) {
72  if (_throwOnMissing) {
73  throw LSST_EXCEPT(
75  (boost::format("No constituent fields to evaluate at point %f, %f")
76  % position.getX() % position.getY()).str()
77  );
78  } else {
79  return _default;
80  }
81  }
82  return sum / wSum;
83 }
84 
85 // ---------- Persistence -----------------------------------------------------------------------------------
86 
87 // For persistence of CoaddBoundedField, we have two catalogs: the first has just one record, and contains
88 // the archive ID of the coadd WCS and the parameters that control missing data. The other catalog
89 // has one record for each element, with fields corresponding to the data members of the Element struct.
90 
91 namespace {
92 
93 namespace tbl = afw::table;
94 
95 // Singleton class that manages the first persistence catalog's schema and keys
96 class CoaddBoundedFieldPersistenceKeys1 {
97 public:
98  tbl::Schema schema;
99  tbl::PointKey<int> bboxMin;
100  tbl::PointKey<int> bboxMax;
101  tbl::Key<int> coaddWcs;
102  tbl::Key<tbl::Flag> throwOnMissing;
103  tbl::Key<double > default_;
104 
105  static CoaddBoundedFieldPersistenceKeys1 const & get() {
106  static CoaddBoundedFieldPersistenceKeys1 const instance;
107  return instance;
108  }
109 
110  // No copying
111  CoaddBoundedFieldPersistenceKeys1 (const CoaddBoundedFieldPersistenceKeys1&) = delete;
112  CoaddBoundedFieldPersistenceKeys1& operator=(const CoaddBoundedFieldPersistenceKeys1&) = delete;
113 
114  // No moving
115  CoaddBoundedFieldPersistenceKeys1 (CoaddBoundedFieldPersistenceKeys1&&) = delete;
116  CoaddBoundedFieldPersistenceKeys1& operator=(CoaddBoundedFieldPersistenceKeys1&&) = delete;
117 
118 private:
119  CoaddBoundedFieldPersistenceKeys1() :
120  schema(),
121  bboxMin(tbl::PointKey<int>::addFields(
122  schema, "bbox_min", "lower-left corner of bounding box", "pixel")),
123  bboxMax(tbl::PointKey<int>::addFields(
124  schema, "bbox_max", "upper-right corner of bounding box", "pixel")),
125  coaddWcs(schema.addField<int>("coaddWcs", "archive ID of the coadd's WCS")),
126  throwOnMissing(schema.addField<tbl::Flag>("throwOnMissing",
127  "whether to throw an exception on missing data")),
128  default_(schema.addField<double>("default", "default value to use when throwOnMissing is False"))
129  {
130  schema.getCitizen().markPersistent();
131  }
132 };
133 
134 // Singleton class that manages the second persistence catalog's schema and keys
135 class CoaddBoundedFieldPersistenceKeys2 {
136 public:
137  tbl::Schema schema;
138  tbl::Key<int> field;
139  tbl::Key<int> wcs;
140  tbl::Key<int> validPolygon;
141  tbl::Key<double> weight;
142 
143  static CoaddBoundedFieldPersistenceKeys2 const & get() {
144  static CoaddBoundedFieldPersistenceKeys2 const instance;
145  return instance;
146  }
147 
148  // No copying
149  CoaddBoundedFieldPersistenceKeys2 (const CoaddBoundedFieldPersistenceKeys2&) = delete;
150  CoaddBoundedFieldPersistenceKeys2& operator=(const CoaddBoundedFieldPersistenceKeys2&) = delete;
151 
152  // No moving
153  CoaddBoundedFieldPersistenceKeys2 (CoaddBoundedFieldPersistenceKeys2&&) = delete;
154  CoaddBoundedFieldPersistenceKeys2& operator=(CoaddBoundedFieldPersistenceKeys2&&) = delete;
155 
156 private:
157  CoaddBoundedFieldPersistenceKeys2() :
158  schema(),
159  field(schema.addField<int>("field", "archive ID of the BoundedField to be coadded")),
160  wcs(schema.addField<int>("wcs", "archive ID of the Wcs associated with this element")),
161  validPolygon(schema.addField<int>("validPolygon", "archive ID of the Polygon associated with this element")),
162  weight(schema.addField<double>("weight", "weight value for this element"))
163  {
164  schema.getCitizen().markPersistent();
165  }
166 };
167 
168 } // anonymous
169 
170 class CoaddBoundedField::Factory : public tbl::io::PersistableFactory {
171 public:
172 
173  virtual PTR(tbl::io::Persistable)
174  read(InputArchive const & archive, CatalogVector const & catalogs) const {
175  CoaddBoundedFieldPersistenceKeys1 const & keys1 = CoaddBoundedFieldPersistenceKeys1::get();
176  CoaddBoundedFieldPersistenceKeys2 const & keys2 = CoaddBoundedFieldPersistenceKeys2::get();
177  LSST_ARCHIVE_ASSERT(catalogs.size() == 2u);
178  LSST_ARCHIVE_ASSERT(catalogs.front().getSchema() == keys1.schema);
179  LSST_ARCHIVE_ASSERT(catalogs.back().getSchema() == keys2.schema);
180  tbl::BaseRecord const & record1 = catalogs.front().front();
181  ElementVector elements;
182  elements.reserve(catalogs.back().size());
183  for (tbl::BaseCatalog::const_iterator i = catalogs.back().begin(); i != catalogs.back().end(); ++i) {
184  elements.push_back(
185  Element(
186  archive.get<afw::math::BoundedField>(i->get(keys2.field)),
187  archive.get<afw::image::Wcs>(i->get(keys2.wcs)),
188  archive.get<afw::geom::polygon::Polygon>(i->get(keys2.validPolygon)),
189  i->get(keys2.weight)
190  )
191  );
192  }
193  return std::make_shared<CoaddBoundedField>(
194  afw::geom::Box2I(record1.get(keys1.bboxMin), record1.get(keys1.bboxMax)),
195  archive.get<afw::image::Wcs>(record1.get(keys1.coaddWcs)),
196  elements,
197  record1.get(keys1.default_)
198  );
199  }
200 
201  Factory(std::string const & name) : tbl::io::PersistableFactory(name) {}
202 
203 };
204 
205 namespace {
206 
207 std::string getCoaddBoundedFieldPersistenceName() { return "CoaddBoundedField"; }
208 
209 CoaddBoundedField::Factory registration(getCoaddBoundedFieldPersistenceName());
210 
211 } // anonymous
212 
213 std::string CoaddBoundedField::getPersistenceName() const { return getCoaddBoundedFieldPersistenceName(); }
214 
215 std::string CoaddBoundedField::getPythonModule() const { return "lsst.meas.algorithms"; }
216 
218  CoaddBoundedFieldPersistenceKeys1 const & keys1 = CoaddBoundedFieldPersistenceKeys1::get();
219  CoaddBoundedFieldPersistenceKeys2 const & keys2 = CoaddBoundedFieldPersistenceKeys2::get();
220  tbl::BaseCatalog cat1 = handle.makeCatalog(keys1.schema);
221  PTR(tbl::BaseRecord) record1 = cat1.addNew();
222  record1->set(keys1.bboxMin, getBBox().getMin());
223  record1->set(keys1.bboxMax, getBBox().getMax());
224  record1->set(keys1.coaddWcs, handle.put(_coaddWcs));
225  record1->set(keys1.default_, _default);
226  handle.saveCatalog(cat1);
227  tbl::BaseCatalog cat2 = handle.makeCatalog(keys2.schema);
228  for (ElementVector::const_iterator i = _elements.begin(); i != _elements.end(); ++i) {
229  PTR(tbl::BaseRecord) record2 = cat2.addNew();
230  record2->set(keys2.field, handle.put(i->field));
231  record2->set(keys2.wcs, handle.put(i->wcs));
232  record2->set(keys2.validPolygon, handle.put(i->validPolygon));
233  record2->set(keys2.weight, i->weight);
234  }
235  handle.saveCatalog(cat2);
236 }
237 
239  throw LSST_EXCEPT(pex::exceptions::NotFoundError, "Scaling of CoaddBoundedField is not implemented");
240 }
241 
243  auto rhsCasted = dynamic_cast<CoaddBoundedField const *>(&rhs);
244  if (!rhsCasted) return false;
245 
246  return (getBBox() == rhsCasted->getBBox()) && (_default == rhsCasted->_default) &&
247  ((*_coaddWcs) == (*rhsCasted->_coaddWcs)) && (_elements == rhsCasted->_elements);
248 }
249 
250 
251 }}} // namespace lsst::meas::algorithms
252 
253 
virtual std::string getPersistenceName() const
virtual std::string getPythonModule() const
afw::geom::Box2D bbox
tbl::Key< double > weight
#define LSST_ARCHIVE_ASSERT(EXPR)
tbl::Key< int > wcs
#define PTR(...)
T end(T... args)
virtual void write(OutputArchiveHandle &handle) const
STL class.
tbl::Key< int > validPolygon
BoundedField & operator=(BoundedField const &)=delete
geom::Box2I getBBox() const
T push_back(T... args)
BoundedField(BoundedField const &)=default
virtual double evaluate(afw::geom::Point2D const &position) const
virtual bool operator==(BoundedField const &rhs) const
BoundedFields (of the same sublcass) are equal if their bounding boxes and parameters are equal...
tbl::Key< int > field
tbl::Key< double > default_
CoaddBoundedField(afw::geom::Box2I const &bbox, boost::shared_ptr< afw::image::Wcs const > coaddWcs, ElementVector const &elements)
tbl::Schema schema
#define LSST_EXCEPT(type,...)
tbl::PointKey< int > bboxMax
T begin(T... args)
tbl::Key< tbl::Flag > throwOnMissing
virtual boost::shared_ptr< afw::math::BoundedField > operator*(double const scale) const
io::OutputArchiveHandle OutputArchiveHandle
tbl::Key< int > coaddWcs
T reserve(T... args)
std::shared_ptr< RecordT > addNew()
tbl::PointKey< int > bboxMin