LSST Applications  21.0.0+04719a4bac,21.0.0-1-ga51b5d4+f5e6047307,21.0.0-11-g2b59f77+a9c1acf22d,21.0.0-11-ga42c5b2+86977b0b17,21.0.0-12-gf4ce030+76814010d2,21.0.0-13-g1721dae+760e7a6536,21.0.0-13-g3a573fe+768d78a30a,21.0.0-15-g5a7caf0+f21cbc5713,21.0.0-16-g0fb55c1+b60e2d390c,21.0.0-19-g4cded4ca+71a93a33c0,21.0.0-2-g103fe59+bb20972958,21.0.0-2-g45278ab+04719a4bac,21.0.0-2-g5242d73+3ad5d60fb1,21.0.0-2-g7f82c8f+8babb168e8,21.0.0-2-g8f08a60+06509c8b61,21.0.0-2-g8faa9b5+616205b9df,21.0.0-2-ga326454+8babb168e8,21.0.0-2-gde069b7+5e4aea9c2f,21.0.0-2-gecfae73+1d3a86e577,21.0.0-2-gfc62afb+3ad5d60fb1,21.0.0-25-g1d57be3cd+e73869a214,21.0.0-3-g357aad2+ed88757d29,21.0.0-3-g4a4ce7f+3ad5d60fb1,21.0.0-3-g4be5c26+3ad5d60fb1,21.0.0-3-g65f322c+e0b24896a3,21.0.0-3-g7d9da8d+616205b9df,21.0.0-3-ge02ed75+a9c1acf22d,21.0.0-4-g591bb35+a9c1acf22d,21.0.0-4-g65b4814+b60e2d390c,21.0.0-4-gccdca77+0de219a2bc,21.0.0-4-ge8a399c+6c55c39e83,21.0.0-5-gd00fb1e+05fce91b99,21.0.0-6-gc675373+3ad5d60fb1,21.0.0-64-g1122c245+4fb2b8f86e,21.0.0-7-g04766d7+cd19d05db2,21.0.0-7-gdf92d54+04719a4bac,21.0.0-8-g5674e7b+d1bd76f71f,master-gac4afde19b+a9c1acf22d,w.2021.13
LSST Data Management Base Package
_transform.cc
Go to the documentation of this file.
1 /*
2  * This file is part of afw.
3  *
4  * Developed for the LSST Data Management System.
5  * This product includes software developed by the LSST Project
6  * (https://www.lsst.org).
7  * See the COPYRIGHT file at the top-level directory of this distribution
8  * for details of code ownership.
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <https://www.gnu.org/licenses/>.
22  */
23 
24 #include "pybind11/pybind11.h"
25 #include "lsst/utils/python.h"
26 #include "pybind11/eigen.h"
27 
28 #include <memory>
29 
30 #include "astshim.h"
31 #include "pybind11/stl.h"
32 #include "ndarray/pybind11.h"
33 
35 #include "lsst/afw/geom/Endpoint.h"
37 
38 namespace py = pybind11;
39 using namespace py::literals;
40 
41 namespace lsst {
42 namespace afw {
43 namespace geom {
44 namespace {
45 
46 // Return a string consisting of "_pythonClassName_[_fromNAxes_->_toNAxes_]",
47 // for example "TransformGenericToPoint2[4->2]"
48 template <class Class>
49 std::string formatStr(Class const &self, std::string const &pyClassName) {
51  os << pyClassName;
52  os << "[" << self.getFromEndpoint().getNAxes() << "->" << self.getToEndpoint().getNAxes() << "]";
53  return os.str();
54 }
55 
56 template <class FromEndpoint, class ToEndpoint, class NextToEndpoint, class PyClass>
57 void declareMethodTemplates(PyClass &cls) {
58  using ThisTransform = Transform<FromEndpoint, ToEndpoint>;
59  using NextTransform = Transform<ToEndpoint, NextToEndpoint>;
60  using SeriesTransform = Transform<FromEndpoint, NextToEndpoint>;
61  // Need Python-specific logic to give sensible errors for mismatched Transform types
62  cls.def("_then",
63  (std::shared_ptr<SeriesTransform>(ThisTransform::*)(NextTransform const &, bool) const) &
64  ThisTransform::template then<NextToEndpoint>,
65  "next"_a, "simplify"_a = true);
66 }
67 
68 // Declare Transform<FromEndpoint, ToEndpoint> using python class name Transform<X>To<Y>
69 // where <X> and <Y> are the prefix of the from endpoint and to endpoint class, respectively,
70 // for example TransformGenericToPoint2
71 template <class FromEndpoint, class ToEndpoint>
72 void declareTransform(lsst::utils::python::WrapperCollection &wrappers) {
73  using Class = Transform<FromEndpoint, ToEndpoint>;
74  using ToPoint = typename ToEndpoint::Point;
75  using ToArray = typename ToEndpoint::Array;
76  using FromPoint = typename FromEndpoint::Point;
77  using FromArray = typename FromEndpoint::Array;
78 
79  std::string const pyClassName = Class::getShortClassName();
80  wrappers.wrapType(
81  py::class_<Class, std::shared_ptr<Class>>(wrappers.module, pyClassName.c_str()),
82  [](auto &mod, auto &cls) {
83  std::string const pyClassName = Class::getShortClassName();
84  cls.def(py::init<ast::FrameSet const &, bool>(), "frameSet"_a, "simplify"_a = true);
85  cls.def(py::init<ast::Mapping const &, bool>(), "mapping"_a, "simplify"_a = true);
86 
87  cls.def_property_readonly("hasForward", &Class::hasForward);
88  cls.def_property_readonly("hasInverse", &Class::hasInverse);
89  cls.def_property_readonly("fromEndpoint", &Class::getFromEndpoint);
90  cls.def_property_readonly("toEndpoint", &Class::getToEndpoint);
91 
92  // Return a copy of the contained Mapping in order to assure changing the returned Mapping
93  // will not affect the contained Mapping (since Python ignores constness)
94  cls.def("getMapping", [](Class const &self) { return self.getMapping()->copy(); });
95 
96  cls.def("applyForward",
97  py::overload_cast<FromArray const &>(&Class::applyForward, py::const_), "array"_a);
98  cls.def("applyForward",
99  py::overload_cast<FromPoint const &>(&Class::applyForward, py::const_), "point"_a);
100  cls.def("applyInverse", py::overload_cast<ToArray const &>(&Class::applyInverse, py::const_),
101  "array"_a);
102  cls.def("applyInverse", py::overload_cast<ToPoint const &>(&Class::applyInverse, py::const_),
103  "point"_a);
104  cls.def("inverted", &Class::inverted);
105  /* Need some extra handling of ndarray return type in Python to prevent dimensions
106  * of length 1 from being deleted */
107  cls.def("_getJacobian", &Class::getJacobian);
108  // Do not wrap getShortClassName because it returns the name of the class;
109  // use `<class>.__name__` or `type(<instance>).__name__` instead.
110  // Do not wrap readStream or writeStream because C++ streams are not easy to wrap.
111  cls.def_static("readString", &Class::readString);
112  cls.def("writeString", &Class::writeString);
113 
114  declareMethodTemplates<FromEndpoint, ToEndpoint, GenericEndpoint>(cls);
115  declareMethodTemplates<FromEndpoint, ToEndpoint, Point2Endpoint>(cls);
116  declareMethodTemplates<FromEndpoint, ToEndpoint, SpherePointEndpoint>(cls);
117 
118  // str(self) = "<Python class name>[<nIn>-><nOut>]"
119  cls.def("__str__", [pyClassName](Class const &self) { return formatStr(self, pyClassName); });
120  // repr(self) = "lsst.afw.geom.<Python class name>[<nIn>-><nOut>]"
121  cls.def("__repr__", [pyClassName](Class const &self) {
122  return "lsst.afw.geom." + formatStr(self, pyClassName);
123  });
124 
125  table::io::python::addPersistableMethods<Class>(cls);
126  });
127 }
128 } // namespace
130  wrappers.addSignatureDependency("lsst.afw.table.io");
131  wrappers.addSignatureDependency("astshim");
132  declareTransform<GenericEndpoint, GenericEndpoint>(wrappers);
133  declareTransform<GenericEndpoint, Point2Endpoint>(wrappers);
134  declareTransform<GenericEndpoint, SpherePointEndpoint>(wrappers);
135  declareTransform<Point2Endpoint, GenericEndpoint>(wrappers);
136  declareTransform<Point2Endpoint, Point2Endpoint>(wrappers);
137  declareTransform<Point2Endpoint, SpherePointEndpoint>(wrappers);
138  declareTransform<SpherePointEndpoint, GenericEndpoint>(wrappers);
139  declareTransform<SpherePointEndpoint, Point2Endpoint>(wrappers);
140  declareTransform<SpherePointEndpoint, SpherePointEndpoint>(wrappers);
141 }
142 } // namespace geom
143 } // namespace afw
144 } // namespace lsst
std::ostream * os
Definition: Schema.cc:746
T c_str(T... args)
A helper class for subdividing pybind11 module across multiple translation units (i....
Definition: python.h:242
pybind11::module module
The module object passed to the PYBIND11_MODULE block that contains this WrapperCollection.
Definition: python.h:448
PyType wrapType(PyType cls, ClassWrapperCallback function, bool setModuleName=true)
Add a type (class or enum) wrapper, deferring method and other attribute definitions until finish() i...
Definition: python.h:391
void addSignatureDependency(std::string const &name)
Indicate an external module that provides a type used in function/method signatures.
Definition: python.h:357
void wrapTransform(lsst::utils::python::WrapperCollection &)
Definition: _transform.cc:129
py::class_< PixelAreaBoundedField, std::shared_ptr< PixelAreaBoundedField >, BoundedField > PyClass
A base class for image defects.