Mantid
Loading...
Searching...
No Matches
ElasticWindow.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 +
7//----------------------------------------------------------------------
8// Includes
9//----------------------------------------------------------------------
11#include "MantidAPI/Axis.h"
17
18namespace Mantid::Algorithms {
19
20// Register the algorithm into the AlgorithmFactory
21DECLARE_ALGORITHM(ElasticWindow)
22
23using namespace Kernel;
24using namespace API;
25
27 declareProperty(std::make_unique<WorkspaceProperty<>>("InputWorkspace", "", Direction::Input,
28 std::make_shared<WorkspaceUnitValidator>("DeltaE")),
29 "The input workspace.");
30 declareProperty(std::make_unique<WorkspaceProperty<>>("OutputInQ", "", Direction::Output),
31 "The name for output workspace with the X axis in units of Q");
32 declareProperty(std::make_unique<WorkspaceProperty<>>("OutputInQSquared", "", Direction::Output),
33 "The name for output workspace with the X axis in units of Q^2.");
34 declareProperty("IntegrationRangeStart", EMPTY_DBL(), std::make_shared<MandatoryValidator<double>>(),
35 "Start Point of Range 1");
36 declareProperty("IntegrationRangeEnd", EMPTY_DBL(), std::make_shared<MandatoryValidator<double>>(),
37 "End Point of Range 1");
38 declareProperty("BackgroundRangeStart", EMPTY_DBL(), "Start Point of Range 2", Direction::Input);
39 declareProperty("BackgroundRangeEnd", EMPTY_DBL(), "End Point of Range 2.", Direction::Input);
40}
41
43 MatrixWorkspace_sptr inputWorkspace = getProperty("InputWorkspace");
44
45 double intRangeStart = getProperty("IntegrationRangeStart");
46 double intRangeEnd = getProperty("IntegrationRangeEnd");
47 double bgRangeStart = getProperty("BackgroundRangeStart");
48 double bgRangeEnd = getProperty("BackgroundRangeEnd");
49
50 // Create the output workspaces
52
54 MatrixWorkspace_sptr outputQSquared;
55
56 const bool childAlgLogging(true);
57 double startProgress(0.0), endProgress(0.0);
58
59 // Determine if we are converting from spectra number (red) or Q (Sqw)
60 const bool axisIsSpectrumNumber = inputWorkspace->getAxis(1)->isSpectra();
61 g_log.information() << "Axis is spectrum number: " << axisIsSpectrumNumber << '\n';
62
63 // Determine if we need to use the second time range...
64 const bool backgroundSubtraction = !((bgRangeStart == bgRangeEnd) && (bgRangeStart == EMPTY_DBL()));
65 g_log.information() << "Use background subtraction: " << backgroundSubtraction << '\n';
66
67 // Calculate number of steps
68 size_t numSteps = 4;
69 if (backgroundSubtraction)
70 numSteps += 1;
71 if (axisIsSpectrumNumber)
72 numSteps += 1;
73
74 double stepProgress = 1.0 / static_cast<double>(numSteps);
75
76 if (backgroundSubtraction) {
77 // ... CalculateFlatBackground, Minus, Integration...
78 auto flatBG = createChildAlgorithm("CalculateFlatBackground", startProgress, endProgress, childAlgLogging);
79 flatBG->setProperty<MatrixWorkspace_sptr>("InputWorkspace", inputWorkspace);
80 flatBG->setProperty<double>("StartX", bgRangeStart);
81 flatBG->setProperty<double>("EndX", bgRangeEnd);
82 flatBG->setPropertyValue("Mode", "Mean");
83 flatBG->setPropertyValue("OutputWorkspace", "flatBG");
84 flatBG->execute();
85 startProgress += stepProgress;
86 endProgress += stepProgress;
87
88 MatrixWorkspace_sptr flatBGws = flatBG->getProperty("OutputWorkspace");
89
90 auto integ = createChildAlgorithm("Integration", startProgress, endProgress, childAlgLogging);
91 integ->setProperty<MatrixWorkspace_sptr>("InputWorkspace", flatBGws);
92 integ->setProperty<double>("RangeLower", intRangeStart);
93 integ->setProperty<double>("RangeUpper", intRangeEnd);
94 integ->setPropertyValue("OutputWorkspace", "integ");
95 integ->execute();
96
97 integWS = integ->getProperty("OutputWorkspace");
98 } else {
99 // ... Just Integration ...
100 auto integ = createChildAlgorithm("Integration", startProgress, endProgress, childAlgLogging);
101 integ->setProperty<MatrixWorkspace_sptr>("InputWorkspace", inputWorkspace);
102 integ->setProperty<double>("RangeLower", intRangeStart);
103 integ->setProperty<double>("RangeUpper", intRangeEnd);
104 integ->setPropertyValue("OutputWorkspace", "integ");
105 integ->execute();
106
107 integWS = integ->getProperty("OutputWorkspace");
108 }
109 startProgress += stepProgress;
110 endProgress += stepProgress;
111
112 auto const detectorCount = integWS->spectrumInfo().detectorCount();
113 if (axisIsSpectrumNumber || detectorCount > 0) {
114 if (!axisIsSpectrumNumber) {
115 auto spectraAxis = std::make_unique<SpectraAxis>(integWS.get());
116 integWS->replaceAxis(1, std::move(spectraAxis));
117 }
118
119 // Use ConvertSpectrumAxis v2 for correct result
120 const int convertSpectrumAxisVersion = 2;
121
122 // ... ConvertSpectrumAxis (Q) ...
123 auto csaQ = createChildAlgorithm("ConvertSpectrumAxis", startProgress, endProgress, childAlgLogging,
124 convertSpectrumAxisVersion);
125 csaQ->setProperty<MatrixWorkspace_sptr>("InputWorkspace", integWS);
126 csaQ->setPropertyValue("Target", "ElasticQ");
127 csaQ->setPropertyValue("EMode", "Indirect");
128 csaQ->setPropertyValue("OutputWorkspace", "csaQ");
129 csaQ->execute();
130 MatrixWorkspace_sptr csaQws = csaQ->getProperty("OutputWorkspace");
131 startProgress += stepProgress;
132 endProgress += stepProgress;
133
134 // ... ConvertSpectrumAxis (Q2) ...
135 auto csaQ2 = createChildAlgorithm("ConvertSpectrumAxis", startProgress, endProgress, childAlgLogging,
136 convertSpectrumAxisVersion);
137 csaQ2->setProperty<MatrixWorkspace_sptr>("InputWorkspace", integWS);
138 csaQ2->setPropertyValue("Target", "ElasticQSquared");
139 csaQ2->setPropertyValue("EMode", "Indirect");
140 csaQ2->setPropertyValue("OutputWorkspace", "csaQ2");
141 csaQ2->execute();
142 MatrixWorkspace_sptr csaQ2ws = csaQ2->getProperty("OutputWorkspace");
143 startProgress += stepProgress;
144 endProgress += stepProgress;
145
146 // ... Transpose (Q) ...
147 auto tranQ = createChildAlgorithm("Transpose", startProgress, endProgress, childAlgLogging);
148 tranQ->setProperty<MatrixWorkspace_sptr>("InputWorkspace", csaQws);
149 tranQ->setPropertyValue("OutputWorkspace", "outQ");
150 tranQ->execute();
151 outputQ = tranQ->getProperty("OutputWorkspace");
152 startProgress += stepProgress;
153 endProgress += stepProgress;
154
155 // ... Transpose (Q2) ...
156 auto tranQ2 = createChildAlgorithm("Transpose", startProgress, endProgress, childAlgLogging);
157 tranQ2->setProperty<MatrixWorkspace_sptr>("InputWorkspace", csaQ2ws);
158 tranQ2->setPropertyValue("OutputWorkspace", "outQSquared");
159 tranQ2->execute();
160 outputQSquared = tranQ2->getProperty("OutputWorkspace");
161 } else {
162 // ... Transpose (Q) ...
163 auto tranQ = createChildAlgorithm("Transpose", startProgress, endProgress, childAlgLogging);
164 tranQ->setProperty<MatrixWorkspace_sptr>("InputWorkspace", integWS);
165 tranQ->setPropertyValue("OutputWorkspace", "outQ");
166 tranQ->execute();
167 outputQ = tranQ->getProperty("OutputWorkspace");
168 startProgress += stepProgress;
169 endProgress += stepProgress;
170
171 // ... Convert to Histogram (Q2) ...
172 auto histQ2 = createChildAlgorithm("ConvertToHistogram", startProgress, endProgress, childAlgLogging);
173 histQ2->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputQ);
174 histQ2->setPropertyValue("OutputWorkspace", "outQ");
175 histQ2->execute();
176 MatrixWorkspace_sptr qHistWS = histQ2->getProperty("OutputWorkspace");
177 startProgress += stepProgress;
178 endProgress += stepProgress;
179
180 // ... Convert Units (Q2) ...
181 auto convUnitQ2 = createChildAlgorithm("ConvertUnits", startProgress, endProgress, childAlgLogging);
182 convUnitQ2->setProperty<MatrixWorkspace_sptr>("InputWorkspace", qHistWS);
183 convUnitQ2->setPropertyValue("Target", "QSquared");
184 convUnitQ2->setPropertyValue("EMode", "Indirect");
185 convUnitQ2->setPropertyValue("OutputWorkspace", "outQSquared");
186 convUnitQ2->execute();
187 outputQSquared = convUnitQ2->getProperty("OutputWorkspace");
188 }
189 auto yLabel = outputQSquared->YUnitLabel();
190 outputQSquared->setYUnitLabel("ln(" + yLabel + ")");
191
192 setProperty("OutputInQ", outputQ);
193 setProperty("OutputInQSquared", outputQSquared);
194}
195
196} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
IntArray detectorCount
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.
virtual 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)
Create a Child Algorithm.
Kernel::Logger & g_log
Definition Algorithm.h:422
A property class for workspaces.
void exec() override
Execution code.
void init() override
Initialisation code.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
Validator to check that a property is not left empty.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition EmptyValues.h:42
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54