Mantid
Loading...
Searching...
No Matches
SaveParameterFile.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 <boost/lexical_cast.hpp>
20#include <boost/tuple/tuple.hpp>
21
22#include <fstream>
23
24namespace Mantid::DataHandling {
25
26// Register the algorithm into the AlgorithmFactory
27DECLARE_ALGORITHM(SaveParameterFile)
28
29using namespace Kernel;
30using namespace API;
31using namespace Geometry;
32
33using namespace Poco;
34
35//----------------------------------------------------------------------------------------------
37const std::string SaveParameterFile::name() const { return "SaveParameterFile"; }
38
40int SaveParameterFile::version() const { return 1; }
41
43const std::string SaveParameterFile::category() const { return "DataHandling\\Instrument"; }
44
45//----------------------------------------------------------------------------------------------
46
47//----------------------------------------------------------------------------------------------
52 std::make_unique<WorkspaceProperty<>>("Workspace", "", Direction::Input, std::make_shared<InstrumentValidator>()),
53 "Workspace to save the instrument parameters from.");
54
55 declareProperty(std::make_unique<API::FileProperty>("Filename", "", API::FileProperty::Save, ".xml"),
56 "The name of the file into which the instrument parameters will be "
57 "saved.");
58
59 declareProperty("LocationParameters", false, "Save the location parameters used to calibrate the instrument.",
61}
62
63//----------------------------------------------------------------------------------------------
67 const MatrixWorkspace_const_sptr ws = getProperty("Workspace");
68 const bool saveLocationParams = getProperty("LocationParameters");
69 const std::string filename = getProperty("Filename");
70
71 const Instrument_const_sptr instrument = ws->getInstrument();
72 // The parameters, with positions and other parameters extracted from DetectorInfo
73 const auto params = instrument->legacyParameters();
74
75 const auto &componentInfo = ws->componentInfo();
76 const auto &detectorInfo = ws->detectorInfo();
77
78 // maps component indices to a tuple of parameters' name, type, and value
79 std::map<size_t, std::vector<boost::tuple<std::string, std::string, std::string>>> toSave;
80
81 // Set up a progress bar
82 Progress prog(this, 0.0, 0.3, params.size());
83
84 // Build a list of parameters to save;
85 for (auto const &paramsIt : params) {
87 break;
88 prog.report("Generating parameters");
89 const size_t cID = paramsIt.first;
90 const std::string pName = paramsIt.second->name();
91 const std::string pType = paramsIt.second->type();
92 const std::string pValue = paramsIt.second->asString();
93
94 if (pName == "x" || pName == "y" || pName == "z" || pName == "r-position" || pName == "t-position" ||
95 pName == "p-position" || pName == "rotx" || pName == "roty" || pName == "rotz") {
96 g_log.warning() << "The parameter name '" << pName << "' is reserved and has not been saved. "
97 << "Please contact the Mantid team for more information.";
98 continue;
99 }
100
101 if (pName == "pos") {
102 if (saveLocationParams) {
103 V3D pos;
104 std::istringstream pValueSS(pValue);
105 pos.readPrinted(pValueSS);
106 toSave[cID].emplace_back("x", "double", boost::lexical_cast<std::string>(pos.X()));
107 toSave[cID].emplace_back("y", "double", boost::lexical_cast<std::string>(pos.Y()));
108 toSave[cID].emplace_back("z", "double", boost::lexical_cast<std::string>(pos.Z()));
109 }
110 } else if (pName == "rot") {
111 if (saveLocationParams) {
112 V3D rot;
113 std::istringstream pValueSS(pValue);
114 rot.readPrinted(pValueSS);
115 toSave[cID].emplace_back("rotx", "double", boost::lexical_cast<std::string>(rot.X()));
116 toSave[cID].emplace_back("roty", "double", boost::lexical_cast<std::string>(rot.Y()));
117 toSave[cID].emplace_back("rotz", "double", boost::lexical_cast<std::string>(rot.Z()));
118 }
119 }
120 // If it isn't a position or rotation parameter, we can just add it to the
121 // list to save directly and move on.
122 else {
123 if (pType == "fitting") {
124 // With fitting parameters we do something special (i.e. silly)
125 // We create an entire XML element to be inserted into the output,
126 // instead of just giving a single fixed value
127 const auto &fitParam = paramsIt.second->value<FitParameter>();
128 const std::string fpName = fitParam.getFunction() + ":" + fitParam.getName();
129 std::stringstream fpValue;
130 fpValue << "<formula";
131 fpValue << " eq=\"" << fitParam.getFormula() << "\"";
132 fpValue << " unit=\"" << fitParam.getFormulaUnit() << "\"";
133 fpValue << " result-unit=\"" << fitParam.getResultUnit() << "\"";
134 fpValue << "/>";
135 toSave[cID].emplace_back(boost::make_tuple(fpName, "fitting", fpValue.str()));
136 } else
137 toSave[cID].emplace_back(boost::make_tuple(pName, pType, pValue));
138 }
139 }
140
141 // Begin writing the XML manually
142 std::ofstream file(filename.c_str(), std::ofstream::trunc);
143 file << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
144 file << "<parameter-file instrument=\"" << ws->getInstrumentName() << "\"";
145 file << " valid-from=\"" << ws->instrumentMetadata().validFromDate().toISO8601String() << "\">\n";
146
147 prog.resetNumSteps(static_cast<int64_t>(toSave.size()), 0.6, 1.0);
148 // Iterate through all the parameters we want to save and build an XML
149 // document out of them.
150 for (const auto &comp : toSave) {
152 break;
153 prog.report("Saving parameters");
154 // Component data
155 const size_t cID = comp.first;
156 const std::string cFullName = componentInfo.fullName(cID);
157 const detid_t cDetID = componentInfo.isDetector(cID) ? detectorInfo.detectorIDs()[cID] : 0;
158
159 file << " <component-link";
160 if (cDetID != 0)
161 file << " id=\"" << cDetID << "\"";
162 file << " name=\"" << cFullName << "\">\n";
163 for (const auto &param : comp.second) {
164 const std::string pName = param.get<0>();
165 const std::string pType = param.get<1>();
166 const std::string pValue = param.get<2>();
167
168 // With fitting parameters, we're actually inserting an entire element, as
169 // constructed above
170 if (pType == "fitting") {
171 file << " <parameter name=\"" << pName << "\" type=\"fitting\" >\n";
172 file << " " << pValue << "\n";
173 file << " </parameter>\n";
174 } else {
175 file << " <parameter name=\"" << pName << "\"" << (pType == "string" ? " type=\"string\"" : "")
176 << ">\n";
177 file << " <value val=\"" << pValue << "\"/>\n";
178 file << " </parameter>\n";
179 }
180 }
181 file << " </component-link>\n";
182 }
183 file << "</parameter-file>\n";
184
185 file.flush();
186 file.close();
187}
188
189} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:547
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.
Kernel::Logger & g_log
Definition Algorithm.h:426
@ Save
to specify a file to write to, the file may or may not exist
Helper class for reporting progress from algorithms.
Definition Progress.h:25
bool hasCancellationBeenRequested() const override
Definition Progress.cpp:85
A property class for workspaces.
int version() const override
Algorithm's version for identification.
const std::string category() const override
Algorithm's category for identification.
void init() override
Initialize the algorithm's properties.
const std::string name() const override
Algorithm's name for identification.
void exec() override
Execute the algorithm.
Store information about a fitting parameter such as its value if it is constrained or tied.
const std::string & getFunction() const
get function
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
void resetNumSteps(int64_t nsteps, double start, double end)
Change the number of steps between start/end.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
Class for 3D vectors.
Definition V3D.h:35
constexpr double X() const noexcept
Get x.
Definition V3D.h:239
constexpr double Y() const noexcept
Get y.
Definition V3D.h:240
void readPrinted(std::istream &)
Read data from a stream in the format returned by printSelf ("[x,y,z]").
Definition V3D.cpp:356
constexpr double Z() const noexcept
Get z.
Definition V3D.h:241
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
int32_t detid_t
Typedef for a detector ID.
@ Input
An input workspace.
Definition Property.h:54