Mantid
Loading...
Searching...
No Matches
SaveCanSAS1D.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
10#include "MantidAPI/Run.h"
12
15
20
21#include <boost/algorithm/string/split.hpp>
22#include <boost/algorithm/string/trim.hpp>
23#include <memory>
24
25#include <list>
26
27namespace {
28void encode(std::string &data) {
29 std::string buffer;
30 buffer.reserve(data.size());
31
32 for (auto const &element : data) {
33 switch (element) {
34 case '&':
35 buffer.append("&amp;");
36 break;
37 case '\"':
38 buffer.append("&quot;");
39 break;
40 case '\'':
41 buffer.append("&apos;");
42 break;
43 case '<':
44 buffer.append("&lt;");
45 break;
46 case '>':
47 buffer.append("&gt;");
48 break;
49 default:
50 buffer.push_back(element);
51 }
52 }
53
54 data.swap(buffer);
55}
56} // namespace
57
58using namespace Mantid::Kernel;
59using namespace Mantid::Geometry;
60using namespace Mantid::API;
61
62namespace Mantid::DataHandling {
63
64// Register the algorithm into the AlgorithmFactory
66
67
68void SaveCanSAS1D::init() {
69 declareProperty(
70 std::make_unique<API::WorkspaceProperty<>>("InputWorkspace", "", Kernel::Direction::Input,
71 std::make_shared<API::WorkspaceUnitValidator>("MomentumTransfer")),
72 "The input workspace, which must be in units of Q. Must be a 1D workspace.");
73 declareProperty(std::make_unique<API::FileProperty>("Filename", "", API::FileProperty::Save, ".xml"),
74 "The name of the xml file to save");
75
76 std::vector<std::string> radiation_source{"Spallation Neutron Source",
77 "Pulsed Reactor Neutron Source",
78 "Reactor Neutron Source",
79 "Synchrotron X-ray Source",
80 "Pulsed Muon Source",
81 "Rotating Anode X-ray",
82 "Fixed Tube X-ray",
83 "neutron",
84 "x-ray",
85 "muon",
86 "electron"};
87 declareProperty("RadiationSource", "Spallation Neutron Source",
88 std::make_shared<Kernel::StringListValidator>(radiation_source), "The type of radiation used.");
89 declareProperty("Append", false,
90 "Selecting append allows the workspace to "
91 "be added to an existing canSAS 1-D file as "
92 "a new SASentry");
93 declareProperty("Process", "", "Text to append to Process section");
94 declareProperty("DetectorNames", "",
95 "Specify in a comma separated list, which detectors to store "
96 "information about; \nwhere each name must match a name "
97 "given for a detector in the [[IDF|instrument definition "
98 "file (IDF)]]. \nIDFs are located in the instrument "
99 "sub-directory of the Mantid install directory.");
100
101 // Collimation information
102 std::vector<std::string> collimationGeometry{
103 "Cylinder", "FlatPlate", "Flat plate", "Disc", "Unknown",
104 };
105 declareProperty("Geometry", "Unknown", std::make_shared<Kernel::StringListValidator>(collimationGeometry),
106 "The geometry type of the collimation.");
107 auto mustBePositiveOrZero = std::make_shared<Kernel::BoundedValidator<double>>();
108 mustBePositiveOrZero->setLower(0);
109 declareProperty("SampleHeight", 0.0, mustBePositiveOrZero,
110 "The height of the collimation element in mm. If specified "
111 "as 0 it will not be recorded.");
112 declareProperty("SampleWidth", 0.0, mustBePositiveOrZero,
113 "The width of the collimation element in mm. If specified as "
114 "0 it will not be recorded.");
115
116 // Sample information
117 declareProperty("SampleThickness", 0.0, mustBePositiveOrZero,
118 "The thickness of the sample in mm. If specified as 0 it "
119 "will not be recorded.");
120}
128void SaveCanSAS1D::setOtherProperties(API::IAlgorithm *alg, const std::string &propertyName,
129 const std::string &propertyValue, int perioidNum) {
130 // call the base class method
131 Algorithm::setOtherProperties(alg, propertyName, propertyValue, perioidNum);
132
133 if ((propertyName == "Append") && (perioidNum > 1)) {
134 alg->setPropertyValue(propertyName, "1");
135 }
136}
139 m_workspace = getProperty("InputWorkspace");
140 if (!m_workspace) {
141 throw std::invalid_argument("Invalid inputworkspace ,Error in SaveCanSAS1D");
142 }
143
144 if (m_workspace->getNumberHistograms() > 1) {
145 throw std::invalid_argument("Error in SaveCanSAS1D - more than one histogram.");
146 }
147
148 // write xml manually as the user requires a specific format were the
149 // placement of new line characters is controled
150 // and this can't be done in using the stylesheet part in Poco or libXML
152
153 m_outFile << "\n\t<SASentry name=\"" << m_workspace->getName() << "\">";
154
155 std::string sasTitle;
156 createSASTitleElement(sasTitle);
157 m_outFile << sasTitle;
158
159 std::string sasRun;
160 createSASRunElement(sasRun);
161 m_outFile << sasRun;
162
163 std::string dataUnit = m_workspace->YUnitLabel();
164 // look for xml special characters and replace with entity refrence
166
167 std::string sasData;
168 createSASDataElement(sasData, 0);
169 m_outFile << sasData;
170
171 std::string sasSample;
172 createSASSampleElement(sasSample);
173 m_outFile << sasSample;
174
175 // Recording the SAS instrument can throw, if there
176 // are no detecors present
177 std::string sasInstrument;
178 try {
179 createSASInstrument(sasInstrument);
181 throw;
182 } catch (std::runtime_error &) {
183 throw;
184 }
185 m_outFile << sasInstrument;
186
187 std::string sasProcess;
188 createSASProcessElement(sasProcess);
189 m_outFile << sasProcess;
190
191 std::string sasNote = "\n\t\t<SASnote>";
192 sasNote += "\n\t\t</SASnote>";
193 m_outFile << sasNote;
194
195 m_outFile << "\n\t</SASentry>";
196 m_outFile << "\n</SASroot>";
197 m_outFile.close();
198}
206void SaveCanSAS1D::prepareFileToWriteEntry(const std::string &fileName) {
207 // reduce error handling code by making file access errors throw
208 m_outFile.exceptions(std::ios::eofbit | std::ios::failbit | std::ios::badbit);
209
210 bool append(getProperty("Append"));
211
212 // write xml manually as the user requires a specific format were the
213 // placement of new line characters is controled
214 // and this can't be done in using the stylesheet part in Poco or libXML
215 if (append) {
216 append = openForAppending(fileName);
217 }
218
219 if (append) {
221 } else {
222 writeHeader(fileName);
223 }
224}
229bool SaveCanSAS1D::openForAppending(const std::string &filename) {
230 try {
231 m_outFile.open(filename.c_str(), std::ios::out | std::ios::in);
232 // check if the file already has data
233 m_outFile.seekg(0, std::ios::end);
234 if (m_outFile.tellg() > 0) {
235 // a file exists with data leave the file open and state that appending
236 // should be possible
237 return true;
238 }
239 } catch (std::fstream::failure &) {
240 g_log.information() << "File " << filename << " couldn't be opened for a appending, will try to create the file\n";
241 }
242 m_outFile.clear();
243 if (m_outFile.is_open()) {
244 m_outFile.close();
245 }
246 return false;
247}
254 const int rootTagLen = static_cast<int>(std::string("</SASroot>").length());
255
256 try {
257 static const int LAST_TAG_LEN = 11;
258
259 // move to the place _near_ the end of the file where the data will be
260 // appended to
261 m_outFile.seekg(-LAST_TAG_LEN - rootTagLen, std::ios::end);
262 char test_tag[LAST_TAG_LEN + 1];
263 m_outFile.read(test_tag, LAST_TAG_LEN);
264 // check we're in the correct place in the file
265 static const char LAST_TAG[LAST_TAG_LEN + 1] = "</SASentry>";
266 if (std::string(test_tag, LAST_TAG_LEN) != std::string(LAST_TAG, LAST_TAG_LEN)) {
267 // we'll allow some extra charaters so there is some variablity in where
268 // the tag might be found
269 bool tagFound(false);
270 // UNCERT should be less than the length of a SASentry
271 static const int UNCERT = 20;
272 for (int i = 1; i < UNCERT; ++i) {
273 // together this seek and read move the file pointer back on byte at a
274 // time and read
275 m_outFile.seekg(-i - LAST_TAG_LEN - rootTagLen, std::ios::end);
276 m_outFile.read(test_tag, LAST_TAG_LEN);
277 std::string read = std::string(test_tag, LAST_TAG_LEN);
278 if (read == std::string(LAST_TAG, LAST_TAG_LEN)) {
279 tagFound = true;
280 break;
281 }
282 }
283 if (!tagFound) {
284 throw std::logic_error("Couldn't find the end of the existing data, "
285 "missing </SASentry> tag");
286 }
287 }
288 // prepare to write to the place found by reading
289 m_outFile.seekp(m_outFile.tellg(), std::ios::beg);
290 } catch (std::fstream::failure &) {
291 // give users more explaination about no being able to read their files
292 throw std::logic_error("Trouble reading existing data in the output file, "
293 "are you appending to an invalid CanSAS1D file?");
294 }
295}
301void SaveCanSAS1D::writeHeader(const std::string &fileName) {
302 try {
303 m_outFile.open(fileName.c_str(), std::ios::out | std::ios::trunc);
304 // write the file header
305 m_outFile << "<?xml version=\"1.0\"?>\n"
306 << "<?xml-stylesheet type=\"text/xsl\" "
307 "href=\"cansasxml-html.xsl\" ?>\n";
308 std::string sasroot;
309 createSASRootElement(sasroot);
310 m_outFile << sasroot;
311 } catch (std::fstream::failure &) {
312 throw Exception::FileError("Error opening the output file for writing", fileName);
313 }
314}
320 std::string specialchars = "&<>'\"";
321 std::string::size_type searchIndex = 0;
322 std::string::size_type findIndex;
323 for (char specialchar : specialchars) {
324 while (searchIndex < input.length()) {
325 findIndex = input.find(specialchar, searchIndex);
326 if (findIndex != std::string::npos) {
327 searchIndex = findIndex + 1;
328 // replace with xml entity refrence
329 replacewithEntityReference(input, findIndex);
330
331 } else {
332 searchIndex = 0;
333 break;
334 }
335 }
336 }
337}
338
344void SaveCanSAS1D::replacewithEntityReference(std::string &input, const std::string::size_type &index) {
345 std::basic_string<char>::reference str = input.at(index);
346 switch (str) {
347 case '&':
348 input.replace(index, 1, "&amp;");
349 break;
350 case '<':
351 input.replace(index, 1, "&lt;");
352 break;
353 case '>':
354 input.replace(index, 1, "&gt;");
355 break;
356 case '\'':
357 input.replace(index, 1, "&apos;");
358 break;
359 case '\"':
360 input.replace(index, 1, "&quot;");
361 break;
362 }
363}
364
368void SaveCanSAS1D::createSASRootElement(std::string &rootElem) {
369 rootElem = "<SASroot version=\"1.0\"";
370 rootElem += "\n\t\t xmlns=\"cansas1d/1.0\"";
371 rootElem += "\n\t\t xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"";
372 rootElem += "\n\t\t xsi:schemaLocation=\"cansas1d/1.0 "
373 "http://svn.smallangles.net/svn/canSAS/1dwg/trunk/"
374 "cansas1d.xsd\">";
375}
376
380void SaveCanSAS1D::createSASTitleElement(std::string &sasTitle) {
381 std::string title = m_workspace->getTitle();
382 // look for xml special characters and replace with entity refrence
384 sasTitle = "\n\t\t<Title>";
385 sasTitle += title;
386 sasTitle += "</Title>";
387}
388
392void SaveCanSAS1D::createSASRunElement(std::string &sasRun) {
393 // initialise the run number to an empty string, this may or may not be
394 // changed later
395 std::string run;
396 if (m_workspace->run().hasProperty("run_number")) {
397 Kernel::Property const *logP = m_workspace->run().getLogData("run_number");
398 run = logP->value();
399 } else {
400 g_log.debug() << "Didn't find RunNumber log in workspace. Writing "
401 "<Run></Run> to the CANSAS file\n";
402 }
403
405
406 sasRun = "\n\t\t<Run>";
407 sasRun += run;
408 sasRun += "</Run>";
409}
410
415void SaveCanSAS1D::createSASDataElement(std::string &sasData, size_t workspaceIndex) {
416 std::string dataUnit = m_workspace->YUnitLabel();
417 // look for xml special characters and replace with entity refrence
419
420 // Workspaces that come out of the ISIS SANS reduction have had their
421 // YUnitLabel
422 // changed to "I(q) (cm-1)", but the CanSAS schema requires that the intensity
423 // unit
424 // be "1/cm"... In lieu of a better way to handle YUnitLabels, (and trying to
425 // avoid
426 // *always* writing out "1/cm") we have the following (brittle) if-statement.
427 if (dataUnit == "I(q) (cm-1)")
428 dataUnit = "1/cm";
429
430 const auto intensities = m_workspace->points(workspaceIndex);
431 auto intensityDeltas = m_workspace->pointStandardDeviations(workspaceIndex);
432 if (!intensityDeltas)
433 intensityDeltas = HistogramData::PointStandardDeviations(intensities.size(), 0.0);
434 const auto &ydata = m_workspace->y(workspaceIndex);
435 const auto &edata = m_workspace->e(workspaceIndex);
436 sasData += "\n\t\t<SASdata>";
437 for (size_t j = 0; j < ydata.size(); ++j) {
438 // x data is the QData in xml.If histogramdata take the mean
439 std::stringstream x;
440 x << intensities[j];
441 std::stringstream dx_str;
442 dx_str << intensityDeltas[j];
443 sasData += "\n\t\t\t<Idata><Q unit=\"1/A\">";
444 sasData += x.str();
445 sasData += "</Q>";
446 sasData += "<I unit=";
447 sasData += "\"";
448 sasData += dataUnit;
449 sasData += "\">";
451 std::stringstream y;
452 y << (ydata[j]);
453 sasData += y.str();
454 sasData += "</I>";
455
456 // workspace error data is the Idev data in the xml file
457 std::stringstream e;
458 e << edata[j];
459
460 sasData += "<Idev unit=";
461 sasData += "\"";
462 sasData += dataUnit;
463 sasData += "\">";
464
465 sasData += e.str();
466 sasData += "</Idev>";
467
468 sasData += "<Qdev unit=\"1/A\">";
469 sasData += dx_str.str();
470 sasData += "</Qdev>";
471
472 sasData += "</Idata>";
473 }
474 sasData += "\n\t\t</SASdata>";
475}
476
480void SaveCanSAS1D::createSASSampleElement(std::string &sasSample) {
481 sasSample = "\n\t\t<SASsample>";
482 // outFile<<sasSample;
483 std::string sasSampleId = "\n\t\t\t<ID>";
484 std::string sampleid = m_workspace->getTitle();
485 // look for xml special characters and replace with entity refrence
487 sasSampleId += sampleid;
488 sasSampleId += "</ID>";
489 sasSample += sasSampleId;
490 // Add sample thickness information here. We only add it if
491 // has been given a value larger than 0
492 double thickness = getProperty("SampleThickness");
493 if (thickness > 0) {
494 std::string thicknessTag = "\n\t\t\t<thickness unit=\"mm\">";
495 thicknessTag += std::to_string(thickness);
496 thicknessTag += "</thickness>";
497 sasSample += thicknessTag;
498 }
499 sasSample += "\n\t\t</SASsample>";
500}
501
505void SaveCanSAS1D::createSASSourceElement(std::string &sasSource) {
506 sasSource = "\n\t\t\t<SASsource>";
507 // outFile<<sasSource;
508
509 std::string radiation_source = getPropertyValue("RadiationSource");
510 std::string sasrad = "\n\t\t\t\t<radiation>";
511 sasrad += radiation_source;
512 sasrad += "</radiation>";
513 sasSource += sasrad;
514 // outFile<<sasrad;
515 sasSource += "\n\t\t\t</SASsource>";
516}
521void SaveCanSAS1D::createSASDetectorElement(std::string &sasDet) {
522 const std::string detectorNames = getProperty("DetectorNames");
523
524 if (detectorNames.empty()) {
525 sasDet += "\n\t\t\t<SASdetector>";
526 std::string sasDetname = "\n\t\t\t\t<name/>";
527 sasDet += sasDetname;
528 sasDet += "\n\t\t\t</SASdetector>";
529 return;
530 }
531
532 std::list<std::string> detList;
533 using std::placeholders::_1;
534 boost::algorithm::split(detList, detectorNames, std::bind(std::equal_to<char>(), _1, ','));
535 for (auto detectorName : detList) {
536 boost::algorithm::trim(detectorName);
537
538 // get first component with name detectorName in IDF
539 std::shared_ptr<const IComponent> comp = m_workspace->getInstrument()->getComponentByName(detectorName);
540 if (comp != std::shared_ptr<const IComponent>()) {
541 sasDet += "\n\t\t\t<SASdetector>";
542
543 std::string sasDetname = "\n\t\t\t\t<name>";
544 sasDetname += detectorName;
545 sasDetname += "</name>";
546 sasDet += sasDetname;
547
548 std::string sasDetUnit = "\n\t\t\t\t<SDD unit=\"m\">";
549
550 std::stringstream sdd;
551 double distance = comp->getDistance(*m_workspace->getInstrument()->getSample());
552 sdd << distance;
553
554 sasDetUnit += sdd.str();
555 sasDetUnit += "</SDD>";
556
557 sasDet += sasDetUnit;
558 sasDet += "\n\t\t\t</SASdetector>";
559 } else {
560 g_log.notice() << "Detector with name " << detectorName
561 << " does not exist in the instrument of the workspace: " << m_workspace->getName() << '\n';
562 }
563 }
564}
565
569void SaveCanSAS1D::createSASProcessElement(std::string &sasProcess) {
570 sasProcess = "\n\t\t<SASprocess>";
571 // outFile<<sasProcess;
572
573 std::string sasProcname = "\n\t\t\t<name>";
574 sasProcname += "Mantid generated CanSAS1D XML";
575 sasProcname += "</name>";
576 sasProcess += sasProcname;
577
578 time_t rawtime;
579 time(&rawtime);
580
581 char temp[25];
582 strftime(temp, 25, "%d-%b-%Y %H:%M:%S", localtime(&rawtime));
583 std::string sasDate(temp);
584
585 std::string sasProcdate = "\n\t\t\t<date>";
586 sasProcdate += sasDate;
587 sasProcdate += "</date>";
588 sasProcess += sasProcdate;
589
590 std::string sasProcsvn = "\n\t\t\t<term name=\"svn\">";
591 sasProcsvn += MantidVersion::version();
592 sasProcsvn += "</term>";
593 sasProcess += sasProcsvn;
594
595 const API::Run &run = m_workspace->run();
596 std::string user_file;
597 if (run.hasProperty("UserFile")) {
598 user_file = run.getLogData("UserFile")->value();
599 }
600
601 std::string sasProcuserfile = "\n\t\t\t<term name=\"user_file\">";
602 sasProcuserfile += user_file;
603 sasProcuserfile += "</term>";
604 // outFile<<sasProcuserfile;
605 sasProcess += sasProcuserfile;
606
607 // Reduction process note, if available
608 std::string process_xml = getProperty("Process");
609 if (!process_xml.empty()) {
610 std::string processNote = "\n\t\t\t<SASprocessnote>";
611 encode(process_xml);
612 processNote += process_xml;
613 processNote += "</SASprocessnote>";
614 sasProcess += processNote;
615 } else {
616 sasProcess += "\n\t\t\t<SASprocessnote/>";
617 }
618
619 sasProcess += "\n\t\t</SASprocess>";
620}
621
641void SaveCanSAS1D::createSASInstrument(std::string &sasInstrument) {
642 sasInstrument = "\n\t\t<SASinstrument>";
643
644 // Set name(r)
645 std::string sasInstrName = "\n\t\t\t<name>";
646 std::string instrname = m_workspace->getInstrument()->getName();
647 // look for xml special characters and replace with entity refrence
649 sasInstrName += instrname;
650 sasInstrName += "</name>";
651 sasInstrument += sasInstrName;
652
653 // Set SASsource(r)
654 std::string sasSource;
655 createSASSourceElement(sasSource);
656 sasInstrument += sasSource;
657
658 // Set SAScollimation(r)
659 // Add the collimation. We add the collimation information if
660 // either the width of the height is different from 0
661 double collimationHeight = getProperty("SampleHeight");
662 double collimationWidth = getProperty("SampleWidth");
663 std::string sasCollimation = "\n\t\t\t<SAScollimation/>";
664 if (collimationHeight > 0 || collimationWidth > 0) {
665 sasCollimation = "\n\t\t\t<SAScollimation>";
666
667 // aperture with name
668 std::string collimationGeometry = getProperty("Geometry");
669 sasCollimation += "\n\t\t\t\t<aperture name=\"" + collimationGeometry + "\">";
670
671 // size
672 sasCollimation += "\n\t\t\t\t\t<size>";
673
674 // Width
675 sasCollimation += "\n\t\t\t\t\t\t<x unit=\"mm\">" + std::to_string(collimationWidth) + "</x>";
676 // Height
677 sasCollimation += "\n\t\t\t\t\t\t<y unit=\"mm\">" + std::to_string(collimationHeight) + "</y>";
678
679 sasCollimation += "\n\t\t\t\t\t</size>";
680 sasCollimation += "\n\t\t\t\t</aperture>";
681 sasCollimation += "\n\t\t\t</SAScollimation>";
682 }
683 sasInstrument += sasCollimation;
684
685 // Set SASdetector
686 std::string sasDet;
688 sasInstrument += sasDet;
689 sasInstrument += "\n\t\t</SASinstrument>";
690}
691} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
std::map< DeltaEMode::Type, std::string > index
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.
Kernel::Logger & g_log
Definition Algorithm.h:422
virtual void setOtherProperties(IAlgorithm *alg, const std::string &propertyName, const std::string &propertyValue, int periodNum)
Virtual method to set the non workspace properties for this algorithm.
@ Save
to specify a file to write to, the file may or may not exist
IAlgorithm is the interface implemented by the Algorithm base class.
Definition IAlgorithm.h:45
bool hasProperty(const std::string &name) const
Does the property exist on the object.
Kernel::Property * getLogData(const std::string &name) const
Access a single log entry.
Definition LogManager.h:141
This class stores information regarding an experimental run as a series of log entries.
Definition Run.h:35
A property class for workspaces.
bool openForAppending(const std::string &filename)
opens the named file if possible or returns false
void createSASSourceElement(std::string &sasSource)
this method creates a sasSource element
std::fstream m_outFile
an fstream object is used to write the xml manually as the user requires a specific format with new l...
void findEndofLastEntry()
Moves to the end of the last entry in the file.
void createSASTitleElement(std::string &sasTitle)
this method creates a sasTitle element
void createSASInstrument(std::string &sasInstrument)
this method creates a sasInstrument element
virtual void createSASRootElement(std::string &rootElem)
sasroot element
void setOtherProperties(API::IAlgorithm *alg, const std::string &propertyName, const std::string &propertyValue, int perioidNum) override
overriden method sets appending for workspace groups
void searchandreplaceSpecialChars(std::string &input)
this method searches for xml special characters and replace with entity references
void createSASProcessElement(std::string &sasProcess)
this method creates a sasProcess element
void createSASDataElement(std::string &sasData, size_t workspaceIndex)
this method creates a sasData element
void createSASDetectorElement(std::string &sasDet)
this method creates a sasDetector element
void createSASSampleElement(std::string &sasSample)
this method creates a sasSample element
virtual void writeHeader(const std::string &fileName)
Write xml header tags.
void prepareFileToWriteEntry(const std::string &fileName)
Opens the output file and, as necessary blanks it, writes the file header and moves the file pointer.
void createSASRunElement(std::string &sasRun)
this method creates a sasRun Element
API::MatrixWorkspace_const_sptr m_workspace
points to the workspace that will be written to file
void replacewithEntityReference(std::string &input, const std::string::size_type &index)
replaces the charcter at index in the input string with xml entity reference(eg.replace '&' with "&")
void exec() override
Overwrites Algorithm method.
Records the filename and the description of failure.
Definition Exception.h:98
Exception for when an item is not found in a collection.
Definition Exception.h:145
virtual void setPropertyValue(const std::string &name, const std::string &value)=0
Sets property value from a string.
void debug(const std::string &msg)
Logs at debug level.
Definition Logger.cpp:145
void notice(const std::string &msg)
Logs at notice level.
Definition Logger.cpp:126
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
static const char * version()
The full version number.
Base class for properties.
Definition Property.h:94
virtual std::string value() const =0
Returns the value of the property as a string.
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Input
An input workspace.
Definition Property.h:53