LSST Applications  21.0.0+c4f5df5339,21.0.0+e70536a077,21.0.0-1-ga51b5d4+7c60f8a6ea,21.0.0-10-gcf60f90+74aa0801fd,21.0.0-12-g63909ac9+643a1044a5,21.0.0-15-gedb9d5423+1041c3824f,21.0.0-2-g103fe59+a356b2badb,21.0.0-2-g1367e85+6d3f3f41db,21.0.0-2-g45278ab+e70536a077,21.0.0-2-g5242d73+6d3f3f41db,21.0.0-2-g7f82c8f+8d7c04eab9,21.0.0-2-g8f08a60+9c9a9cfcc8,21.0.0-2-ga326454+8d7c04eab9,21.0.0-2-gde069b7+bedfc5e1fb,21.0.0-2-gecfae73+6cb6558258,21.0.0-2-gfc62afb+6d3f3f41db,21.0.0-3-g21c7a62+f6e98b25aa,21.0.0-3-g357aad2+bd62456bea,21.0.0-3-g4be5c26+6d3f3f41db,21.0.0-3-g65f322c+03a4076c01,21.0.0-3-g7d9da8d+c4f5df5339,21.0.0-3-gaa929c8+c6b98066dc,21.0.0-3-gc44e71e+a26d5c1aea,21.0.0-3-ge02ed75+04b527a9d5,21.0.0-35-g64f566ff+b27e5ef93e,21.0.0-4-g591bb35+04b527a9d5,21.0.0-4-g88306b8+8773047b2e,21.0.0-4-gc004bbf+80a0b7acb7,21.0.0-4-gccdca77+a5c54364a0,21.0.0-4-ge8fba5a+ccfc328107,21.0.0-5-gdf36809+87b8d260e6,21.0.0-6-g00874e7+7eeda2b6ba,21.0.0-6-g2d4f3f3+e70536a077,21.0.0-6-g4e60332+04b527a9d5,21.0.0-6-g5ef7dad+f53629abd8,21.0.0-7-gc8ca178+b63e69433b,21.0.0-8-gfbe0b4b+c6b98066dc,w.2021.06
LSST Data Management Base Package
ProductBoundedField.cc
Go to the documentation of this file.
1 // -*- LSST-C++ -*-
2 /*
3  * LSST Data Management System
4  * Copyright 2008-2014 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 
24 #include <algorithm>
25 
26 #include "ndarray/eigen.h"
27 
28 #include "lsst/pex/exceptions.h"
35 
36 namespace lsst {
37 namespace afw {
38 
39 template std::shared_ptr<math::ProductBoundedField> table::io::PersistableFacade<
40  math::ProductBoundedField>::dynamicCast(std::shared_ptr<table::io::Persistable> const&);
41 
42 namespace math {
43 
44 namespace {
45 
46 lsst::geom::Box2I checkAndExtractBBox(std::vector<std::shared_ptr<BoundedField const>> const & factors) {
47  if (factors.size() < 1u) {
48  throw LSST_EXCEPT(
49  pex::exceptions::LengthError,
50  "ProductBoundedField requires at least one BoundedField factor."
51  );
52  }
53  auto iter = factors.begin();
54  auto bbox = (**iter).getBBox();
55  ++iter;
56  for (; iter != factors.end(); ++iter) {
57  if ((**iter).getBBox() != bbox) {
58  throw LSST_EXCEPT(
59  pex::exceptions::InvalidParameterError,
60  (boost::format("Inconsistency in ProductBoundedField bboxes: %s != %s") %
61  bbox % (**iter).getBBox()).str()
62  );
63  }
64  }
65  return bbox;
66 }
67 
68 } // anonymous
69 
71  BoundedField(checkAndExtractBBox(factors)), _factors(factors)
72 {}
73 
77 
78 double ProductBoundedField::evaluate(lsst::geom::Point2D const& position) const {
79  double product = 1.0;
80  for (auto const & field : _factors) {
81  product *= field->evaluate(position);
82  }
83  return product;
84 }
85 
86 ndarray::Array<double, 1, 1> ProductBoundedField::evaluate(
87  ndarray::Array<double const, 1> const& x,
88  ndarray::Array<double const, 1> const& y
89 ) const {
90  if (x.getShape() != y.getShape()) {
91  throw LSST_EXCEPT(
93  (boost::format("Inconsistent shapes: %s != %s") % x.getShape() % y.getShape()).str()
94  );
95  }
96  ndarray::Array<double, 1, 1> z = ndarray::allocate(x.getShape());
97  std::fill(z.begin(), z.end(), 1.0);
98  for (auto const & field : _factors) {
99  ndarray::asEigenArray(z) *= ndarray::asEigenArray(field->evaluate(x, y));
100  }
101  return z;
102 }
103 
104 // ------------------ persistence ---------------------------------------------------------------------------
105 
106 namespace {
107 
108 struct PersistenceHelper {
109  table::Schema schema;
110  table::Key<int> id;
111 
112  static PersistenceHelper const & get() {
113  static PersistenceHelper const instance;
114  return instance;
115  }
116 
117 private:
118 
119  PersistenceHelper() :
120  schema(),
121  id(schema.addField<int>("id", "Archive ID of a BoundedField factor."))
122  {}
123 
124  PersistenceHelper(PersistenceHelper const &) = delete;
125  PersistenceHelper(PersistenceHelper &&) = delete;
126  PersistenceHelper & operator=(PersistenceHelper const &) = delete;
127  PersistenceHelper & operator=(PersistenceHelper &&) = delete;
128 
129  ~PersistenceHelper() noexcept = default;
130 
131 };
132 
133 class ProductBoundedFieldFactory : public table::io::PersistableFactory {
134 public:
135  explicit ProductBoundedFieldFactory(std::string const& name)
136  : afw::table::io::PersistableFactory(name) {}
137 
138  std::shared_ptr<table::io::Persistable> read(InputArchive const& archive,
139  CatalogVector const& catalogs) const override {
140  LSST_ARCHIVE_ASSERT(catalogs.size() == 1u);
141  auto const & keys = PersistenceHelper::get();
142  auto const & cat = catalogs.front();
144  factors.reserve(cat.size());
145  for (auto const & record : cat) {
146  factors.push_back(archive.get<BoundedField>(record.get(keys.id)));
147  }
148  return std::make_shared<ProductBoundedField>(factors);
149  }
150 };
151 
152 std::string getProductBoundedFieldPersistenceName() { return "ProductBoundedField"; }
153 
154 ProductBoundedFieldFactory registration(getProductBoundedFieldPersistenceName());
155 
156 } // namespace
157 
158 bool ProductBoundedField::isPersistable() const noexcept {
159  return std::all_of(_factors.begin(), _factors.end(),
160  [](auto const & field) { return field->isPersistable(); });
161 }
162 
164  return getProductBoundedFieldPersistenceName();
165 }
166 
167 std::string ProductBoundedField::getPythonModule() const { return "lsst.afw.math"; }
168 
170  auto const & keys = PersistenceHelper::get();
171  table::BaseCatalog catalog = handle.makeCatalog(keys.schema);
172  catalog.reserve(_factors.size());
173  for (auto const & field : _factors) {
174  catalog.addNew()->set(keys.id, handle.put(field));
175  }
176  handle.saveCatalog(catalog);
177 }
178 
179 // ------------------ operators -----------------------------------------------------------------------------
180 
183  bool multiplied = false;
184  for (auto & field : factors) {
185  try {
186  field = (*field) * scale;
187  multiplied = true;
188  break;
189  } catch (pex::exceptions::LogicError &) {}
190  }
191  if (!multiplied) {
192  ndarray::Array<double, 2, 2> coefficients = ndarray::allocate(1, 1);
193  coefficients[0][0] = scale;
194  factors.push_back(std::make_shared<ChebyshevBoundedField>(getBBox(), coefficients));
195  }
196  return std::make_shared<ProductBoundedField>(factors);
197 }
198 
200  auto rhsCasted = dynamic_cast<ProductBoundedField const*>(&rhs);
201  if (!rhsCasted) return false;
202 
203  return (getBBox() == rhsCasted->getBBox()) &&
204  std::equal(_factors.begin(), _factors.end(),
205  rhsCasted->_factors.begin(), rhsCasted->_factors.end(),
206  [](auto const & a, auto const & b) { return *a == *b; });
207 }
208 
209 std::string ProductBoundedField::toString() const {
211  os << "ProductBoundedField([";
212  for (auto const & field : _factors) {
213  os << (*field) << ", ";
214  }
215  os << "])";
216  return os.str();
217 }
218 
219 } // namespace math
220 } // namespace afw
221 } // namespace lsst
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
double z
Definition: Match.cc:44
std::ostream * os
Definition: Schema.cc:746
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
Definition: Persistable.h:48
T all_of(T... args)
An abstract base class for 2-d functions defined on an integer bounding boxes.
Definition: BoundedField.h:55
lsst::geom::Box2I getBBox() const
Return the bounding box that defines the region where the field is valid.
Definition: BoundedField.h:112
A BoundedField that lazily multiplies a sequence of other BoundedFields.
bool operator==(BoundedField const &rhs) const override
BoundedFields (of the same sublcass) are equal if their bounding boxes and parameters are equal.
bool isPersistable() const noexcept override
ProductBoundedField is persistable if and only if all of its factors are.
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
ProductBoundedField(std::vector< std::shared_ptr< BoundedField const >> const &factors)
Construct from a sequence of BoundedField factors.
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
std::shared_ptr< BoundedField > operator*(double const scale) const override
Return a scaled BoundedField.
std::string getPythonModule() const override
Return the fully-qualified Python module that should be imported to guarantee that its factory is reg...
virtual double evaluate(lsst::geom::Point2D const &position) const=0
Evaluate the field at the given point.
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
void reserve(size_type n)
Increase the capacity of the catalog to the given size.
Definition: Catalog.h:428
An object passed to Persistable::write to allow it to persist itself.
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
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...
An integer coordinate rectangle.
Definition: Box.h:55
Reports invalid arguments.
Definition: Runtime.h:66
Reports errors in the logical structure of the program.
Definition: Runtime.h:46
T equal(T... args)
T fill(T... args)
def scale(algorithm, min, max=None, frame=None)
Definition: ds9.py:109
FilterProperty & operator=(FilterProperty const &)=default
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:174
A base class for image defects.
T push_back(T... args)
T reserve(T... args)
AmpInfoBoxKey bbox
Definition: Amplifier.cc:117
int y
Definition: SpanSet.cc:49
table::Key< int > field
Definition: ApCorrMap.cc:77
table::Key< int > b
table::Key< int > a
ndarray::Array< double const, 2, 2 > coefficients
double x
table::Key< int > id
table::Schema schema