Mantid
Loading...
Searching...
No Matches
CalculateDIFC.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 +
14
15namespace Mantid {
16namespace PropertyNames {
17const std::string INPUT_WKSP("InputWorkspace");
18const std::string OUTPUT_WKSP("OutputWorkspace");
19const std::string CALIB_WKSP("CalibrationWorkspace");
20const std::string OFFSTS_WKSP("OffsetsWorkspace");
21const std::string OFFSET_MODE("OffsetMode");
22const std::string BINWIDTH("BinWidth");
23} // namespace PropertyNames
24namespace {
25
26enum class OffsetMode { RELATIVE_OFFSET, ABSOLUTE_OFFSET, SIGNED_OFFSET, enum_count };
27const std::vector<std::string> offsetModeNames{"Relative", "Absolute", "Signed"};
29
39void calculateFromOffset(API::Progress &progress, DataObjects::SpecialWorkspace2D &outputWs,
40 const DataObjects::OffsetsWorkspace *const offsetsWS,
41 const Geometry::DetectorInfo &detectorInfo, double binWidth, OFFSETMODE offsetMode) {
42 const auto &detectorIDs = detectorInfo.detectorIDs();
43 const bool haveOffset = (offsetsWS != nullptr);
44 const double l1 = detectorInfo.l1();
45
46 std::function<double(size_t const &, double const &)> difc_for_offset_mode;
47 if (offsetMode == OffsetMode::SIGNED_OFFSET) {
48 difc_for_offset_mode = [l1, detectorInfo, binWidth](size_t const &i, double const &offset) {
49 return Geometry::Conversion::calculateDIFCCorrection(l1, detectorInfo.l2(i), detectorInfo.twoTheta(i), offset,
50 binWidth);
51 };
52 } else {
53 difc_for_offset_mode = [l1, detectorInfo](size_t const &i, double const &offset) {
54 return 1. / Geometry::Conversion::tofToDSpacingFactor(l1, detectorInfo.l2(i), detectorInfo.twoTheta(i), offset);
55 };
56 }
57
58 for (size_t i = 0; i < detectorInfo.size(); ++i) {
59 if ((!detectorInfo.isMasked(i)) && (!detectorInfo.isMonitor(i))) {
60 // offset=0 means that geometry is correct
61 const double offset = (haveOffset ? offsetsWS->getValue(detectorIDs[i], 0.) : 0.);
62 outputWs.setValue(detectorIDs[i], difc_for_offset_mode(i, offset));
63 }
64
65 progress.report("Calculate DIFC");
66 }
67}
68
69// look through the columns of detid and difc and copy them into the
70// SpecialWorkspace2D
71void calculateFromTable(API::Progress &progress, DataObjects::SpecialWorkspace2D &outputWs,
72 const API::ITableWorkspace &calibWs) {
73 API::ConstColumnVector<double> difcCol = calibWs.getVector("difc");
74 API::ConstColumnVector<int> detIDs = calibWs.getVector("detid");
75
76 const size_t numRows = detIDs.size();
77 for (size_t i = 0; i < numRows; ++i) {
78 outputWs.setValue(detIDs[i], difcCol[i]);
79 progress.report("Calculate DIFC");
80 }
81}
82} // namespace
83
84namespace Algorithms {
85
94
95// Register the algorithm into the AlgorithmFactory
96DECLARE_ALGORITHM(CalculateDIFC)
97
98//----------------------------------------------------------------------------------------------
99
100
101const std::string CalculateDIFC::name() const { return "CalculateDIFC"; }
102
104int CalculateDIFC::version() const { return 1; }
105
107const std::string CalculateDIFC::category() const { return "Diffraction\\Utility"; }
108
110const std::string CalculateDIFC::summary() const { return "Calculate the DIFC for every pixel"; }
111
112//----------------------------------------------------------------------------------------------
117 "Name of the workspace to have DIFC calculated from");
120 "Workspace containing DIFC for each pixel");
123 "Optional: A TableWorkspace containing the DIFC values, "
124 "which will be copied. This property cannot be set in "
125 "conjunction with property OffsetsWorkspace.");
126
129 "Optional: Whether to calculate a relative, absolute, or signed offset. Default relative");
130
132 "Optional: The bin width of the X axis. If using 'Signed' OffsetMode, this value is mandatory");
135 "Optional: A OffsetsWorkspace containing the calibration "
136 "offsets. This property cannot be set in conjunction with "
137 "property CalibrationWorkspace.");
138}
139
140std::map<std::string, std::string> CalculateDIFC::validateInputs() {
141 std::map<std::string, std::string> result;
142
145
146 if ((bool(offsetsWS)) && (bool(calibrationWS))) {
147 std::string msg = "Only specify calibration one way";
148 result[PropertyNames::OFFSTS_WKSP] = msg;
149 result[PropertyNames::CALIB_WKSP] = msg;
150 }
151
152 OFFSETMODE offsetMode = std::string(getProperty(PropertyNames::OFFSET_MODE));
153 if (isDefault(PropertyNames::BINWIDTH) && (offsetMode == OffsetMode::SIGNED_OFFSET)) {
154 std::string msg = "Signed offset mode requires bin width to be specified.";
155 result[PropertyNames::BINWIDTH] = msg;
156 result[PropertyNames::OFFSET_MODE] = msg;
157 }
158
159 return result;
160}
161
162//----------------------------------------------------------------------------------------------
166
171 double binWidth = getProperty(PropertyNames::BINWIDTH);
172
173 if ((!bool(inputWs == outputWs)) ||
174 // SpecialWorkspace2D is a Workspace2D where each spectrum
175 // has one detector pixel, one X-value, and one Y-value.
176 (!bool(std::dynamic_pointer_cast<SpecialWorkspace2D>(outputWs)))) {
177 outputWs =
178 std::dynamic_pointer_cast<MatrixWorkspace>(std::make_shared<SpecialWorkspace2D>(inputWs->getInstrument()));
179 outputWs->setTitle("DIFC workspace");
180 }
181
182 // convert to actual type being used
184 std::dynamic_pointer_cast<DataObjects::SpecialWorkspace2D>(outputWs);
185
186 API::Progress progress(this, 0.0, 1.0, inputWs->getNumberHistograms());
187 if (bool(calibWs)) {
188 calculateFromTable(progress, *outputSpecialWs, *calibWs);
189 } else {
190 // this method handles calculating from instrument geometry as well,
191 // and even when OffsetsWorkspace hasn't been set
192 const auto &detectorInfo = inputWs->detectorInfo();
193 OFFSETMODE offsetMode = std::string(getProperty(PropertyNames::OFFSET_MODE));
194 calculateFromOffset(progress, *outputSpecialWs, offsetsWs.get(), detectorInfo, binWidth, offsetMode);
195 }
196
198}
199
200} // namespace Algorithms
201} // namespace Mantid
std::string name
Definition Run.cpp:60
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
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.
bool isDefault(const std::string &name) const
Base MatrixWorkspace Abstract Class.
Helper class for reporting progress from algorithms.
Definition Progress.h:25
A property class for workspaces.
CalculateDIFC : Calculate the DIFC for every pixel.
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
const std::string category() const override
Algorithm's category for identification.
int version() const override
Algorithm's version for identification.
std::map< std::string, std::string > validateInputs() override
Cross-check properties with each other.
void init() override
Initialize the algorithm's properties.
void exec() override
Execute the algorithm.
An OffsetsWorkspace is a specialized Workspace2D where the Y value at each pixel is the offset to be ...
A concrete property based on user options of a finite list of strings.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
std::shared_ptr< const ITableWorkspace > ITableWorkspace_const_sptr
shared pointer to Mantid::API::ITableWorkspace (const version)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< const OffsetsWorkspace > OffsetsWorkspace_const_sptr
shared pointer to a const OffsetsWorkspace
std::shared_ptr< SpecialWorkspace2D > SpecialWorkspace2D_sptr
shared pointer to the SpecialWorkspace2D class
MANTID_GEOMETRY_DLL double calculateDIFCCorrection(const double l1, const double l2, const double twoTheta, const double offset, const double binWidth)
MANTID_GEOMETRY_DLL double tofToDSpacingFactor(const double l1, const double l2, const double twoTheta, const double offset)
Calculate and return conversion factor from tof to d-spacing.
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
const std::string BINWIDTH("BinWidth")
const std::string OFFSET_MODE("OffsetMode")
const std::string OFFSTS_WKSP("OffsetsWorkspace")
const std::string CALIB_WKSP("CalibrationWorkspace")
const std::string OUTPUT_WKSP("OutputWorkspace")
const std::string INPUT_WKSP("InputWorkspace")
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.
Definition EmptyValues.h:42
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