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
28// Register the algorithm into the AlgorithmFactory
30
31
32const std::string ApplyDiffCal::name() const { return "ApplyDiffCal"; }
33
35int ApplyDiffCal::version() const { return 1; }
36
38const std::string ApplyDiffCal::category() const { return "DataHandling\\Instrument;Diffraction\\DataHandling"; }
39
41const std::string ApplyDiffCal::summary() const {
42 return "Applies a calibration to a workspace for powder diffraction";
43}
44
48 declareProperty(std::make_unique<WorkspaceProperty<API::Workspace>>("InstrumentWorkspace", "", Direction::InOut),
49 "Set the workspace whose instrument should be updated");
50 const std::vector<std::string> exts{".h5", ".hd5", ".hdf", ".cal"};
51 declareProperty(std::make_unique<FileProperty>("CalibrationFile", "", FileProperty::OptionalLoad, exts),
52 "Optional: The .cal file containing the position correction factors. "
53 "Either this, CalibrationWorkspace or OffsetsWorkspace needs to be "
54 "specified.");
55 declareProperty(std::make_unique<WorkspaceProperty<ITableWorkspace>>("CalibrationWorkspace", "", Direction::Input,
57 "Optional: Set the Diffraction Calibration workspace");
58 declareProperty(std::make_unique<WorkspaceProperty<OffsetsWorkspace>>("OffsetsWorkspace", "", Direction::Input,
60 "Optional: A OffsetsWorkspace containing the calibration offsets. Either "
61 "this, CalibrationWorkspace or CalibrationFile needs to be specified.");
62 declareProperty("ClearCalibration", false, "Remove any existing calibration from the workspace");
63 setPropertySettings("CalibrationFile", std::make_unique<Kernel::EnabledWhenProperty>(
64 "ClearCalibration", Kernel::ePropertyCriterion::IS_EQUAL_TO, "0"));
65 setPropertySettings("CalibrationWorkspace", std::make_unique<Kernel::EnabledWhenProperty>(
66 "ClearCalibration", Kernel::ePropertyCriterion::IS_EQUAL_TO, "0"));
67 setPropertySettings("OffsetsWorkspace", std::make_unique<Kernel::EnabledWhenProperty>(
68 "ClearCalibration", Kernel::ePropertyCriterion::IS_EQUAL_TO, "0"));
69}
70
71std::map<std::string, std::string> ApplyDiffCal::validateInputs() {
72 std::map<std::string, std::string> result;
73
74 // Check workspace type has ExperimentInfo fields
77 Workspace_sptr inputWS = getProperty("InstrumentWorkspace");
78 if (!std::dynamic_pointer_cast<ExperimentInfo>(inputWS)) {
79 result["InstrumentWorkspace"] = "InputWorkspace type invalid. "
80 "Expected MatrixWorkspace, "
81 "PeaksWorkspace.";
82 }
83
84 int numWays = 0;
85
86 const std::string calFileName = getProperty("CalibrationFile");
87 if (!calFileName.empty())
88 numWays += 1;
89
90 ITableWorkspace_const_sptr calibrationWS = getProperty("CalibrationWorkspace");
91 if (bool(calibrationWS))
92 numWays += 1;
93
94 OffsetsWorkspace_const_sptr offsetsWS = getProperty("OffsetsWorkspace");
95 if (bool(offsetsWS))
96 numWays += 1;
97
98 bool clearCalibration = getProperty("ClearCalibration");
99 std::string message;
100 if ((clearCalibration) && (numWays > 0)) {
101 message = "You cannot supply a calibration input when clearing the calibration.";
102 }
103 if (!clearCalibration) {
104 if (numWays == 0) {
105 message = "You must specify only one of CalibrationFile, "
106 "CalibrationWorkspace, OffsetsWorkspace.";
107 }
108 if (numWays > 1) {
109 message = "You must specify one of CalibrationFile, "
110 "CalibrationWorkspace, OffsetsWorkspace.";
111 }
112 }
113
114 if (!message.empty()) {
115 result["CalibrationFile"] = message;
116 result["CalibrationWorkspace"] = message;
117 }
118
119 return result;
120}
121
122void ApplyDiffCal::loadCalFile(const Workspace_sptr &inputWS, const std::string &filename) {
123 auto alg = createChildAlgorithm("LoadDiffCal");
124 alg->setProperty("InputWorkspace", inputWS);
125 alg->setPropertyValue("Filename", filename);
126 alg->setProperty<bool>("MakeCalWorkspace", true);
127 alg->setProperty<bool>("MakeGroupingWorkspace", false);
128 alg->setProperty<bool>("MakeMaskWorkspace", false);
129 alg->setPropertyValue("WorkspaceName", "temp");
130 alg->executeAsChildAlg();
131
132 m_calibrationWS = alg->getProperty("OutputCalWorkspace");
133}
134
136 m_calibrationWS = getProperty("CalibrationWorkspace");
137 if (m_calibrationWS)
138 return; // nothing more to do
139
140 OffsetsWorkspace_sptr offsetsWS = getProperty("OffsetsWorkspace");
141 if (offsetsWS) {
142 auto alg = createChildAlgorithm("ConvertDiffCal");
143 alg->setProperty("OffsetsWorkspace", offsetsWS);
144 alg->executeAsChildAlg();
145 m_calibrationWS = alg->getProperty("OutputWorkspace");
146 m_calibrationWS->setTitle(offsetsWS->getTitle());
147 return;
148 }
149
150 const std::string calFileName = getPropertyValue("CalibrationFile");
151 if (!calFileName.empty()) {
152 progress(0.0, "Reading calibration file");
153 loadCalFile(inputWS, calFileName);
154 return;
155 }
156
157 throw std::runtime_error("Failed to determine calibration information");
158}
159
160//----------------------------------------------------------------------------------------------
164
165 Workspace_sptr InstrumentWorkspace = getProperty("InstrumentWorkspace");
166 // validateInputs guarantees this will be an ExperimentInfo object
167 auto experimentInfo = std::dynamic_pointer_cast<API::ExperimentInfo>(InstrumentWorkspace);
168 auto instrument = experimentInfo->getInstrument();
169 auto &paramMap = experimentInfo->instrumentParameters();
170 bool clearCalibration = getProperty("ClearCalibration");
171 if (clearCalibration) {
172 paramMap.clearParametersByName("DIFC");
173 paramMap.clearParametersByName("DIFA");
174 paramMap.clearParametersByName("TZERO");
175 } else {
176 this->getCalibrationWS(InstrumentWorkspace);
177
178 Column_const_sptr detIdColumn = m_calibrationWS->getColumn("detid");
179 Column_const_sptr difcColumn = m_calibrationWS->getColumn("difc");
180 Column_const_sptr difaColumn = m_calibrationWS->getColumn("difa");
181 Column_const_sptr tzeroColumn = m_calibrationWS->getColumn("tzero");
182
183 auto detids = instrument->getDetectorIDs();
184 std::sort(detids.begin(), detids.end());
185
186 for (size_t i = 0; i < m_calibrationWS->rowCount(); ++i) {
187 auto detid = static_cast<detid_t>((*detIdColumn)[i]);
188 double difc = (*difcColumn)[i];
189 double difa = (*difaColumn)[i];
190 double tzero = (*tzeroColumn)[i];
191
192 if (std::binary_search(detids.begin(), detids.end(), detid)) {
193 // found the detector
194 auto det = instrument->getDetector(detid);
195 paramMap.addDouble(det->getComponentID(), "DIFC", difc);
196 paramMap.addDouble(det->getComponentID(), "DIFA", difa);
197 paramMap.addDouble(det->getComponentID(), "TZERO", tzero);
198 } else {
199 // cannot find the detector, use default zero for difc, difa, and tzero
200 g_log.information() << "Cannot find det " << detid << ", skipping.\n";
201 }
202 }
203 }
204}
205
206} // namespace Mantid::DataHandling
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.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
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
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
@ OptionalLoad
to specify a file to read but the file doesn't have to exist
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
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:136
The concrete, templated class for properties.
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
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:233
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.
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