18using namespace Kernel;
20using namespace Geometry;
24 "Input sensitivity workspace to be patched");
26 "Workspace defining the patch. Masked detectors will be patched.");
28 "If true, a linear regression "
29 "will be used instead of "
30 "computing the average");
37 bool useRegression =
getProperty(
"UseLinearRegression");
38 const int nx_pixels =
static_cast<int>(inputWS->getInstrument()->getNumberParameter(
"number-of-x-pixels")[0]);
39 const int ny_pixels =
static_cast<int>(inputWS->getInstrument()->getNumberParameter(
"number-of-y-pixels")[0]);
41 const auto numberOfSpectra =
static_cast<int>(inputWS->getNumberHistograms());
43 auto &inSpectrumInfo = inputWS->mutableSpectrumInfo();
44 const auto &spectrumInfo = patchWS->spectrumInfo();
46 for (
int i = 0; i < nx_pixels; i++) {
47 std::vector<int> patched_ids;
49 double totalUnmasked = 0.0;
50 double errorUnmasked = 0.0;
57 progress(0.9 * i / nx_pixels,
"Processing patch");
59 for (
int j = 0; j < ny_pixels; j++) {
61 int iDet = ny_pixels * i + j;
62 if (iDet >= numberOfSpectra) {
63 g_log.
notice() <<
"Got an invalid detector ID " << iDet <<
'\n';
68 if (spectrumInfo.isMonitor(iDet))
71 const MantidVec &YValues = inputWS->readY(iDet);
72 const MantidVec &YErrors = inputWS->readE(iDet);
75 if (spectrumInfo.isMasked(iDet))
76 patched_ids.emplace_back(iDet);
78 if (!inSpectrumInfo.isMasked(iDet)) {
79 double yPosition = spectrumInfo.position(iDet).Y();
80 totalUnmasked += YErrors[0] * YErrors[0] * YValues[0];
81 errorUnmasked += YErrors[0] * YErrors[0];
84 sumXY += yPosition * YValues[0];
86 sumX2 += yPosition * yPosition;
92 if (nUnmasked > 0 && errorUnmasked > 0) {
97 double beta = (sumXY - sumX * sumY) / (sumX2 - sumX * sumX);
98 double alpha = sumY - beta * sumX;
99 double error = sqrt(errorUnmasked) / nUnmasked;
100 double average = totalUnmasked / errorUnmasked;
104 for (
auto patched_id : patched_ids) {
105 if (!inSpectrumInfo.hasDetectors(patched_id)) {
106 g_log.
warning() <<
"Spectrum " << patched_id <<
" has no detector, skipping (not clearing mask)\n";
109 MantidVec &YValues = inputWS->dataY(patched_id);
110 MantidVec &YErrors = inputWS->dataE(patched_id);
112 YValues[0] = alpha + beta * inSpectrumInfo.position(patched_id).Y();
115 YValues[0] = average;
118 inSpectrumInfo.setMasked(patched_id,
false);
126 effAlg->setProperty(
"InputWorkspace", inputWS);
127 effAlg->setProperty(
"OutputWorkspace", inputWS);
129 inputWS = effAlg->getProperty(
"OutputWorkspace");
132 setProperty(
"OutputMessage",
"Applied wavelength-dependent sensitivity correction");
#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.
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 property class for workspaces.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void notice(const std::string &msg)
Logs at notice level.
void warning(const std::string &msg)
Logs at warning level.
void init() override
Initialisation code.
void exec() override
Execution code.
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
@ InOut
Both an input & output workspace.
@ Input
An input workspace.
@ Output
An output workspace.