19#include "MantidHistogramData/Histogram.h"
29using namespace Kernel;
31using namespace DataObjects;
32using namespace HistogramData;
36 auto wsValidator = std::make_shared<CompositeValidator>();
43 "The workspace containing the sample beam-spreader run");
46 "The workspace containing the direct beam-spreader run");
48 "The workspace containing the sample scattering run");
50 "The workspace containing the direct beam scattering run");
52 "The fitted transmission correction");
54 auto zeroOrMore = std::make_shared<BoundedValidator<int>>();
55 zeroOrMore->setLower(0);
57 declareProperty(
"IncidentBeamMonitor", 2, zeroOrMore,
"The UDET of the incident beam monitor");
59 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
60 mustBePositive->setLower(0.0);
62 declareProperty(
"SpreaderTransmissionValue", 1.0, mustBePositive,
"Transmission coefficient of the beam spreader");
64 "Uncertainty on the transmission coefficient of the beam spreader");
66 declareProperty(
"MinWavelength", 2.2, mustBePositive,
"The minimum wavelength for the fit");
67 declareProperty(
"MaxWavelength", 10.0, mustBePositive,
"The maximum wavelength for the fit");
69 std::vector<std::string> options(2);
70 options[0] =
"Linear";
72 declareProperty(
"FitMethod",
"Log", std::make_shared<StringListValidator>(options),
73 "Whether to fit directly to the transmission curve (Linear) "
74 "or to the log of it (Log)");
86 if (sample_spreaderWS->getInstrument()->getName() != direct_spreaderWS->getInstrument()->getName() ||
87 sample_spreaderWS->getInstrument()->getName() != sample_scatterWS->getInstrument()->getName() ||
88 sample_spreaderWS->getInstrument()->getName() != direct_scatterWS->getInstrument()->getName()) {
89 g_log.
error(
"The input workspaces do not come from the same instrument");
90 throw std::invalid_argument(
"The input workspaces do not come from the same instrument");
96 g_log.
error(
"Input workspaces do not have matching binning");
97 throw std::invalid_argument(
"Input workspaces do not have matching binning");
109 std::vector<size_t> indices = sample_scatterWS->getIndicesFromDetectorIDs(udets);
110 if (indices.size() != 1) {
111 g_log.
error() <<
"Could not find the incident monitor spectra\n";
112 throw std::invalid_argument(
"Could not find the incident monitor spectra\n");
128 std::vector<MatrixWorkspace_sptr> in_ws{sample_scatterWS, direct_scatterWS, sample_spreaderWS, direct_spreaderWS};
130 std::vector<MatrixWorkspace_sptr> out_ws(4);
133 for (
int i = 0; i < 4; i++) {
136 sample_scatter_sum = out_ws[0];
137 direct_scatter_sum = out_ws[1];
138 sample_spreader_sum = out_ws[2];
139 direct_spreader_sum = out_ws[3];
143 spreader_trans->setYUnit(
"");
144 spreader_trans->setDistribution(
true);
145 spreader_trans->mutableX(0)[0] = 0.0;
146 spreader_trans->mutableY(0)[0] =
getProperty(
"SpreaderTransmissionValue");
147 spreader_trans->mutableE(0)[0] =
getProperty(
"SpreaderTransmissionError");
151 sample_spreader_sum / sample_spreader_mon - spreader_trans * sample_scatter_sum / sample_scatter_mon;
154 direct_spreader_sum / direct_spreader_mon - spreader_trans * direct_scatter_sum / direct_scatter_mon;
159 const bool outputRaw =
getProperty(
"OutputUnfittedData");
162 outputWSName +=
"_unfitted";
169 if (transmission->y(0).size() == 1) {
173 const std::string fitMethod =
getProperty(
"FitMethod");
174 logFit = (fitMethod ==
"Log");
176 g_log.
debug(
"Fitting to the logarithm of the transmission");
182 auto &
Y = logTransmission->mutableY(0);
183 auto &E = logTransmission->mutableE(0);
185 for (
size_t i = 0; i <
Y.size(); ++i) {
186 E[i] = std::abs(E[i] /
Y[i]);
187 Y[i] = std::log10(
Y[i]);
188 progress.report(
"Calculate Transmission");
195 g_log.
debug(
"Fitting directly to the data (i.e. linearly)");
210 childAlg->setProperty<
bool>(
"IncludeMonitors",
false);
211 childAlg->executeAsChildAlg();
212 return childAlg->getProperty(
"OutputWorkspace");
222 const size_t index) {
224 if (!WS->spectrumInfo().isMonitor(
index)) {
225 g_log.
information(
"The Incident Beam Monitor UDET provided is not marked as a monitor");
230 childAlg->setProperty<
int>(
"WorkspaceIndex",
static_cast<int>(
index));
231 childAlg->executeAsChildAlg();
232 return childAlg->getProperty(
"OutputWorkspace");
244 const double lambdaMin =
getProperty(
"MinWavelength");
245 const double lambdaMax =
getProperty(
"MaxWavelength");
246 childAlg->setProperty<
double>(
"StartX", lambdaMin);
247 childAlg->setProperty<
double>(
"EndX", lambdaMax);
248 childAlg->executeAsChildAlg();
250 std::string fitStatus = childAlg->getProperty(
"FitStatus");
251 if (fitStatus !=
"success") {
252 g_log.
error(
"Unable to successfully fit the data: " + fitStatus);
253 throw std::runtime_error(
"Unable to successfully fit the data");
261 double b = childAlg->getProperty(
"FitIntercept");
262 double m = childAlg->getProperty(
"FitSlope");
266 auto X = result->points(0);
267 auto &
Y = result->mutableY(0);
268 auto &E = result->mutableE(0);
269 for (
size_t i = 0; i <
Y.size(); ++i) {
270 Y[i] = b * (std::pow(
m,
X[i]));
271 E[i] = std::abs(E[i] *
Y[i]);
#define DECLARE_ALGORITHM(classname)
std::map< DeltaEMode::Type, std::string > index
#define PARALLEL_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
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.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
A validator which provides a TENTATIVE check that a workspace contains common bins in each spectrum.
A validator which checks that a workspace contains histogram data (the default) or point data as requ...
Helper class for reporting progress from algorithms.
A property class for workspaces.
A validator which checks that the unit of the workspace referred to by a WorkspaceProperty is the exp...
void init() override
Initialisation code.
API::MatrixWorkspace_sptr fitToData(const API::MatrixWorkspace_sptr &WS)
Call the Linear fitting algorithm as a child algorithm.
API::MatrixWorkspace_sptr extractSpectrum(const API::MatrixWorkspace_sptr &WS, const size_t index)
Pull out a single spectrum from a 2D workspace.
bool logFit
If true, will take log of transmission curve before fitting.
API::MatrixWorkspace_sptr sumSpectra(const API::MatrixWorkspace_sptr &WS)
Sum the total detector, excluding masked pixels and monitors.
void exec() override
Execution code.
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 information(const std::string &msg)
Logs at information level.
std::shared_ptr< Algorithm > Algorithm_sptr
Typedef for a shared pointer to an Algorithm.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
int32_t detid_t
Typedef for a detector ID.
static bool matchingBins(const MatrixWorkspace &ws1, const MatrixWorkspace &ws2, const bool firstOnly=false)
Checks whether the bins (X values) of two workspace are the same.
@ Input
An input workspace.
@ Output
An output workspace.