14#include "MantidPythonInterface/geometry/DetectorInfoPythonIterator.h"
15#include <boost/iterator/iterator_facade.hpp>
16#include <boost/python/class.hpp>
17#include <boost/python/copy_const_reference.hpp>
18#include <boost/python/copy_non_const_reference.hpp>
19#include <boost/python/iterator.hpp>
20#include <boost/python/return_by_value.hpp>
21#include <boost/python/return_value_policy.hpp>
24#define PY_ARRAY_UNIQUE_SYMBOL GEOMETRY_ARRAY_API
25#define NO_IMPORT_ARRAY
26#include <numpy/ndarrayobject.h>
31using Mantid::PythonInterface::DetectorInfoPythonIterator;
41 return DetectorInfoPythonIterator(detectorInfo);
44using return_readonly_numpy = return_value_policy<Policies::VectorRefToNumpy<Converters::WrapReadOnly>>;
46PyObject *numpyArrayFromVector(
const std::vector<V3D> &
vec) {
47 const size_t n_detectors =
vec.size();
48 constexpr size_t vec_size = 3;
49 npy_intp dims[2] = {
static_cast<npy_intp
>(n_detectors), vec_size};
50 PyObject *numpy_array = PyArray_SimpleNew(2, dims, NPY_DOUBLE);
52 PyErr_SetString(PyExc_RuntimeError,
"Failed to create numpy array");
53 throw boost::python::error_already_set();
55 double *data =
static_cast<double *
>(PyArray_DATA(
reinterpret_cast<PyArrayObject *
>(numpy_array)));
56 for (
size_t i = 0; i < n_detectors; ++i) {
57 const size_t base_index = i * vec_size;
58 data[base_index + 0] =
vec[i].X();
59 data[base_index + 1] =
vec[i].Y();
60 data[base_index + 2] =
vec[i].Z();
67 return numpyArrayFromVector(positions);
72 return numpyArrayFromVector(positions);
77 const size_t n_detectors = rotations.size();
78 const size_t quat_size = 4;
79 npy_intp dims[2] = {
static_cast<npy_intp
>(n_detectors), quat_size};
80 PyObject *numpy_rotations_array = PyArray_SimpleNew(2, dims, NPY_DOUBLE);
81 if (!numpy_rotations_array) {
82 PyErr_SetString(PyExc_RuntimeError,
"Failed to create numpy array");
83 throw boost::python::error_already_set();
85 double *data =
static_cast<double *
>(PyArray_DATA(
reinterpret_cast<PyArrayObject *
>(numpy_rotations_array)));
86 for (
size_t i = 0; i < n_detectors; ++i) {
87 const size_t base_index = i * quat_size;
88 data[base_index + 0] = rotations[i].imagI();
89 data[base_index + 1] = rotations[i].imagJ();
90 data[base_index + 2] = rotations[i].imagK();
91 data[base_index + 3] = rotations[i].real();
93 return numpy_rotations_array;
121 class_<DetectorInfo, boost::noncopyable>(
"DetectorInfo", no_init)
126 "Returns the size of the DetectorInfo, i.e., the number of "
127 "detectors in the instrument.")
130 "Returns the size of the DetectorInfo, i.e., the number of "
131 "detectors in the instrument.")
134 "Returns the index of the detector with the given id.")
136 .def(
"isMonitor", isMonitor, (arg(
"self"), arg(
"index")),
"Returns True if the detector is a monitor.")
138 .def(
"isMasked", isMasked, (arg(
"self"), arg(
"index")),
"Returns True if the detector is masked.")
140 .def(
"setMasked", setMasked, (arg(
"self"), arg(
"index"), arg(
"masked")),
141 "Set the mask flag of the detector where the detector is identified "
147 "Returns True if the content of this "
148 "detector is equivalent to the content "
149 "of the other detector.")
151 .def(
"twoTheta",
twoTheta, (arg(
"self"), arg(
"index")),
152 "Returns 2 theta (scattering angle w.r.t beam direction).")
153 .def(
"signedTwoTheta", signedTwoTheta, (arg(
"self"), arg(
"index")),
154 "Returns signed 2 theta (signed scattering angle w.r.t beam direction).")
155 .def(
"azimuthal", azimuthal, (arg(
"self"), arg(
"index")),
156 "Returns the out-of-plane angle in radians angle w.r.t. to "
157 "vecPointingHorizontal")
158 .def(
"position",
position, (arg(
"self"), arg(
"index")),
159 "Returns the absolute position of the detector where the detector "
160 "is identified by 'index'.")
161 .def(
"allPositions", &allPositions, (arg(
"self")),
162 "Returns the absolute positions of all detectors as a numpy array.")
163 .def(
"rotation",
rotation, (arg(
"self"), arg(
"index")),
164 "Returns the absolute rotation of the detector where the detector "
165 "is identified by 'index'.")
166 .def(
"allRotations", &allRotations, (arg(
"self")),
167 "Returns the absolute rotations of all detectors as a numpy array of quarternions, [i, j, k, w].")
168 .def(
"allScaleFactors", &allScaleFactors, (arg(
"self")),
169 "Returns the scale factors of all detectors as a numpy array.")
171 "Returns all detector ids sorted by detector index")
172 .def(
"l2",
l2, (arg(
"self"), arg(
"index")),
"Returns the l2 scattering distance")
173 .def(
"l1", &
DetectorInfo::l1, arg(
"self"),
"Returns the l1 scattering distance")
175 "Returns if there are masked detectors")
177 "Return the memory footprint of the detector info in bytes.");
tagPyArrayObject PyArrayObject
std::vector< T > const * vec
SpectrumInfoPythonIterator make_pyiterator(SpectrumInfo &spectrumInfo)
Mantid::Kernel::Quat(ComponentInfo::* rotation)(const size_t) const
void export_DetectorInfo()
DetectorInfoIterator for random access iteration over DetectorInfo.
Geometry::DetectorInfo is an intermediate step towards a DetectorInfo that is part of Instrument-2....
double twoTheta(const size_t index) const
Returns 2 theta (scattering angle w.r.t. to beam direction).
double l2(const size_t index) const
Returns L2 (distance from sample to spectrum).
std::vector< Kernel::Quat > allRotations() const
Returns the absolute rotations of all detectors in a vector ordered by index.
bool hasMaskedDetectors() const
Returns true if there are masked detectors.
Kernel::Quat rotation(const size_t index) const
Returns the rotation of the detector with given index.
bool isMasked(const size_t index) const
Returns true if the detector is masked.
void setMasked(const size_t index, bool masked)
Set the mask flag of the detector with given index. Not thread safe.
std::vector< Kernel::V3D > allPositions() const
Returns the absolute positions of all detectors in a vector ordered by index.
const std::vector< detid_t > & detectorIDs() const
Returns a sorted vector of all detector IDs.
Kernel::V3D position(const size_t index) const
Returns the position of the detector with given index.
size_t getMemorySize() const
Return memory used by the detector info, in bytes.
void clearMaskFlags()
Sets all mask flags to false (unmasked).
bool isEquivalent(const DetectorInfo &other) const
Returns true if the content of this is equivalent to the content of other.
double signedTwoTheta(const size_t index) const
Returns signed 2 theta (signed scattering angle w.r.t. to beam direction).
double l1() const
Returns L1 (distance from source to sample).
std::vector< Kernel::V3D > allScaleFactors() const
Returns the scale factors of all detectors in a vector ordered by index.
size_t indexOf(const detid_t id) const
Returns the index of the detector with the given detector ID.
size_t size() const
Returns the size of the DetectorInfo, i.e., the number of detectors in the instrument.
bool isMonitor(const size_t index) const
Returns true if the detector is a monitor.
double azimuthal(const size_t index) const