Mantid
Loading...
Searching...
No Matches
EstimateDivergence.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
16#include "MantidKernel/V3D.h"
17#include "MantidTypes/SpectrumDefinition.h"
18
19namespace Mantid::Algorithms {
20
21using namespace std;
22using Mantid::API::WorkspaceProperty; // NOLINT
23using Mantid::Kernel::Direction; // NOLINT
24
25// Register the algorithm into the AlgorithmFactory
26DECLARE_ALGORITHM(EstimateDivergence)
27
28//----------------------------------------------------------------------------------------------
29
30
31const std::string EstimateDivergence::name() const { return "EstimateDivergence"; }
32
34int EstimateDivergence::version() const { return 1; }
35
37const std::string EstimateDivergence::category() const { return "Diffraction\\Utility"; }
38
40const std::string EstimateDivergence::summary() const { return "Estimate the divergence of each detector pixel"; }
41
42//----------------------------------------------------------------------------------------------
46 declareProperty(std::make_unique<WorkspaceProperty<API::MatrixWorkspace>>("InputWorkspace", "", Direction::Input),
47 "Workspace to have divergence calculated from");
48
49 auto positiveParameter = std::make_shared<Kernel::BoundedValidator<double>>();
50 positiveParameter->setLower(0.);
51 positiveParameter->setLowerExclusive(false); // zero is allowed
52
53 declareProperty("alpha", 0., positiveParameter, "Vertical divergence parameter");
54 declareProperty("beta0", 0., positiveParameter, "Horizontal divergence parameter");
55 declareProperty("beta1", 0., positiveParameter, "Other horizontal divergence parameter");
56
57 declareProperty(std::make_unique<WorkspaceProperty<API::MatrixWorkspace>>("OutputWorkspace", "", Direction::Output),
58 "Workspace containing the divergence of each detector/spectrum");
59}
60
61//----------------------------------------------------------------------------------------------
65 // read input parameters
66 API::MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
67 const double alpha = getProperty("alpha");
68 const double beta0 = getProperty("beta0");
69 const double beta1 = getProperty("beta1");
70
71 // derived terms
72 const double horizontal = alpha * alpha;
73 const double vertical_numerator = 4. * (beta0 * beta0 + beta1 * beta1);
74
75 // create output workspaces
76 API::MatrixWorkspace_sptr divergenceWS =
77 DataObjects::create<DataObjects::Workspace2D>(*inputWS, HistogramData::Points(1));
78
79 // do the math
80 const auto &spectrumInfo = inputWS->spectrumInfo();
81 const auto samplepos = spectrumInfo.samplePosition();
82 const auto &componentInfo = inputWS->componentInfo();
83 const auto &detectorInfo = inputWS->detectorInfo();
84 size_t numspec = inputWS->getNumberHistograms();
85 double solidangletotal = 0.;
86 for (size_t i = 0; i < numspec; ++i) {
87 // angle
88 const double twotheta = spectrumInfo.isMonitor(i) ? 0.0 : spectrumInfo.twoTheta(i);
89 const double sintwotheta = sin(twotheta);
90 // vertical term
91 const double vertical = vertical_numerator / (sintwotheta * sintwotheta);
92
93 // solid angle
94 auto &spectrumDefinition = spectrumInfo.spectrumDefinition(i);
95 // No scanning support for solidAngle currently, use only first component
96 // of index, ignore time index
97 const double solidangle =
98 std::accumulate(spectrumDefinition.cbegin(), spectrumDefinition.cend(), 0.,
99 [&componentInfo, &detectorInfo, &samplepos](const auto sum, const auto &index) {
100 if (!detectorInfo.isMasked(index.first)) {
101 return sum + componentInfo.solidAngle(index.first, samplepos);
102 } else {
103 return sum;
104 }
105 });
106 solidangletotal += solidangle;
107 const double deltatwotheta = sqrt(solidangle);
108
109 // put it all together and set it in the output workspace
110 const double divergence = .5 * sqrt(deltatwotheta * deltatwotheta + horizontal + vertical);
111 divergenceWS->mutableX(i)[0] = static_cast<double>(i);
112 if (spectrumInfo.isMonitor(i))
113 divergenceWS->mutableY(i)[0] = 0.;
114 else
115 divergenceWS->mutableY(i)[0] = divergence;
116 }
117 g_log.notice() << "total solid angle " << solidangletotal << "\n";
118
119 setProperty("OutputWorkspace", divergenceWS);
120}
121
122} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Definition: Algorithm.cpp:1913
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
A property class for workspaces.
EstimateDivergence : Calculate the instrument divergence according to Windsor.
void init() override
Initialize the algorithm's properties.
const std::string category() const override
Algorithm's category for identification.
void exec() override
Execute the algorithm.
int version() const override
Algorithm's version for identification.
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
void notice(const std::string &msg)
Logs at notice level.
Definition: Logger.cpp:95
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
STL namespace.
Describes the direction (within an algorithm) of a Property.
Definition: Property.h:50
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54