14#include <boost/python/class.hpp>
15#include <boost/python/copy_non_const_reference.hpp>
16#define PY_ARRAY_UNIQUE_SYMBOL API_ARRAY_API
17#define NO_IMPORT_ARRAY
18#include <numpy/arrayobject.h>
43PyObject *WrapReadOnlyNumpyFArray(
const Mantid::signal_t *arr, std::vector<Py_intptr_t> dims) {
45#if NPY_API_VERSION >= 0x00000007
47 PyArray_New(&PyArray_Type,
static_cast<int>(dims.size()), &dims[0], datatype,
nullptr,
48 static_cast<void *
>(
const_cast<double *
>(arr)), 0, NPY_ARRAY_FARRAY,
nullptr));
49 PyArray_CLEARFLAGS(nparray, NPY_ARRAY_WRITEABLE);
52 PyArray_New(&PyArray_Type,
static_cast<int>(dims.size()), &dims[0], datatype,
nullptr,
53 static_cast<void *
>(
const_cast<double *
>(arr)), 0, NPY_FARRAY,
nullptr));
54 nparray->flags &= ~NPY_WRITEABLE;
56 return reinterpret_cast<PyObject *
>(nparray);
66 std::vector<size_t> nd;
70 for (
size_t i = 0; i < ndims; ++i) {
75 std::vector<Py_intptr_t> dims(ndims);
76 for (
size_t i = 0; i < ndims; ++i)
77 dims[i] =
static_cast<Py_intptr_t
>(nd[i]);
80 throw std::runtime_error(
"Workspace has zero dimensions!");
91 auto dims = countDimensions(self);
100 auto dims = countDimensions(self);
109 auto dims = countDimensions(self);
121 auto wsShape = countDimensions(self);
122 const size_t ndims = wsShape.size();
123 auto arrShape = signal.attr(
"shape");
124 if (ndims !=
static_cast<size_t>(len(arrShape))) {
125 std::ostringstream os;
127 <<
": The number of dimensions doe not match the current "
128 "workspace size. Workspace="
129 << ndims <<
" array=" << len(arrShape);
130 throw std::invalid_argument(os.str());
133 for (
size_t i = 0; i < ndims; ++i) {
134 int arrDim = extract<int>(arrShape[i])();
135 if (wsShape[i] != arrDim) {
136 std::ostringstream os;
137 os << fnLabel <<
": The dimension size for the " <<
std::to_string(i) <<
"th dimension do not match. "
138 <<
"Workspace dimension size=" << wsShape[i] <<
", array size=" << arrDim;
139 throw std::invalid_argument(os.str());
153 throwIfSizeIncorrect(self, signalValues,
"setSignalArray");
154 object rav = signalValues.attr(
"ravel")(
"F");
155 object flattened = rav.attr(
"flat");
156 auto length = len(flattened);
157 for (
auto i = 0; i < length; ++i) {
158 self.
setSignalAt(i, extract<double>(flattened[i])());
172 throwIfSizeIncorrect(self, errorSquared,
"setErrorSquaredArray");
173 object rav = errorSquared.attr(
"ravel")(
"F");
174 object flattened = rav.attr(
"flat");
175 auto length = len(flattened);
176 for (
auto i = 0; i < length; ++i) {
190 throwIfSizeIncorrect(self, numEvents,
"setNumEventsArray");
191 object rav =
numEvents.attr(
"ravel")(
"F");
192 object flattened = rav.attr(
"flat");
193 const auto length =
static_cast<size_t>(len(flattened));
195 std::vector<double> values;
196 values.reserve(length);
197 for (
size_t i = 0; i < length; ++i) {
198 values.emplace_back(extract<double>(flattened[i])());
201 for (
size_t i = 0; i < values.size(); ++i) {
212 throw std::invalid_argument(
"setSignalAt: The index is greater than the "
213 "number of bins in the workspace");
221 class_<IMDHistoWorkspace, bases<IMDWorkspace, MultipleExperimentInfos>, boost::noncopyable>(
"IMDHistoWorkspace",
223 .def(
"getSignalArray", &getSignalArrayAsNumpyArray, arg(
"self"),
224 "Returns a read-only numpy array containing the signal values")
226 .def(
"getErrorSquaredArray", &getErrorSquaredArrayAsNumpyArray, arg(
"self"),
227 "Returns a read-only numpy array containing the square of the error "
230 .def(
"getNumEventsArray", &getNumEventsArrayAsNumpyArray, arg(
"self"),
231 "Returns a read-only numpy array containing the number of MD events "
235 return_value_policy<copy_non_const_reference>(),
"Return a reference to the signal at the linear index")
238 return_value_policy<copy_non_const_reference>(),
"Return the squared-errors at the linear index")
240 .def(
"setSignalAt", &setSignalAt, (arg(
"self"), arg(
"index"), arg(
"value")),
241 "Sets the signal at the specified index.")
244 "Sets the squared-error at the specified index.")
246 .def(
"setSignalArray", &setSignalArray, (arg(
"self"), arg(
"signalValues")),
247 "Sets the signal from a numpy array. The sizes must match the "
248 "current workspace sizes. A ValueError is thrown if not. Any link "
249 "to the original MDEventWorkspace(s) is cleared.")
251 .def(
"setErrorSquaredArray", &setErrorSquaredArray, (arg(
"self"), arg(
"errorSquared")),
252 "Sets the square of the errors from a numpy array. The sizes must "
253 "match the current workspace sizes. A ValueError is thrown if not. Any "
254 "link to the original MDEventWorkspace(s) is cleared.")
256 .def(
"setNumEventsArray", &setNumEventsArray, (arg(
"self"), arg(
"numEvents")),
257 "Sets the number of events from a numpy array. The sizes must match "
258 "the current workspace sizes, otherwise a ValueError is thrown. Any link "
259 "to the original MDEventWorkspace(s) is cleared.")
262 "Sets all signals/errors in the workspace to the given values")
265 return_value_policy<return_by_value>(),
"Return the inverse of volume of EACH cell in the workspace.")
268 (arg(
"self"), arg(
"index1"), arg(
"index2")), return_value_policy<return_by_value>(),
269 "Get the 1D linear index from the 2D array")
271 .def(
"getLinearIndex",
273 (arg(
"self"), arg(
"index1"), arg(
"index2"), arg(
"index3")), return_value_policy<return_by_value>(),
274 "Get the 1D linear index from the 3D array")
276 .def(
"getLinearIndex",
278 (arg(
"self"), arg(
"index1"), arg(
"index2"), arg(
"index3"), arg(
"index4")),
279 return_value_policy<return_by_value>(),
"Get the 1D linear index from the 4D array")
282 return_value_policy<return_by_value>(),
"Return the position of the center of a bin at a given position")
285 "Sets the visual normalization of"
double value
The value of the point.
#define GET_POINTER_SPECIALIZATION(TYPE)
std::map< DeltaEMode::Type, std::string > index
tagPyArrayObject PyArrayObject
void export_IMDHistoWorkspace()
Abstract interface to MDHistoWorkspace, for use in exposing to Python.
virtual signal_t & errorSquaredAt(size_t index)=0
virtual Mantid::Kernel::VMD getCenter(size_t linearIndex) const =0
virtual const signal_t * getErrorSquaredArray() const =0
virtual const signal_t * getNumEventsArray() const =0
virtual signal_t & signalAt(size_t index)=0
virtual signal_t * mutableNumEventsArray()=0
virtual void setErrorSquaredAt(size_t index, signal_t value)=0
virtual const signal_t * getSignalArray() const =0
virtual void setDisplayNormalization(const Mantid::API::MDNormalization &preferredNormalization)=0
virtual void setSignalAt(size_t index, signal_t value)=0
virtual coord_t getInverseVolume() const =0
See the MDHistoWorkspace definition for descriptions of these.
virtual size_t getLinearIndex(size_t index1, size_t index2) const =0
virtual void setTo(signal_t signal, signal_t errorSquared, signal_t numEvents)=0
virtual uint64_t getNPoints() const =0
Get the number of points associated with the workspace.
virtual std::shared_ptr< const Mantid::Geometry::IMDDimension > getDimension(size_t index) const
Get a dimension.
virtual size_t getNumDims() const
void clearOriginalWorkspaces()
Clear original workspaces.
Thin object wrapper around a numpy array.
std::size_t numEvents(Nexus::File &file, bool &hasTotalCounts, bool &oldNeXusFileNames, const std::string &prefix)
Get the number of events in the currently opened group.
double signal_t
Typedef for the signal recorded in a MDBox, etc.
std::string to_string(const wide_integer< Bits, Signed > &n)
Defines a mapping between C++ type given by the template parameter and numpy type enum NPY_TYPES.
Encapsulates the registration required for an interface type T that sits on top of a Kernel::DataItem...