27 const std::string emode = hostAlgorithm->
getProperty(
"EMode");
30 if (emode ==
"Direct")
32 else if (emode ==
"Indirect")
46 throw std::runtime_error(
"Input workspace contains Ei but its "
47 "property type is not a double.");
50 throw std::invalid_argument(
"Input workspace does not contain an "
51 "EFixed value. Please provide one or run "
84 throw std::runtime_error(
"Cannot find EFixed parameter for component \"" + det.
getName() +
85 "\". This is required in indirect mode. Please check the IDF "
86 "contains these values.");
116 const double maxE)
const {
131 const double ki = std::sqrt(
m_efixed / E_mev_toNeutronWavenumberSq);
132 const double kf = std::sqrt((
m_efixed - deltaE) / E_mev_toNeutronWavenumberSq);
133 return std::sqrt(ki * ki + kf * kf - 2. * ki * kf * std::cos(
twoTheta));
146 throw std::runtime_error(
"indirectQ: det is nullptr.");
149 const double ki = std::sqrt((
efixed + deltaE) / E_mev_toNeutronWavenumberSq);
150 const double kf = std::sqrt(
efixed / E_mev_toNeutronWavenumberSq);
151 return std::sqrt(ki * ki + kf * kf - 2. * ki * kf * std::cos(
twoTheta));
163 const double maxE)
const {
166 throw std::invalid_argument(
"Cannot compute Q binning range: maximum "
167 "energy transfer is greater than the incident "
170 auto minTwoTheta = std::numeric_limits<double>::max();
171 auto maxTwoTheta = std::numeric_limits<double>::lowest();
173 for (
size_t i = 0; i < spectrumInfo.size(); ++i) {
174 if (spectrumInfo.isMasked(i) || spectrumInfo.isMonitor(i)) {
177 const auto twoTheta = spectrumInfo.twoTheta(i);
178 minTwoTheta = std::min(minTwoTheta,
twoTheta);
179 maxTwoTheta = std::max(maxTwoTheta,
twoTheta);
181 if (minTwoTheta == std::numeric_limits<double>::max()) {
182 throw std::runtime_error(
"Could not determine Q binning: workspace does "
183 "not contain usable spectra.");
185 std::array<double, 4>
q;
190 const auto minmaxQ = std::minmax_element(
q.cbegin(),
q.cend());
191 return std::make_pair(*minmaxQ.first, *minmaxQ.second);
205 const double maxE)
const {
207 auto minQ = std::numeric_limits<double>::max();
208 auto maxQ = std::numeric_limits<double>::lowest();
210 for (
size_t i = 0; i < detectorInfo.size(); ++i) {
211 if (detectorInfo.isMasked(i) || detectorInfo.isMonitor(i)) {
214 const auto twoTheta = detectorInfo.twoTheta(i);
215 const auto &det = detectorInfo.detector(i);
218 if (!std::isfinite(Q1) || !std::isfinite(Q2)) {
219 throw std::invalid_argument(
"Cannot compute Q binning range: non-finite "
220 "Q found for detector ID " +
223 const auto minmaxQ = std::minmax(Q1, Q2);
224 minQ = std::min(minQ, minmaxQ.first);
225 maxQ = std::max(maxQ, minmaxQ.second);
227 if (minQ == std::numeric_limits<double>::max()) {
228 throw std::runtime_error(
"Could not determine Q binning: workspace does "
229 "not contain usable spectra.");
231 return std::make_pair(minQ, maxQ);
IPeaksWorkspace_sptr workspace
Base class from which all concrete algorithm classes should be derived.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
const SpectrumInfo & spectrumInfo() const
Return a reference to the SpectrumInfo object.
const Geometry::DetectorInfo & detectorInfo() const
Return a const reference to the DetectorInfo object.
Base MatrixWorkspace Abstract Class.
virtual std::vector< double > getNumberParameter(const std::string &pname, bool recursive=true) const =0
Get a parameter defined as a double.
virtual std::string getName() const =0
Get the IComponent name.
Interface class for detector objects.
The concrete, templated class for properties.
Base class for properties.
A namespace containing physical constants that are required by algorithms and unit routines.
static constexpr double E_mev_toNeutronWavenumberSq
Transformation coefficient to transform neutron energy into neutron wavevector: K-neutron[m^-10] = sq...
std::string to_string(const wide_integer< Bits, Signed > &n)
std::pair< double, double > qBinHintsDirect(const API::MatrixWorkspace &ws, const double minE, const double maxE) const
Return a pair of (minimum Q, maximum Q) for given direct geometry workspace.
double indirectQ(const double deltaE, const double twoTheta, const Geometry::IDetector *det) const
Calculate the Q value for an indirect instrument.
std::pair< double, double > qBinHints(const API::MatrixWorkspace &ws, const double minE, const double maxE) const
Estimate minimum and maximum momentum transfer.
double directQ(const double deltaE, const double twoTheta) const
Calculate the Q value for a direct instrument.
bool m_efixedGiven
EFixed has been provided.
double getEFixed(const Geometry::IDetector &det) const
Get the efixed value for the given detector.
std::pair< double, double > qBinHintsIndirect(const API::MatrixWorkspace &ws, const double minE, const double maxE) const
Return a pair of (minimum Q, maximum Q) for given indirect geometry workspace.
double q(const double deltaE, const double twoTheta, const Geometry::IDetector *det) const
Calculate the Q value.
void initCachedValues(const API::MatrixWorkspace &workspace, API::Algorithm *const hostAlgorithm)
The procedure analyses emode and efixed properties provided to the algorithm and identify the energy ...