LSSTApplications  19.0.0-14-gb0260a2+72efe9b372,20.0.0+7927753e06,20.0.0+8829bf0056,20.0.0+995114c5d2,20.0.0+b6f4b2abd1,20.0.0+bddc4f4cbe,20.0.0-1-g253301a+8829bf0056,20.0.0-1-g2b7511a+0d71a2d77f,20.0.0-1-g5b95a8c+7461dd0434,20.0.0-12-g321c96ea+23efe4bbff,20.0.0-16-gfab17e72e+fdf35455f6,20.0.0-2-g0070d88+ba3ffc8f0b,20.0.0-2-g4dae9ad+ee58a624b3,20.0.0-2-g61b8584+5d3db074ba,20.0.0-2-gb780d76+d529cf1a41,20.0.0-2-ged6426c+226a441f5f,20.0.0-2-gf072044+8829bf0056,20.0.0-2-gf1f7952+ee58a624b3,20.0.0-20-geae50cf+e37fec0aee,20.0.0-25-g3dcad98+544a109665,20.0.0-25-g5eafb0f+ee58a624b3,20.0.0-27-g64178ef+f1f297b00a,20.0.0-3-g4cc78c6+e0676b0dc8,20.0.0-3-g8f21e14+4fd2c12c9a,20.0.0-3-gbd60e8c+187b78b4b8,20.0.0-3-gbecbe05+48431fa087,20.0.0-38-ge4adf513+a12e1f8e37,20.0.0-4-g97dc21a+544a109665,20.0.0-4-gb4befbc+087873070b,20.0.0-4-gf910f65+5d3db074ba,20.0.0-5-gdfe0fee+199202a608,20.0.0-5-gfbfe500+d529cf1a41,20.0.0-6-g64f541c+d529cf1a41,20.0.0-6-g9a5b7a1+a1cd37312e,20.0.0-68-ga3f3dda+5fca18c6a4,20.0.0-9-g4aef684+e18322736b,w.2020.45
LSSTDataManagementBasePackage
_rangeSet.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 <https://www.lsstcorp.org/LegalNotices/>.
21  */
22 #include "pybind11/pybind11.h"
23 
24 #include "lsst/sphgeom/python.h"
25 
26 #include "lsst/sphgeom/RangeSet.h"
28 
29 namespace py = pybind11;
30 using namespace pybind11::literals;
31 
32 namespace lsst {
33 namespace sphgeom {
34 
35 namespace {
36 
38 uint64_t _uint64(py::handle const &obj) {
39  try {
40  return obj.cast<uint64_t>();
41  } catch (py::cast_error const &) {
42  throw py::value_error(
43  "RangeSet elements and range beginning and "
44  "end points must be non-negative integers "
45  "less than 2**64");
46  }
47 }
48 
51 RangeSet makeRangeSet(py::iterable iterable) {
52  RangeSet rs;
53  for (py::handle item : iterable) {
54  PyObject *o = item.ptr();
55  if (PySequence_Check(o) && PySequence_Size(o) == 2) {
56  uint64_t first = _uint64(py::reinterpret_steal<py::object>(
57  PySequence_GetItem(o, 0)));
58  uint64_t last = _uint64(py::reinterpret_steal<py::object>(
59  PySequence_GetItem(o, 1)));
60  rs.insert(first, last);
61  } else {
62  rs.insert(_uint64(item));
63  }
64  }
65  return rs;
66 }
67 
69 py::list ranges(RangeSet const &self) {
70  py::list list;
71  for (auto t : self) {
72  list.append(py::make_tuple(py::int_(std::get<0>(t)),
73  py::int_(std::get<1>(t))));
74  }
75  return list;
76 }
77 
78 // TODO: In C++, the end-point of a range containing 2**64 - 1 is 0, because
79 // unsigned integer arithmetic is modular, and 2**64 does not fit in a
80 // uint64_t. In Python, it would perhaps be nicer to map between C++
81 // range end-point values of 0 and the Python integer 2**64. Since this is
82 // somewhat involved, it is left as future work.
83 
84 } // <anonymous>
85 
86 template <>
88  cls.def(py::init<>());
89  cls.def(py::init<uint64_t>(), "integer"_a);
90  cls.def(py::init([](uint64_t a, uint64_t b) {
91  return new RangeSet(a, b);
92  }),
93  "first"_a, "last"_a);
94  cls.def(py::init<RangeSet const &>(), "rangeSet"_a);
95  cls.def(py::init(
96  [](py::iterable iterable) {
97  return new RangeSet(makeRangeSet(iterable));
98  }),
99  "iterable"_a);
100  cls.def("__eq__", &RangeSet::operator==, py::is_operator());
101  cls.def("__ne__", &RangeSet::operator!=, py::is_operator());
102 
103  cls.def("insert", (void (RangeSet::*)(uint64_t)) & RangeSet::insert,
104  "integer"_a);
105  cls.def("insert",
106  (void (RangeSet::*)(uint64_t, uint64_t)) & RangeSet::insert,
107  "first"_a, "last"_a);
108  cls.def("erase", (void (RangeSet::*)(uint64_t)) & RangeSet::erase,
109  "integer"_a);
110  cls.def("erase", (void (RangeSet::*)(uint64_t, uint64_t)) & RangeSet::erase,
111  "first"_a, "last"_a);
112 
113  cls.def("complement", &RangeSet::complement);
114  cls.def("complemented", &RangeSet::complemented);
115  cls.def("intersection", &RangeSet::intersection, "rangeSet"_a);
116  // In C++, the set union function is named join because union is a keyword.
117  // Python does not suffer from the same restriction.
118  cls.def("union", &RangeSet::join, "rangeSet"_a);
119  cls.def("difference", &RangeSet::difference, "rangeSet"_a);
120  cls.def("symmetricDifference", &RangeSet::symmetricDifference,
121  "rangeSet"_a);
122  cls.def("__invert__", &RangeSet::operator~, py::is_operator());
123  cls.def("__and__", &RangeSet::operator&, py::is_operator());
124  cls.def("__or__", &RangeSet::operator|, py::is_operator());
125  cls.def("__sub__", &RangeSet::operator-, py::is_operator());
126  cls.def("__xor__", &RangeSet::operator^, py::is_operator());
127  cls.def("__iand__", &RangeSet::operator&=);
128  cls.def("__ior__", &RangeSet::operator|=);
129  cls.def("__isub__", &RangeSet::operator-=);
130  cls.def("__ixor__", &RangeSet::operator^=);
131 
132  cls.def("__len__", &RangeSet::size);
133  cls.def("__getitem__", [](RangeSet const &self, py::int_ i) {
134  auto j = python::convertIndex(static_cast<ptrdiff_t>(self.size()), i);
135  return py::cast(self.begin()[j]);
136  });
137 
138  cls.def("intersects",
139  (bool (RangeSet::*)(uint64_t) const) & RangeSet::intersects,
140  "integer"_a);
141  cls.def("intersects",
142  (bool (RangeSet::*)(uint64_t, uint64_t) const) &
143  RangeSet::intersects,
144  "first"_a, "last"_a);
145  cls.def("intersects",
146  (bool (RangeSet::*)(RangeSet const &) const) & RangeSet::intersects,
147  "rangeSet"_a);
148 
149  cls.def("contains",
150  (bool (RangeSet::*)(uint64_t) const) & RangeSet::contains,
151  "integer"_a);
152  cls.def("contains",
153  (bool (RangeSet::*)(uint64_t, uint64_t) const) & RangeSet::contains,
154  "first"_a, "last"_a);
155  cls.def("contains",
156  (bool (RangeSet::*)(RangeSet const &) const) & RangeSet::contains,
157  "rangeSet"_a);
158  cls.def("__contains__",
159  (bool (RangeSet::*)(uint64_t) const) & RangeSet::contains,
160  "integer"_a, py::is_operator());
161  cls.def("__contains__",
162  (bool (RangeSet::*)(uint64_t, uint64_t) const) & RangeSet::contains,
163  "first"_a, "last"_a, py::is_operator());
164  cls.def("__contains__",
165  (bool (RangeSet::*)(RangeSet const &) const) & RangeSet::contains,
166  "rangeSet"_a, py::is_operator());
167 
168  cls.def("isWithin",
169  (bool (RangeSet::*)(uint64_t) const) & RangeSet::isWithin,
170  "integer"_a);
171  cls.def("isWithin",
172  (bool (RangeSet::*)(uint64_t, uint64_t) const) & RangeSet::isWithin,
173  "first"_a, "last"_a);
174  cls.def("isWithin",
175  (bool (RangeSet::*)(RangeSet const &) const) & RangeSet::isWithin,
176  "rangeSet"_a);
177 
178  cls.def("isDisjointFrom",
179  (bool (RangeSet::*)(uint64_t) const) & RangeSet::isDisjointFrom,
180  "integer"_a);
181  cls.def("isDisjointFrom",
182  (bool (RangeSet::*)(uint64_t, uint64_t) const) &
183  RangeSet::isDisjointFrom,
184  "first"_a, "last"_a);
185  cls.def("isDisjointFrom",
186  (bool (RangeSet::*)(RangeSet const &) const) &
187  RangeSet::isDisjointFrom,
188  "rangeSet"_a);
189 
190  cls.def("simplify", &RangeSet::simplify, "n"_a);
191  cls.def("simplified", &RangeSet::simplified, "n"_a);
192  cls.def("scale", &RangeSet::scale, "factor"_a);
193  cls.def("scaled", &RangeSet::scaled, "factor"_a);
194  cls.def("fill", &RangeSet::fill);
195  cls.def("clear", &RangeSet::clear);
196  cls.def("empty", &RangeSet::empty);
197  cls.def("full", &RangeSet::full);
198  cls.def("size", &RangeSet::size);
199  cls.def("cardinality", &RangeSet::cardinality);
200  // max_size() and swap() are omitted. The former is a C++ container
201  // requirement, and the latter doesn't seem relevant to Python.
202  cls.def("isValid", &RangeSet::cardinality);
203  cls.def("ranges", &ranges);
204 
205  cls.def("__str__",
206  [](RangeSet const &self) { return py::str(ranges(self)); });
207  cls.def("__repr__", [](RangeSet const &self) {
208  return py::str("RangeSet({!s})").format(ranges(self));
209  });
210 
211  cls.def("__reduce__", [cls](RangeSet const &self) {
212  return py::make_tuple(cls, py::make_tuple(ranges(self)));
213  });
214 }
215 
216 } // sphgeom
217 } // lsst
std::shared_ptr
STL class.
lsst::afw::table._match.first
first
Definition: _match.py:74
python.h
lsst::afw::geom.transform.transformContinued.cls
cls
Definition: transformContinued.py:33
lsst::geom::polynomials::simplified
PolynomialFunction1d simplified(ScaledPolynomialFunction1d const &f)
Calculate the standard polynomial function that is equivalent to a scaled standard polynomial functio...
Definition: PolynomialFunction1d.cc:32
astshim.fitsChanContinued.contains
def contains(self, name)
Definition: fitsChanContinued.py:127
b
table::Key< int > b
Definition: TransmissionCurve.cc:467
lsst
A base class for image defects.
Definition: imageAlgorithm.dox:1
list
daf::base::PropertyList * list
Definition: fits.cc:913
a
table::Key< int > a
Definition: TransmissionCurve.cc:466
lsst::afw.display.ds9.scale
def scale(algorithm, min, max=None, frame=None)
Definition: ds9.py:109
utils.h
pybind11
Definition: _GenericMap.cc:40
RangeSet.h
This file provides a type for representing integer sets.
lsst::sphgeom::RangeSet
A RangeSet is a set of unsigned 64 bit integers.
Definition: RangeSet.h:99
lsst::utils.tests.init
def init()
Definition: tests.py:59
lsst::afw.display.ds9.erase
def erase(frame=None)
Definition: ds9.py:97
lsst::sphgeom::defineClass
void defineClass(py::class_< RangeSet, std::shared_ptr< RangeSet >> &cls)
Definition: _rangeSet.cc:87