14#include "MantidHistogramData/Histogram.h"
15#include "MantidHistogramData/HistogramBuilder.h"
27using namespace Kernel;
35 "Workspace must have one axis with units of Q");
37 "Output workspace name.");
39 declareProperty(
"IonName",
"Cu2", std::make_shared<StringListValidator>(keys),
40 "The name of the ion: an element symbol with a number "
41 "indicating the valence, e.g. Fe2 for Fe2+ / Fe(II)");
44 "If specified the algorithm will create a 1D workspace with "
45 "the form factor vs Q with a name given by this field.");
50 const std::string ionNameStr =
getProperty(
"IonName");
51 const std::string ffwsStr =
getProperty(
"FormFactorWorkspace");
52 const bool isHist = inputWS->isHistogramData();
53 const int64_t numHists = inputWS->getNumberHistograms();
54 const int64_t specSize = inputWS->blocksize();
57 int64_t numAxes = inputWS->axes();
59 std::vector<double> Qvals;
61 for (iax = 0; iax < numAxes; iax++) {
62 Axis *QAxis = inputWS->getAxis(iax);
63 std::string unitID = QAxis->
unit()->unitID();
64 if (unitID ==
"MomentumTransfer") {
67 if (isHist || iax > 0) {
68 int64_t nQ = QAxis->
length() - 1;
69 for (int64_t iQ = 0; iQ < nQ; iQ++) {
70 Qvals.emplace_back(0.5 *
71 (QAxis->
getValue(
static_cast<size_t>(iQ)) + QAxis->
getValue(
static_cast<size_t>(iQ + 1))));
74 int64_t nQ = QAxis->
length();
75 for (int64_t iQ = 0; iQ < nQ; iQ++) {
76 Qvals.emplace_back(QAxis->
getValue(
static_cast<size_t>(iQ)));
83 throw std::runtime_error(
"Expected a MatrixWorkspace with a "
84 "MomentumTransfer axis. Cannot apply form factor "
85 "without knowing Q.");
91 std::vector<double> FF;
92 FF.reserve(Qvals.size());
94 std::transform(Qvals.begin(), Qvals.end(), std::back_inserter(FF),
95 [&ion](
double qval) { return ion.analyticalFormFactor(qval * qval); });
97 if (!ffwsStr.empty()) {
98 HistogramBuilder builder;
99 builder.setX(Qvals.size());
100 builder.setY(FF.size());
102 ffws->mutableX(0).assign(Qvals.begin(), Qvals.end());
103 ffws->mutableY(0).assign(FF.begin(), FF.end());
105 ffws->setYUnitLabel(
"F(Q)");
111 for (int64_t i = 0; i < numHists; i++) {
112 auto &
Y = outputWS->mutableY(i);
113 auto &E = outputWS->mutableE(i);
114 for (int64_t j = 0; j < specSize; j++) {
115 double ff = (iax == 0) ? FF[j] : FF[i];
#define DECLARE_ALGORITHM(classname)
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.
Class to represent the axis of a workspace.
virtual std::size_t length() const =0
Get the length of the axis.
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.
A property class for workspaces.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
A namespace containing physical constants that are required by algorithms and unit routines.
MANTID_KERNEL_DLL std::vector< std::string > getMagneticIonList()
Returns a list of all ions.
MANTID_KERNEL_DLL const MagneticIon & getMagneticIon(const std::string &symbol, const uint16_t charge)
Returns the magnetic ion for the given symbol and charge.
@ Input
An input workspace.
@ Output
An output workspace.
Struture to hold information about magnetic form factor for 3d, 4d, rare earth, and actinide atoms an...