23 #ifndef AFW_TABLE_PYTHON_CATALOG_H_INCLUDED
24 #define AFW_TABLE_PYTHON_CATALOG_H_INCLUDED
26 #include "pybind11/pybind11.h"
37 template <
typename Record>
41 template <
typename T,
typename Record>
46 ndarray::Array<typename Field<T>::Value, 1, 1> out = ndarray::allocate(catalog.
size());
47 auto outIter = out.begin();
48 auto inIter = catalog.
begin();
49 for (; inIter != catalog.
end(); ++inIter, ++outIter) {
50 *outIter = inIter->get(
key);
57 template <
typename Record>
62 ndarray::Array<double, 1, 1> out = ndarray::allocate(catalog.
size());
63 auto outIter = out.begin();
64 auto inIter = catalog.
begin();
65 for (; inIter != catalog.
end(); ++inIter, ++outIter) {
66 *outIter = inIter->get(
key).asRadians();
79 template <
typename T,
typename Record>
82 using namespace pybind11::literals;
87 cls.def(
"isSorted", (
bool (
Catalog::*)(
Key<T> const &)
const) & Catalog::isSorted);
90 auto iter =
self.find(value,
key);
97 return self.upper_bound(value,
key) -
self.begin();
100 return self.lower_bound(value,
key) -
self.begin();
103 auto p =
self.equal_range(value,
key);
104 return py::slice(p.first -
self.begin(), p.second -
self.begin(), 1);
106 cls.def(
"between", [](
Catalog &
self, Value
const &lower, Value
const &upper,
Key<T> const &
key) {
109 return py::slice(
a,
b, 1);
129 template <
typename Record>
131 bool isBase =
false) {
133 using namespace pybind11::literals;
136 using Table =
typename Record::Table;
140 fullName =
"_" +
name +
"CatalogBase";
142 fullName =
name +
"Catalog";
149 [](
auto &mod,
auto &
cls) {
151 cls.def(py::init<Schema const &>(),
"schema"_a);
152 cls.def(py::init<std::shared_ptr<Table> const &>(),
"table"_a);
153 cls.def(py::init<Catalog const &>(),
"other"_a);
156 cls.def_static(
"readFits", (Catalog(*)(std::string const &, int, int)) & Catalog::readFits,
157 "filename"_a,
"hdu"_a = fits::DEFAULT_HDU,
"flags"_a = 0);
158 cls.def_static(
"readFits", (Catalog(*)(fits::MemFileManager &, int, int)) & Catalog::readFits,
159 "manager"_a,
"hdu"_a = fits::DEFAULT_HDU,
"flags"_a = 0);
163 cls.def(
"getTable", &Catalog::getTable);
164 cls.def_property_readonly(
"table", &Catalog::getTable);
165 cls.def(
"getSchema", &Catalog::getSchema);
166 cls.def_property_readonly(
"schema", &Catalog::getSchema);
167 cls.def(
"capacity", &Catalog::capacity);
168 cls.def(
"__len__", &Catalog::size);
169 cls.def(
"resize", &Catalog::resize);
173 cls.def(
"_getColumnView", &Catalog::getColumnView);
174 cls.def(
"_addNew", &Catalog::addNew);
175 cls.def(
"_extend", [](Catalog &self, Catalog const &other, bool deep) {
176 self.insert(self.end(), other.begin(), other.end(), deep);
186 cls.def(
"_delslice_", [](
Catalog &
self, py::slice
const &s) {
187 Py_ssize_t start = 0, stop = 0,
step = 0,
length = 0;
188 if (PySlice_GetIndicesEx(s.ptr(),
self.size(), &start, &stop, &
step, &
length) != 0) {
189 throw py::error_already_set();
192 throw py::index_error(
"Slice step must not exactly 1");
194 self.erase(
self.begin() + start,
self.begin() + stop);
199 cls.def(
"_getitem_", [](
Catalog &
self,
int i) {
202 cls.def(
"isContiguous", &Catalog::isContiguous);
206 "filename"_a,
"mode"_a =
"w",
"flags"_a = 0);
210 "manager"_a,
"mode"_a =
"w",
"flags"_a = 0);
211 cls.def(
"reserve", &Catalog::reserve);
213 (
Catalog(
Catalog::*)(ndarray::Array<bool const, 1>
const &)
const) & Catalog::subset);
218 declareCatalogOverloads<std::int32_t>(
cls);
219 declareCatalogOverloads<std::int64_t>(
cls);
220 declareCatalogOverloads<float>(
cls);
221 declareCatalogOverloads<double>(
cls);
222 declareCatalogOverloads<lsst::geom::Angle>(
cls);
237 #endif // !LSST_AFW_TABLE_PYTHON_CATALOG_H_INCLUDED