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
_spatialCell.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 <memory>
24 #include <vector>
25 
26 #include <pybind11/pybind11.h>
27 #include <lsst/utils/python.h>
28 #include <pybind11/stl.h>
29 
30 #include "lsst/geom/Box.h"
31 #include "lsst/afw/image.h"
33 
34 namespace py = pybind11;
35 using namespace pybind11::literals;
36 
37 namespace lsst {
38 namespace afw {
39 namespace math {
40 
41 namespace {
42 
44 
45 // Wrap SpatialCellCandidate (an abstract class so no constructor is wrapped)
46 void declareSpatialCellCandidate(lsst::utils::python::WrapperCollection &wrappers) {
47  using PyClass = py::class_<SpatialCellCandidate, std::shared_ptr<SpatialCellCandidate>>;
48  auto clsSpatialCellCandidate =
49  wrappers.wrapType(PyClass(wrappers.module, "SpatialCellCandidate"), [](auto &mod, auto &cls) {
50  cls.def("getXCenter", &SpatialCellCandidate::getXCenter);
51  cls.def("getYCenter", &SpatialCellCandidate::getYCenter);
52  cls.def("instantiate", &SpatialCellCandidate::instantiate);
53  cls.def("getCandidateRating", &SpatialCellCandidate::getCandidateRating);
54  cls.def("setCandidateRating", &SpatialCellCandidate::setCandidateRating);
55  cls.def("getId", &SpatialCellCandidate::getId);
56  cls.def("getStatus", &SpatialCellCandidate::getStatus);
57  cls.def("setStatus", &SpatialCellCandidate::setStatus);
58  cls.def("isBad", &SpatialCellCandidate::isBad);
59  });
60  wrappers.wrapType(py::enum_<SpatialCellCandidate::Status>(clsSpatialCellCandidate, "Status"),
61  [](auto &mod, auto &enm) {
62  enm.value("BAD", SpatialCellCandidate::Status::BAD);
63  enm.value("GOOD", SpatialCellCandidate::Status::GOOD);
64  enm.value("UNKNOWN", SpatialCellCandidate::Status::UNKNOWN);
65  enm.export_values();
66  });
67 }
68 
69 // Wrap SpatialCellCandidateIterator
70 void declareSpatialCellCandidateIterator(lsst::utils::python::WrapperCollection &wrappers) {
71  wrappers.wrapType(
72  py::class_<SpatialCellCandidateIterator>(wrappers.module, "SpatialCellCandidateIterator"),
73  [](auto &mod, auto &cls) {
74  cls.def("__incr__", &SpatialCellCandidateIterator::operator++, py::is_operator());
75  cls.def(
76  "__deref__",
77  [](SpatialCellCandidateIterator &it) -> std::shared_ptr<SpatialCellCandidate> {
78  return *it;
79  },
80  py::is_operator());
81  cls.def("__eq__", &SpatialCellCandidateIterator::operator==, py::is_operator());
82  cls.def("__ne__", &SpatialCellCandidateIterator::operator!=, py::is_operator());
83  cls.def("__sub__", &SpatialCellCandidateIterator::operator-, py::is_operator());
84  });
85 }
86 
87 // Wrap SpatialCell
88 void declareSpatialCell(lsst::utils::python::WrapperCollection &wrappers) {
89  wrappers.wrapType(
90  py::class_<SpatialCell, std::shared_ptr<SpatialCell>>(wrappers.module, "SpatialCell"),
91  [](auto &mod, auto &cls) {
92  cls.def(py::init<std::string const &, lsst::geom::Box2I const &, CandidateList const &>(),
93  "label"_a, "bbox"_a = lsst::geom::Box2I(), "candidateList"_a = CandidateList());
94 
95  cls.def("empty", &SpatialCell::empty);
96  cls.def("size", &SpatialCell::size);
97  cls.def("__len__", &SpatialCell::size);
98  cls.def("getLabel", &SpatialCell::getLabel);
99  cls.def("begin", (SpatialCellCandidateIterator(SpatialCell::*)()) & SpatialCell::begin);
100  cls.def("begin", (SpatialCellCandidateIterator(SpatialCell::*)(bool)) & SpatialCell::begin);
101  cls.def("end", (SpatialCellCandidateIterator(SpatialCell::*)()) & SpatialCell::end);
102  cls.def("end", (SpatialCellCandidateIterator(SpatialCell::*)(bool)) & SpatialCell::end);
103  cls.def("insertCandidate", &SpatialCell::insertCandidate);
104  cls.def("removeCandidate", &SpatialCell::removeCandidate);
105  cls.def("setIgnoreBad", &SpatialCell::setIgnoreBad, "ignoreBad"_a);
106  cls.def("getIgnoreBad", &SpatialCell::getIgnoreBad);
107  cls.def("getCandidateById", &SpatialCell::getCandidateById, "id"_a, "noThrow"_a = false);
108  cls.def("getLabel", &SpatialCell::getLabel);
109  cls.def("getBBox", &SpatialCell::getBBox);
110  cls.def("sortCandidates", &SpatialCell::sortCandidates);
111  cls.def("visitCandidates",
112  (void (SpatialCell::*)(CandidateVisitor *, int const, bool const, bool const)) &
113  SpatialCell::visitCandidates,
114  "visitor"_a, "nMaxPerCell"_a = -1, "ignoreExceptions"_a = false, "reset"_a = true);
115  cls.def("visitAllCandidates",
116  (void (SpatialCell::*)(CandidateVisitor *, bool const, bool const)) &
117  SpatialCell::visitAllCandidates,
118  "visitor"_a, "ignoreExceptions"_a = false, "reset"_a = true);
119  });
120 }
121 
122 // Wrap SpatialCellSet
123 void declareSpatialCellSet(lsst::utils::python::WrapperCollection &wrappers) {
124  wrappers.wrapType(
125  py::class_<SpatialCellSet, std::shared_ptr<SpatialCellSet>>(wrappers.module, "SpatialCellSet"),
126  [](auto &mod, auto &cls) {
127  cls.def(py::init<lsst::geom::Box2I const &, int, int>(), "region"_a, "xSize"_a,
128  "ySize"_a = 0);
129 
130  cls.def("getCellList", &SpatialCellSet::getCellList);
131  cls.def("getBBox", &SpatialCellSet::getBBox);
132  cls.def("insertCandidate", &SpatialCellSet::insertCandidate);
133  cls.def("sortCandidates", &SpatialCellSet::sortCandidates);
134  cls.def("visitCandidates",
135  (void (SpatialCellSet::*)(CandidateVisitor *, int const, bool const)) &
136  SpatialCellSet::visitCandidates,
137  "visitor"_a, "nMaxPerCell"_a = -1, "ignoreExceptions"_a = false);
138  cls.def("visitAllCandidates",
139  (void (SpatialCellSet::*)(CandidateVisitor *, bool const)) &
140  SpatialCellSet::visitAllCandidates,
141  "visitor"_a, "ignoreExceptions"_a = false);
142  cls.def("getCandidateById", &SpatialCellSet::getCandidateById, "id"_a, "noThrow"_a = false);
143  cls.def("setIgnoreBad", &SpatialCellSet::setIgnoreBad, "ignoreBad"_a);
144  });
145 }
146 
147 // Wrap CandidateVisitor
148 void declareCandidateVisitor(lsst::utils::python::WrapperCollection &wrappers) {
149  wrappers.wrapType(py::class_<CandidateVisitor, std::shared_ptr<CandidateVisitor>>(wrappers.module,
150  "CandidateVisitor"),
151  [](auto &mod, auto &cls) {
152  cls.def(py::init<>());
153 
154  cls.def("reset", &CandidateVisitor::reset);
155  cls.def("processCandidate", &CandidateVisitor::processCandidate);
156  });
157 }
158 
159 // Wrap class SpatialCellImageCandidate (an abstract class, so no constructor is wrapped)
160 void declareSpatialCellImageCandidate(lsst::utils::python::WrapperCollection &wrappers) {
161  wrappers.wrapType(py::class_<SpatialCellImageCandidate, std::shared_ptr<SpatialCellImageCandidate>,
162  SpatialCellCandidate>(wrappers.module, "SpatialCellImageCandidate"),
163  [](auto &mod, auto &cls) {
164  cls.def_static("setWidth", &SpatialCellImageCandidate::setWidth, "width"_a);
165  cls.def_static("getWidth", &SpatialCellImageCandidate::getWidth);
166  cls.def_static("setHeight", &SpatialCellImageCandidate::setHeight, "height"_a);
167  cls.def_static("getHeight", &SpatialCellImageCandidate::getHeight);
168  cls.def("setChi2", &SpatialCellImageCandidate::setChi2, "chi2"_a);
169  cls.def("getChi2", &SpatialCellImageCandidate::getChi2);
170  });
171 }
172 
173 void declareTestClasses(lsst::utils::python::WrapperCollection &wrappers) {
174  /*
175  * Test class for SpatialCellCandidate
176  */
177  class TestCandidate : public SpatialCellCandidate {
178  public:
179  TestCandidate(float const xCenter,
180  float const yCenter,
181  float const flux
182  )
183  : SpatialCellCandidate(xCenter, yCenter), _flux(flux) {}
184 
186  virtual double getCandidateRating() const { return _flux; }
187  virtual void setCandidateRating(double flux) { _flux = flux; }
188 
189  private:
190  double _flux;
191  };
192 
194  class TestCandidateVisitor : public CandidateVisitor {
195  public:
196  TestCandidateVisitor() : CandidateVisitor(), _n(0) {}
197 
198  // Called by SpatialCellSet::visitCandidates before visiting any Candidates
199  void reset() { _n = 0; }
200 
201  // Called by SpatialCellSet::visitCandidates for each Candidate
202  void processCandidate(SpatialCellCandidate *candidate) { ++_n; }
203 
204  int getN() const { return _n; }
205 
206  private:
207  int _n; // number of TestCandidates
208  };
209 
210  class TestImageCandidate : public SpatialCellImageCandidate {
211  public:
212  typedef image::MaskedImage<float> MaskedImageT;
213 
214  TestImageCandidate(float const xCenter,
215  float const yCenter,
216  float const flux
217  )
218  : SpatialCellImageCandidate(xCenter, yCenter), _flux(flux) {}
219 
221  double getCandidateRating() const { return _flux; }
222 
224  std::shared_ptr<MaskedImageT const> getMaskedImage() const {
225  if (!_image) {
226  _image = std::make_shared<MaskedImageT>(lsst::geom::ExtentI(getWidth(), getHeight()));
227  *_image->getImage() = _flux;
228  }
229  return _image;
230  }
231 
232  private:
233  mutable std::shared_ptr<MaskedImageT> _image;
234  double _flux;
235  };
236 
237  wrappers.wrapType(py::class_<TestCandidate, std::shared_ptr<TestCandidate>, SpatialCellCandidate>(
238  wrappers.module, "TestCandidate"),
239  [](auto &mod, auto &cls) {
240  cls.def(py::init<float const, float const, float const>());
241  cls.def("getCandidateRating", &TestCandidate::getCandidateRating);
242  cls.def("setCandidateRating", &TestCandidate::setCandidateRating);
243  });
244  wrappers.wrapType(
245  py::class_<TestCandidateVisitor, std::shared_ptr<TestCandidateVisitor>, CandidateVisitor>(
246  wrappers.module, "TestCandidateVisitor"),
247  [](auto &mod, auto &cls) {
248  cls.def(py::init<>());
249  cls.def("getN", &TestCandidateVisitor::getN);
250  });
251  wrappers.wrapType(
252  py::class_<TestImageCandidate, std::shared_ptr<TestImageCandidate>, SpatialCellImageCandidate>(
253  wrappers.module, "TestImageCandidate"),
254  [](auto &mod, auto &cls) {
255  cls.def(py::init<float const, float const, float const>(), "xCenter"_a, "yCenter"_a,
256  "flux"_a);
257  cls.def("getCandidateRating", &TestImageCandidate::getCandidateRating);
258  cls.def("getMaskedImage", &TestImageCandidate::getMaskedImage);
259  });
260 };
261 } // namespace
263  declareSpatialCellCandidate(wrappers);
264  declareSpatialCellCandidateIterator(wrappers);
265  declareSpatialCell(wrappers);
266  declareSpatialCellSet(wrappers);
267  declareCandidateVisitor(wrappers);
268  declareSpatialCellImageCandidate(wrappers);
269  /* Test Members */
270  declareTestClasses(wrappers);
271 }
272 } // namespace math
273 } // namespace afw
274 } // namespace lsst
A class to manipulate images, masks, and variance as a single object.
Definition: MaskedImage.h:73
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 wrapSpatialCell(lsst::utils::python::WrapperCollection &)
py::class_< PixelAreaBoundedField, std::shared_ptr< PixelAreaBoundedField >, BoundedField > PyClass
A base class for image defects.