20#include <boost/optional.hpp>
21#include <boost/scoped_array.hpp>
45 :
IMDHistoWorkspace(), numDimensions(0), m_nEventsContributed(
std::numeric_limits<uint64_t>::quiet_NaN()),
46 m_coordSystem(
None), m_displayNormalization(displayNormalization) {
47 std::vector<Mantid::Geometry::MDHistoDimension_sptr> dimensions;
49 dimensions.emplace_back(std::move(dimX));
51 dimensions.emplace_back(std::move(dimY));
53 dimensions.emplace_back(std::move(dimZ));
55 dimensions.emplace_back(std::move(dimT));
56 this->
init(dimensions);
67 :
IMDHistoWorkspace(), numDimensions(0), m_nEventsContributed(
std::numeric_limits<uint64_t>::quiet_NaN()),
68 m_coordSystem(
None), m_displayNormalization(displayNormalization) {
69 this->
init(dimensions);
80 :
IMDHistoWorkspace(), numDimensions(0), m_nEventsContributed(
std::numeric_limits<uint64_t>::quiet_NaN()),
81 m_coordSystem(
None), m_displayNormalization(displayNormalization) {
82 this->
init(dimensions);
91 :
IMDHistoWorkspace(other), m_nEventsContributed(other.m_nEventsContributed), m_coordSystem(other.m_coordSystem),
92 m_displayNormalization(other.m_displayNormalization) {
112 std::vector<IMDDimension_sptr> dim2;
113 dim2.reserve(dimensions.size());
114 std::transform(dimensions.cbegin(), dimensions.cend(), std::back_inserter(dim2),
115 [](
const auto dimension) { return std::dynamic_pointer_cast<IMDDimension>(dimension); });
134 signal_t nan = std::numeric_limits<signal_t>::quiet_NaN();
135 this->
setTo(nan, nan, nan);
192 for (
size_t i = 0; i < numVertices; ++i) {
194 size_t outIndex = i * nd;
197 for (
size_t d = 0;
d < nd;
d++) {
200 size_t mask =
size_t{1} <<
d;
201 if ((i & mask) > 0) {
213 m_origin = std::vector<coord_t>(nd);
214 for (
size_t d = 0;
d < nd;
d++) {
221 for (
size_t d = 0;
d < nd;
d++)
252 throw std::invalid_argument(
"Need 3 dimensions for ImplicitFunction.");
289 size_t dimIndexes[10];
294 auto out = std::make_unique<coord_t[]>(
numDimensions * numVertices);
295 for (
size_t i = 0; i < numVertices; ++i) {
314 size_t dimIndexes[10];
340 return m_signals[linearIndex] * normalizer;
342 return std::numeric_limits<signal_t>::quiet_NaN();
357 if (linearIndex == std::numeric_limits<size_t>::max() || this->
getIsMaskedAt(linearIndex)) {
371 size_t linearIndex = 0;
391std::vector<std::unique_ptr<Mantid::API::IMDIterator>>
393 size_t numCores = suggestedNumCores;
397 if (numCores > numElements)
398 numCores = numElements;
403 std::vector<std::unique_ptr<IMDIterator>> out;
404 for (
size_t i = 0; i < numCores; i++) {
405 size_t begin = (i * numElements) / numCores;
406 size_t end = ((i + 1) * numElements) / numCores;
407 if (end > numElements)
415 out.emplace_back(std::make_unique<MDHistoWorkspaceIterator>(
this, clonedFunction, begin, end));
427 std::vector<signal_t> out;
429 for (
size_t i = 0; i <
m_length; ++i)
437 std::vector<signal_t> out;
439 for (
size_t i = 0; i <
m_length; ++i)
450 if ((point[
d] < dim->getMinimum()) || (point[
d] > dim->getMaximum()))
492 const bool bin_centres)
const {
497 throw std::runtime_error(
"Start point must have the same number of "
498 "dimensions as the workspace.");
500 throw std::runtime_error(
"End point must have the same number of dimensions as the workspace.");
503 VMD dir = end - start;
508 if (boundaries.empty()) {
513 line.
x.emplace_back(length);
518 std::set<coord_t>::iterator it;
519 it = boundaries.cbegin();
522 VMD lastPos = start + (dir * lastLinePos);
524 line.
x.emplace_back(lastLinePos);
528 for (; it != boundaries.cend(); ++it) {
533 VMD pos = start + (dir * linePos);
536 VMD middle = (pos + lastPos) * 0.5;
541 if (bin_centres && !(linearIndex == std::numeric_limits<size_t>::max() || this->
getIsMaskedAt(linearIndex))) {
542 auto bin_centrePos =
static_cast<coord_t>((linePos + lastLinePos) * 0.5);
543 line.
x.emplace_back(bin_centrePos);
544 }
else if (!bin_centres)
545 line.
x.emplace_back(linePos);
551 auto signal = this->
getSignalAt(linearIndex) * normalizer;
552 if (std::isinf(signal)) {
554 signal = std::numeric_limits<signal_t>::quiet_NaN();
557 line.
y.emplace_back(signal);
558 line.
e.emplace_back(this->
getErrorAt(linearIndex) * normalizer);
564 line.
y.emplace_back(std::numeric_limits<signal_t>::quiet_NaN());
565 line.
e.emplace_back(std::numeric_limits<signal_t>::quiet_NaN());
568 lastLinePos = linePos;
573 if (line.
x.empty()) {
629 std::set<coord_t> boundaries;
633 boundaries.insert(0.0f);
635 boundaries.insert(length);
639 for (
size_t d = 0;
d < nd;
d++) {
644 auto nbounds = dim->getNBoundaries();
645 for (
size_t i = 0; i < nbounds; i++) {
649 coord_t linePos = (thisX - lineStartX) / dir[
d];
650 if (linePos >= 0 && linePos <= length) {
652 VMD pos = start + (dir * linePos);
655 boundaries.insert(linePos);
677 if (other.getNumDims() != this->getNumDims())
678 throw std::invalid_argument(
"Cannot perform the " + operation +
679 " operation on this MDHistoWorkspace. The "
680 "number of dimensions does not match.");
681 if (other.m_length != this->m_length)
682 throw std::invalid_argument(
"Cannot perform the " + operation +
683 " operation on this MDHistoWorkspace. The "
684 "length of the signals vector does not match.");
704 for (
size_t i = 0; i <
m_length; ++i) {
720 for (
size_t i = 0; i <
m_length; ++i) {
743 for (
size_t i = 0; i <
m_length; ++i) {
759 for (
size_t i = 0; i <
m_length; ++i) {
791 for (
size_t i = 0; i <
m_length; ++i) {
799 signal_t df2 = da2 * b * b + db2 * a * a;
822 for (
size_t i = 0; i <
m_length; ++i) {
827 signal_t df2 = da2 * b * b + db2 * a * a;
860 for (
size_t i = 0; i <
m_length; ++i) {
868 signal_t df2 = da2 / (b * b) + db2 * f * f / (b * b);
890 signal_t db2_relative = db2 / (b * b);
891 for (
size_t i = 0; i <
m_length; ++i) {
896 signal_t df2 = da2 / (b * b) + db2_relative * f * f;
910 for (
size_t i = 0; i <
m_length; ++i) {
930 for (
size_t i = 0; i <
m_length; ++i) {
950 for (
size_t i = 0; i <
m_length; ++i) {
966 double exponent_squared = exponent * exponent;
967 for (
size_t i = 0; i <
m_length; ++i) {
992 for (
size_t i = 0; i <
m_length; ++i) {
1009 for (
size_t i = 0; i <
m_length; ++i) {
1026 for (
size_t i = 0; i <
m_length; ++i) {
1040 for (
size_t i = 0; i <
m_length; ++i) {
1056 for (
size_t i = 0; i <
m_length; ++i) {
1071 for (
size_t i = 0; i <
m_length; ++i) {
1087 for (
size_t i = 0; i <
m_length; ++i) {
1102 for (
size_t i = 0; i <
m_length; ++i) {
1119 for (
size_t i = 0; i <
m_length; ++i) {
1136 for (
size_t i = 0; i <
m_length; ++i) {
1162 for (
size_t i = 0; i <
m_length; ++i) {
1190 for (
size_t i = 0; i <
m_length; ++i) {
1204 if (maskingRegion !=
nullptr) {
1205 for (
size_t i = 0; i < this->
getNPoints(); ++i) {
1208 if (maskingRegion->isPointContained(this->getCenter(i))) {
1235 for (
size_t i = 0; i < this->
getNPoints(); ++i) {
1253 for (
size_t i = 0; i <
m_length; ++i)
1265 auto coordinatesFromMDFrames = converter(
this);
1266 auto coordinates = m_coordSystem;
1267 if (coordinatesFromMDFrames) {
1268 coordinates = coordinatesFromMDFrames.get();
std::map< DeltaEMode::Type, std::string > index
#define GNU_DIAG_OFF(x)
This is a collection of macros for turning compiler warnings off in a controlled manner.
Abstract interface to MDHistoWorkspace, for use in exposing to Python.
void makeSinglePointWithNaN(std::vector< coord_t > &x, std::vector< signal_t > &y, std::vector< signal_t > &e) const
Make a single point with NaN as the signal and error This can be returned when there would otherwise ...
void initGeometry(const std::vector< std::shared_ptr< Geometry::IMDDimension > > &dimensions)
Initialize the geometry.
virtual std::shared_ptr< const Mantid::Geometry::IMDDimension > getDimension(size_t index) const
Get a dimension.
std::vector< std::shared_ptr< Geometry::IMDDimension > > m_dimensions
Vector of the dimensions used, in the order X Y Z t, etc.
virtual size_t getNumDims() const
bool threadSafe() const override
Marks the workspace as safe for multiple threads to edit data simutaneously.
MDFrameFromMDWorkspace: Each dimension of the MDWorkspace contains an MDFrame.
MDHistoWorkspace & operator*=(const MDHistoWorkspace &b_ws)
Perform the *= operation, element-by-element, for two MDHistoWorkspace's.
virtual std::vector< signal_t > getErrorDataVector() const
size_t getLinearIndexAtCoord(const coord_t *coords) const
Get the linear index into the histo array at these coordinates.
coord_t m_inverseVolume
Inverse of the volume of EACH cell.
uint64_t sumNContribEvents() const
sum the array of contributing events m_numEvents array
std::unique_ptr< bool[]> m_masks
Linear array of masks for each bin.
void init(std::vector< Mantid::Geometry::MDHistoDimension_sptr > &dimensions)
Constructor helper method.
void clearMDMasking() override
Clear masking.
MDHistoWorkspace & operator^=(const MDHistoWorkspace &b)
A boolean ^= (xor) operation, element-by-element, for two MDHistoWorkspace's.
virtual std::vector< signal_t > getSignalDataVector() const
Return a vector containing a copy of the signal data in the workspace.
LinePlot getLinePlot(const Mantid::Kernel::VMD &start, const Mantid::Kernel::VMD &end, Mantid::API::MDNormalization normalize) const override
Obtain coordinates for a line plot through a MDWorkspace.
Kernel::VMD getCenter(size_t linearIndex) const override
Return the position of the center of a bin at a given position.
signal_t getSignalAtCoord(const coord_t *coords, const Mantid::API::MDNormalization &normalization) const override
Returns the (normalized) signal at a given coordinates.
MDHistoWorkspace(Mantid::Geometry::MDHistoDimension_sptr dimX, Mantid::Geometry::MDHistoDimension_sptr dimY=Mantid::Geometry::MDHistoDimension_sptr(), Mantid::Geometry::MDHistoDimension_sptr dimZ=Mantid::Geometry::MDHistoDimension_sptr(), Mantid::Geometry::MDHistoDimension_sptr dimT=Mantid::Geometry::MDHistoDimension_sptr(), Mantid::API::MDNormalization displayNormalization=Mantid::API::NoNormalization)
Constructor given the 4 dimensions.
LinePlot getLineData(const Mantid::Kernel::VMD &start, const Mantid::Kernel::VMD &end, Mantid::API::MDNormalization normalize) const override
Obtain coordinates for a line plot through a MDWorkspace.
std::vector< size_t > m_indexMax
Max index into each dimension.
size_t getMemorySize() const override
Return the memory used, in bytes.
void setDisplayNormalization(const Mantid::API::MDNormalization &preferredNormalization) override
size_t numDimensions
Number of dimensions in this workspace.
void equalTo(const MDHistoWorkspace &b, const signal_t tolerance=1e-5)
Turn this workspace into a boolean workspace, where signal[i] -> becomes true (1.0) if it is == b[i].
signal_t getErrorAt(size_t index) const override
Get the error of the signal at the specified index.
void subtract(const MDHistoWorkspace &b)
Perform the -= operation, element-by-element, for two MDHistoWorkspace's.
LinePlot getLinePoints(const Mantid::Kernel::VMD &start, const Mantid::Kernel::VMD &end, Mantid::API::MDNormalization normalize, const bool bin_centres) const
Obtain coordinates for a line plot through a MDWorkspace.
void setCoordinateSystem(const Kernel::SpecialCoordinateSystem coordinateSystem) override
Set the special coordinate system.
void applyImplicitFunction(Mantid::Geometry::MDImplicitFunction *function, signal_t signal, signal_t errorSquared)
Apply an implicit function to each point; if false, set to the given value.
std::set< coord_t > getBinBoundariesOnLine(const Kernel::VMD &start, const Kernel::VMD &end, size_t nd, const Kernel::VMD &dir, coord_t length) const
Get ordered list of boundaries in position-along-the-line coordinates.
Mantid::API::MDNormalization displayNormalization() const override
Preferred visual normalization method.
Mantid::API::MDNormalization displayNormalizationHisto() const override
Preferred visual normalization method.
void power(double exponent)
Perform the power function (signal^exponent) on each signal S in the workspace.
signal_t getSignalAt(size_t index) const override
Get the signal at the specified index.
std::vector< coord_t > m_origin
Vector of the origin in each dimension.
static size_t sizeOfElement()
Get the size of an element in the HistoWorkspace.
std::vector< std::unique_ptr< Mantid::API::IMDIterator > > createIterators(size_t suggestedNumCores=1, Mantid::Geometry::MDImplicitFunction *function=nullptr) const override
Create IMDIterators from this MDHistoWorkspace.
signal_t getNormalizationFactor(const API::MDNormalization &normalize, size_t linearIndex) const
Find the normalization factor.
uint64_t m_nEventsContributed
the number of events, contributed into the workspace;
MDHistoWorkspace & operator+=(const MDHistoWorkspace &b)
Perform the += operation, element-by-element, for two MDHistoWorkspace's.
uint64_t getNPoints() const override
Get the number of points (bins in this case) associated with the workspace;.
std::vector< signal_t > m_errorsSquared
Linear array of errors for each bin.
std::vector< coord_t > m_boxLength
Vector of the length of the box in each dimension.
void log10(double filler=0.0)
Perform the base-10 logarithm on each signal in the workspace.
size_t m_length
Length of the m_signals / m_errorsSquared arrays.
void exp()
Perform the exp() function on each signal in the workspace.
void log(double filler=0.0)
Perform the natural logarithm on each signal in the workspace.
MDHistoWorkspace & operator&=(const MDHistoWorkspace &b)
void initVertexesArray()
After initialization, call this to initialize the vertexes array to the vertexes of the 0th box.
std::vector< size_t > m_indexMaker
For converting to/from linear index to tdimensions.
std::unique_ptr< coord_t[]> getVertexesArray(size_t linearIndex, size_t &numVertices) const
For the volume at the given linear index, Return the vertices of every corner of the box,...
void checkWorkspaceSize(const MDHistoWorkspace &other, const std::string &operation)
Check if the two workspace's sizes match (for comparison or element-by-element operation.
std::vector< coord_t > m_vertexesArray
Pre-calculated vertexes array for the 0th box.
signal_t getSignalWithMaskAtCoord(const coord_t *coords, const Mantid::API::MDNormalization &normalization) const override
Returns the (normalized) signal at a given coordinates.
void divide(const MDHistoWorkspace &b_ws)
Perform the /= operation, element-by-element, for two MDHistoWorkspace's.
uint64_t getNEvents() const override
get number of contributed events
bool getIsMaskedAt(size_t index) const
Getter for the masking at a specified linear index.
Mantid::API::MDNormalization m_displayNormalization
Display normalization to use.
MDHistoWorkspace & operator|=(const MDHistoWorkspace &b)
A boolean |= (or) operation, element-by-element, for two MDHistoWorkspace's.
void add(const MDHistoWorkspace &b)
Perform the += operation, element-by-element, for two MDHistoWorkspace's.
void greaterThan(const MDHistoWorkspace &b)
Turn this workspace into a boolean workspace, where signal[i] -> becomes true (1.0) if it is > b[i].
std::vector< size_t > indexMultiplier
To find the index into the linear array, dim0 + indexMultiplier[0]*dim1 + ...
MDHistoWorkspace & operator/=(const MDHistoWorkspace &b_ws)
Perform the /= operation, element-by-element, for two MDHistoWorkspace's.
std::vector< signal_t > m_signals
Linear array of signals for each bin.
void setSignalAt(size_t index, signal_t value) override
Sets the signal at the specified index.
void cacheValues()
When all dimensions have been initialized, this caches all the necessary values for later use.
void setMDMasking(std::unique_ptr< Mantid::Geometry::MDImplicitFunction > maskingRegion) override
Apply masking.
void setErrorSquaredAt(size_t index, signal_t value) override
Sets the error (squared) at the specified index.
void operatorNot()
A boolean not operation, performed in-place.
void lessThan(const MDHistoWorkspace &b)
Turn this workspace into a boolean workspace, where signal[i] -> becomes true (1.0) if it is < b[i].
void setMDMaskAt(const size_t &index, bool mask)
Apply masking.
void setUsingMask(const MDHistoWorkspace &mask, const MDHistoWorkspace &values)
Copy the values from another workspace onto this workspace, but only where a mask is true (non-zero)
void multiply(const MDHistoWorkspace &b_ws)
Perform the *= operation, element-by-element, for two MDHistoWorkspace's.
void setTo(signal_t signal, signal_t errorSquared, signal_t numEvents) override
Sets all signals/errors in the workspace to the given values.
MDHistoWorkspace & operator-=(const MDHistoWorkspace &b)
Perform the -= operation, element-by-element, for two MDHistoWorkspace's.
std::vector< signal_t > m_numEvents
Number of contributing events for each bin.
Kernel::SpecialCoordinateSystem m_coordSystem
An "ImplicitFunction" defining a hyper-cuboid-shaped region in N dimensions.
virtual bool isPointContained(const coord_t *coords)
Is a point in MDimensions contained by this ImplicitFunction? If the point is bounded by ALL planes c...
TYPE normalize()
Normalize this vector to unity length.
size_t getNumDims() const
static const signal_t MDMaskValue
MDNormalization
Enum describing different ways to normalize the signal in a MDWorkspace.
@ VolumeNormalization
Divide the signal by the volume of the box/bin.
@ NumEventsNormalization
Divide the signal by the number of events that contributed to it.
@ NoNormalization
Don't normalize = return raw counts.
std::size_t numEvents(::NeXus::File &file, bool &hasTotalCounts, bool &oldNeXusFileNames, const std::string &prefix, const NexusHDF5Descriptor &descriptor)
Get the number of events in the currently opened group.
bool pointInWorkspace(const MDHistoWorkspace *ws, const VMD &point)
std::shared_ptr< MDHistoDimension > MDHistoDimension_sptr
Shared pointer to a MDHistoDimension.
std::shared_ptr< const IMDDimension > IMDDimension_const_sptr
Shared Pointer to const IMDDimension.
void GetIndicesFromLinearIndex(const size_t numDims, const size_t linear_index, const size_t *index_maker, const size_t *index_max, size_t *out_indices)
Set up a nested for loop by creating an array of counters.
void SetUpIndexMaker(const size_t numDims, size_t *out, const size_t *index_max)
Set up an "index maker" for a nested for loop.
SpecialCoordinateSystem
Special coordinate systems for Q3D.
MANTID_KERNEL_DLL V3D normalize(V3D v)
Normalizes a V3D.
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
double signal_t
Typedef for the signal recorded in a MDBox, etc.
Holds X, Y, E for a line plot.
std::vector< signal_t > y
std::vector< signal_t > e