LSSTApplications  20.0.0
LSSTDataManagementBasePackage
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 
25 #include "lsst/geom/Box.h"
32 
33 namespace lsst {
34 namespace afw {
35 namespace table {
36 namespace io {
37 
40 
41 } // namespace io
42 } // namespace table
43 } // namespace afw
44 namespace meas {
45 namespace algorithms {
46 namespace {
47 
48 /*
49  * Compare two pointers of the same type
50  *
51  * If both pointers are set then return *a == *b
52  * else return a == b
53  */
54 template <typename T>
55 bool ptrEquals(T a, T b) {
56  if (a == b) {
57  // test this first for efficiency
58  return true;
59  } else if (a && b) {
60  // both pointers are set, so it is safe to check value equality
61  return *a == *b;
62  }
63  return false;
64 }
65 
66 } // namespace
67 
68 bool CoaddBoundedFieldElement::operator==(CoaddBoundedFieldElement const& rhs) const {
69  return ptrEquals(field, rhs.field) && ptrEquals(wcs, rhs.wcs) &&
70  ptrEquals(validPolygon, rhs.validPolygon) && (weight == rhs.weight);
71 }
72 
73 CoaddBoundedField::CoaddBoundedField(geom::Box2I const& bbox, PTR(afw::geom::SkyWcs const) coaddWcs,
74  ElementVector const& elements)
75  : afw::math::BoundedField(bbox),
76  _throwOnMissing(true),
77  _default(0.0), // unused
78  _coaddWcs(coaddWcs),
79  _elements(elements) {}
80 
82  ElementVector const& elements, double default_)
83  : afw::math::BoundedField(bbox),
84  _throwOnMissing(false),
85  _default(default_),
86  _coaddWcs(coaddWcs),
87  _elements(elements) {}
88 
89 double CoaddBoundedField::evaluate(geom::Point2D const& position) const {
90  auto coord = _coaddWcs->pixelToSky(position);
91  double sum = 0.0;
92  double wSum = 0.0;
93  for (ElementVector::const_iterator i = _elements.begin(); i != _elements.end(); ++i) {
94  geom::Point2D transformedPosition = i->wcs->skyToPixel(coord);
95  bool inValidArea = i->validPolygon ? i->validPolygon->contains(transformedPosition) : true;
96  if (geom::Box2D(i->field->getBBox()).contains(transformedPosition) && inValidArea) {
97  sum += i->weight * i->field->evaluate(transformedPosition);
98  wSum += i->weight;
99  }
100  }
101  if (wSum == 0.0) {
102  if (_throwOnMissing) {
104  (boost::format("No constituent fields to evaluate at point %f, %f") %
105  position.getX() % position.getY())
106  .str());
107  } else {
108  return _default;
109  }
110  }
111  return sum / wSum;
112 }
113 
114 // ---------- Persistence -----------------------------------------------------------------------------------
115 
116 // For persistence of CoaddBoundedField, we have two catalogs: the first has just one record, and contains
117 // the archive ID of the coadd WCS and the parameters that control missing data. The other catalog
118 // has one record for each element, with fields corresponding to the data members of the Element struct.
119 
120 namespace {
121 
122 // Singleton class that manages the first persistence catalog's schema and keys
123 class CoaddBoundedFieldPersistenceKeys1 {
124 public:
125  afw::table::Schema schema;
126  afw::table::PointKey<int> bboxMin;
127  afw::table::PointKey<int> bboxMax;
128  afw::table::Key<int> coaddWcs;
129  afw::table::Key<afw::table::Flag> throwOnMissing;
130  afw::table::Key<double> default_;
131 
132  static CoaddBoundedFieldPersistenceKeys1 const& get() {
133  static CoaddBoundedFieldPersistenceKeys1 const instance;
134  return instance;
135  }
136 
137  // No copying
138  CoaddBoundedFieldPersistenceKeys1(const CoaddBoundedFieldPersistenceKeys1&) = delete;
139  CoaddBoundedFieldPersistenceKeys1& operator=(const CoaddBoundedFieldPersistenceKeys1&) = delete;
140 
141  // No moving
142  CoaddBoundedFieldPersistenceKeys1(CoaddBoundedFieldPersistenceKeys1&&) = delete;
143  CoaddBoundedFieldPersistenceKeys1& operator=(CoaddBoundedFieldPersistenceKeys1&&) = delete;
144 
145 private:
146  CoaddBoundedFieldPersistenceKeys1()
147  : schema(),
148  bboxMin(afw::table::PointKey<int>::addFields(schema, "bbox_min",
149  "lower-left corner of bounding box", "pixel")),
150  bboxMax(afw::table::PointKey<int>::addFields(schema, "bbox_max",
151  "upper-right corner of bounding box", "pixel")),
152  coaddWcs(schema.addField<int>("coaddWcs", "archive ID of the coadd's WCS")),
153  throwOnMissing(schema.addField<afw::table::Flag>(
154  "throwOnMissing", "whether to throw an exception on missing data")),
155  default_(schema.addField<double>("default",
156  "default value to use when throwOnMissing is False")) {}
157 };
158 
159 // Singleton class that manages the second persistence catalog's schema and keys
160 class CoaddBoundedFieldPersistenceKeys2 {
161 public:
162  afw::table::Schema schema;
163  afw::table::Key<int> field;
164  afw::table::Key<int> wcs;
165  afw::table::Key<int> validPolygon;
166  afw::table::Key<double> weight;
167 
168  static CoaddBoundedFieldPersistenceKeys2 const& get() {
169  static CoaddBoundedFieldPersistenceKeys2 const instance;
170  return instance;
171  }
172 
173  // No copying
174  CoaddBoundedFieldPersistenceKeys2(const CoaddBoundedFieldPersistenceKeys2&) = delete;
175  CoaddBoundedFieldPersistenceKeys2& operator=(const CoaddBoundedFieldPersistenceKeys2&) = delete;
176 
177  // No moving
178  CoaddBoundedFieldPersistenceKeys2(CoaddBoundedFieldPersistenceKeys2&&) = delete;
179  CoaddBoundedFieldPersistenceKeys2& operator=(CoaddBoundedFieldPersistenceKeys2&&) = delete;
180 
181 private:
182  CoaddBoundedFieldPersistenceKeys2()
183  : schema(),
184  field(schema.addField<int>("field", "archive ID of the BoundedField to be coadded")),
185  wcs(schema.addField<int>("wcs", "archive ID of the Wcs associated with this element")),
186  validPolygon(schema.addField<int>("validPolygon",
187  "archive ID of the Polygon associated with this element")),
188  weight(schema.addField<double>("weight", "weight value for this element")) {}
189 };
190 
191 } // namespace
192 
194 public:
196  read(InputArchive const& archive, CatalogVector const& catalogs) const {
197  CoaddBoundedFieldPersistenceKeys1 const& keys1 = CoaddBoundedFieldPersistenceKeys1::get();
198  CoaddBoundedFieldPersistenceKeys2 const& keys2 = CoaddBoundedFieldPersistenceKeys2::get();
199  LSST_ARCHIVE_ASSERT(catalogs.size() == 2u);
200  LSST_ARCHIVE_ASSERT(catalogs.front().getSchema() == keys1.schema);
201  LSST_ARCHIVE_ASSERT(catalogs.back().getSchema() == keys2.schema);
202  afw::table::BaseRecord const& record1 = catalogs.front().front();
203  ElementVector elements;
204  elements.reserve(catalogs.back().size());
205  for (afw::table::BaseCatalog::const_iterator i = catalogs.back().begin(); i != catalogs.back().end();
206  ++i) {
207  elements.push_back(Element(archive.get<afw::math::BoundedField>(i->get(keys2.field)),
208  archive.get<afw::geom::SkyWcs>(i->get(keys2.wcs)),
209  archive.get<afw::geom::polygon::Polygon>(i->get(keys2.validPolygon)),
210  i->get(keys2.weight)));
211  }
212  return std::make_shared<CoaddBoundedField>(
213  geom::Box2I(record1.get(keys1.bboxMin), record1.get(keys1.bboxMax)),
214  archive.get<afw::geom::SkyWcs>(record1.get(keys1.coaddWcs)), elements,
215  record1.get(keys1.default_));
216  }
217 
218  Factory(std::string const& name) : afw::table::io::PersistableFactory(name) {}
219 };
220 
221 namespace {
222 
223 std::string getCoaddBoundedFieldPersistenceName() { return "CoaddBoundedField"; }
224 
225 CoaddBoundedField::Factory registration(getCoaddBoundedFieldPersistenceName());
226 
227 } // namespace
228 
229 std::string CoaddBoundedField::getPersistenceName() const { return getCoaddBoundedFieldPersistenceName(); }
230 
231 std::string CoaddBoundedField::getPythonModule() const { return "lsst.meas.algorithms"; }
232 
234  CoaddBoundedFieldPersistenceKeys1 const& keys1 = CoaddBoundedFieldPersistenceKeys1::get();
235  CoaddBoundedFieldPersistenceKeys2 const& keys2 = CoaddBoundedFieldPersistenceKeys2::get();
236  afw::table::BaseCatalog cat1 = handle.makeCatalog(keys1.schema);
237  PTR(afw::table::BaseRecord) record1 = cat1.addNew();
238  record1->set(keys1.bboxMin, getBBox().getMin());
239  record1->set(keys1.bboxMax, getBBox().getMax());
240  record1->set(keys1.coaddWcs, handle.put(_coaddWcs));
241  record1->set(keys1.default_, _default);
242  handle.saveCatalog(cat1);
243  afw::table::BaseCatalog cat2 = handle.makeCatalog(keys2.schema);
244  for (ElementVector::const_iterator i = _elements.begin(); i != _elements.end(); ++i) {
245  PTR(afw::table::BaseRecord) record2 = cat2.addNew();
246  record2->set(keys2.field, handle.put(i->field));
247  record2->set(keys2.wcs, handle.put(i->wcs));
248  record2->set(keys2.validPolygon, handle.put(i->validPolygon));
249  record2->set(keys2.weight, i->weight);
250  }
251  handle.saveCatalog(cat2);
252 }
253 
255  throw LSST_EXCEPT(pex::exceptions::NotFoundError, "Scaling of CoaddBoundedField is not implemented");
256 }
257 
258 bool CoaddBoundedField::operator==(BoundedField const& rhs) const {
259  auto rhsCasted = dynamic_cast<CoaddBoundedField const*>(&rhs);
260  if (!rhsCasted) return false;
261 
262  return (getBBox() == rhsCasted->getBBox()) && (_default == rhsCasted->_default) &&
263  ptrEquals(_coaddWcs, rhsCasted->_coaddWcs) && (_elements == rhsCasted->_elements);
264 }
265 
266 } // namespace algorithms
267 } // namespace meas
268 } // namespace lsst
lsst::meas::algorithms::CoaddBoundedField::operator==
bool operator==(BoundedField const &rhs) const override
BoundedFields (of the same sublcass) are equal if their bounding boxes and parameters are equal.
Definition: CoaddBoundedField.cc:258
Box.h
CoaddBoundedField.h
std::string
STL class.
std::shared_ptr
STL class.
lsst::afw::math::BoundedField
An abstract base class for 2-d functions defined on an integer bounding boxes.
Definition: BoundedField.h:55
default_
afw::table::Key< double > default_
Definition: CoaddBoundedField.cc:130
lsst::afw::table::BaseRecord::get
Field< T >::Value get(Key< T > const &key) const
Return the value of a field for the given key.
Definition: BaseRecord.h:151
std::vector::reserve
T reserve(T... args)
lsst::afw::table::io::OutputArchiveHandle
An object passed to Persistable::write to allow it to persist itself.
Definition: OutputArchive.h:118
bboxMax
afw::table::PointKey< int > bboxMax
Definition: CoaddBoundedField.cc:127
std::vector< Element >
Persistable.cc
lsst::pex::exceptions::NotFoundError
Reports attempts to access elements using an invalid key.
Definition: Runtime.h:151
lsst::geom::Box2D::contains
bool contains(Point2D const &point) const noexcept
Return true if the box contains the point.
Definition: Box.cc:322
lsst::afw::table::io::OutputArchiveHandle::saveCatalog
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
Definition: OutputArchive.cc:211
pex.config.history.format
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:174
bboxMin
afw::table::PointKey< int > bboxMin
Definition: CoaddBoundedField.cc:126
schema
afw::table::Schema schema
Definition: CoaddBoundedField.cc:125
lsst::afw
Definition: imageAlgorithm.dox:1
lsst::afw::table::io::InputArchive
A multi-catalog archive object used to load table::io::Persistable objects.
Definition: InputArchive.h:31
lsst::meas::algorithms::CoaddBoundedFieldElement::validPolygon
boost::shared_ptr< afw::geom::polygon::Polygon const > validPolygon
Definition: CoaddBoundedField.h:55
lsst::meas::algorithms::CoaddBoundedFieldElement::wcs
boost::shared_ptr< afw::geom::SkyWcs const > wcs
Definition: CoaddBoundedField.h:54
CatalogVector.h
lsst::afw::geom::SkyWcs
A 2-dimensional celestial WCS that transform pixels to ICRS RA/Dec, using the LSST standard for pixel...
Definition: SkyWcs.h:117
lsst::afw::geom.transform.transformContinued.name
string name
Definition: transformContinued.py:32
aggregates.h
lsst::meas::algorithms::CoaddBoundedField::getPythonModule
std::string getPythonModule() const override
Return the fully-qualified Python module that should be imported to guarantee that its factory is reg...
Definition: CoaddBoundedField.cc:231
std::vector::push_back
T push_back(T... args)
lsst::afw::table::io::OutputArchiveHandle::makeCatalog
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
Definition: OutputArchive.cc:207
LSST_ARCHIVE_ASSERT
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
Definition: Persistable.h:48
validPolygon
afw::table::Key< int > validPolygon
Definition: CoaddBoundedField.cc:165
coaddWcs
afw::table::Key< int > coaddWcs
Definition: CoaddBoundedField.cc:128
lsst::meas::algorithms::CoaddBoundedField::write
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
Definition: CoaddBoundedField.cc:233
lsst::pex::exceptions::DomainError
Reports arguments outside the domain of an operation.
Definition: Runtime.h:57
lsst::afw::geom::polygon::Polygon
Cartesian polygons.
Definition: Polygon.h:59
lsst::meas::algorithms::CoaddBoundedField::evaluate
double evaluate(geom::Point2D const &position) const override
Evaluate the field at the given point.
Definition: CoaddBoundedField.cc:89
field
afw::table::Key< int > field
Definition: CoaddBoundedField.cc:163
lsst::meas::algorithms::CoaddBoundedField::CoaddBoundedField
CoaddBoundedField(geom::Box2I const &bbox, boost::shared_ptr< afw::geom::SkyWcs const > coaddWcs, ElementVector const &elements)
Definition: CoaddBoundedField.cc:73
lsst::afw::table::BaseRecord
Base class for all records.
Definition: BaseRecord.h:31
lsst::afw::table::io::CatalogVector
A vector of catalogs used by Persistable.
Definition: CatalogVector.h:29
wcs
afw::table::Key< int > wcs
Definition: CoaddBoundedField.cc:164
lsst::afw::table::CatalogIterator
Iterator class for CatalogT.
Definition: Catalog.h:39
lsst::afw::table::io::PersistableFactory
A base class for factory classes used to reconstruct objects from records.
Definition: Persistable.h:228
weight
afw::table::Key< double > weight
Definition: CoaddBoundedField.cc:166
b
table::Key< int > b
Definition: TransmissionCurve.cc:467
lsst::meas::algorithms::CoaddBoundedField
Definition: CoaddBoundedField.h:60
lsst
A base class for image defects.
Definition: imageAlgorithm.dox:1
LSST_EXCEPT
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
lsst::afw::math::BoundedField::getBBox
lsst::geom::Box2I getBBox() const
Return the bounding box that defines the region where the field is valid.
Definition: BoundedField.h:112
lsst::meas::algorithms::CoaddBoundedFieldElement
Struct used to hold one Exposure's data in a CoaddBoundedField.
Definition: CoaddBoundedField.h:37
lsst::afw::table::io::Persistable
A base class for objects that can be persisted via afw::table::io Archive classes.
Definition: Persistable.h:74
Runtime.h
lsst::afw::image.slicing.Factory
Factory
Definition: slicing.py:252
lsst::afw::table::io::PersistableFacade::dynamicCast
static std::shared_ptr< T > dynamicCast(std::shared_ptr< Persistable > const &ptr)
Dynamically cast a shared_ptr.
Definition: Persistable.cc:18
a
table::Key< int > a
Definition: TransmissionCurve.cc:466
std::vector::begin
T begin(T... args)
PTR
#define PTR(...)
Definition: base.h:41
lsst::geom::Point< double, 2 >
lsst::meas::algorithms::CoaddBoundedFieldElement::field
boost::shared_ptr< afw::math::BoundedField > field
Definition: CoaddBoundedField.h:51
lsst::meas::algorithms::CoaddBoundedField::Factory::Factory
Factory(std::string const &name)
Definition: CoaddBoundedField.cc:218
lsst::geom::Box2I
An integer coordinate rectangle.
Definition: Box.h:55
lsst::afw.display.ds9.scale
def scale(algorithm, min, max=None, frame=None)
Definition: ds9.py:109
InputArchive.h
lsst::afw::table::io::OutputArchiveHandle::put
int put(Persistable const *obj, bool permissive=false)
Save an object to the archive and return a unique ID that can be used to retrieve it from an InputArc...
Definition: OutputArchive.cc:216
std::vector::end
T end(T... args)
lsst::afw::table::CatalogT::addNew
std::shared_ptr< RecordT > addNew()
Create a new record, add it to the end of the catalog, and return a pointer to it.
Definition: Catalog.h:485
lsst::meas::algorithms::CoaddBoundedFieldElement::weight
double weight
Definition: CoaddBoundedField.h:56
lsst::geom::Box2D
A floating-point coordinate rectangle geometry.
Definition: Box.h:413
lsst::meas::algorithms::CoaddBoundedField::operator*
boost::shared_ptr< afw::math::BoundedField > operator*(double const scale) const override
Return a scaled BoundedField.
Definition: CoaddBoundedField.cc:254
lsst::afw::table::CatalogT< BaseRecord >
OutputArchive.h
bbox
AmpInfoBoxKey bbox
Definition: Amplifier.cc:117
throwOnMissing
afw::table::Key< afw::table::Flag > throwOnMissing
Definition: CoaddBoundedField.cc:129
lsst::meas::algorithms::CoaddBoundedField::getPersistenceName
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
Definition: CoaddBoundedField.cc:229