Mantid
Loading...
Searching...
No Matches
SofTwoThetaTOF.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 +
8
18
19#include <filesystem>
20
22
23namespace {
25namespace Prop {
26std::string const ANGLE_STEP{"AngleStep"};
27std::string const FILENAME{"GroupingFilename"};
28std::string const INPUT_WS{"InputWorkspace"};
29std::string const OUTPUT_WS{"OutputWorkspace"};
30} // namespace Prop
31
33struct RemoveFileAtScopeExit {
34 explicit RemoveFileAtScopeExit(std::string filename = "") : name(std::move(filename)) {}
35 std::string name;
36 ~RemoveFileAtScopeExit() {
37 if (!name.empty()) {
38 auto const path = std::filesystem::path(name);
39 if (std::filesystem::exists(path)) {
40 std::filesystem::remove(path);
41 }
42 }
43 }
44};
45
47struct MinMax {
48 double min{std::numeric_limits<double>::max()};
49 double max{std::numeric_limits<double>::lowest()};
50};
51
57MinMax minMaxX(Mantid::API::MatrixWorkspace const &ws) {
58 auto const nHisto = ws.getNumberHistograms();
59 MinMax mm;
60 for (size_t i = 0; i < nHisto; ++i) {
61 auto const &x = ws.x(i);
62 mm.min = std::min(mm.min, x.front());
63 mm.max = std::max(mm.max, x.back());
64 }
65 return mm;
66}
67
73double binWidth(Mantid::API::MatrixWorkspace const &ws) {
74 auto const &x = ws.x(0);
75 return x[1] - x[0];
76}
77
83std::string ensureXMLExtension(std::string const &filename) {
84 std::string name = filename;
85 auto const path = std::filesystem::path(filename);
86 if (path.extension() != ".xml") {
87 name += ".xml";
88 }
89 return name;
90}
91} // namespace
92
94
95// Register the algorithm into the AlgorithmFactory
96DECLARE_ALGORITHM(SofTwoThetaTOF)
97
98
99const std::string SofTwoThetaTOF::name() const { return "SofTwoThetaTOF"; }
100
102int SofTwoThetaTOF::version() const { return 1; }
103
105const std::string SofTwoThetaTOF::category() const { return "Inelastic;ILL\\Direct"; }
106
108const std::string SofTwoThetaTOF::summary() const {
109 return "Calculates the intensity as a function of scattering angle and time "
110 "of flight.";
111}
112
116 auto histogrammedTOF = std::make_shared<Kernel::CompositeValidator>();
117 histogrammedTOF->add(std::make_shared<API::WorkspaceUnitValidator>("TOF"));
118 histogrammedTOF->add(std::make_shared<API::HistogramValidator>());
119 histogrammedTOF->add(std::make_shared<API::InstrumentValidator>());
120 declareProperty(
121 std::make_unique<API::WorkspaceProperty<>>(Prop::INPUT_WS, "", Kernel::Direction::Input, histogrammedTOF),
122 "A workspace to be converted.");
123 declareProperty(std::make_unique<API::WorkspaceProperty<>>(Prop::OUTPUT_WS, "", Kernel::Direction::Output),
124 "A workspace with (2theta, TOF) units.");
125 auto positiveDouble = std::make_shared<Kernel::BoundedValidator<double>>();
126 positiveDouble->setLowerExclusive(0.);
127 declareProperty(Prop::ANGLE_STEP, EMPTY_DBL(), positiveDouble, "The angle step for detector grouping, in degrees.");
128 declareProperty(std::make_unique<API::FileProperty>(Prop::FILENAME, "", API::FileProperty::OptionalSave,
129 std::vector<std::string>{".xml"}),
130 "A grouping file that will be created; a corresponding .par "
131 "file wille be created as well.");
132}
133
137 API::MatrixWorkspace_sptr in = getProperty(Prop::INPUT_WS);
138 auto ragged = convertToConstantL2(in);
139 auto equalBinning = rebinToNonRagged(ragged);
140 auto ws = maskEmptyBins(equalBinning, ragged);
141 ws = groupByTwoTheta(ws, clarifyAngleStep(*in));
142 ws = convertToTwoTheta(ws);
143 setProperty(Prop::OUTPUT_WS, ws);
144}
145
147 if (!isDefault(Prop::ANGLE_STEP)) {
148 return getProperty(Prop::ANGLE_STEP);
149 } else {
150 auto instrument = ws.getInstrument();
151 if (!instrument) {
152 throw std::invalid_argument("Missing " + Prop::ANGLE_STEP);
153 }
154 auto const &paramMap = ws.constInstrumentParameters();
155 auto const paramValues = paramMap.getDouble(instrument->getName(), "natural-angle-step");
156 if (paramValues.empty()) {
157 throw std::invalid_argument("Missing " + Prop::ANGLE_STEP +
158 " or 'natural-angle-step' not defined in "
159 "instrument parameters file.");
160 }
161 return paramValues.front();
162 }
163}
164
166 auto toConstantL2 = createChildAlgorithm("ConvertToConstantL2", 0., 0.2);
167 toConstantL2->setProperty("InputWorkspace", ws);
168 toConstantL2->setPropertyValue("OutputWorkspace", "out");
169 toConstantL2->execute();
170 return toConstantL2->getProperty("OutputWorkspace");
171}
172
174 auto convertAxis = createChildAlgorithm("ConvertSpectrumAxis", 0.9, 1.0);
175 convertAxis->setProperty("InputWorkspace", ws);
176 convertAxis->setProperty("OutputWorkspace", "out");
177 convertAxis->setProperty("Target", "Theta");
178 convertAxis->execute();
179 return convertAxis->getProperty("OutputWorkspace");
180}
181
183 const std::string GROUP_WS("softwothetatof_groupWS");
184 auto generateGrouping = createChildAlgorithm("GenerateGroupingPowder", 0.2, 0.5);
185 generateGrouping->setProperty("InputWorkspace", ws);
186 generateGrouping->setProperty("AngleStep", twoThetaStep);
187 generateGrouping->setProperty("GroupingWorkspace", GROUP_WS);
188 std::string filename;
189 RemoveFileAtScopeExit deleteThisLater;
190 if (isDefault(Prop::FILENAME)) {
191 const std::string shortname = "detector-grouping-" + randomString(4) + "-" + randomString(4) + "-" +
192 randomString(4) + "-" + randomString(4) + ".xml";
193 const auto tempPath = std::filesystem::temp_directory_path() / shortname;
194 filename = tempPath.string();
195 generateGrouping->setProperty("GenerateParFile", false);
196 // Make sure the file gets deleted at scope exit.
197 deleteThisLater = RemoveFileAtScopeExit(filename);
198 } else {
199 filename = static_cast<std::string>(getProperty(Prop::FILENAME));
200 filename = ensureXMLExtension(filename);
201 }
202 generateGrouping->setProperty("GroupingFilename", filename);
203 generateGrouping->execute();
204
205 auto groupDetectors = createChildAlgorithm("GroupDetectors", 0.7, 0.9);
206 groupDetectors->setProperty("InputWorkspace", ws);
207 groupDetectors->setProperty("OutputWorkspace", "out");
208 // TODO make this algo work with the GroupingWorkspace from GenerateGroupingPowder
209 // Mantid::DataObjects::GroupingWorkspace_sptr gws = generateGrouping->getProperty("GroupingWorkspace");
210 // groupDetectors->setProperty("CopyGroupingFromWorkspace", gws);
211 groupDetectors->setProperty("MapFile", filename);
212 groupDetectors->setProperty("Behaviour", "Average");
213 groupDetectors->execute();
214 return groupDetectors->getProperty("OutputWorkspace");
215}
216
218 API::MatrixWorkspace_sptr &comparison) {
219 auto maskNonOverlapping = createChildAlgorithm("MaskNonOverlappingBins", 0.6, 0.7);
220 maskNonOverlapping->setProperty("InputWorkspace", maskable);
221 maskNonOverlapping->setProperty("OutputWorkspace", "out");
222 maskNonOverlapping->setProperty("ComparisonWorkspace", comparison);
223 maskNonOverlapping->setProperty("MaskPartiallyOverlapping", true);
224 maskNonOverlapping->setProperty("RaggedInputs", "Ragged");
225 maskNonOverlapping->setProperty("CheckSortedX", false);
226 maskNonOverlapping->execute();
227 return maskNonOverlapping->getProperty("OutputWorkspace");
228}
229
231 auto const xRange = minMaxX(*ws);
232 std::vector<double> const rebinParams{xRange.min, binWidth(*ws), xRange.max};
233 auto rebin = createChildAlgorithm("Rebin", 0.5, 0.6);
234 rebin->setProperty("InputWorkspace", ws);
235 rebin->setProperty("OutputWorkspace", "out");
236 rebin->setProperty("Params", rebinParams);
237 rebin->setProperty("FullBinsOnly", true);
238 rebin->execute();
239 return rebin->getProperty("OutputWorkspace");
240}
241
242} // namespace Mantid::WorkflowAlgorithms
std::string name
Definition Run.cpp:60
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:542
const Geometry::ParameterMap & constInstrumentParameters() const
Const version.
Geometry::Instrument_const_sptr getInstrument() const
Returns the parameterized instrument.
@ OptionalSave
to specify a file to write to but an empty string is
std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1) override
Create a Child Algorithm.
Kernel::IPropertyManager::TypedValue getProperty(const std::string &name) const override
Get the property held by this object.
Base MatrixWorkspace Abstract Class.
virtual std::size_t getNumberHistograms() const =0
Returns the number of histograms in the workspace.
const HistogramData::HistogramX & x(const size_t index) const
A property class for workspaces.
std::vector< double > getDouble(const std::string &compName, const std::string &name) const
Returns a double parameter as vector's first element if exists and an empty vector if it doesn't.
SofTwoThetaTOF : Convert a S(spectrum number, TOF) workspace to S(twoTheta, TOF) workspace.
API::MatrixWorkspace_sptr convertToTwoTheta(API::MatrixWorkspace_sptr &ws)
const std::string category() const override
Algorithm's category for identification.
API::MatrixWorkspace_sptr maskEmptyBins(API::MatrixWorkspace_sptr &maskable, API::MatrixWorkspace_sptr &comparison)
void init() override
Initialize the algorithm's properties.
int version() const override
Algorithm's version for identification.
void exec() override
Execute the algorithm.
API::MatrixWorkspace_sptr groupByTwoTheta(API::MatrixWorkspace_sptr &ws, double const twoThetaStep)
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
API::MatrixWorkspace_sptr rebinToNonRagged(API::MatrixWorkspace_sptr &ws)
API::MatrixWorkspace_sptr convertToConstantL2(API::MatrixWorkspace_sptr &ws)
double clarifyAngleStep(API::MatrixWorkspace const &ws)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
MANTID_KERNEL_DLL std::string randomString(const size_t len)
Generates random alpha-numeric string.
Definition Strings.cpp:1185
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition EmptyValues.h:42
String constants for algorithm's properties.
STL namespace.
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54