LSST Applications  21.0.0+c4f5df5339,21.0.0+e70536a077,21.0.0-1-ga51b5d4+7c60f8a6ea,21.0.0-10-g560fb7b+411cd868f8,21.0.0-10-gcf60f90+8c49d86aa0,21.0.0-13-gc485e61d+38156233bf,21.0.0-16-g7a993c7b9+1041c3824f,21.0.0-2-g103fe59+d9ceee3e5a,21.0.0-2-g1367e85+0b2f7db15a,21.0.0-2-g45278ab+e70536a077,21.0.0-2-g5242d73+0b2f7db15a,21.0.0-2-g7f82c8f+feb9862f5e,21.0.0-2-g8f08a60+9c9a9cfcc8,21.0.0-2-ga326454+feb9862f5e,21.0.0-2-gde069b7+bedfc5e1fb,21.0.0-2-gecfae73+417509110f,21.0.0-2-gfc62afb+0b2f7db15a,21.0.0-3-g21c7a62+a91f7c0b59,21.0.0-3-g357aad2+062581ff1a,21.0.0-3-g4be5c26+0b2f7db15a,21.0.0-3-g65f322c+85aa0ead76,21.0.0-3-g7d9da8d+c4f5df5339,21.0.0-3-gaa929c8+411cd868f8,21.0.0-3-gc44e71e+fd4029fd48,21.0.0-3-ge02ed75+5d9b90b8aa,21.0.0-38-g070523fc+44fda2b515,21.0.0-4-g591bb35+5d9b90b8aa,21.0.0-4-g88306b8+3cdc83ea97,21.0.0-4-gc004bbf+d52368b591,21.0.0-4-gccdca77+a5c54364a0,21.0.0-5-g7ebb681+81e2098694,21.0.0-5-gdf36809+87b8d260e6,21.0.0-6-g2d4f3f3+e70536a077,21.0.0-6-g4e60332+5d9b90b8aa,21.0.0-6-g5ef7dad+3f4e29eeae,21.0.0-7-gc8ca178+0f5e56d48f,21.0.0-9-g9eb8d17+cc2c7a81aa,master-gac4afde19b+5d9b90b8aa,w.2021.07
LSST Data Management Base Package
transform.cc
Go to the documentation of this file.
1 /*
2  * LSST Data Management System
3  * See COPYRIGHT file at the top of the source tree.
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 <http://www.lsstcorp.org/LegalNotices/>.
21  */
22 #include "pybind11/pybind11.h"
23 #include "pybind11/eigen.h"
24 
25 #include <memory>
26 
27 #include "astshim.h"
28 #include "pybind11/stl.h"
29 #include "ndarray/pybind11.h"
30 
32 #include "lsst/afw/geom/Endpoint.h"
34 
35 namespace py = pybind11;
36 using namespace py::literals;
37 
38 namespace lsst {
39 namespace afw {
40 namespace geom {
41 namespace {
42 
43 // Return a string consisting of "_pythonClassName_[_fromNAxes_->_toNAxes_]",
44 // for example "TransformGenericToPoint2[4->2]"
45 template <class Class>
46 std::string formatStr(Class const &self, std::string const &pyClassName) {
48  os << pyClassName;
49  os << "[" << self.getFromEndpoint().getNAxes() << "->" << self.getToEndpoint().getNAxes() << "]";
50  return os.str();
51 }
52 
53 template <class FromEndpoint, class ToEndpoint, class NextToEndpoint, class PyClass>
54 void declareMethodTemplates(PyClass &cls) {
55  using ThisTransform = Transform<FromEndpoint, ToEndpoint>;
56  using NextTransform = Transform<ToEndpoint, NextToEndpoint>;
57  using SeriesTransform = Transform<FromEndpoint, NextToEndpoint>;
58  // Need Python-specific logic to give sensible errors for mismatched Transform types
59  cls.def("_then",
60  (std::shared_ptr<SeriesTransform>(ThisTransform::*)(NextTransform const &, bool) const) &
61  ThisTransform::template then<NextToEndpoint>,
62  "next"_a, "simplify"_a = true);
63 }
64 
65 // Declare Transform<FromEndpoint, ToEndpoint> using python class name Transform<X>To<Y>
66 // where <X> and <Y> are the prefix of the from endpoint and to endpoint class, respectively,
67 // for example TransformGenericToPoint2
68 template <class FromEndpoint, class ToEndpoint>
69 void declareTransform(py::module &mod) {
70  using Class = Transform<FromEndpoint, ToEndpoint>;
71  using ToPoint = typename ToEndpoint::Point;
72  using ToArray = typename ToEndpoint::Array;
73  using FromPoint = typename FromEndpoint::Point;
74  using FromArray = typename FromEndpoint::Array;
75 
76  std::string const pyClassName = Class::getShortClassName();
77 
78  py::class_<Class, std::shared_ptr<Class>> cls(mod, pyClassName.c_str());
79 
80  cls.def(py::init<ast::FrameSet const &, bool>(), "frameSet"_a, "simplify"_a = true);
81  cls.def(py::init<ast::Mapping const &, bool>(), "mapping"_a, "simplify"_a = true);
82 
83  cls.def_property_readonly("hasForward", &Class::hasForward);
84  cls.def_property_readonly("hasInverse", &Class::hasInverse);
85  cls.def_property_readonly("fromEndpoint", &Class::getFromEndpoint);
86  cls.def_property_readonly("toEndpoint", &Class::getToEndpoint);
87 
88  // Return a copy of the contained Mapping in order to assure changing the returned Mapping
89  // will not affect the contained Mapping (since Python ignores constness)
90  cls.def("getMapping", [](Class const &self) { return self.getMapping()->copy(); });
91 
92  cls.def("applyForward", py::overload_cast<FromArray const &>(&Class::applyForward, py::const_),
93  "array"_a);
94  cls.def("applyForward", py::overload_cast<FromPoint const &>(&Class::applyForward, py::const_),
95  "point"_a);
96  cls.def("applyInverse", py::overload_cast<ToArray const &>(&Class::applyInverse, py::const_), "array"_a);
97  cls.def("applyInverse", py::overload_cast<ToPoint const &>(&Class::applyInverse, py::const_), "point"_a);
98  cls.def("inverted", &Class::inverted);
99  /* Need some extra handling of ndarray return type in Python to prevent dimensions
100  * of length 1 from being deleted */
101  cls.def("_getJacobian", &Class::getJacobian);
102  // Do not wrap getShortClassName because it returns the name of the class;
103  // use `<class>.__name__` or `type(<instance>).__name__` instead.
104  // Do not wrap readStream or writeStream because C++ streams are not easy to wrap.
105  cls.def_static("readString", &Class::readString);
106  cls.def("writeString", &Class::writeString);
107 
108  declareMethodTemplates<FromEndpoint, ToEndpoint, GenericEndpoint>(cls);
109  declareMethodTemplates<FromEndpoint, ToEndpoint, Point2Endpoint>(cls);
110  declareMethodTemplates<FromEndpoint, ToEndpoint, SpherePointEndpoint>(cls);
111 
112  // str(self) = "<Python class name>[<nIn>-><nOut>]"
113  cls.def("__str__", [pyClassName](Class const &self) { return formatStr(self, pyClassName); });
114  // repr(self) = "lsst.afw.geom.<Python class name>[<nIn>-><nOut>]"
115  cls.def("__repr__",
116  [pyClassName](Class const &self) { return "lsst.afw.geom." + formatStr(self, pyClassName); });
117 
118  table::io::python::addPersistableMethods<Class>(cls);
119 }
120 
122  py::module::import("astshim");
123  py::module::import("lsst.afw.geom.endpoint");
124 
125  declareTransform<GenericEndpoint, GenericEndpoint>(mod);
126  declareTransform<GenericEndpoint, Point2Endpoint>(mod);
127  declareTransform<GenericEndpoint, SpherePointEndpoint>(mod);
128  declareTransform<Point2Endpoint, GenericEndpoint>(mod);
129  declareTransform<Point2Endpoint, Point2Endpoint>(mod);
130  declareTransform<Point2Endpoint, SpherePointEndpoint>(mod);
131  declareTransform<SpherePointEndpoint, GenericEndpoint>(mod);
132  declareTransform<SpherePointEndpoint, Point2Endpoint>(mod);
133  declareTransform<SpherePointEndpoint, SpherePointEndpoint>(mod);
134 }
135 
136 } // namespace
137 } // namespace geom
138 } // namespace afw
139 } // namespace lsst
std::ostream * os
Definition: Schema.cc:746
T c_str(T... args)
T copy(T... args)
py::class_< PixelAreaBoundedField, std::shared_ptr< PixelAreaBoundedField >, BoundedField > PyClass
PYBIND11_MODULE(transform, mod)
Definition: transform.cc:36
A base class for image defects.
table::Key< int > transform