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
16
17#include <boost/lexical_cast.hpp>
18#include <boost/tuple/tuple.hpp>
19
20#include <fstream>
21
22namespace Mantid::DataHandling {
23
24// Register the algorithm into the AlgorithmFactory
25DECLARE_ALGORITHM(SaveParameterFile)
26
27using namespace Kernel;
28using namespace API;
29using namespace Geometry;
30
31using namespace Poco;
32
33//----------------------------------------------------------------------------------------------
35const std::string SaveParameterFile::name() const { return "SaveParameterFile"; }
36
38int SaveParameterFile::version() const { return 1; }
39
41const std::string SaveParameterFile::category() const { return "DataHandling\\Instrument"; }
42
43//----------------------------------------------------------------------------------------------
44
45//----------------------------------------------------------------------------------------------
50 std::make_unique<WorkspaceProperty<>>("Workspace", "", Direction::Input, std::make_shared<InstrumentValidator>()),
51 "Workspace to save the instrument parameters from.");
52
53 declareProperty(std::make_unique<API::FileProperty>("Filename", "", API::FileProperty::Save, ".xml"),
54 "The name of the file into which the instrument parameters will be "
55 "saved.");
56
57 declareProperty("LocationParameters", false, "Save the location parameters used to calibrate the instrument.",
59}
60
61//----------------------------------------------------------------------------------------------
65 const MatrixWorkspace_const_sptr ws = getProperty("Workspace");
66 const bool saveLocationParams = getProperty("LocationParameters");
67 const std::string filename = getProperty("Filename");
68
69 const Instrument_const_sptr instrument = ws->getInstrument();
70 // Create legacy parameter map with positions and other parameters extracted
71 // from DetectorInfo.
72 const ParameterMap_sptr params = instrument->makeLegacyParameterMap();
73
74 // maps components to a tuple of parameters' name, type, and value
75 std::map<ComponentID, std::vector<boost::tuple<std::string, std::string, std::string>>> toSave;
76
77 // Set up a progress bar
78 Progress prog(this, 0.0, 0.3, params->size());
79
80 // Build a list of parameters to save;
81 for (auto const &paramsIt : params->entries()) {
83 break;
84 prog.report("Generating parameters");
85 const ComponentID cID = paramsIt.first;
86 const std::string pName = paramsIt.second->name();
87 const std::string pType = paramsIt.second->type();
88 const std::string pValue = paramsIt.second->asString();
89
90 if (pName == "x" || pName == "y" || pName == "z" || pName == "r-position" || pName == "t-position" ||
91 pName == "p-position" || pName == "rotx" || pName == "roty" || pName == "rotz") {
92 g_log.warning() << "The parameter name '" << pName << "' is reserved and has not been saved. "
93 << "Please contact the Mantid team for more information.";
94 continue;
95 }
96
97 if (pName == "pos") {
98 if (saveLocationParams) {
99 V3D pos;
100 std::istringstream pValueSS(pValue);
101 pos.readPrinted(pValueSS);
102 toSave[cID].emplace_back("x", "double", boost::lexical_cast<std::string>(pos.X()));
103 toSave[cID].emplace_back("y", "double", boost::lexical_cast<std::string>(pos.Y()));
104 toSave[cID].emplace_back("z", "double", boost::lexical_cast<std::string>(pos.Z()));
105 }
106 } else if (pName == "rot") {
107 if (saveLocationParams) {
108 V3D rot;
109 std::istringstream pValueSS(pValue);
110 rot.readPrinted(pValueSS);
111 toSave[cID].emplace_back("rotx", "double", boost::lexical_cast<std::string>(rot.X()));
112 toSave[cID].emplace_back("roty", "double", boost::lexical_cast<std::string>(rot.Y()));
113 toSave[cID].emplace_back("rotz", "double", boost::lexical_cast<std::string>(rot.Z()));
114 }
115 }
116 // If it isn't a position or rotation parameter, we can just add it to the
117 // list to save directly and move on.
118 else {
119 if (pType == "fitting") {
120 // With fitting parameters we do something special (i.e. silly)
121 // We create an entire XML element to be inserted into the output,
122 // instead of just giving a single fixed value
123 const auto &fitParam = paramsIt.second->value<FitParameter>();
124 const std::string fpName = fitParam.getFunction() + ":" + fitParam.getName();
125 std::stringstream fpValue;
126 fpValue << "<formula";
127 fpValue << " eq=\"" << fitParam.getFormula() << "\"";
128 fpValue << " unit=\"" << fitParam.getFormulaUnit() << "\"";
129 fpValue << " result-unit=\"" << fitParam.getResultUnit() << "\"";
130 fpValue << "/>";
131 toSave[cID].emplace_back(boost::make_tuple(fpName, "fitting", fpValue.str()));
132 } else
133 toSave[cID].emplace_back(boost::make_tuple(pName, pType, pValue));
134 }
135 }
136
137 // Begin writing the XML manually
138 std::ofstream file(filename.c_str(), std::ofstream::trunc);
139 file << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
140 file << "<parameter-file instrument=\"" << instrument->getName() << "\"";
141 file << " valid-from=\"" << ws->instrumentMetadata().validFromDate().toISO8601String() << "\">\n";
142
143 prog.resetNumSteps(static_cast<int64_t>(toSave.size()), 0.6, 1.0);
144 // Iterate through all the parameters we want to save and build an XML
145 // document out of them.
146 for (const auto &comp : toSave) {
148 break;
149 prog.report("Saving parameters");
150 // Component data
151 const ComponentID cID = comp.first;
152 const std::string cFullName = cID->getFullName();
153 const IDetector *cDet = dynamic_cast<IDetector *>(cID);
154 const detid_t cDetID = (cDet) ? cDet->getID() : 0;
155
156 file << " <component-link";
157 if (cDetID != 0)
158 file << " id=\"" << cDetID << "\"";
159 file << " name=\"" << cFullName << "\">\n";
160 for (const auto &param : comp.second) {
161 const std::string pName = param.get<0>();
162 const std::string pType = param.get<1>();
163 const std::string pValue = param.get<2>();
164
165 // With fitting parameters, we're actually inserting an entire element, as
166 // constructed above
167 if (pType == "fitting") {
168 file << " <parameter name=\"" << pName << "\" type=\"fitting\" >\n";
169 file << " " << pValue << "\n";
170 file << " </parameter>\n";
171 } else {
172 file << " <parameter name=\"" << pName << "\"" << (pType == "string" ? " type=\"string\"" : "")
173 << ">\n";
174 file << " <value val=\"" << pValue << "\"/>\n";
175 file << " </parameter>\n";
176 }
177 }
178 file << " </component-link>\n";
179 }
180 file << "</parameter-file>\n";
181
182 file.flush();
183 file.close();
184}
185
186} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:542
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:423
@ 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
base class for Geometric IComponent
Definition IComponent.h:53
virtual std::string type() const
Returns a string representation of the IComponent type.
Definition IComponent.h:56
virtual std::string getFullName() const =0
Get the IComponent full path name.
Interface class for detector objects.
Definition IDetector.h:43
virtual detid_t getID() const =0
Get the detector ID.
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:34
constexpr double X() const noexcept
Get x.
Definition V3D.h:238
constexpr double Y() const noexcept
Get y.
Definition V3D.h:239
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:240
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< ParameterMap > ParameterMap_sptr
ParameterMap shared pointer typedef.
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:53