Mantid
Loading...
Searching...
No Matches
EQSANSPatchSensitivity.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
12
14
15// Register the algorithm into the AlgorithmFactory
16DECLARE_ALGORITHM(EQSANSPatchSensitivity)
17
18using namespace Kernel;
19using namespace API;
20using namespace Geometry;
21
23 declareProperty(std::make_unique<WorkspaceProperty<>>("Workspace", "", Direction::InOut),
24 "Input sensitivity workspace to be patched");
25 declareProperty(std::make_unique<WorkspaceProperty<>>("PatchWorkspace", "", Direction::Input),
26 "Workspace defining the patch. Masked detectors will be patched.");
27 declareProperty("UseLinearRegression", true,
28 "If true, a linear regression "
29 "will be used instead of "
30 "computing the average");
31 declareProperty("OutputMessage", "", Direction::Output);
32}
33
35 MatrixWorkspace_sptr inputWS = getProperty("Workspace");
36 MatrixWorkspace_sptr patchWS = getProperty("PatchWorkspace");
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]);
40
41 const auto numberOfSpectra = static_cast<int>(inputWS->getNumberHistograms());
42
43 auto &inSpectrumInfo = inputWS->mutableSpectrumInfo();
44 const auto &spectrumInfo = patchWS->spectrumInfo();
45 // Loop over all tubes and patch as necessary
46 for (int i = 0; i < nx_pixels; i++) {
47 std::vector<int> patched_ids;
48 int nUnmasked = 0;
49 double totalUnmasked = 0.0;
50 double errorUnmasked = 0.0;
51
52 double sumXY = 0.0;
53 double sumX = 0.0;
54 double sumX2 = 0.0;
55 double sumY = 0.0;
56
57 progress(0.9 * i / nx_pixels, "Processing patch");
58
59 for (int j = 0; j < ny_pixels; j++) {
60 // EQSANS-specific: get detector ID from pixel coordinates
61 int iDet = ny_pixels * i + j;
62 if (iDet >= numberOfSpectra) {
63 g_log.notice() << "Got an invalid detector ID " << iDet << '\n';
64 continue;
65 }
66
67 // If this detector is a monitor, skip to the next one
68 if (spectrumInfo.isMonitor(iDet))
69 continue;
70
71 const MantidVec &YValues = inputWS->readY(iDet);
72 const MantidVec &YErrors = inputWS->readE(iDet);
73
74 // If this detector is masked, skip to the next one
75 if (spectrumInfo.isMasked(iDet))
76 patched_ids.emplace_back(iDet);
77 else {
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];
82 nUnmasked++;
83
84 sumXY += yPosition * YValues[0];
85 sumX += yPosition;
86 sumX2 += yPosition * yPosition;
87 sumY += YValues[0];
88 }
89 }
90 }
91
92 if (nUnmasked > 0 && errorUnmasked > 0) {
93 sumXY /= nUnmasked;
94 sumX /= nUnmasked;
95 sumX2 /= nUnmasked;
96 sumY /= nUnmasked;
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;
101
102 // Apply patch
103 progress(0.91, "Applying patch");
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";
107 continue;
108 }
109 MantidVec &YValues = inputWS->dataY(patched_id);
110 MantidVec &YErrors = inputWS->dataE(patched_id);
111 if (useRegression) {
112 YValues[0] = alpha + beta * inSpectrumInfo.position(patched_id).Y();
113 YErrors[0] = error;
114 } else {
115 YValues[0] = average;
116 YErrors[0] = error;
117 }
118 inSpectrumInfo.setMasked(patched_id, false);
119 }
120 }
121 }
122
123 // Call Calculate efficiency to renormalize
124 progress(0.91, "Renormalizing");
125 auto effAlg = createChildAlgorithm("CalculateEfficiency", 0.91, 1, true, 1);
126 effAlg->setProperty("InputWorkspace", inputWS);
127 effAlg->setProperty("OutputWorkspace", inputWS);
128 effAlg->execute();
129 inputWS = effAlg->getProperty("OutputWorkspace");
130 setProperty("Workspace", inputWS);
131
132 setProperty("OutputMessage", "Applied wavelength-dependent sensitivity correction");
133}
134
135} // namespace Mantid::WorkflowAlgorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
double error
Definition: IndexPeaks.cpp:133
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Definition: Algorithm.cpp:1913
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
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.
Definition: Algorithm.cpp:842
Kernel::Logger & g_log
Definition: Algorithm.h:451
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
Definition: Algorithm.cpp:231
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.
Definition: Logger.cpp:95
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
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
Definition: cow_ptr.h:172
@ InOut
Both an input & output workspace.
Definition: Property.h:55
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54