Mantid
Loading...
Searching...
No Matches
Qhelper.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 +
7#include <utility>
8
12
13namespace Mantid::Algorithms {
14
15using namespace Kernel;
16using namespace API;
17using namespace Geometry;
18
30 const API::MatrixWorkspace_const_sptr &detectAdj,
31 const API::MatrixWorkspace_const_sptr &qResolution) {
32
33 // Check the compatibility of dataWS, binAdj and detectAdj
34 examineInput(dataWS, binAdj, detectAdj);
35
36 // Check the compatibility of the QResolution workspace
37 if (qResolution) {
38 // We require the same number of histograms
39 if (qResolution->getNumberHistograms() != dataWS->getNumberHistograms()) {
40 throw std::invalid_argument("The QResolution should have one spectrum"
41 "per spectrum of the input workspace");
42 }
43
44 // We require the same binning for the input workspace and the q resolution
45 // workspace
46 auto reqX = dataWS->x(0).cbegin();
47 auto qResX = qResolution->x(0).cbegin();
48 for (; reqX != dataWS->x(0).end(); ++reqX, ++qResX) {
49 if (*reqX != *qResX) {
50 throw std::invalid_argument("The QResolution needs to have the same binning as"
51 "as the input workspace.");
52 }
53 }
54 }
55}
56
67 const API::MatrixWorkspace_const_sptr &detectAdj) {
68 if (dataWS->getNumberHistograms() < 1) {
69 throw std::invalid_argument("Empty data workspace passed, can not continue");
70 }
71
72 // it is not an error for these workspaces not to exist
73 if (binAdj) {
74 if (binAdj->getNumberHistograms() != 1) {
75 throw std::invalid_argument("The WavelengthAdj workspace must have one spectrum");
76 }
77 if (binAdj->y(0).size() != dataWS->y(0).size()) {
78 throw std::invalid_argument("The WavelengthAdj workspace's bins must "
79 "match those of the detector bank workspace");
80 }
81 auto reqX = dataWS->x(0).cbegin();
82 auto testX = binAdj->x(0).cbegin();
83 for (; reqX != dataWS->x(0).cend(); ++reqX, ++testX) {
84 if (*reqX != *testX) {
85 throw std::invalid_argument("The WavelengthAdj workspace must have "
86 "matching bins with the detector bank "
87 "workspace");
88 }
89 }
90 if (binAdj->isDistribution() != dataWS->isDistribution()) {
91 throw std::invalid_argument("The distrbution/raw counts status of the "
92 "wavelengthAdj and DetBankWorkspace must be "
93 "the same, use ConvertToDistribution");
94 }
95 } else if (!dataWS->isDistribution()) {
96 // throw std::invalid_argument("The data workspace must be a distrbution if
97 // there is no Wavelength dependent adjustment");
98 }
99
100 // Perform tests on detectAdj
101
102 if (detectAdj) {
103 if (detectAdj->blocksize() != 1) {
104 throw std::invalid_argument("The PixelAdj workspace must point to a "
105 "workspace with single bin spectra, as only "
106 "the first bin is used");
107 }
108 if (detectAdj->getNumberHistograms() != dataWS->getNumberHistograms()) {
109 throw std::invalid_argument("The PixelAdj workspace must have one "
110 "spectrum for each spectrum in the detector "
111 "bank workspace");
112 }
113
114 // test that when detector adjustment value less than or equal to zero that
115 // the corresponding detector
116 // in the workspace is masked
117
118 size_t num_histograms = dataWS->getNumberHistograms();
119 const auto &spectrumInfo = dataWS->spectrumInfo();
120 for (size_t i = 0; i < num_histograms; i++) {
121 auto adj = static_cast<double>(detectAdj->y(i)[0]);
122 if (adj <= 0.0) {
123 bool det_is_masked;
124 if (!spectrumInfo.hasDetectors(i)) {
125 // just ignore. There are times, when the detector is not masked
126 // because it does not exist at all.
127 det_is_masked = true;
128 } else {
129 det_is_masked = spectrumInfo.isMasked(i);
130 }
131 if (!det_is_masked) {
132 throw std::invalid_argument("Every detector with non-positive PixelAdj value must be masked");
133 }
134 }
135 }
136 }
137}
138
151 const double RCut, const double WCut, const size_t wsInd) const {
152 double l_WCutOver = 0.0;
153 double l_RCut = 0.0; // locally we store RCut in units of meters
154 if (RCut > 0 && WCut > 0) {
155 l_RCut = RCut / 1000.0; // convert to meters
156 // l_RCut = RCut; // convert to meters
157 l_WCutOver = WCut / l_RCut;
158 }
159
160 if (!(l_RCut > 0)) {
161 return 0;
162 }
163 // get the distance of between this detector and the origin, which should be
164 // the along the beam center
165 const V3D posOnBank = spectrumInfo.position(wsInd);
166 double R = (posOnBank.X() * posOnBank.X()) + (posOnBank.Y() * posOnBank.Y());
167 R = std::sqrt(R);
168
169 const double WMin = l_WCutOver * (l_RCut - R);
170 const auto &Xs = dataWS->x(wsInd);
171 return std::lower_bound(Xs.begin(), Xs.end(), WMin) - Xs.begin();
172}
173
184 const API::MatrixWorkspace_sptr &sumOfNormFactors) {
185 std::string baseName = alg->getPropertyValue("OutputWorkspace");
186
187 alg->declareProperty(
189 "The name of the MatrixWorkspace to store sum of counts");
190 alg->setPropertyValue("SumOfCounts", baseName + "_sumOfCounts");
191
192 alg->setProperty("SumOfCounts", sumOfCounts);
193
194 alg->declareProperty(
195 std::make_unique<API::WorkspaceProperty<API::MatrixWorkspace>>("sumOfNormFactors", "", Kernel::Direction::Output),
196 "The name of the MatrixWorkspace to store sum of normalising factors");
197 alg->setPropertyValue("sumOfNormFactors", baseName + "_sumOfNormFactors");
198
199 alg->setProperty("sumOfNormFactors", sumOfNormFactors);
200}
201
202} // namespace Mantid::Algorithms
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:85
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
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
Definition: Algorithm.cpp:2026
void setPropertyValue(const std::string &name, const std::string &value) override
Set the value of a property by string N.B.
Definition: Algorithm.cpp:1975
API::SpectrumInfo is an intermediate step towards a SpectrumInfo that is part of Instrument-2....
Definition: SpectrumInfo.h:53
Kernel::V3D position(const size_t index) const
Returns the position of the spectrum with given index.
A property class for workspaces.
size_t waveLengthCutOff(const API::MatrixWorkspace_const_sptr &dataWS, const API::SpectrumInfo &spectrumInfo, const double RCut, const double WCut, const size_t wsInd) const
Finds the first index number of the first wavelength bin that should included based on the the calcul...
Definition: Qhelper.cpp:150
void outputParts(API::Algorithm *alg, const API::MatrixWorkspace_sptr &sumOfCounts, const API::MatrixWorkspace_sptr &sumOfNormFactors)
This method performs the common work between Qxy and Q1D2 if algorihtm parameter OutputParts=True.
Definition: Qhelper.cpp:183
void examineInput(const API::MatrixWorkspace_const_sptr &dataWS, const API::MatrixWorkspace_const_sptr &binAdj, const API::MatrixWorkspace_const_sptr &detectAdj, const API::MatrixWorkspace_const_sptr &qResolution)
Checks if workspaces input to Q1D or Qxy are reasonable.
Definition: Qhelper.cpp:29
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
Class for 3D vectors.
Definition: V3D.h:34
constexpr double X() const noexcept
Get x.
Definition: V3D.h:232
constexpr double Y() const noexcept
Get y.
Definition: V3D.h:233
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
@ Output
An output workspace.
Definition: Property.h:54