15#include "boost/lexical_cast.hpp"
25bool checkForDouble(
const std::string &val) {
26 auto isDouble =
false;
28 boost::lexical_cast<double>(val);
30 }
catch (boost::bad_lexical_cast
const &) {
38using namespace Kernel;
49 const double defaultLColim = 4.0;
50 auto collimationLengthID =
"collimation-length-correction";
52 if (!
workspace->getInstrument()->hasParameter(collimationLengthID)) {
53 g_log.
error(
"Error in SANSCollimtionLengthEstimator: The instrument "
54 "parameter file does not contain a collimation length "
56 "a default of 4 is provided. Please update the instrument "
62 const V3D samplePos =
workspace->getInstrument()->getSample()->getPos();
63 const V3D sourcePos =
workspace->getInstrument()->getSource()->getPos();
64 const V3D SSD = samplePos - sourcePos;
65 const double L1 = SSD.
norm();
67 auto collimationLengthCorrection =
workspace->getInstrument()->getNumberParameter(collimationLengthID);
69 if (
workspace->getInstrument()->hasParameter(
"special-default-collimation-length-method")) {
70 auto specialCollimationMethod =
71 workspace->getInstrument()->getStringParameter(
"special-default-collimation-length-method");
72 if (specialCollimationMethod[0] ==
"guide") {
75 }
catch (std::invalid_argument &ex) {
77 g_log.
notice() <<
"SANSCollimationLengthEstimator: Not using any guides";
78 return L1 - collimationLengthCorrection[0];
81 throw std::invalid_argument(
"Error in SANSCollimationLengthEstimator: "
82 "Unknown special collimation method.");
85 return L1 - collimationLengthCorrection[0];
101 const double collimationLengthCorrection)
const {
102 auto lCollim = L1 - collimationLengthCorrection;
105 if (!inOutWS->getInstrument()->hasParameter(
"guide-cutoff")) {
106 throw std::invalid_argument(
"TOFSANSResolutionByPixel: Could not get a "
107 "GuideCutoff from the instrument");
111 if (!inOutWS->getInstrument()->hasParameter(
"number-of-guides")) {
112 throw std::invalid_argument(
"TOFSANSResolutionByPixel: Could not get the number of guides.");
116 if (!inOutWS->getInstrument()->hasParameter(
"guide-collimation-length-increment")) {
117 throw std::invalid_argument(
"TOFSANSResolutionByPixel: Could not find a guide increment.");
120 auto numberOfGuides =
static_cast<unsigned int>(inOutWS->getInstrument()->getNumberParameter(
"number-of-guides")[0]);
121 auto guideIncrement = inOutWS->getInstrument()->getNumberParameter(
"guide-collimation-length-increment")[0];
127 std::vector<double> guideValues;
128 for (
unsigned int i = 1; i <= numberOfGuides; i++) {
130 if (inOutWS->run().hasProperty(guideName)) {
131 auto guideValue =
getGuideValue(inOutWS->run().getProperty(guideName));
132 guideValues.emplace_back(guideValue);
134 throw std::invalid_argument(
"TOFSANSResolutionByPixel: Mismatch between "
135 "specified number of Guides and actual "
140 auto guideCutoff = inOutWS->getInstrument()->getNumberParameter(
"guide-cutoff")[0];
151 unsigned int largerSmallerCounter = 0;
152 for (
auto it = guideValues.rbegin(); it != guideValues.rend(); ++it) {
153 bool guideIsLarger = largerSmallerCounter % 2 == 0;
154 if (guideIsLarger && (*it > guideCutoff)) {
155 lCollim += guideIncrement;
156 }
else if (!guideIsLarger && (*it < guideCutoff)) {
157 lCollim += guideIncrement;
161 largerSmallerCounter++;
173 return timeSeriesProperty->firstValue();
175 auto val = doubleProperty->value();
176 if (checkForDouble(val)) {
177 g_log.
warning(
"SANSCollimationLengthEstimator: The Guide was not "
178 "recoginized as a TimeSeriesProperty, but rather as a "
180 return boost::lexical_cast<double, std::string>(val);
183 throw std::invalid_argument(
"TOFSANSResolutionByPixel: Unknown type for "
184 "Guides. Currently only Numeric and TimeSeries "
IPeaksWorkspace_sptr workspace
double getGuideValue(Mantid::Kernel::Property *prop) const
Extracts the value of the guide.
double getCollimationLengthWithGuides(const Mantid::API::MatrixWorkspace_sptr &inOutWS, const double L1, const double collimationLengthCorrection) const
This extraction strategy gets applied when guides are used to calculate the collimation length.
double provideCollimationLength(const Mantid::API::MatrixWorkspace_sptr &workspace)
Provide the collimation length which is associated with the instrument.
The Logger class is in charge of the publishing messages from the framework through various channels.
void notice(const std::string &msg)
Logs at notice level.
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
The concrete, templated class for properties.
Base class for properties.
A specialised Property class for holding a series of time-value pairs.
double norm() const noexcept
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::string to_string(const wide_integer< Bits, Signed > &n)