LSSTApplications  18.1.0
LSSTDataManagementBasePackage
aggregates.cc
Go to the documentation of this file.
1 /*
2  * LSST Data Management System
3  * Copyright 2008-2016 AURA/LSST.
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 <https://www.lsstcorp.org/LegalNotices/>.
21  */
22 
23 #include "pybind11/pybind11.h"
24 #include "pybind11/eigen.h"
25 #include "pybind11/stl.h"
26 
27 #include "ndarray/pybind11.h"
28 
30 
31 #include "lsst/geom/Angle.h"
32 #include "lsst/geom/SpherePoint.h"
33 #include "lsst/geom/Box.h"
34 #include "lsst/afw/table/Key.h"
35 #include "lsst/afw/table/Schema.h"
39 
40 namespace py = pybind11;
41 using namespace pybind11::literals;
42 
43 namespace lsst {
44 namespace afw {
45 namespace table {
46 namespace {
47 
48 // We don't expose base classes (e.g. FunctorKey) to Python, since they're just used to
49 // define a CRTP interface in C++ and in Python that's just duck-typing.
50 
51 template <typename T>
52 using PyPointKey = py::class_<PointKey<T>, std::shared_ptr<PointKey<T>>>;
53 
54 template <typename Box>
55 using PyBoxKey = py::class_<BoxKey<Box>, std::shared_ptr<BoxKey<Box>>>;
56 
57 using PyCoordKey = py::class_<CoordKey, std::shared_ptr<CoordKey>>;
58 
59 using PyQuadrupoleKey = py::class_<QuadrupoleKey, std::shared_ptr<QuadrupoleKey>>;
60 
61 using PyEllipseKey = py::class_<EllipseKey, std::shared_ptr<EllipseKey>>;
62 
63 template <typename T, int N>
64 using PyCovarianceMatrixKey =
65  py::class_<CovarianceMatrixKey<T, N>, std::shared_ptr<CovarianceMatrixKey<T, N>>>;
66 
67 template <typename T>
68 static void declarePointKey(py::module &mod, std::string const &suffix) {
69  PyPointKey<T> cls(mod, ("Point" + suffix + "Key").c_str());
70  cls.def(py::init<>());
71  cls.def(py::init<Key<T> const &, Key<T> const &>(), "x"_a, "y"_a);
72  cls.def(py::init<SubSchema const &>());
73  cls.def("__eq__", &PointKey<T>::operator==, py::is_operator());
74  cls.def("__ne__", &PointKey<T>::operator!=, py::is_operator());
75  cls.def("getX", &PointKey<T>::getX);
76  cls.def("getY", &PointKey<T>::getY);
77  cls.def("isValid", &PointKey<T>::isValid);
78  cls.def_static("addFields", &PointKey<T>::addFields, "schema"_a, "name"_a, "doc"_a, "unit"_a);
79  cls.def("set", [](PointKey<T> &self, BaseRecord &record, lsst::geom::Point<T, 2> const &value) {
80  return self.set(record, value);
81  });
82  cls.def("get", &PointKey<T>::get);
83 };
84 
85 template <typename Box>
86 static void declareBoxKey(py::module &mod, std::string const &suffix) {
87  using Element = typename Box::Element;
88  PyBoxKey<Box> cls(mod, ("Box" + suffix + "Key").c_str());
89  cls.def(py::init<>());
90  cls.def(py::init<PointKey<Element> const &, PointKey<Element> const &>(), "min"_a, "max"_a);
91  cls.def(py::init<SubSchema const &>());
92  cls.def("__eq__", &BoxKey<Box>::operator==, py::is_operator());
93  cls.def("__ne__", &BoxKey<Box>::operator!=, py::is_operator());
94  cls.def("getMin", &BoxKey<Box>::getMin);
95  cls.def("getMax", &BoxKey<Box>::getMax);
96  cls.def("isValid", &BoxKey<Box>::isValid);
97  cls.def_static("addFields", &BoxKey<Box>::addFields, "schema"_a, "name"_a, "doc"_a, "unit"_a);
98  cls.def("set", &BoxKey<Box>::set);
99  cls.def("get", &BoxKey<Box>::get);
100 };
101 
102 static void declareCoordKey(py::module &mod) {
103  PyCoordKey cls(mod, "CoordKey");
104  cls.def(py::init<>());
105  cls.def(py::init<Key<lsst::geom::Angle>, Key<lsst::geom::Angle>>(), "ra"_a, "dec"_a);
106  cls.def(py::init<SubSchema const &>());
107  cls.def("__eq__", &CoordKey::operator==, py::is_operator());
108  cls.def("__ne__", &CoordKey::operator!=, py::is_operator());
109  cls.def_static("addFields", &CoordKey::addFields, "schema"_a, "name"_a, "doc"_a);
110  cls.def("getRa", &CoordKey::getRa);
111  cls.def("getDec", &CoordKey::getDec);
112  cls.def("isValid", &CoordKey::isValid);
113  cls.def("get", [](CoordKey &self, BaseRecord const &record) { return self.get(record); });
114  cls.def("set", &CoordKey::set);
115 }
116 
117 static void declareQuadrupoleKey(py::module &mod) {
118  PyQuadrupoleKey cls(mod, "QuadrupoleKey");
119  cls.def(py::init<>());
120  cls.def(py::init<Key<double> const &, Key<double> const &, Key<double> const &>(), "ixx"_a, "iyy"_a,
121  "ixy"_a);
122  cls.def(py::init<SubSchema const &>());
123  cls.def("__eq__", &QuadrupoleKey::operator==, py::is_operator());
124  cls.def("__nq__", &QuadrupoleKey::operator!=, py::is_operator());
125  cls.def_static("addFields", &QuadrupoleKey::addFields, "schema"_a, "name"_a, "doc"_a,
126  "coordType"_a = CoordinateType::PIXEL);
127  cls.def("getIxx", &QuadrupoleKey::getIxx);
128  cls.def("getIyy", &QuadrupoleKey::getIyy);
129  cls.def("getIxy", &QuadrupoleKey::getIxy);
130  cls.def("isValid", &QuadrupoleKey::isValid);
131  cls.def("set", &QuadrupoleKey::set);
132  cls.def("get", &QuadrupoleKey::get);
133 }
134 
135 static void declareEllipseKey(py::module &mod) {
136  PyEllipseKey cls(mod, "EllipseKey");
137  cls.def(py::init<>());
138  cls.def(py::init<QuadrupoleKey const &, PointKey<double> const &>(), "qKey"_a, "pKey"_a);
139  cls.def(py::init<SubSchema const &>());
140  cls.def("__eq__", &EllipseKey::operator==, py::is_operator());
141  cls.def("__nq__", &EllipseKey::operator!=, py::is_operator());
142  cls.def_static("addFields", &EllipseKey::addFields, "schema"_a, "name"_a, "doc"_a, "unit"_a);
143  cls.def("get", &EllipseKey::get);
144  cls.def("set", &EllipseKey::set);
145  cls.def("isValid", &EllipseKey::isValid);
146  cls.def("getCore", &EllipseKey::getCore);
147  cls.def("getCenter", &EllipseKey::getCenter);
148 }
149 
150 template <typename T, int N>
151 static void declareCovarianceMatrixKey(py::module &mod, const ::std::string &suffix) {
152  typedef std::vector<Key<T>> ErrKeyArray;
153  typedef std::vector<Key<T>> CovarianceKeyArray;
154  typedef std::vector<std::string> NameArray;
155 
156  PyCovarianceMatrixKey<T, N> cls(mod, ("CovarianceMatrix" + suffix + "Key").c_str());
157 
158  cls.def(py::init<>());
159  // Ordering of the next two ctor declaration matters, as a workaround for DM-8580.
160  cls.def(py::init<SubSchema const &, NameArray const &>());
161  cls.def(py::init<ErrKeyArray const &, CovarianceKeyArray const &>(), "err"_a,
162  "cov"_a = CovarianceKeyArray());
163  cls.def("__eq__", &CovarianceMatrixKey<T, N>::operator==, py::is_operator());
164  cls.def("__ne__", &CovarianceMatrixKey<T, N>::operator!=, py::is_operator());
165  cls.def_static("addFields", (CovarianceMatrixKey<T, N>(*)(Schema &, std::string const &,
166  NameArray const &, std::string const &, bool)) &
167  CovarianceMatrixKey<T, N>::addFields,
168  "schema"_a, "prefix"_a, "names"_a, "unit"_a, "diagonalOnly"_a = false);
169  cls.def_static("addFields", (CovarianceMatrixKey<T, N>(*)(Schema &, std::string const &,
170  NameArray const &, NameArray const &, bool)) &
171  CovarianceMatrixKey<T, N>::addFields,
172  "schema"_a, "prefix"_a, "names"_a, "units"_a, "diagonalOnly"_a = false);
173  cls.def("set", [](CovarianceMatrixKey<T, N> &cov, BaseRecord &record,
174  Eigen::Matrix<T, N, N> const &value) { return cov.set(record, value); });
175  cls.def("get", [](CovarianceMatrixKey<T, N> &cov, BaseRecord const &record) { return cov.get(record); });
176  cls.def("isValid", &CovarianceMatrixKey<T, N>::isValid);
177  cls.def("setElement", &CovarianceMatrixKey<T, N>::setElement);
178  cls.def("getElement", &CovarianceMatrixKey<T, N>::getElement);
179 };
180 
181 } // namespace lsst::afw::table::<anonymous>
182 
183 PYBIND11_MODULE(aggregates, mod) {
184  py::module::import("lsst.afw.geom.ellipses");
185  py::module::import("lsst.afw.table.base");
186  py::enum_<CoordinateType>(mod, "CoordinateType")
187  .value("PIXEL", CoordinateType::PIXEL)
188  .value("CELESTIAL", CoordinateType::CELESTIAL)
189  .export_values();
190 
191  declarePointKey<double>(mod, "2D");
192  declarePointKey<int>(mod, "2I");
193 
194  declareBoxKey<lsst::geom::Box2D>(mod, "2D");
195  declareBoxKey<lsst::geom::Box2I>(mod, "2I");
196 
197  declareCoordKey(mod);
198  declareQuadrupoleKey(mod);
199  declareEllipseKey(mod);
200 
201  declareCovarianceMatrixKey<float, 2>(mod, "2f");
202  declareCovarianceMatrixKey<float, 3>(mod, "3f");
203  declareCovarianceMatrixKey<float, 4>(mod, "4f");
204  declareCovarianceMatrixKey<float, Eigen::Dynamic>(mod, "Xf");
205  declareCovarianceMatrixKey<double, 2>(mod, "2d");
206  declareCovarianceMatrixKey<double, 3>(mod, "3d");
207  declareCovarianceMatrixKey<double, 4>(mod, "4d");
208  declareCovarianceMatrixKey<double, Eigen::Dynamic>(mod, "Xd");
209 }
210 }
211 }
212 } // namespace lsst::afw::table
A coordinate class intended to represent absolute positions (2-d specialization). ...
Definition: Point.h:211
def init()
Definition: tests.py:75
PYBIND11_MODULE(aggregates, mod)
Definition: aggregates.cc:183
daf::base::PropertySet * set
Definition: fits.cc:884
STL class.
A base class for image defects.
bool isValid
Definition: fits.cc:380
STL class.