Newer
Older
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAlgorithms/ChangeBinOffset.h"
#include "MantidDataObjects/EventWorkspace.h"
#include "MantidKernel/BoundedValidator.h"
namespace Mantid {
namespace Algorithms {
using namespace Kernel;
using namespace API;
using namespace DataObjects;
// Register the class into the algorithm factory
DECLARE_ALGORITHM(ChangeBinOffset)
/**
* Default constructor
*/
Federico Montesino Pouzols
committed
ChangeBinOffset::ChangeBinOffset()
: API::Algorithm(), m_progress(NULL), offset(0.), wi_min(0), wi_max(0) {}
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
/**
* Destructor
*/
ChangeBinOffset::~ChangeBinOffset() {
if (m_progress) {
delete m_progress;
}
}
/** Initialisation method. Declares properties to be used in algorithm.
*
*/
void ChangeBinOffset::init() {
declareProperty(new WorkspaceProperty<MatrixWorkspace>("InputWorkspace", "",
Direction::Input),
"Name of the input workspace");
declareProperty(new WorkspaceProperty<MatrixWorkspace>("OutputWorkspace", "",
Direction::Output),
"Name of the output workspace");
auto isDouble = boost::make_shared<BoundedValidator<double>>();
declareProperty("Offset", 0.0, isDouble,
"The amount to change each time bin by");
auto mustBePositive = boost::make_shared<BoundedValidator<int>>();
mustBePositive->setLower(0);
declareProperty(
"IndexMin", 0, mustBePositive,
"The workspace index of the first spectrum to shift. Only used if\n"
"IndexMax is set.");
declareProperty(
"IndexMax", Mantid::EMPTY_INT(), mustBePositive,
"The workspace index of the last spectrum to shift. Only used if\n"
"explicitly set.");
}
/** Executes the algorithm
*
*/
void ChangeBinOffset::exec() {
// Get input workspace and offset
const MatrixWorkspace_sptr inputW = getProperty("InputWorkspace");
offset = getProperty("Offset");
API::MatrixWorkspace_sptr outputW = createOutputWS(inputW);
// Get number of histograms
int64_t histnumber = static_cast<int64_t>(inputW->getNumberHistograms());
m_progress = new API::Progress(this, 0.0, 1.0, histnumber);
wi_min = 0;
wi_max = histnumber - 1;
// check if workspace indexes have been set
int tempwi_min = getProperty("IndexMin");
int tempwi_max = getProperty("IndexMax");
if (tempwi_max != Mantid::EMPTY_INT()) {
// check wimin<=tempwi_min<=tempwi_max<=wi_max
if ((wi_min <= tempwi_min) && (tempwi_min <= tempwi_max) &&
(tempwi_max <= wi_max)) {
wi_min = size_t(tempwi_min);
wi_max = size_t(tempwi_max);
} else {
g_log.error("Invalid Workspace Index min/max properties");
throw std::invalid_argument("Inconsistent properties defined");
Gigg, Martyn Anthony
committed
}
}
// Check if its an event workspace
EventWorkspace_const_sptr eventWS =
boost::dynamic_pointer_cast<const EventWorkspace>(inputW);
if (eventWS != NULL) {
this->execEvent();
return;
}
// do the shift in X
PARALLEL_FOR2(inputW, outputW)
for (int64_t i = 0; i < histnumber; ++i) {
PARALLEL_START_INTERUPT_REGION
// Do the offsetting
for (size_t j = 0; j < inputW->readX(i).size(); ++j) {
// Change bin value by offset
if ((i >= wi_min) && (i <= wi_max))
outputW->dataX(i)[j] = inputW->readX(i)[j] + offset;
outputW->dataX(i)[j] = inputW->readX(i)[j];
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// Copy y and e data
outputW->dataY(i) = inputW->dataY(i);
outputW->dataE(i) = inputW->dataE(i);
m_progress->report();
PARALLEL_END_INTERUPT_REGION
}
PARALLEL_CHECK_INTERUPT_REGION
// Copy units
if (outputW->getAxis(0)->unit().get())
outputW->getAxis(0)->unit() = inputW->getAxis(0)->unit();
try {
if (inputW->getAxis(1)->unit().get())
outputW->getAxis(1)->unit() = inputW->getAxis(1)->unit();
} catch (Exception::IndexError &) {
// OK, so this isn't a Workspace2D
}
// Assign it to the output workspace property
setProperty("OutputWorkspace", outputW);
}
API::MatrixWorkspace_sptr
ChangeBinOffset::createOutputWS(API::MatrixWorkspace_sptr input) {
MatrixWorkspace_sptr output = getProperty("OutputWorkspace");
// Check whether input = output to see whether a new workspace is required.
if (input != output) {
// Create new workspace for output from old
output = API::WorkspaceFactory::Instance().create(input);
}
return output;
}
void ChangeBinOffset::execEvent() {
g_log.information("Processing event workspace");
const MatrixWorkspace_const_sptr matrixInputWS =
this->getProperty("InputWorkspace");
EventWorkspace_const_sptr inputWS =
boost::dynamic_pointer_cast<const EventWorkspace>(matrixInputWS);
// generate the output workspace pointer
API::MatrixWorkspace_sptr matrixOutputWS =
this->getProperty("OutputWorkspace");
EventWorkspace_sptr outputWS;
if (matrixOutputWS == matrixInputWS)
outputWS = boost::dynamic_pointer_cast<EventWorkspace>(matrixOutputWS);
else {
// Make a brand new EventWorkspace
outputWS = boost::dynamic_pointer_cast<EventWorkspace>(
API::WorkspaceFactory::Instance().create(
"EventWorkspace", inputWS->getNumberHistograms(), 2, 1));
// Copy geometry over.
API::WorkspaceFactory::Instance().initializeFromParent(inputWS, outputWS,
false);
// You need to copy over the data as well.
outputWS->copyDataFrom((*inputWS));
// Cast to the matrixOutputWS and save it
matrixOutputWS = boost::dynamic_pointer_cast<MatrixWorkspace>(outputWS);
this->setProperty("OutputWorkspace", matrixOutputWS);
}
int64_t numHistograms = static_cast<int64_t>(inputWS->getNumberHistograms());
PARALLEL_FOR1(outputWS)
for (int64_t i = 0; i < numHistograms; ++i) {
PARALLEL_START_INTERUPT_REGION
// Do the offsetting
if ((i >= wi_min) && (i <= wi_max))
outputWS->getEventList(i).addTof(offset);
m_progress->report();
PARALLEL_END_INTERUPT_REGION
}
PARALLEL_CHECK_INTERUPT_REGION
outputWS->clearMRU();
}
} // namespace Algorithm
} // namespace Mantid