Mantid
Loading...
Searching...
No Matches
ApplyDiffCal.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2020 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
11#include "MantidAPI/Progress.h"
12#include "MantidAPI/Run.h"
13#include "MantidAPI/TableRow.h"
14#include "MantidAPI/Workspace.h"
19
20using namespace Mantid::API;
21using namespace Mantid::DataObjects;
22
23namespace Mantid::DataHandling {
24
27
28namespace {
29namespace PropertyNames {
30const std::string CAL_FILE("Filename");
31const std::string GROUP_FILE("GroupFilename");
32const std::string MAKE_CAL("MakeCalWorkspace");
33const std::string MAKE_GRP("MakeGroupingWorkspace");
34const std::string MAKE_MSK("MakeMaskWorkspace");
35} // namespace PropertyNames
36} // namespace
37
38// Register the algorithm into the AlgorithmFactory
40
41
42const std::string ApplyDiffCal::name() const { return "ApplyDiffCal"; }
43
45int ApplyDiffCal::version() const { return 1; }
46
48const std::string ApplyDiffCal::category() const { return "DataHandling\\Instrument;Diffraction\\DataHandling"; }
49
51const std::string ApplyDiffCal::summary() const {
52 return "Applies a calibration to a workspace for powder diffraction";
53}
54
58 declareProperty(std::make_unique<WorkspaceProperty<API::Workspace>>("InstrumentWorkspace", "", Direction::InOut),
59 "Set the workspace whose instrument should be updated");
60 const std::vector<std::string> exts{".h5", ".hd5", ".hdf", ".cal"};
61 declareProperty(std::make_unique<FileProperty>("CalibrationFile", "", FileProperty::OptionalLoad, exts),
62 "Optional: The .cal file containing the position correction factors. "
63 "Either this, CalibrationWorkspace or OffsetsWorkspace needs to be "
64 "specified.");
65 declareProperty(std::make_unique<WorkspaceProperty<ITableWorkspace>>("CalibrationWorkspace", "", Direction::Input,
67 "Optional: Set the Diffraction Calibration workspace");
68 declareProperty(std::make_unique<WorkspaceProperty<OffsetsWorkspace>>("OffsetsWorkspace", "", Direction::Input,
70 "Optional: A OffsetsWorkspace containing the calibration offsets. Either "
71 "this, CalibrationWorkspace or CalibrationFile needs to be specified.");
72 declareProperty("ClearCalibration", false, "Remove any existing calibration from the workspace");
73 setPropertySettings("CalibrationFile", std::make_unique<Kernel::EnabledWhenProperty>(
74 "ClearCalibration", Kernel::ePropertyCriterion::IS_EQUAL_TO, "0"));
75 setPropertySettings("CalibrationWorkspace", std::make_unique<Kernel::EnabledWhenProperty>(
76 "ClearCalibration", Kernel::ePropertyCriterion::IS_EQUAL_TO, "0"));
77 setPropertySettings("OffsetsWorkspace", std::make_unique<Kernel::EnabledWhenProperty>(
78 "ClearCalibration", Kernel::ePropertyCriterion::IS_EQUAL_TO, "0"));
79}
80
81std::map<std::string, std::string> ApplyDiffCal::validateInputs() {
82 std::map<std::string, std::string> result;
83
84 // Check workspace type has ExperimentInfo fields
87 Workspace_sptr inputWS = getProperty("InstrumentWorkspace");
88 if (!std::dynamic_pointer_cast<ExperimentInfo>(inputWS)) {
89 result["InstrumentWorkspace"] = "InputWorkspace type invalid. "
90 "Expected MatrixWorkspace, "
91 "PeaksWorkspace.";
92 }
93
94 int numWays = 0;
95
96 const std::string calFileName = getProperty("CalibrationFile");
97 if (!calFileName.empty())
98 numWays += 1;
99
100 ITableWorkspace_const_sptr calibrationWS = getProperty("CalibrationWorkspace");
101 if (bool(calibrationWS))
102 numWays += 1;
103
104 OffsetsWorkspace_const_sptr offsetsWS = getProperty("OffsetsWorkspace");
105 if (bool(offsetsWS))
106 numWays += 1;
107
108 bool clearCalibration = getProperty("ClearCalibration");
109 std::string message;
110 if ((clearCalibration) && (numWays > 0)) {
111 message = "You cannot supply a calibration input when clearing the calibration.";
112 }
113 if (!clearCalibration) {
114 if (numWays == 0) {
115 message = "You must specify only one of CalibrationFile, "
116 "CalibrationWorkspace, OffsetsWorkspace.";
117 }
118 if (numWays > 1) {
119 message = "You must specify one of CalibrationFile, "
120 "CalibrationWorkspace, OffsetsWorkspace.";
121 }
122 }
123
124 if (!message.empty()) {
125 result["CalibrationFile"] = message;
126 result["CalibrationWorkspace"] = message;
127 }
128
129 return result;
130}
131
132void ApplyDiffCal::loadCalFile(const Workspace_sptr &inputWS, const std::string &filename) {
133 auto alg = createChildAlgorithm("LoadDiffCal");
134 alg->setProperty("InputWorkspace", inputWS);
135 alg->setPropertyValue("Filename", filename);
136 alg->setProperty<bool>("MakeCalWorkspace", true);
137 alg->setProperty<bool>("MakeGroupingWorkspace", false);
138 alg->setProperty<bool>("MakeMaskWorkspace", false);
139 alg->setPropertyValue("WorkspaceName", "temp");
140 alg->executeAsChildAlg();
141
142 m_calibrationWS = alg->getProperty("OutputCalWorkspace");
143}
144
146 m_calibrationWS = getProperty("CalibrationWorkspace");
147 if (m_calibrationWS)
148 return; // nothing more to do
149
150 OffsetsWorkspace_sptr offsetsWS = getProperty("OffsetsWorkspace");
151 if (offsetsWS) {
152 auto alg = createChildAlgorithm("ConvertDiffCal");
153 alg->setProperty("OffsetsWorkspace", offsetsWS);
154 alg->executeAsChildAlg();
155 m_calibrationWS = alg->getProperty("OutputWorkspace");
156 m_calibrationWS->setTitle(offsetsWS->getTitle());
157 return;
158 }
159
160 const std::string calFileName = getPropertyValue("CalibrationFile");
161 if (!calFileName.empty()) {
162 progress(0.0, "Reading calibration file");
163 loadCalFile(inputWS, calFileName);
164 return;
165 }
166
167 throw std::runtime_error("Failed to determine calibration information");
168}
169
170//----------------------------------------------------------------------------------------------
174
175 Workspace_sptr InstrumentWorkspace = getProperty("InstrumentWorkspace");
176 // validateInputs guarantees this will be an ExperimentInfo object
177 auto experimentInfo = std::dynamic_pointer_cast<API::ExperimentInfo>(InstrumentWorkspace);
178 auto instrument = experimentInfo->getInstrument();
179 auto &paramMap = experimentInfo->instrumentParameters();
180 bool clearCalibration = getProperty("ClearCalibration");
181 if (clearCalibration) {
182 paramMap.clearParametersByName("DIFC");
183 paramMap.clearParametersByName("DIFA");
184 paramMap.clearParametersByName("TZERO");
185 } else {
186 this->getCalibrationWS(InstrumentWorkspace);
187
188 Column_const_sptr detIdColumn = m_calibrationWS->getColumn("detid");
189 Column_const_sptr difcColumn = m_calibrationWS->getColumn("difc");
190 Column_const_sptr difaColumn = m_calibrationWS->getColumn("difa");
191 Column_const_sptr tzeroColumn = m_calibrationWS->getColumn("tzero");
192
193 auto detids = instrument->getDetectorIDs();
194 std::sort(detids.begin(), detids.end());
195
196 for (size_t i = 0; i < m_calibrationWS->rowCount(); ++i) {
197 auto detid = static_cast<detid_t>((*detIdColumn)[i]);
198 double difc = (*difcColumn)[i];
199 double difa = (*difaColumn)[i];
200 double tzero = (*tzeroColumn)[i];
201
202 if (std::binary_search(detids.begin(), detids.end(), detid)) {
203 // found the detector
204 auto det = instrument->getDetector(detid);
205 paramMap.addDouble(det->getComponentID(), "DIFC", difc);
206 paramMap.addDouble(det->getComponentID(), "DIFA", difa);
207 paramMap.addDouble(det->getComponentID(), "TZERO", tzero);
208 } else {
209 // cannot find the detector, use default zero for difc, difa, and tzero
210 g_log.information() << "Cannot find det " << detid << ", skipping.\n";
211 }
212 }
213 }
214}
215
216} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
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
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
Definition: Algorithm.cpp:2026
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
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.
Definition: Algorithm.cpp:842
Kernel::Logger & g_log
Definition: Algorithm.h:451
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
Definition: Algorithm.cpp:231
@ OptionalLoad
to specify a file to read but the file doesn't have to exist
Definition: FileProperty.h:53
A property class for workspaces.
void exec() override
Execute the algorithm.
void getCalibrationWS(const Mantid::API::Workspace_sptr &inputWS)
std::map< std::string, std::string > validateInputs() override
Cross-check properties with each other.
void loadCalFile(const Mantid::API::Workspace_sptr &inputWS, const std::string &filename)
void init() override
Initialize the algorithm's properties.
int version() const override
Algorithm's version for identification.
const std::string category() const override
Algorithm's category for identification.
Mantid::API::ITableWorkspace_sptr m_calibrationWS
Definition: ApplyDiffCal.h:39
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
void setPropertySettings(const std::string &name, std::unique_ptr< IPropertySettings > settings)
void information(const std::string &msg)
Logs at information level.
Definition: Logger.cpp:105
The concrete, templated class for properties.
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
Definition: Workspace_fwd.h:20
std::shared_ptr< ExperimentInfo > ExperimentInfo_sptr
Shared pointer to ExperimentInfo.
std::shared_ptr< const ITableWorkspace > ITableWorkspace_const_sptr
shared pointer to Mantid::API::ITableWorkspace (const version)
std::shared_ptr< const Column > Column_const_sptr
Definition: Column.h:229
std::shared_ptr< const OffsetsWorkspace > OffsetsWorkspace_const_sptr
shared pointer to a const OffsetsWorkspace
std::shared_ptr< OffsetsWorkspace > OffsetsWorkspace_sptr
shared pointer to the OffsetsWorkspace class
int32_t detid_t
Typedef for a detector ID.
Definition: SpectrumInfo.h:21
STL namespace.
Describes the direction (within an algorithm) of a Property.
Definition: Property.h:50
@ InOut
Both an input & output workspace.
Definition: Property.h:55
@ Input
An input workspace.
Definition: Property.h:53