21#include "MantidHistogramData/Histogram.h"
37using namespace Kernel;
60 auto wsValidator = std::make_shared<CompositeValidator>();
69 "The input workspace must be a distribution with units of Q");
71 "The name of the output workspace");
74 std::set<std::string> plottype;
76 plottype.insert(it->first);
78 declareProperty(
"TransformType",
"", std::make_shared<StringListValidator>(plottype),
79 "The name of the transformation to be performed on the workspace");
83 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
84 mustBePositive->setLower(0.0);
86 "A constant value to subtract from the data prior to its transformation");
89 "A workspace to subtract from the input workspace prior to its "
91 "Must be compatible with the input (as for the Minus algorithm).");
94 "A set of 10 constants to be used (only) with the 'General' "
101 if (inputWS->getNumberHistograms() > 1) {
102 g_log.
warning(
"This algorithm is intended for use on single-spectrum workspaces.\n"
103 "Only the first spectrum will be transformed.");
117 const size_t length = tmpWS->blocksize();
120 outputWS->setYUnit(
"");
122 outputWS->setPoints(0, tmpWS->points(0));
123 outputWS->setSharedY(0, tmpWS->sharedY(0));
124 outputWS->setSharedE(0, tmpWS->sharedE(0));
127 const double background =
getProperty(
"BackgroundValue");
128 if (background > 0.0)
129 outputWS->mutableY(0) -= background;
133 (this->*f)(outputWS);
137 if (!
m_label->caption().empty())
138 outputWS->getAxis(0)->unit() =
m_label;
152 g_log.
debug() <<
"Subtracting the workspace " << background->getName() <<
" from the input workspace.\n";
153 return ws - background;
165 auto &
X = ws->mutableX(0);
166 auto &
Y = ws->mutableY(0);
167 auto &E = ws->mutableE(0);
169 std::transform(E.cbegin(), E.cend(),
Y.begin(), E.begin(), std::divides<double>());
172 ws->setYUnitLabel(
"Ln(I)");
182 auto &
X = ws->mutableX(0);
183 auto &
Y = ws->mutableY(0);
184 auto &E = ws->mutableE(0);
186 std::transform(E.cbegin(), E.cend(),
Y.begin(), E.begin(), std::divides<double>());
187 std::transform(
Y.cbegin(),
Y.cend(),
X.begin(),
Y.begin(), std::multiplies<double>());
191 ws->setYUnitLabel(
"Ln(I x Q)");
201 auto &
X = ws->mutableX(0);
202 auto &
Y = ws->mutableY(0);
203 auto &E = ws->mutableE(0);
205 std::transform(E.cbegin(), E.cend(),
Y.begin(), E.begin(), std::divides<double>());
207 std::transform(
Y.cbegin(),
Y.cend(),
X.begin(),
Y.begin(), std::multiplies<double>());
210 ws->setYUnitLabel(
"Ln(I x Q^2)");
219 auto &
X = ws->mutableX(0);
220 auto &
Y = ws->mutableY(0);
221 auto &E = ws->mutableE(0);
223 for (
size_t i = 0; i <
Y.size(); ++i) {
226 E[i] *= std::pow(
Y[i], 2);
233 ws->setYUnitLabel(
"1/I");
242 auto &
X = ws->mutableX(0);
243 auto &
Y = ws->mutableY(0);
244 auto &E = ws->mutableE(0);
246 for (
size_t i = 0; i <
Y.size(); ++i) {
248 Y[i] = 1.0 / std::sqrt(
Y[i]);
249 E[i] *= std::pow(
Y[i], 3);
256 ws->setYUnitLabel(
"1/sqrt(I)");
264 auto &
X = ws->mutableX(0);
265 auto &
Y = ws->mutableY(0);
266 auto &E = ws->mutableE(0);
267 std::transform(
Y.cbegin(),
Y.cend(),
X.begin(),
Y.begin(), std::multiplies<double>());
268 std::transform(E.cbegin(), E.cend(),
X.begin(), E.begin(), std::multiplies<double>());
270 ws->setYUnitLabel(
"I x Q");
277 auto &
X = ws->mutableX(0);
278 auto &
Y = ws->mutableY(0);
279 auto &E = ws->mutableE(0);
282 std::transform(
Y.cbegin(),
Y.cend(), Q2.begin(),
Y.begin(), std::multiplies<double>());
283 std::transform(E.cbegin(), E.cend(), Q2.begin(), E.begin(), std::multiplies<double>());
285 ws->setYUnitLabel(
"I x Q^2");
292 auto &
X = ws->mutableX(0);
293 auto &
Y = ws->mutableY(0);
294 auto &E = ws->mutableE(0);
297 std::transform(
Y.cbegin(),
Y.cend(), Q4.begin(),
Y.begin(), std::multiplies<double>());
298 std::transform(E.cbegin(), E.cend(), Q4.begin(), E.begin(), std::multiplies<double>());
300 ws->setYUnitLabel(
"I x Q^4");
309 auto &
X = ws->mutableX(0);
310 auto &
Y = ws->mutableY(0);
311 auto &E = ws->mutableE(0);
314 std::transform(E.cbegin(), E.cend(),
Y.begin(), E.begin(), std::divides<double>());
317 ws->setYUnitLabel(
"Ln(I)");
330 auto &
X = ws->mutableX(0);
331 auto &
Y = ws->mutableY(0);
332 auto &E = ws->mutableE(0);
333 const std::vector<double> C =
getProperty(
"GeneralFunctionConstants");
335 if (C.size() != 10) {
336 std::string mess(
"The General transformation requires 10 values to be provided.");
338 throw std::invalid_argument(mess);
341 for (
size_t i = 0; i <
Y.size(); ++i) {
342 double tmpX = std::pow(
X[i], C[7]) * std::pow(
Y[i], C[8]) * C[9];
344 throw std::range_error(
"Attempt to take log of a zero or negative number.");
345 tmpX = std::pow(
X[i], C[5]) * std::pow(
Y[i], C[6]) * std::log(tmpX);
346 const double tmpY = std::pow(
X[i], C[2]) * std::pow(
Y[i], C[3]) * C[4];
348 throw std::range_error(
"Attempt to take log of a zero or negative number.");
349 const double newY = std::pow(
X[i], C[0]) * std::pow(
Y[i], C[1]) * std::log(tmpY);
351 E[i] *= std::pow(
X[i], C[0]) *
352 (C[1] * std::pow(
Y[i], C[1] - 1) * std::log(tmpY) +
353 ((std::pow(
Y[i], C[1]) * std::pow(
X[i], C[2]) * C[4] * C[3] * std::pow(
Y[i], C[3] - 1)) / tmpY));
358 std::stringstream ylabel;
359 ylabel <<
"Q^" << C[0] <<
" x I^" << C[1] <<
" x Ln( Q^" << C[2] <<
" x I^" << C[3] <<
" x " << C[4] <<
")";
360 ws->setYUnitLabel(ylabel.str());
361 std::stringstream xlabel;
362 xlabel <<
"Q^" << C[5] <<
" x I^" << C[6] <<
" x Ln( Q^" << C[7] <<
" x I^" << C[8] <<
" x " << C[9] <<
")";
363 m_label->setLabel(xlabel.str());
#define DECLARE_ALGORITHM(classname)
Base class from which all concrete algorithm classes should be derived.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
A validator which checks that the X axis of a workspace is increasing from left to right.
A validator which checks that a workspace contains raw counts in its bins.
A property class for workspaces.
A validator which checks that the unit of the workspace referred to by a WorkspaceProperty is the exp...
Support for a property that holds an array of values.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::vector< double > MantidVec
typedef for the data storage used in Mantid matrix workspaces
@ Input
An input workspace.
@ Output
An output workspace.
Functor giving the product of the squares of the arguments.