23#include "MantidTypes/SpectrumDefinition.h"
39const double MICROSEC_TO_SEC = 1.0E-6;
43const double WAVELENGTH_MAX = 1000.;
51 return "Estimate the resolution of each detector pixel for a powder "
61 "Name of the workspace to have detector resolution calculated");
64 "Workspace containing the divergence");
66 "Name of the output workspace containing delta(d)/d of each "
69 auto positiveDeltaTOF = std::make_shared<BoundedValidator<double>>();
70 positiveDeltaTOF->setLower(0.);
71 positiveDeltaTOF->setLowerExclusive(
true);
72 declareProperty(
"DeltaTOF", 0., positiveDeltaTOF,
"DeltaT as the resolution of TOF with unit microsecond");
74 auto positiveWavelength = std::make_shared<BoundedValidator<double>>();
75 positiveWavelength->setLower(0.);
76 positiveWavelength->setLowerExclusive(
true);
78 "Wavelength setting in Angstroms. This overrides what is in "
83 "Workspaces created showing the various resolution terms");
92 std::string partials_prefix =
getPropertyValue(
"PartialResolutionWorkspaces");
93 m_resTof = DataObjects::create<DataObjects::Workspace2D>(*
m_inputWS, HistogramData::Points(1));
95 m_resAngle = DataObjects::create<DataObjects::Workspace2D>(*
m_inputWS, HistogramData::Points(1));
96 m_outputWS = DataObjects::create<DataObjects::Workspace2D>(*
m_inputWS, HistogramData::Points(1));
103 auto partialsGroup = std::make_shared<WorkspaceGroup>();
107 partialsGroup->addWorkspace(
m_resTof);
110 setProperty(
"PartialResolutionWorkspaces", partialsGroup);
129 throw runtime_error(
"Unable to locate property LambdaRequest as central wavelength. ");
134 throw runtime_error(
"LambdaReqeust is not a TimeSeriesProperty in double. ");
136 string unit = cwltimeseries->units();
137 if ((unit !=
"Angstrom") && (unit !=
"A")) {
138 throw runtime_error(
"Unit is not recognized: " + unit);
141 return cwltimeseries->timeAverageValue();
146 g_log.
notice() <<
"Centre wavelength = " << centrewavelength <<
" Angstrom\n";
147 if (centrewavelength > WAVELENGTH_MAX) {
148 throw runtime_error(
"unphysical wavelength used");
157 const auto &spectrumInfo =
m_inputWS->spectrumInfo();
158 const auto l1 = spectrumInfo.l1();
159 const auto &componentInfo =
m_inputWS->componentInfo();
160 const auto &detectorInfo =
m_inputWS->detectorInfo();
162 const auto samplepos = spectrumInfo.samplePosition();
164 const size_t numspec =
m_inputWS->getNumberHistograms();
166 double mintwotheta = 2. * M_PI;
167 double maxtwotheta = 0.;
172 size_t count_nodetsize = 0;
174 for (
size_t i = 0; i < numspec; ++i) {
175 const auto &det = spectrumInfo.detector(i);
177 const auto realdet =
dynamic_cast<const Detector *
>(&det);
180 const double dx = realdet->getWidth();
181 detdim = sqrt(dx * dx + dy * dy) * 0.5;
189 const double l2 = spectrumInfo.l2(i);
195 const double twotheta = spectrumInfo.isMonitor(i) ? 0.0 : spectrumInfo.twoTheta(i);
196 const double theta = 0.5 * twotheta;
198 double deltatheta = 0.;
202 auto &spectrumDefinition = spectrumInfo.spectrumDefinition(i);
203 const double solidangle =
204 std::accumulate(spectrumDefinition.cbegin(), spectrumDefinition.cend(), 0.,
205 [&componentInfo, &detectorInfo, &samplepos](
const auto sum,
const auto &
index) {
206 if (!detectorInfo.isMasked(index.first)) {
207 return sum + componentInfo.solidAngle(index.first, samplepos);
212 deltatheta = sqrt(solidangle);
216 const double t1 =
m_deltaT / centraltof;
217 const double t2 = detdim / (l1 +
l2);
218 const double t3 = deltatheta / tan(theta);
220 if (spectrumInfo.isMonitor(i)) {
226 const double resolution = sqrt(t1 * t1 + t2 * t2 + t3 * t3);
233 m_resTof->mutableX(i) =
static_cast<double>(i);
235 m_resAngle->mutableX(i) =
static_cast<double>(i);
236 m_outputWS->mutableX(i) =
static_cast<double>(i);
238 maxtwotheta = std::max(twotheta, maxtwotheta);
239 mintwotheta = std::min(twotheta, mintwotheta);
241 if (
fabs(t3) < mint3)
243 else if (
fabs(t3) > maxt3)
246 g_log.
debug() << det.type() <<
" " << i <<
"\t\t" << twotheta <<
"\t\tdT/T = " << t1 * t1 <<
"\t\tdL/L = " << t2
247 <<
"\t\tdTheta*cotTheta = " << t3 <<
"\n";
250 g_log.
notice() <<
"2theta range: " << mintwotheta <<
", " << maxtwotheta <<
"\n";
251 g_log.
notice() <<
"t3 range: " << mint3 <<
", " << maxt3 <<
"\n";
252 g_log.
notice() <<
"Number of detector having NO size information = " << count_nodetsize <<
"\n";
#define DECLARE_ALGORITHM(classname)
std::map< DeltaEMode::Type, std::string > index
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
A property class for workspaces.
API::MatrixWorkspace_sptr m_resTof
workspace holding the term for just the time-of-flight portion of the resolution
API::MatrixWorkspace_sptr m_resAngle
workspace holding the term for just the angular/solid angle portion of the resolution
double getWavelength()
Returns the wavelength from either the property or the input workspace.
API::MatrixWorkspace_sptr m_outputWS
Output workspace.
void processAlgProperties()
Process input properties for algorithm.
const std::string category() const override
Algorithm's category for identification overriding a virtual method.
void retrieveInstrumentParameters()
void exec() override
Implement abstract Algorithm methods.
API::MatrixWorkspace_sptr m_inputWS
Input workspace.
void init() override
Implement abstract Algorithm methods.
const std::string alias() const override
function to return any aliases to the algorithm
API::MatrixWorkspace_sptr m_divergenceWS
Workspace with custom divergence term.
API::MatrixWorkspace_sptr m_resPathLength
workspace holding the term for just the flight path portion of the resolution
void estimateDetectorResolution()
Calculate detector resolution.
const std::string summary() const override
Summary of algorithms purpose.
int version() const override
Algorithm's version for identification overriding a virtual method.
const std::string name() const override
Algorithm's name for identification overriding a virtual method.
double m_centreVelocity
Centre neutron velocity.
This class represents a detector - i.e.
virtual double getHeight() const
get Height (Y-dimension) value for component
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
void notice(const std::string &msg)
Logs at notice level.
Base class for properties.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
A specialised Property class for holding a series of time-value pairs.
Kernel::Logger g_log("ExperimentInfo")
static logger object
static constexpr double NeutronMass
Mass of the neutron in kg.
static constexpr double h
Planck constant in J*s.
Helper class which provides the Collimation Length for SANS instruments.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
@ Input
An input workspace.
@ Output
An output workspace.