28 const std::string emode = hostAlgorithm->
getProperty(
"EMode");
31 if (emode ==
"Direct")
33 else if (emode ==
"Indirect")
47 throw std::runtime_error(
"Input workspace contains Ei but its "
48 "property type is not a double.");
51 throw std::invalid_argument(
"Input workspace does not contain an "
52 "EFixed value. Please provide one or run "
85 throw std::runtime_error(
"Cannot find EFixed parameter for component \"" + det.
getName() +
86 "\". This is required in indirect mode. Please check the IDF "
87 "contains these values.");
106 const std::vector<double> param = componentInfo.
getNumberParameter(componentIndex,
"EFixed");
108 throw std::runtime_error(
"Cannot find EFixed parameter for component \"" + componentInfo.
name(componentIndex) +
109 "\". This is required in indirect mode. Please check the IDF "
110 "contains these values.");
152 const double maxE)
const {
167 const double ki = std::sqrt(
m_efixed / E_mev_toNeutronWavenumberSq);
168 const double kf = std::sqrt((
m_efixed - deltaE) / E_mev_toNeutronWavenumberSq);
169 return std::sqrt(ki * ki + kf * kf - 2. * ki * kf * std::cos(
twoTheta));
181 throw std::runtime_error(
"indirectQ: det is nullptr.");
195 const double ki = std::sqrt((
efixed + deltaE) / E_mev_toNeutronWavenumberSq);
196 const double kf = std::sqrt(
efixed / E_mev_toNeutronWavenumberSq);
197 return std::sqrt(ki * ki + kf * kf - 2. * ki * kf * std::cos(
twoTheta));
209 const double maxE)
const {
212 throw std::invalid_argument(
"Cannot compute Q binning range: maximum "
213 "energy transfer is greater than the incident "
216 auto minTwoTheta = std::numeric_limits<double>::max();
217 auto maxTwoTheta = std::numeric_limits<double>::lowest();
219 for (
size_t i = 0; i < spectrumInfo.size(); ++i) {
220 if (spectrumInfo.isMasked(i) || spectrumInfo.isMonitor(i)) {
224 minTwoTheta = std::min(minTwoTheta,
twoTheta);
225 maxTwoTheta = std::max(maxTwoTheta,
twoTheta);
227 if (minTwoTheta == std::numeric_limits<double>::max()) {
228 throw std::runtime_error(
"Could not determine Q binning: workspace does "
229 "not contain usable spectra.");
231 std::array<double, 4> qArr;
232 qArr[0] =
directQ(minE, minTwoTheta);
233 qArr[1] =
directQ(minE, maxTwoTheta);
234 qArr[2] =
directQ(maxE, minTwoTheta);
235 qArr[3] =
directQ(maxE, maxTwoTheta);
236 const auto minmaxQ = std::minmax_element(qArr.cbegin(), qArr.cend());
237 return std::make_pair(*minmaxQ.first, *minmaxQ.second);
251 const double maxE)
const {
253 auto minQ = std::numeric_limits<double>::max();
254 auto maxQ = std::numeric_limits<double>::lowest();
257 for (
size_t i = 0; i < detectorInfo.size(); ++i) {
258 if (detectorInfo.isMasked(i) || detectorInfo.isMonitor(i)) {
261 const auto twoTheta = detectorInfo.twoTheta(i);
265 if (!std::isfinite(Q1) || !std::isfinite(Q2)) {
266 throw std::invalid_argument(
"Cannot compute Q binning range: non-finite "
267 "Q found for detector ID " +
270 const auto minmaxQ = std::minmax(Q1, Q2);
271 minQ = std::min(minQ, minmaxQ.first);
272 maxQ = std::max(maxQ, minmaxQ.second);
274 if (minQ == std::numeric_limits<double>::max()) {
275 throw std::runtime_error(
"Could not determine Q binning: workspace does "
276 "not contain usable spectra.");
278 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.
const Geometry::ComponentInfo & componentInfo() const
Base MatrixWorkspace Abstract Class.
double twoTheta(const size_t index) const
Returns the scattering angle 2 theta in radians (angle w.r.t.
ComponentInfo : Provides a component centric view on to the instrument.
std::vector< double > getNumberParameter(const size_t componentIndex, const std::string &name, bool recursive=true) const
const std::string & name(const size_t componentIndex) const
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.
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 ...
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.
static double indirectQFromEFixed(const double deltaE, const double twoTheta, const double efixed)
Calculate the Q value for an indirect instrument.
double q(const double deltaE, const double twoTheta, const Geometry::IDetector *det) const
Calculate the Q value.