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();
 
   71 template <
typename Record>
 
   75     ndarray::Array<bool const, 1> 
const & array
 
   77     if (array.size() != catalog.
size()) {
 
   80             (
boost::format(
"Catalog has %d rows, while array has %d elements.")
 
   81              % catalog.
size() % array.size()).str()
 
   84     auto catIter = catalog.
begin();
 
   85     auto arrayIter = array.begin();
 
   86     for (; catIter != catalog.
end(); ++catIter, ++arrayIter) {
 
   87         catIter->set(
key, *arrayIter);
 
   91 template <
typename Record>
 
   97     for (
auto catIter = catalog.
begin(); catIter != catalog.
end(); ++catIter) {
 
   98         catIter->set(
key, value);
 
  110 template <
typename T, 
typename Record>
 
  113     using namespace pybind11::literals;
 
  118     cls.def(
"isSorted", (
bool (
Catalog::*)(
Key<T> const &) 
const) & Catalog::isSorted);
 
  121         auto iter = 
self.find(value, 
key);
 
  128         return self.upper_bound(value, 
key) - 
self.begin();
 
  131         return self.lower_bound(value, 
key) - 
self.begin();
 
  134         auto p = 
self.equal_range(value, 
key);
 
  135         return py::slice(p.first - 
self.begin(), p.second - 
self.begin(), 1);
 
  137     cls.def(
"between", [](
Catalog &
self, Value 
const &lower, Value 
const &upper, 
Key<T> const &
key) {
 
  140         return py::slice(
a, 
b, 1);
 
  172 template <
typename Record>
 
  174                                  bool isBase = 
false) {
 
  176     using namespace pybind11::literals;
 
  179     using Table = 
typename Record::Table;
 
  183         fullName = 
"_" + 
name + 
"CatalogBase";
 
  185         fullName = 
name + 
"Catalog";
 
  192             [](
auto &mod, 
auto &
cls) {
 
  194                 cls.def(py::init<Schema const &>(), 
"schema"_a);
 
  195                 cls.def(py::init<std::shared_ptr<Table> const &>(), 
"table"_a);
 
  196                 cls.def(py::init<Catalog const &>(), 
"other"_a);
 
  199                 cls.def_static(
"readFits", (Catalog(*)(std::string const &, int, int)) & Catalog::readFits,
 
  200                                "filename"_a, 
"hdu"_a = fits::DEFAULT_HDU, 
"flags"_a = 0);
 
  201                 cls.def_static(
"readFits", (Catalog(*)(fits::MemFileManager &, int, int)) & Catalog::readFits,
 
  202                                "manager"_a, 
"hdu"_a = fits::DEFAULT_HDU, 
"flags"_a = 0);
 
  206                 cls.def(
"getTable", &Catalog::getTable);
 
  207                 cls.def_property_readonly(
"table", &Catalog::getTable);
 
  208                 cls.def(
"getSchema", &Catalog::getSchema);
 
  209                 cls.def_property_readonly(
"schema", &Catalog::getSchema);
 
  210                 cls.def(
"capacity", &Catalog::capacity);
 
  211                 cls.def(
"__len__", &Catalog::size);
 
  212                 cls.def(
"resize", &Catalog::resize);
 
  216                 cls.def(
"_getColumnView", &Catalog::getColumnView);
 
  217                 cls.def(
"_addNew", &Catalog::addNew);
 
  218                 cls.def(
"_extend", [](Catalog &self, Catalog const &other, bool deep) {
 
  219                     self.insert(self.end(), other.begin(), other.end(), deep);
 
  229                 cls.def(
"_delslice_", [](
Catalog &
self, py::slice 
const &s) {
 
  230                     Py_ssize_t start = 0, stop = 0, 
step = 0, 
length = 0;
 
  231                     if (PySlice_GetIndicesEx(s.ptr(), 
self.size(), &start, &stop, &
step, &
length) != 0) {
 
  232                         throw py::error_already_set();
 
  235                         throw py::index_error(
"Slice step must not exactly 1");
 
  237                     self.erase(
self.begin() + start, 
self.begin() + stop);
 
  242                 cls.def(
"_getitem_", [](
Catalog &
self, 
int i) {
 
  245                 cls.def(
"isContiguous", &Catalog::isContiguous);
 
  249                         "filename"_a, 
"mode"_a = 
"w", 
"flags"_a = 0);
 
  253                         "manager"_a, 
"mode"_a = 
"w", 
"flags"_a = 0);
 
  254                 cls.def(
"reserve", &Catalog::reserve);
 
  256                         (
Catalog(
Catalog::*)(ndarray::Array<bool const, 1> 
const &) 
const) & Catalog::subset);
 
  261                 declareCatalogOverloads<std::int32_t>(
cls);
 
  262                 declareCatalogOverloads<std::int64_t>(
cls);
 
  263                 declareCatalogOverloads<float>(
cls);
 
  264                 declareCatalogOverloads<double>(
cls);
 
  265                 declareCatalogOverloads<lsst::geom::Angle>(
cls);
 
  280 #endif  // !LSST_AFW_TABLE_PYTHON_CATALOG_H_INCLUDED