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);
119 cls.def(
"sort", (
void (
Catalog::*)(
Key<T> const &)) & Catalog::sort);
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();
133 cls.def(
"equal_range", [](
Catalog &
self, Value
const &value,
Key<T> const &key) {
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);
147 [](
Catalog &
self,
Key<Flag> const & key, ndarray::Array<bool const, 1>
const & array) {
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";
190 return wrappers.wrapType(
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);
222 self.insert(
mapper,
self.
end(), other.begin(), other.end());
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);
268 [](
Catalog const &
self,
Key<Flag> const &key) -> ndarray::Array<bool const, 1, 0> {
table::Key< std::string > name
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Lifetime-management for memory that goes into FITS memory files.
A custom container class for records, based on std::vector.
size_type size() const
Return the number of elements in the catalog.
iterator begin()
Iterator access.
Key specialization for Flag.
A class used as a handle to a particular field in a table.
A mapping between the keys of two Schemas, used to copy data between them.
Reports attempts to exceed implementation-defined length limits for some classes.
daf::base::PropertySet * set
void _setFlagColumnToArray(CatalogT< Record > &catalog, Key< Flag > const &key, ndarray::Array< bool const, 1 > const &array)
ndarray::Array< typename Field< T >::Value const, 1, 1 > _getArrayFromCatalog(CatalogT< Record > const &catalog, Key< T > const &key)
Extract a column from a potentially non-contiguous Catalog.
PyCatalog< Record > declareCatalog(utils::python::WrapperCollection &wrappers, std::string const &name, bool isBase=false)
Wrap an instantiation of lsst::afw::table::CatalogT<Record>.
void _setFlagColumnToScalar(CatalogT< Record > &catalog, Key< Flag > const &key, bool value)
pybind11::class_< CatalogT< Record >, std::shared_ptr< CatalogT< Record > >> PyCatalog
void declareCatalogOverloads(PyCatalog< Record > &cls)
Declare field-type-specific overloaded catalog member functions for one field type.
std::size_t cppIndex(std::ptrdiff_t size, std::ptrdiff_t i)
Compute a C++ index from a Python index (negative values count from the end) and range-check.
def writeFits(filename, stamps, metadata, type_name, write_mask, write_variance, write_archive=False)
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
A base class for image defects.
T Value
the type returned by BaseRecord::get