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