26using namespace Kernel;
28using namespace Geometry;
29using namespace DataObjects;
35 std::make_shared<WorkspaceUnitValidator>(
"MomentumTransfer")),
36 "Name the workspace to calculate the resolution for");
38 auto wsValidator = std::make_shared<WorkspaceUnitValidator>(
"Wavelength");
46 auto positiveDouble = std::make_shared<BoundedValidator<double>>();
47 positiveDouble->setLower(0);
48 declareProperty(
"PixelSizeX", 5.15, positiveDouble,
"Pixel size in the X direction (mm).");
49 declareProperty(
"PixelSizeY", 5.15, positiveDouble,
"Pixel size in the Y direction (mm).");
50 declareProperty(
"SampleApertureRadius", 5.0, positiveDouble,
"Sample aperture radius (mm).");
51 declareProperty(
"SourceApertureRadius", 10.0, positiveDouble,
"Source aperture radius (mm).");
52 declareProperty(
"DeltaT", 250.0, positiveDouble,
"TOF spread (microsec).");
68 return pixel_size_x / 1000.0;
76 return pixel_size_y / 1000.0;
95 const std::vector<double> binParams =
getProperty(
"OutputBinning");
98 const auto xLength =
static_cast<int>(iqWS->x(0).size());
99 std::vector<double> XNorm(xLength - 1, 0.0);
107 thetaWS->setSharedX(0, iqWS->sharedX(0));
108 auto &ThetaY = thetaWS->mutableY(0);
114 tofWS->setSharedX(0, iqWS->sharedX(0));
115 auto &TOFY = tofWS->mutableY(0);
118 HistogramData::HistogramDx DxOut(xLength - 1, 0.0);
120 const auto numberOfSpectra =
static_cast<int>(reducedWS->getNumberHistograms());
123 const auto &spectrumInfo = reducedWS->spectrumInfo();
124 const double L1 = spectrumInfo.l1();
127 for (
int i = 0; i < numberOfSpectra; i++) {
129 if (!spectrumInfo.hasDetectors(i)) {
130 g_log.
warning() <<
"Workspace index " << i <<
" has no detector assigned to it - discarding\n";
134 if (spectrumInfo.isMonitor(i) || spectrumInfo.isMasked(i))
137 const double L2 = spectrumInfo.l2(i);
141 const double theta = spectrumInfo.twoTheta(i);
142 const double factor = 4.0 * M_PI * sin(0.5 * theta);
144 const auto &XIn = reducedWS->x(i);
145 const auto &YIn = reducedWS->y(i);
146 const auto wlLength =
static_cast<int>(XIn.size());
148 std::vector<double> _dx(xLength - 1, 0.0);
149 std::vector<double> _norm(xLength - 1, 0.0);
150 std::vector<double> _tofy(xLength - 1, 0.0);
151 std::vector<double> _thetay(xLength - 1, 0.0);
153 for (
int j = 0; j < wlLength - 1; j++) {
154 const double wl = (XIn[j + 1] + XIn[j]) / 2.0;
155 const double wl_bin = XIn[j + 1] - XIn[j];
156 if (!
isEmpty(min_wl) && wl < min_wl)
158 if (!
isEmpty(max_wl) && wl > max_wl)
160 const double q = factor / wl;
166 if (binParams[1] > 0.0) {
167 iq =
static_cast<int>(floor((q - binParams[0]) / binParams[1]));
169 iq =
static_cast<int>(floor(log(q / binParams[0]) / log(1.0 - binParams[1])));
172 const double src_to_pixel = L1 + L2;
173 const double dTheta2 =
174 (3.0 * R1 * R1 / (L1 * L1) + 3.0 * R2 * R2 * src_to_pixel * src_to_pixel / (L1 * L1 * L2 * L2) +
175 2.0 * (pixel_size_x * pixel_size_x + pixel_size_y * pixel_size_y) / (L2 * L2)) /
179 const double dwl_over_wl = 3.9560 *
getTOFResolution(wl) / (1000.0 * (L1 + L2) * wl);
181 const double wl_bin_over_wl = wl_bin / wl;
182 const double dq_over_q =
183 std::sqrt(dTheta2 / (theta * theta) + dwl_over_wl * dwl_over_wl + wl_bin_over_wl * wl_bin_over_wl);
188 if (iq >= 0 && iq < xLength - 1 && !std::isnan(dq_over_q) && dq_over_q > 0 && YIn[j] > 0) {
189 _dx[iq] += q * dq_over_q * YIn[j];
191 _tofy[iq] += q * std::fabs(dwl_over_wl) * YIn[j];
192 _thetay[iq] += q * std::sqrt(dTheta2) / theta * YIn[j];
199 for (
int iq = 0; iq < xLength - 1; iq++) {
200 DxOut[iq] += _dx[iq];
201 XNorm[iq] += _norm[iq];
202 TOFY[iq] += _tofy[iq];
203 ThetaY[iq] += _thetay[iq];
206 progress.report(
"Computing Q resolution");
213 for (
int i = 0; i < xLength - 1; i++) {
216 DxOut[i] /= XNorm[i];
218 ThetaY[i] /= XNorm[i];
220 iqWS->setPointStandardDeviations(0, std::move(DxOut));
#define DECLARE_ALGORITHM(classname)
#define PARALLEL_START_INTERRUPT_REGION
Begins a block to skip processing is the algorithm has been interupted Note the end of the block if n...
#define PARALLEL_CRITICAL(name)
#define PARALLEL_END_INTERRUPT_REGION
Ends a block to skip processing is the algorithm has been interupted Note the start of the block if n...
#define PARALLEL_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Base class from which all concrete algorithm classes should be derived.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
void setPropertyValue(const std::string &name, const std::string &value) override
Set the value of a property by string N.B.
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
Helper class for reporting progress from algorithms.
A property class for workspaces.
virtual double getEffectiveYPixelSize()
Return the effective pixel size in the y-direction.
double m_wl_resolution
Wavelength resolution (constant for all wavelengths)
virtual double getEffectiveXPixelSize()
Return the effective pixel size in the x-direction.
void init() override
Initialisation code.
void exec() override
Execution code.
TOFSANSResolution()
Defatult constructor.
virtual double getTOFResolution(double wl)
Return the TOF resolution for a particular wavelength.
Support for a property that holds an array of values.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void warning(const std::string &msg)
Logs at warning level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< EventWorkspace > EventWorkspace_sptr
shared pointer to the EventWorkspace class
std::enable_if< std::is_pointer< Arg >::value, bool >::type threadSafe(Arg workspace)
Thread-safety check Checks the workspace to ensure it is suitable for multithreaded access.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
@ InOut
Both an input & output workspace.
@ Input
An input workspace.
@ Output
An output workspace.