LSSTApplications  18.1.0
LSSTDataManagementBasePackage
FunctionLibrary.cc
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 
3 #include <memory>
4 
10 
11 namespace lsst {
12 namespace afw {
13 namespace math {
14 
15 namespace {
16 
17 // Singleton persistence schema for 2-d Gaussians
18 struct GaussianFunction2PersistenceHelper {
19  table::Schema schema;
20  table::Key<double> sigma1;
21  table::Key<double> sigma2;
22  table::Key<double> angle;
23 
24  static GaussianFunction2PersistenceHelper const& get() {
25  static GaussianFunction2PersistenceHelper instance;
26  return instance;
27  }
28 
29  // No copying
30  GaussianFunction2PersistenceHelper(const GaussianFunction2PersistenceHelper&) = delete;
31  GaussianFunction2PersistenceHelper& operator=(const GaussianFunction2PersistenceHelper&) = delete;
32 
33  // No moving
34  GaussianFunction2PersistenceHelper(GaussianFunction2PersistenceHelper&&) = delete;
35  GaussianFunction2PersistenceHelper& operator=(GaussianFunction2PersistenceHelper&&) = delete;
36 
37 private:
38  GaussianFunction2PersistenceHelper()
39  : schema(),
40  sigma1(schema.addField<double>("sigma1", "sigma along axis 1")),
41  sigma2(schema.addField<double>("sigma2", "sigma along axis 2")),
42  angle(schema.addField<double>("angle", "angle of axis 1 in rad (along x=0, y=pi/2)")) {
43  schema.getCitizen().markPersistent();
44  }
45 };
46 
47 // Singleton persistence schema for 2-d circular DoubleGaussians
48 struct DoubleGaussianFunction2PersistenceHelper {
49  table::Schema schema;
50  table::Key<double> sigma1;
51  table::Key<double> sigma2;
52  table::Key<double> ampl2;
53 
54  static DoubleGaussianFunction2PersistenceHelper const& get() {
55  static DoubleGaussianFunction2PersistenceHelper instance;
56  return instance;
57  }
58 
59  // No copying
60  DoubleGaussianFunction2PersistenceHelper(const DoubleGaussianFunction2PersistenceHelper&) = delete;
61  DoubleGaussianFunction2PersistenceHelper& operator=(const DoubleGaussianFunction2PersistenceHelper&) =
62  delete;
63 
64  // No moving
65  DoubleGaussianFunction2PersistenceHelper(DoubleGaussianFunction2PersistenceHelper&&) = delete;
66  DoubleGaussianFunction2PersistenceHelper& operator=(DoubleGaussianFunction2PersistenceHelper&&) = delete;
67 
68 private:
69  DoubleGaussianFunction2PersistenceHelper()
70  : schema(),
71  sigma1(schema.addField<double>("sigma1", "sigma of first Gaussian")),
72  sigma2(schema.addField<double>("sigma2", "sigma of second Gaussian")),
73  ampl2(schema.addField<double>("ampl2", "peak of second Gaussian relative to peak of first")) {
74  schema.getCitizen().markPersistent();
75  }
76 };
77 
78 // Persistence schema for 2-d polynomials; not a singleton because it depends on the order.
79 struct PolynomialFunction2PersistenceHelper {
80  table::Schema schema;
81  table::Key<table::Array<double> > coefficients;
82 
83  explicit PolynomialFunction2PersistenceHelper(int nCoefficients)
84  : schema(),
85  coefficients(schema.addField<table::Array<double> >(
86  "coefficients",
87  "polynomial coefficients, ordered (x,y) [0,0; 1,0; 0,1; 2,0; 1,1; 0,2; ...]",
88  nCoefficients)) {}
89 
90  explicit PolynomialFunction2PersistenceHelper(table::Schema const& schema_)
91  : schema(schema_), coefficients(schema["coefficients"]) {}
92 };
93 
94 // Persistance schema for 2-d Chebyshevs; not a singleton because it depends on the order.
95 struct Chebyshev1Function2PersistenceHelper : public PolynomialFunction2PersistenceHelper {
96  table::PointKey<double> min;
97  table::PointKey<double> max;
98 
99  explicit Chebyshev1Function2PersistenceHelper(int nCoefficients)
100  : PolynomialFunction2PersistenceHelper(nCoefficients),
101  min(table::PointKey<double>::addFields(schema, "min", "minimum point for function's bbox",
102  "pixel")),
103  max(table::PointKey<double>::addFields(schema, "max", "maximum point for function's bbox",
104  "pixel")) {}
105 
106  explicit Chebyshev1Function2PersistenceHelper(table::Schema const& schema_)
107  : PolynomialFunction2PersistenceHelper(schema_), min(schema["min"]), max(schema["max"]) {}
108 };
109 
110 template <typename ReturnT>
111 class GaussianFunction2Factory : public table::io::PersistableFactory {
112 public:
113  std::shared_ptr<table::io::Persistable> read(InputArchive const& archive,
114  CatalogVector const& catalogs) const override {
115  LSST_ARCHIVE_ASSERT(catalogs.size() == 1u);
116  LSST_ARCHIVE_ASSERT(catalogs.front().size() == 1u);
117  GaussianFunction2PersistenceHelper const& keys = GaussianFunction2PersistenceHelper::get();
118  LSST_ARCHIVE_ASSERT(catalogs.front().getSchema().contains(keys.schema));
119  table::BaseRecord const& record = catalogs.front().front();
120  return std::make_shared<GaussianFunction2<ReturnT> >(record.get(keys.sigma1), record.get(keys.sigma2),
121  record.get(keys.angle));
122  }
123 
124  GaussianFunction2Factory(std::string const& name) : table::io::PersistableFactory(name) {}
125 };
126 
127 template <typename ReturnT>
128 class DoubleGaussianFunction2Factory : public table::io::PersistableFactory {
129 public:
130  std::shared_ptr<table::io::Persistable> read(InputArchive const& archive,
131  CatalogVector const& catalogs) const override {
132  LSST_ARCHIVE_ASSERT(catalogs.size() == 1u);
133  LSST_ARCHIVE_ASSERT(catalogs.front().size() == 1u);
134  DoubleGaussianFunction2PersistenceHelper const& keys =
135  DoubleGaussianFunction2PersistenceHelper::get();
136  LSST_ARCHIVE_ASSERT(catalogs.front().getSchema().contains(keys.schema));
137  table::BaseRecord const& record = catalogs.front().front();
138  return std::make_shared<DoubleGaussianFunction2<ReturnT> >(
139  record.get(keys.sigma1), record.get(keys.sigma2), record.get(keys.ampl2));
140  }
141 
142  DoubleGaussianFunction2Factory(std::string const& name) : table::io::PersistableFactory(name) {}
143 };
144 
145 template <typename ReturnT>
146 class PolynomialFunction2Factory : public table::io::PersistableFactory {
147 public:
148  std::shared_ptr<table::io::Persistable> read(InputArchive const& archive,
149  CatalogVector const& catalogs) const override {
150  LSST_ARCHIVE_ASSERT(catalogs.size() == 1u);
151  LSST_ARCHIVE_ASSERT(catalogs.front().size() == 1u);
152  PolynomialFunction2PersistenceHelper const keys(catalogs.front().getSchema());
153  return std::make_shared<PolynomialFunction2<ReturnT> >(
154  keys.coefficients.extractVector(catalogs.front().front()));
155  }
156 
157  PolynomialFunction2Factory(std::string const& name) : table::io::PersistableFactory(name) {}
158 };
159 
160 template <typename ReturnT>
161 class Chebyshev1Function2Factory : public table::io::PersistableFactory {
162 public:
163  std::shared_ptr<table::io::Persistable> read(InputArchive const& archive,
164  CatalogVector const& catalogs) const override {
165  LSST_ARCHIVE_ASSERT(catalogs.size() == 1u);
166  LSST_ARCHIVE_ASSERT(catalogs.front().size() == 1u);
167  Chebyshev1Function2PersistenceHelper keys(catalogs.front().getSchema());
168  table::BaseRecord const& record = catalogs.front().front();
169  lsst::geom::Box2D bbox(record.get(keys.min), record.get(keys.max));
170  return std::make_shared<Chebyshev1Function2<ReturnT> >(keys.coefficients.extractVector(record), bbox);
171  }
172 
173  Chebyshev1Function2Factory(std::string const& name) : table::io::PersistableFactory(name) {}
174 };
175 
176 GaussianFunction2Factory<float> registrationGaussian2F("GaussianFunction2F");
177 GaussianFunction2Factory<double> registrationGaussian2D("GaussianFunction2D");
178 
179 DoubleGaussianFunction2Factory<float> registrationDoubleGaussian2F("DoubleGaussianFunction2F");
180 DoubleGaussianFunction2Factory<double> registrationDoubleGaussian2D("DoubleGaussianFunction2D");
181 
182 PolynomialFunction2Factory<float> registrationPoly2F("PolynomialFunction2F");
183 PolynomialFunction2Factory<double> registrationPoly2D("PolynomialFunction2D");
184 
185 Chebyshev1Function2Factory<float> registrationCheb2F("Chebyshev1Function2F");
186 Chebyshev1Function2Factory<double> registrationCheb2D("Chebyshev1Function2D");
187 
188 template <typename T>
189 struct Suffix;
190 template <>
191 struct Suffix<float> {
192  static std::string get() { return "F"; }
193 };
194 template <>
195 struct Suffix<double> {
196  static std::string get() { return "D"; }
197 };
198 
199 } // namespace
200 
201 template <typename ReturnT>
203  return "GaussianFunction2" + Suffix<ReturnT>::get();
204 }
205 
206 template <typename ReturnT>
208  return "DoubleGaussianFunction2" + Suffix<ReturnT>::get();
209 }
210 
211 template <typename ReturnT>
213  return "PolynomialFunction2" + Suffix<ReturnT>::get();
214 }
215 
216 template <typename ReturnT>
218  return "Chebyshev1Function2" + Suffix<ReturnT>::get();
219 }
220 
221 template <typename ReturnT>
223  GaussianFunction2PersistenceHelper const& keys = GaussianFunction2PersistenceHelper::get();
224  table::BaseCatalog catalog = handle.makeCatalog(keys.schema);
225  std::shared_ptr<table::BaseRecord> record = catalog.addNew();
226  record->set(keys.sigma1, this->getParameters()[0]);
227  record->set(keys.sigma2, this->getParameters()[1]);
228  record->set(keys.angle, this->getParameters()[2]);
229  handle.saveCatalog(catalog);
230 }
231 
232 template <typename ReturnT>
234  DoubleGaussianFunction2PersistenceHelper const& keys = DoubleGaussianFunction2PersistenceHelper::get();
235  table::BaseCatalog catalog = handle.makeCatalog(keys.schema);
236  std::shared_ptr<table::BaseRecord> record = catalog.addNew();
237  record->set(keys.sigma1, this->getParameters()[0]);
238  record->set(keys.sigma2, this->getParameters()[1]);
239  record->set(keys.ampl2, this->getParameters()[2]);
240  handle.saveCatalog(catalog);
241 }
242 
243 template <typename ReturnT>
245  PolynomialFunction2PersistenceHelper const keys(this->getNParameters());
246  table::BaseCatalog catalog = handle.makeCatalog(keys.schema);
247  keys.coefficients.assignVector(*catalog.addNew(), this->getParameters());
248  handle.saveCatalog(catalog);
249 }
250 
251 template <typename ReturnT>
253  Chebyshev1Function2PersistenceHelper const keys(this->getNParameters());
254  table::BaseCatalog catalog = handle.makeCatalog(keys.schema);
255  std::shared_ptr<table::BaseRecord> record = catalog.addNew();
256  keys.coefficients.assignVector(*record, this->getParameters());
257  lsst::geom::Box2D bbox = getXYRange();
258  record->set(keys.min, bbox.getMin());
259  record->set(keys.max, bbox.getMax());
260  handle.saveCatalog(catalog);
261 }
262 
263 // Explicit instantiation
264 #define INSTANTIATE(TYPE) \
265  template class IntegerDeltaFunction1<TYPE>; \
266  template class IntegerDeltaFunction2<TYPE>; \
267  template class GaussianFunction1<TYPE>; \
268  template class GaussianFunction2<TYPE>; \
269  template class DoubleGaussianFunction2<TYPE>; \
270  template class PolynomialFunction1<TYPE>; \
271  template class PolynomialFunction2<TYPE>; \
272  template class Chebyshev1Function1<TYPE>; \
273  template class Chebyshev1Function2<TYPE>; \
274  template class LanczosFunction1<TYPE>; \
275  template class LanczosFunction2<TYPE>;
276 
277 INSTANTIATE(float);
278 INSTANTIATE(double);
279 } // namespace math
280 } // namespace afw
281 } // namespace lsst
void write(afw::table::io::OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
A floating-point coordinate rectangle geometry.
Definition: Box.h:305
An object passed to Persistable::write to allow it to persist itself.
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
void write(afw::table::io::OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
table::Key< double > angle
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
Point2D const getMin() const noexcept
Definition: Box.h:393
table::Key< double > sigma2
STL class.
void write(afw::table::io::OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
#define INSTANTIATE(TYPE)
A base class for image defects.
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
Definition: Persistable.h:48
table::PointKey< double > min
table::PointKey< double > max
table::Box2IKey bbox
Definition: Detector.cc:169
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
Point2D const getMax() const noexcept
Definition: Box.h:397
table::Key< table::Array< double > > coefficients
table::Key< double > ampl2
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
void write(afw::table::io::OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
table::Schema schema
table::Key< double > sigma1
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