-
Notifications
You must be signed in to change notification settings - Fork 122
/
SliceMDHisto.cpp
136 lines (121 loc) · 4.74 KB
/
SliceMDHisto.cpp
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
/**
* This algorithm takes a MDHistoWorkspace and allows to select a slab out of
* it which is stored into the result workspace.
*
* Mark Koennecke, November 2012
*/
#include "MantidSINQ/SliceMDHisto.h"
#include "MantidDataObjects/MDHistoWorkspace.h"
#include "MantidGeometry/MDGeometry/MDTypes.h"
#include "MantidKernel/ArrayProperty.h"
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(SliceMDHisto)
using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace Mantid::Geometry;
using namespace Mantid::DataObjects;
using namespace Mantid;
// A reference to the logger is provided by the base class, it is called g_log.
// It is used to print out information, warning and error messages
SliceMDHisto::SliceMDHisto() : Mantid::API::Algorithm(), m_rank(0), m_dim() {}
void SliceMDHisto::init() {
declareProperty(make_unique<WorkspaceProperty<IMDHistoWorkspace>>(
"InputWorkspace", "", Direction::Input));
declareProperty(make_unique<ArrayProperty<int>>("Start"),
"A comma separated list of min,for each dimension");
declareProperty(make_unique<ArrayProperty<int>>("End"),
"A comma separated list of max for each dimension");
declareProperty(make_unique<WorkspaceProperty<IMDHistoWorkspace>>(
"OutputWorkspace", "", Direction::Output));
}
void SliceMDHisto::exec() {
IMDHistoWorkspace_sptr inWS =
IMDHistoWorkspace_sptr(getProperty("InputWorkspace"));
m_rank = static_cast<unsigned int>(inWS->getNumDims());
for (unsigned int i = 0; i < m_rank; i++) {
boost::shared_ptr<const IMDDimension> arDim = inWS->getDimension(i);
m_dim.push_back(static_cast<int>(arDim->getNBins()));
}
std::vector<int> start = getProperty("Start");
std::vector<int> end = getProperty("End");
// some checks
if (start.size() < m_rank || end.size() < m_rank) {
throw std::runtime_error(
"Start and end need to be given for each dimension of the dataset");
}
for (unsigned int i = 0; i < m_rank; i++) {
if (start[i] < 0) {
start[i] = 0;
}
if (start[i] > m_dim[i]) {
start[i] = m_dim[i];
}
if (end[i] < 0) {
end[i] = 0;
}
if (end[i] >= m_dim[i]) {
end[i] = m_dim[i];
}
if (end[i] < start[i]) {
throw std::runtime_error(
"End must be larger then start for each dimension");
}
}
// create the new dadaset
std::vector<MDHistoDimension_sptr> dimensions;
for (unsigned int k = 0; k < m_rank; ++k) {
boost::shared_ptr<const IMDDimension> arDim = inWS->getDimension(k);
dimensions.push_back(MDHistoDimension_sptr(new MDHistoDimension(
arDim->getName(), arDim->getName(), arDim->getMDFrame(),
arDim->getX(start[k]), arDim->getX(end[k]), end[k] - start[k])));
}
auto outWS = boost::make_shared<MDHistoWorkspace>(dimensions);
coord_t *sourceDim =
reinterpret_cast<coord_t *>(malloc(m_rank * sizeof(coord_t)));
coord_t *targetDim =
reinterpret_cast<coord_t *>(malloc(m_rank * sizeof(coord_t)));
cutData(inWS, outWS, sourceDim, targetDim, start, end, 0);
free(sourceDim);
free(targetDim);
// assign the workspace
copyMetaData(inWS, outWS);
setProperty("OutputWorkspace", outWS);
}
void SliceMDHisto::cutData(Mantid::API::IMDHistoWorkspace_sptr inWS,
Mantid::API::IMDHistoWorkspace_sptr outWS,
Mantid::coord_t *sourceDim,
Mantid::coord_t *targetDim, std::vector<int> start,
std::vector<int> end, unsigned int dim) {
int length;
boost::shared_ptr<const IMDDimension> inDim = inWS->getDimension(dim);
boost::shared_ptr<const IMDDimension> outDim = outWS->getDimension(dim);
length = end[dim] - start[dim];
if (dim == m_rank - 1) {
MDHistoWorkspace_sptr outWSS =
boost::dynamic_pointer_cast<MDHistoWorkspace>(outWS);
for (int i = 0; i < length; i++) {
sourceDim[dim] = inDim->getX(start[dim] + i);
signal_t val = inWS->getSignalAtCoord(
sourceDim, static_cast<Mantid::API::MDNormalization>(0));
targetDim[dim] = outDim->getX(i);
size_t idx = outWSS->getLinearIndexAtCoord(targetDim);
outWS->setSignalAt(idx, val);
outWS->setErrorSquaredAt(idx, val);
}
} else {
for (int i = 0; i < length; i++) {
sourceDim[dim] = inDim->getX(start[dim] + i);
targetDim[dim] = outDim->getX(i);
cutData(inWS, outWS, sourceDim, targetDim, start, end, dim + 1);
}
}
}
void SliceMDHisto::copyMetaData(Mantid::API::IMDHistoWorkspace_sptr inws,
Mantid::API::IMDHistoWorkspace_sptr outws) {
outws->setTitle(inws->getTitle());
ExperimentInfo_sptr info;
if (inws->getNumExperimentInfo() > 0) {
info = inws->getExperimentInfo(0);
outws->addExperimentInfo(info);
}
}