17#include "MantidHistogramData/LinearGenerator.h"
33 void operator()(
void const * )
const {
54 std::string &xAxisLabel) {
59 VMD diff = originalEnd - originalStart;
62 double largest = -1e30;
67 if (nOriginalWorkspaces < 1) {
68 logger.
information(
"No original workspaces. Assume X-axis is Dim0.");
73 std::dynamic_pointer_cast<IMDWorkspace>(inputWorkspace->
getOriginalWorkspace(nOriginalWorkspaces - 1));
76 if (
fabs(diff[
d]) > largest || (originalWS->getDimension(dimIndex)->getIsIntegrated())) {
78 if (originalWS && !originalWS->getDimension(
d)->getIsIntegrated()) {
79 largest =
fabs(diff[
d]);
85 xAxisLabel = originalWS->getDimension(dimIndex)->getName();
98 "An input IMDHistoWorkspace.");
100 "An output Workspace2D.");
102 std::array<std::string, 3> normalizations = {{
"NoNormalization",
"VolumeNormalization",
"NumEventsNormalization"}};
104 declareProperty(
"Normalization", normalizations[0],
106 "Signal normalization method");
109 "If True, tries to automatically determine the dimension to use as the "
110 "output x-axis. Applies to line cut MD workspaces.");
119 if (nonIntegDims.size() == 1) {
121 }
else if (nonIntegDims.size() == 2) {
124 throw std::invalid_argument(
"Cannot convert MD workspace with more than 2 dimensions.");
136 std::string alongDim;
137 if (!nonIntegDims.empty())
138 alongDim = nonIntegDims[0]->getDimensionId();
140 alongDim = inputWorkspace->getDimension(0)->getDimensionId();
142 size_t nd = inputWorkspace->getNumDims();
147 for (
size_t d = 0;
d < nd;
d++) {
149 if (dim->getDimensionId() == alongDim) {
151 start[
d] = dim->getMinimum();
152 end[
d] = dim->getMaximum();
157 start[
d] = (dim->getMaximum() + dim->getMinimum()) / 2.0f;
169 if (normProp ==
"NoNormalization") {
171 }
else if (normProp ==
"VolumeNormalization") {
173 }
else if (normProp ==
"NumEventsNormalization") {
179 auto line = inputWorkspace->getLineData(start, end, normalization);
183 outputWorkspace->mutableY(0) = line.y;
184 outputWorkspace->mutableE(0) = line.e;
186 const size_t numberTransformsToOriginal = inputWorkspace->getNumberTransformsToOriginal();
189 if (numberTransformsToOriginal > 0) {
190 const size_t indexToLastTransform = numberTransformsToOriginal - 1;
194 assert(line.x.size() == outputWorkspace->x(0).size());
196 std::string xAxisLabel = inputWorkspace->getDimension(
id)->getName();
197 const bool autoFind = this->
getProperty(
"FindXAxis");
201 id = findXAxis(start, end, transform.get(), inputWorkspace.get(),
g_log,
id, xAxisLabel);
204 auto &mutableXValues = outputWorkspace->mutableX(0);
206 for (
size_t i = 0; i < line.x.size(); ++i) {
208 VMD wsCoord = start + dir * line.x[i];
210 VMD inTargetCoord = transform->applyVMD(wsCoord);
211 mutableXValues[i] = inTargetCoord[id];
215 std::shared_ptr<Kernel::Units::Label> labelX =
217 labelX->setLabel(xAxisLabel);
218 outputWorkspace->getAxis(0)->unit() = labelX;
220 outputWorkspace->setYUnitLabel(
"Signal");
235 auto xDim = nonIntegDims[0];
236 auto yDim = nonIntegDims[1];
238 size_t nx = xDim->getNBins();
239 size_t ny = yDim->getNBins();
241 size_t xDimIndex = inputWorkspace->getDimensionIndexById(xDim->getDimensionId());
242 size_t xStride =
calcStride(*inputWorkspace, xDimIndex);
244 size_t yDimIndex = inputWorkspace->getDimensionIndexById(yDim->getDimensionId());
245 size_t yStride =
calcStride(*inputWorkspace, yDimIndex);
250 if (normProp ==
"NoNormalization") {
252 }
else if (normProp ==
"VolumeNormalization") {
254 }
else if (normProp ==
"NumEventsNormalization") {
259 auto inverseVolume =
static_cast<signal_t>(inputWorkspace->getInverseVolume());
265 const size_t xValsSize = outputWorkspace->x(0).size();
266 const double dx = xDim->getBinWidth();
267 const double minX = xDim->getMinimum();
268 outputWorkspace->setBinEdges(0, xValsSize, HistogramData::LinearGenerator(minX, dx));
270 for (
size_t i = 0; i < ny; ++i) {
272 outputWorkspace->setSharedX(i, outputWorkspace->sharedX(0));
274 size_t yOffset = i * yStride;
275 for (
size_t j = 0; j < nx; ++j) {
276 size_t linearIndex = yOffset + j * xStride;
277 signal_t signal = inputWorkspace->getSignalArray()[linearIndex];
278 signal_t error = inputWorkspace->getErrorSquaredArray()[linearIndex];
282 signal *= inverseVolume;
283 error *= inverseVolume;
286 signal_t factor = inputWorkspace->getNumEventsArray()[linearIndex];
287 factor = factor != 0.0 ? 1.0 / factor : 1.0;
292 outputWorkspace->mutableY(i)[j] = signal;
293 outputWorkspace->mutableE(i)[j] = sqrt(
error);
299 labelX->setLabel(xDim->getName());
300 outputWorkspace->getAxis(0)->unit() = labelX;
303 auto yAxis = std::make_unique<BinEdgeAxis>(ny + 1);
304 for (
size_t i = 0; i <= ny; ++i) {
305 yAxis->setValue(i, yDim->getX(i));
308 labelY->setLabel(yDim->getName());
309 yAxis->unit() = labelY;
310 outputWorkspace->replaceAxis(1, std::move(yAxis));
313 outputWorkspace->setYUnitLabel(
"Signal");
326 for (
size_t i = 0; i < dim; ++i) {
327 auto dimension =
workspace.getDimension(i);
328 stride *= dimension->getNBins();
#define DECLARE_ALGORITHM(classname)
IPeaksWorkspace_sptr workspace
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Abstract interface to MDHistoWorkspace, for use in exposing to Python.
size_t numOriginalWorkspaces() const
std::shared_ptr< Workspace > getOriginalWorkspace(size_t index=0) const
Get the "original" workspace (the workspace that was the source for a binned MDWorkspace).
A property class for workspaces.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
ListValidator is a validator that requires the value of a property to be one of a defined list of pos...
The Logger class is in charge of the publishing messages from the framework through various channels.
void information(const std::string &msg)
Logs at information level.
The concrete, templated class for properties.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
TYPE normalize()
Normalize this vector to unity length.
size_t getNumDims() const
Creates a single spectrum Workspace2D with X,Y, and E copied from an first non-integrated dimension o...
void exec() override
Execution code.
void make2DWorkspace()
Make 2D MatrixWorkspace.
size_t calcStride(const API::IMDHistoWorkspace &workspace, size_t dim) const
Calculate the stride for a dimension.
void make1DWorkspace()
Make MatrixWorkspace with 1 spectrum.
std::shared_ptr< const CoordTransform > CoordTransform_const_sptr
std::shared_ptr< IMDHistoWorkspace > IMDHistoWorkspace_sptr
shared pointer to Mantid::API::IMDHistoWorkspace
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::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::unique_ptr< T > create(const P &parent, const IndexArg &indexArg, const HistArg &histArg)
This is the create() method that all the other create() methods call.
std::vector< IMDDimension_const_sptr > VecIMDDimension_const_sptr
Vector of constant shared pointers to IMDDimensions.
std::shared_ptr< const IMDDimension > IMDDimension_const_sptr
Shared Pointer to const IMDDimension.
std::shared_ptr< IValidator > IValidator_sptr
A shared_ptr to an IValidator.
VMDBase< VMD_t > VMD
Define the VMD as using the double or float data type.
double signal_t
Typedef for the signal recorded in a MDBox, etc.
@ Input
An input workspace.
@ Output
An output workspace.