22using namespace Kernel;
39 "Name of the input workspace");
41 "Name of the output workspace");
43 std::vector<std::string> axisOptions;
44 axisOptions.emplace_back(
"X");
45 axisOptions.emplace_back(
"Y");
46 declareProperty(
"Axis",
"X", std::make_shared<StringListValidator>(axisOptions),
"The axis to modify");
49 "The formula to use to convert the values, x "
50 "or y may be used to refer to the axis "
51 "values. l1, l2, twotheta and signedtwotheta"
52 "may be used to provide values from the "
53 "instrument geometry.");
54 declareProperty(
"AxisTitle",
"",
"The label of he new axis. If not set then the title will not change.");
55 declareProperty(
"AxisUnits",
"",
"The units of the new axis. If not set then the unit will not change");
71 if (outputWs != inputWs) {
73 duplicate->initialize();
74 duplicate->setProperty<
Workspace_sptr>(
"InputWorkspace", std::dynamic_pointer_cast<Workspace>(inputWs));
77 outputWs = std::dynamic_pointer_cast<MatrixWorkspace>(temp);
83 Axis *axisPtr = outputWs->getAxis(0);
84 Axis *otherAxisPtr = outputWs->getAxis(1);
86 std::swap(axisPtr, otherAxisPtr);
90 throw std::invalid_argument(
"This algorithm only operates on numeric axes");
93 bool isRaggedBins =
false;
94 bool isRefAxis =
false;
95 auto *refAxisPtr =
dynamic_cast<RefAxis *
>(axisPtr);
96 if (refAxisPtr !=
nullptr) {
97 isRaggedBins = !outputWs->isCommonBins();
103 auto *spectrumAxisPtr =
dynamic_cast<SpectraAxis *
>(otherAxisPtr);
104 std::vector<Variable_ptr> variables;
105 variables.reserve(8);
107 variables.emplace_back(std::make_shared<Variable>(
"x",
false));
108 variables.emplace_back(std::make_shared<Variable>(
"X",
false));
109 variables.emplace_back(std::make_shared<Variable>(
"y",
false));
110 variables.emplace_back(std::make_shared<Variable>(
"Y",
false));
112 variables.emplace_back(std::make_shared<Variable>(
"twotheta",
true));
113 variables.emplace_back(std::make_shared<Variable>(
"signedtwotheta",
true));
114 variables.emplace_back(std::make_shared<Variable>(
"l1",
true));
115 variables.emplace_back(std::make_shared<Variable>(
"l2",
true));
117 bool isGeometryRequired =
false;
118 for (
auto variablesIter = variables.begin(); variablesIter != variables.end();) {
119 if (formula.find((*variablesIter)->name) != std::string::npos) {
120 if ((*variablesIter)->isGeometric) {
121 if (!spectrumAxisPtr) {
122 throw std::invalid_argument(
"To use geometry values in the equation, "
123 "the axis not being converted must be a "
126 isGeometryRequired =
true;
131 variablesIter = variables.erase(variablesIter);
139 for (
const auto &variable : variables) {
140 p.DefineVar(variable->name, &(variable->value));
143 p.DefineConst(
"pi", M_PI);
150 }
catch (mu::Parser::exception_type &e) {
151 std::stringstream ss;
152 ss <<
"Cannot process the formula"
153 <<
". Muparser error message is: " << e.GetMsg();
154 throw std::invalid_argument(ss.str());
157 if ((isRaggedBins) || (isGeometryRequired)) {
159 size_t numberOfSpectra_i = outputWs->getNumberHistograms();
160 auto &spectrumInfo = outputWs->mutableSpectrumInfo();
162 size_t failedDetectorCount = 0;
163 Progress prog(
this, 0.6, 1.0, numberOfSpectra_i);
164 for (
size_t i = 0; i < numberOfSpectra_i; ++i) {
169 }
catch (std::runtime_error &)
174 outputWs->getSpectrum(i).clearData();
175 spectrumInfo.setMasked(i,
true);
176 failedDetectorCount++;
180 if (failedDetectorCount != 0) {
181 g_log.
information() <<
"Unable to calculate sample-detector distance for " << failedDetectorCount
182 <<
" spectra. Masking spectrum.\n";
192 auto numberOfSpectra_i =
static_cast<int64_t
>(outputWs->getNumberHistograms());
193 auto xVals = outputWs->refX(0);
194 Progress prog(
this, 0.6, 1.0, numberOfSpectra_i);
196 for (int64_t j = 1; j < numberOfSpectra_i; ++j) {
198 outputWs->setX(j, xVals);
205 size_t axisLength = axisPtr->
length();
206 for (
size_t i = 0; i < axisLength; ++i) {
214 size_t midSpectra = outputWs->getNumberHistograms() / 2;
215 if (!outputWs->dataX(0).empty() && (outputWs->dataX(0).front() > outputWs->dataX(0).back() ||
216 outputWs->dataX(midSpectra).front() > outputWs->dataX(midSpectra).back())) {
217 g_log.
information(
"Reversing data within the workspace to keep the axes in "
218 "increasing order.");
223 if ((!axisUnits.empty()) || (!axisTitle.empty())) {
227 if (axisTitle.empty()) {
228 axisTitle = axisPtr->
unit()->caption();
230 if (axisUnits.empty()) {
231 axisUnits = axisPtr->
unit()->label();
233 axisPtr->
unit() = std::make_shared<Units::Label>(axisTitle, axisUnits);
239 for (
const auto &variable : variables) {
240 if (!variable->isGeometric) {
241 variable->value =
value;
247 MantidVec::iterator iter;
248 for (iter = vec.begin(); iter != vec.end(); ++iter) {
255 const std::vector<Variable_ptr> &variables) {
256 for (
const auto &variable : variables) {
257 if (variable->isGeometric) {
258 if (variable->name ==
"twotheta") {
260 }
else if (variable->name ==
"signedtwotheta") {
262 }
else if (variable->name ==
"l1") {
263 variable->value = specInfo.
l1();
264 }
else if (variable->name ==
"l2") {
265 variable->value = specInfo.
l2(
index);
275 }
catch (mu::Parser::exception_type &e) {
276 std::stringstream ss;
277 ss <<
"Failed while processing axis values"
278 <<
". Muparser error message is: " << e.GetMsg();
279 throw std::invalid_argument(ss.str());
#define DECLARE_ALGORITHM(classname)
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
#define PARALLEL_START_INTERRUPT_REGION
Begins a block to skip processing is the algorithm has been interupted Note the end of the block if n...
#define PARALLEL_END_INTERRUPT_REGION
Ends a block to skip processing is the algorithm has been interupted Note the start of the block if n...
#define PARALLEL_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
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.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
Class to represent the axis of a workspace.
virtual std::size_t length() const =0
Get the length of the axis.
virtual void setValue(const std::size_t &index, const double &value)=0
Sets the value at the specified index.
virtual bool isNumeric() const
Returns true if the axis is numeric.
const std::shared_ptr< Kernel::Unit > & unit() const
The unit for this axis.
double getValue(const std::size_t &index, const std::size_t &verticalIndex=0) const
Gets the value at the specified index.
Helper class for reporting progress from algorithms.
A class to represent the axis of a 2D (or more) workspace where the value at a given point on the axi...
Class to represent the spectra axis of a workspace.
API::SpectrumInfo is an intermediate step towards a SpectrumInfo that is part of Instrument-2....
double signedTwoTheta(const size_t index) const
Returns the signed scattering angle 2 theta in radians (angle w.r.t.
double twoTheta(const size_t index) const
Returns the scattering angle 2 theta in radians (angle w.r.t.
double l2(const size_t index) const
Returns L2 (distance from sample to spectrum).
double l1() const
Returns L1 (distance from source to sample).
A property class for workspaces.
void reverse(const API::MatrixWorkspace_sptr &WS)
Reverses the workspace if X values are in descending order.
Exception for when an item is not found in a collection.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void information(const std::string &msg)
Logs at information level.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::enable_if< std::is_pointer< Arg >::value, bool >::type threadSafe(Arg workspace)
Thread-safety check Checks the workspace to ensure it is suitable for multithreaded access.
static constexpr double NeutronMassAMU
Mass of the neutron in AMU.
static constexpr double NeutronMass
Mass of the neutron in kg.
static constexpr double h
Planck constant in J*s.
static constexpr double h_bar
Planck constant in J*s, divided by 2 PI.
static constexpr double g
Standard acceleration due to gravity.
std::vector< double > MantidVec
typedef for the data storage used in Mantid matrix workspaces
@ Input
An input workspace.
@ Output
An output workspace.