1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
#pragma once
#if defined(__clang__)
#pragma clang diagnostic push
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
#include <nanobind/nanobind.h> // IWYU pragma: export
#include <gemmi/logger.hpp> // for Logger
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
#if NB_VERSION_MAJOR < 2 || (NB_VERSION_MAJOR == 2 && NB_VERSION_MINOR < 2)
#error Required nanobind version >= 2.2
#endif
namespace nb = nanobind;
constexpr auto rv_ri = nb::rv_policy::reference_internal;
void add_elem(nb::module_& m); // elem.cpp
void add_xds(nb::module_& m); // elem.cpp
void add_symmetry(nb::module_& m); // sym.cpp
void add_ccp4(nb::module_& m); // ccp4.cpp
void add_grid(nb::module_& m); // grid.cpp
void add_recgrid(nb::module_& m); // recgrid.cpp
void add_unitcell(nb::module_& m); // unitcell.cpp
void add_hkl(nb::module_& m); // hkl.cpp
void add_meta(nb::module_& m); // meta.cpp
void add_mol(nb::module_& m); // mol.cpp
void add_mtz(nb::module_& m); // mtz.cpp
void add_cif(nb::module_& cif); // cif.cpp
void add_cif_read(nb::module_& cif); // read.cpp
void add_read_structure(nb::module_& m); // read.cpp
void add_small(nb::module_& m); // read.cpp
void add_chemcomp(nb::module_& m); // chemcomp.cpp
void add_monlib(nb::module_& m); // monlib.cpp
void add_topo(nb::module_& m); // topo.cpp
void add_alignment(nb::module_& m); // align.cpp
void add_scaling(nb::module_& m); // scaling.cpp
void add_search(nb::module_& m); // search.cpp
void add_sf(nb::module_& m); // sf.cpp
// defined in write.cpp
namespace gemmi {
struct Structure;
namespace cif { struct Document; }
}
void add_write(nb::module_& m, nb::class_<gemmi::Structure>& structure);
// defined in align.cpp
void add_assign_label_seq_id(nb::class_<gemmi::Structure>& structure);
// convert pythonic index to C++ index
inline int c_index(int index, size_t size) {
if (index < 0)
index += (int) size;
if ((size_t) index >= size)
throw nb::index_error();
return index;
}
template<typename T> int normalize_index(int index, const T& container) {
return c_index(index, container.size());
}
// specialized for cif::Table in cif.cpp
template<typename Vec>
void delitem_at_index(Vec& items, size_t idx) {
items.erase(items.begin() + idx);
}
// specialized for cif::Table in cif.cpp
template<typename Vec>
void delitem_range(Vec& items, size_t start, size_t end) {
items.erase(items.begin() + start, items.begin() + end);
}
template<typename Items>
void delitem_slice(Items& items, const nb::slice& slice) {
auto [start, stop, step, length] = slice.compute(items.size());
if (step == 1) {
delitem_range(items, start, start + length);
} else {
for (size_t i = 0; i < length; ++i)
delitem_at_index(items, start + (step > 0 ? length - 1 - i : i) * step);
}
}
template<typename Items>
nb::list getitem_slice(Items& items, const nb::slice& slice) {
auto [start, stop, step, length] = slice.compute(items.size());
nb::list l;
for (size_t i = 0; i < length; ++i)
l.append(nb::cast(&items[start + i * step]));
return l;
}
// for numpy __array__ method
inline nb::object handle_numpy_array_args(const nb::object& o, nb::handle dtype, nb::handle copy) {
if (dtype.is_none() || dtype.is(o.attr("dtype"))) {
if (copy.ptr() != Py_True)
return o;
dtype = o.attr("dtype");
}
if (copy.ptr() == Py_False) // astype() would copy even with copy=False
throw nb::value_error("Unable to avoid copy while creating an array as requested.");
return o.attr("astype")(dtype);
}
namespace nanobind { namespace detail {
template <> struct type_caster<gemmi::Logger> {
NB_TYPE_CASTER(gemmi::Logger, const_name("object"))
bool from_python(handle src, uint8_t, cleanup_list *) noexcept {
value = {};
if (PyTuple_Check(src.ptr()) && PyTuple_Size(src.ptr()) == 2) {
value.threshold = (int) PyLong_AsLong(PyTuple_GetItem(src.ptr(), 1));
if (value.threshold == -1 && PyErr_Occurred())
return false;
src = PyTuple_GetItem(src.ptr(), 0);
}
if (src.is_none()) {
// nothing
} else if (nb::hasattr(src, "write") && nb::hasattr(src, "flush")) {
value.callback = {[obj=nb::borrow(src)](const std::string& s) {
obj.attr("write")(s + "\n");
obj.attr("flush")();
}};
} else if (PyCallable_Check(src.ptr())) {
value.callback = {[obj=nb::borrow(src)](const std::string& s) { obj(s); }};
} else {
return false;
}
return true;
}
};
}} // namespace nanobind::detail
|