Mantid
Loading...
Searching...
No Matches
PDLoadCharacterizations.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 +
11#include "MantidAPI/TableRow.h"
17#include <Poco/File.h>
18#include <Poco/Path.h>
19#include <boost/algorithm/string.hpp>
20#include <boost/regex.hpp>
21#include <fstream>
22#include <set>
23
24using namespace Mantid::API;
25using namespace Mantid::Kernel;
26
27namespace Mantid::DataHandling {
28
29// Register the algorithm into the AlgorithmFactory
31
32namespace {
34static const std::string IPARM_KEY("Instrument parameter file:");
35static const std::string L1_KEY("L1");
36static const std::string ZERO("0.");
37static const std::string EXP_INI_VAN_KEY("Vana");
38static const std::string EXP_INI_EMPTY_KEY("VanaBg");
39static const std::string EXP_INI_CAN_KEY("MTc");
42static const size_t INFO_OFFSET_V1(6);
43// in the filenames vector, each index has a unique location
44static const int F_INDEX_V0 = 0;
45static const int F_INDEX_V1 = 1;
46static const int F_INDEX_EXPINI = 2;
47static const int F_INDEX_SIZE = 3;
49const boost::regex V1_TABLE_REG_EXP{"^freq.*\\s+w.*l.*\\s+"
50 "van\\s+van_back\\s+"
51 "mt_env\\s+mt_instr(.+)"};
52const boost::regex VERSION_REG_EXP{"^version=([0-9]+)"};
53
58std::vector<std::string> extra_columns(const std::vector<std::string> &filenames) {
59 // only version1 files generate extra columns
60 if (filenames[F_INDEX_V1].empty())
61 return std::vector<std::string>();
62
63 std::set<std::string> columnSet;
64
65 // parse the version1 file
66 std::ifstream file(filenames[F_INDEX_V1].c_str(), std::ios_base::binary);
67 if (!file) {
68 throw Exception::FileError("Unable to open file", filenames[F_INDEX_V1]);
69 }
70
71 for (std::string line = Strings::getLine(file); !file.eof(); Strings::getLine(file, line)) {
72 boost::smatch result;
73 // all instances of table headers
74 if (boost::regex_search(line, result, V1_TABLE_REG_EXP)) {
75 if (result.size() == 2) {
76 line = Strings::strip(result[1]);
78 for (const auto &token : tokenizer) {
79 columnSet.insert(token);
80 }
81 }
82 }
83 // TODO need to get the "extras" line
84 }
85 file.close();
86
87 // convert the result to a sorted vector
88 std::vector<std::string> columnnames;
89 std::copy(columnSet.begin(), columnSet.end(), std::back_inserter(columnnames));
90 std::sort(columnnames.begin(), columnnames.end());
91
92 return columnnames;
93}
94} // namespace
95
96//----------------------------------------------------------------------------------------------
98const std::string PDLoadCharacterizations::name() const { return "PDLoadCharacterizations"; }
99
101int PDLoadCharacterizations::version() const { return 1; }
102
104const std::string PDLoadCharacterizations::category() const { return "Workflow\\DataHandling"; }
105
106//----------------------------------------------------------------------------------------------
110 const auto exts = std::vector<std::string>({".txt"});
111 declareProperty(std::make_unique<MultipleFileProperty>("Filename", exts), "Characterizations file");
112 declareProperty(std::make_unique<FileProperty>("ExpIniFilename", "", FileProperty::OptionalLoad, "ini"),
113 "(Optional) exp.ini file used at NOMAD");
114
115 declareProperty(std::make_unique<WorkspaceProperty<ITableWorkspace>>("OutputWorkspace", "", Direction::Output),
116 "Output for the information of characterizations and runs");
117
118 declareProperty("IParmFilename", std::string(""), "Name of the gsas instrument parameter file.", Direction::Output);
119 declareProperty("PrimaryFlightPath", EMPTY_DBL(), "Primary flight path L1 of the powder diffractomer. ",
121 declareProperty(std::make_unique<ArrayProperty<int32_t>>("SpectrumIDs", Direction::Output),
122 "Spectrum Nos (note that it is not detector ID or workspace "
123 "indices). The list must be either empty or have a size "
124 "equal to input workspace's histogram number. ");
126 "Secondary flight (L2) paths for each detector. Number of L2 "
127 "given must be same as number of histogram.");
128 declareProperty(std::make_unique<ArrayProperty<double>>("Polar", Direction::Output),
129 "Polar angles (two thetas) for detectors. Number of 2theta "
130 "given must be same as number of histogram.");
131 declareProperty(std::make_unique<ArrayProperty<double>>("Azimuthal", Direction::Output),
132 "Azimuthal angles (out-of-plane) for detectors. "
133 "Number of azimuthal angles given must be same as number of histogram.");
134}
135
136//----------------------------------------------------------------------------------------------
140 auto filenames = this->getFilenames();
141 const std::vector<std::string> canColumnNames = extra_columns(filenames);
142
143 // setup the default table workspace for the characterization runs
145 wksp->addColumn("double", "frequency");
146 wksp->addColumn("double", "wavelength");
147 wksp->addColumn("int", "bank");
148 wksp->addColumn("str", "vanadium");
149 wksp->addColumn("str", "vanadium_background");
150 wksp->addColumn("str", "container");
151 wksp->addColumn("str", "empty_environment");
152 wksp->addColumn("str", "empty_instrument");
153 wksp->addColumn("str", "d_min"); // b/c it is an array for NOMAD
154 wksp->addColumn("str", "d_max"); // b/c it is an array for NOMAD
155 wksp->addColumn("double", "tof_min");
156 wksp->addColumn("double", "tof_max");
157 wksp->addColumn("double", "wavelength_min");
158 wksp->addColumn("double", "wavelength_max");
159 for (const auto &name : canColumnNames) {
160 wksp->addColumn("str", name); // all will be strings
161 }
162
163 // first file is assumed to be version 0
164 this->readVersion0(filenames[F_INDEX_V0], wksp);
165
166 // optional second file has container dependent information
167 this->readVersion1(filenames[F_INDEX_V1], wksp);
168
169 // optional exp.ini file for NOMAD
170 this->readExpIni(filenames[F_INDEX_EXPINI], wksp);
171
172 this->setProperty("OutputWorkspace", wksp);
173}
174
175namespace {
176int getVersion(const std::string &filename) {
177 std::ifstream file(filename.c_str(), std::ios_base::binary);
178 if (!file.is_open()) {
179 throw Exception::FileError("Unable to open file", filename);
180 }
181 // first line must be version string
182 std::string line = Strings::getLine(file);
183 file.close(); // cleanup
184
185 boost::smatch result;
186 if (boost::regex_search(line, result, VERSION_REG_EXP) && result.size() == 2) {
187 return boost::lexical_cast<int>(result[1]);
188 }
189
190 // otherwise it is a version=0
191 return 0;
192}
193
194template <typename T>
195T lexical_cast(const std::string &value, const std::string &filename, const int linenum,
196 const std::string &label = "") {
197 try {
198 return boost::lexical_cast<T>(value);
199 } catch (boost::bad_lexical_cast &e) {
200 // check for lexical cast and rethrow as parse error
201 if (label.empty())
202 throw Exception::ParseError("While converting \"" + value + "\": " + e.what(), filename, linenum);
203 else
204 throw Exception::ParseError("In " + label + " while converting \"" + value + "\": " + e.what(), filename,
205 linenum);
206 }
207}
208} // anonymous namespace
209
215std::vector<std::string> PDLoadCharacterizations::getFilenames() {
216 // get the values from the "Filename" property
217 std::vector<std::string> filenamesFromPropertyUnraveld;
218 std::vector<std::vector<std::string>> filenamesFromProperty = this->getProperty("Filename");
219 for (const auto &outer : filenamesFromProperty) {
220 filenamesFromPropertyUnraveld.insert(filenamesFromPropertyUnraveld.end(), outer.cbegin(), outer.cend());
221 }
222 // error check that something sensible was supplied
223 if (filenamesFromPropertyUnraveld.size() > 2) {
224 throw std::runtime_error("Can only specify up to 2 characterization files");
225 }
226
227 // sort out which file is which
228 int v0_index = -1;
229 int v1_index = -1;
230 for (size_t i = 0; i < filenamesFromPropertyUnraveld.size(); ++i) {
231 const int version = getVersion(filenamesFromPropertyUnraveld[i]);
232 g_log.debug() << "Found version " << version << " in \"" << filenamesFromPropertyUnraveld[i] << "\"\n";
233 if (version == 0)
234 v0_index = static_cast<int>(i);
235 else if (version == 1)
236 v1_index = static_cast<int>(i);
237 }
238
239 // fill the output array
240 std::vector<std::string> filenames(F_INDEX_SIZE);
241 if (v0_index >= 0)
242 filenames[F_INDEX_V0] = filenamesFromPropertyUnraveld[v0_index];
243 if (v1_index >= 0)
244 filenames[F_INDEX_V1] = filenamesFromPropertyUnraveld[v1_index];
245
246 // optional exp.ini file for NOMAD
247 std::string iniFilename = this->getProperty("ExpIniFilename");
248 if (!iniFilename.empty()) {
249 filenames[F_INDEX_EXPINI] = iniFilename;
250 }
251
252 // check that things exist
253 for (const auto &filename : filenames) {
254 if (filename.empty())
255 continue;
256
257 Poco::File file(filename);
258 if (!file.exists())
259 throw Exception::FileError("File does not exist", filename);
260 Poco::Path path(filename);
261 if (!path.isFile())
262 throw Exception::FileError("File is not a regular file", filename);
263 }
264 return filenames;
265}
266
275int PDLoadCharacterizations::readFocusInfo(std::ifstream &file, const std::string &filename) {
276 // end early if already at the end of the file
277 if (file.eof())
278 return 0;
279 // look at the first line available now
280 // start of the scan indicator means there are no focused positions
281 const auto peek = Strings::peekLine(file).substr(0, 2);
282 if (peek == "#S" || peek == "#L")
283 return 0;
284
285 std::vector<int32_t> specIds;
286 std::vector<double> l2;
287 std::vector<double> polar;
288 std::vector<double> azi;
289
290 // parse the file
291 // Strings::getLine skips blank lines and lines that start with #
292 int linenum = 1; // first line of file was a keyword that this existed
293 for (std::string line = Strings::getLine(file); !file.eof(); Strings::getLine(file, line)) {
294 linenum += 1;
295 line = Strings::strip(line);
296 // skip empty lines and "comments"
297 if (line.empty())
298 continue;
299 if (line.substr(0, 1) == "#")
300 continue;
301
302 std::vector<std::string> splitted;
303 boost::split(splitted, line, boost::is_any_of("\t "), boost::token_compress_on);
304 if (splitted[0] == L1_KEY) {
305 this->setProperty("PrimaryFlightPath", lexical_cast<double>(splitted[1], filename, linenum, "l1"));
306 break;
307 } else if (splitted.size() >= 3) { // specid, L2, theta
308 specIds.emplace_back(lexical_cast<int32_t>(splitted[0], filename, linenum, "spectrum number"));
309 l2.emplace_back(lexical_cast<double>(splitted[1], filename, linenum, "l2"));
310 polar.emplace_back(lexical_cast<double>(splitted[2], filename, linenum, "polar"));
311 if (splitted.size() >= 4 && (!splitted[3].empty())) { // azimuthal was specified
312 azi.emplace_back(lexical_cast<double>(splitted[3], filename, linenum, "azimuthal"));
313 } else { // just set it to zero
314 azi.emplace_back(0.);
315 }
316 }
317 }
318 // confirm that everything is the same length
319 if (specIds.size() != l2.size() || specIds.size() != polar.size() || specIds.size() != azi.size())
320 throw Exception::FileError("Found different number of spectra, L2 and polar angles", filename);
321
322 // set the values
323 this->setProperty("SpectrumIDs", specIds);
324 this->setProperty("L2", l2);
325 this->setProperty("Polar", polar);
326 this->setProperty("Azimuthal", azi);
327
328 return linenum;
329}
330
341void PDLoadCharacterizations::readCharInfo(std::ifstream &file, ITableWorkspace_sptr &wksp, const std::string &filename,
342 int linenum) {
343 // end early if already at the end of the file
344 if (file.eof())
345 return;
346
347 g_log.debug() << "readCharInfo(file, wksp)\n";
348
349 const size_t num_of_columns = wksp->columnCount();
350
351 // parse the file
352 for (std::string line = Strings::getLine(file); !file.eof(); Strings::getLine(file, line)) {
353 linenum += 1;
354 line = Strings::strip(line);
355 // skip empty lines and "comments"
356 if (line.empty())
357 continue;
358 if (line.substr(0, 1) == "#")
359 continue;
360 g_log.debug(line);
361 // parse the line
362 std::vector<std::string> splitted;
363 boost::split(splitted, line, boost::is_any_of("\t "), boost::token_compress_on);
364 while (splitted.size() < 12)
365 splitted.emplace_back(ZERO); // extra values default to zero
366
367 // add the row
368 API::TableRow row = wksp->appendRow();
369 row << lexical_cast<double>(splitted[0], filename, linenum, "frequency");
370 row << lexical_cast<double>(splitted[1], filename, linenum, "wavelength");
371 row << lexical_cast<int32_t>(splitted[2], filename, linenum, "bank");
372 row << splitted[3]; // vanadium
373 row << splitted[5]; // vanadium_background
374 row << splitted[4]; // container
375 row << "0"; // empty_environment
376 row << "0"; // empty_instrument
377 row << splitted[6]; // d_min
378 row << splitted[7]; // d_max
379 row << lexical_cast<double>(splitted[8], filename, linenum, "tof_min");
380 row << lexical_cast<double>(splitted[9], filename, linenum, "tof_max");
381 row << lexical_cast<double>(splitted[10], filename, linenum, "wavelength_min");
382 row << lexical_cast<double>(splitted[11], filename, linenum, "wavelength_max");
383 // pad all extras with empty string - the 14 required columns have
384 // already been added to the row
385 for (size_t i = 14; i < num_of_columns; ++i) {
386 row << "0";
387 }
388 }
389}
390
391void PDLoadCharacterizations::readVersion0(const std::string &filename, API::ITableWorkspace_sptr &wksp) {
392 // don't bother if there isn't a filename
393 if (filename.empty())
394 return;
395
396 g_log.debug() << "readVersion0(" << filename << ", wksp)\n";
397
398 std::ifstream file(filename.c_str(), std::ios_base::binary);
399 if (!file.is_open()) {
400 throw Exception::FileError("Unable to open version 0 file", filename);
401 }
402
403 // read the first line and decide what to do
404 int linenum = 0;
405 std::string firstLine = Strings::getLine(file);
406 if (firstLine.substr(0, IPARM_KEY.size()) == IPARM_KEY) {
407 firstLine = Strings::strip(firstLine.substr(IPARM_KEY.size()));
408 this->setProperty("IParmFilename", firstLine);
409 linenum = this->readFocusInfo(file, filename);
410 } else {
411 // things expect the L1 to be zero if it isn't set
412 this->setProperty("PrimaryFlightPath", 0.);
413 }
414
415 // now the rest of the file
416 this->readCharInfo(file, wksp, filename, linenum);
417
418 file.close();
419}
420
421namespace {
422bool closeEnough(const double left, const double right) {
423 // the same value
424 const double diff = fabs(left - right);
425 if (diff == 0.)
426 return true;
427
428 // same within 5%
429 const double relativeDiff = diff * 2 / (left + right);
430 return relativeDiff < .05;
431}
432
433int findRow(API::ITableWorkspace_sptr &wksp, const std::vector<std::string> &values) {
434 // don't have a good way to mark error location in these casts
435 const auto frequency = boost::lexical_cast<double>(values[0]);
436 const auto wavelength = boost::lexical_cast<double>(values[1]);
437
438 // find the correct row
439 const size_t numRows = wksp->rowCount();
440 for (size_t i = 0; i < numRows; ++i) {
441 const double frequencyRow = wksp->getRef<double>("frequency", i);
442 const double wavelengthRow = wksp->getRef<double>("wavelength", i);
443 if (closeEnough(frequency, frequencyRow) && closeEnough(wavelength, wavelengthRow)) {
444 return static_cast<int>(i);
445 }
446 }
447 // fall through behavior is -1
448 return -1;
449}
450
451void updateRow(API::ITableWorkspace_sptr &wksp, const size_t rowNum, const std::vector<std::string> &names,
452 const std::vector<std::string> &values) {
453 wksp->getRef<std::string>("vanadium", rowNum) = values[2];
454 wksp->getRef<std::string>("vanadium_background", rowNum) = values[3];
455 wksp->getRef<std::string>("empty_environment", rowNum) = values[4];
456 wksp->getRef<std::string>("empty_instrument", rowNum) = values[5];
457 for (size_t i = 0; i < names.size(); ++i) {
458 const auto name = names[i];
459 wksp->getRef<std::string>(name, rowNum) = values[i + INFO_OFFSET_V1];
460 }
461}
462} // namespace
463
464void PDLoadCharacterizations::readVersion1(const std::string &filename, API::ITableWorkspace_sptr &wksp) {
465 // don't bother if there isn't a filename
466 if (filename.empty())
467 return;
468
469 g_log.debug() << "readVersion1(" << filename << ", wksp)\n";
470
471 g_log.information() << "Opening \"" << filename << "\" as a version 1 file\n";
472 std::ifstream file(filename.c_str(), std::ios_base::binary);
473 if (!file.is_open()) {
474 throw Exception::FileError("Unable to open version 1 file", filename);
475 }
476
477 // first line must be version string
478 std::string line = Strings::getLine(file);
479 boost::smatch versionSearch;
480 if (boost::regex_search(line, versionSearch, VERSION_REG_EXP) && versionSearch.size() == 2) {
481 g_log.debug() << "Found version " << versionSearch[1] << "\n";
482 } else {
483 file.close();
484 throw Exception::ParseError("file must have \"version=1\" as the first line", filename, 0);
485 }
486
487 // store the names of the columns in order
488 int linenum = 0;
489 std::vector<std::string> columnNames;
490 for (Strings::getLine(file, line); !file.eof(); Strings::getLine(file, line)) {
491 linenum += 1;
492 line = Strings::strip(line);
493 if (line.empty())
494 continue;
495 if (line.substr(0, 1) == "#")
496 continue;
497 g_log.debug(line);
498
499 boost::smatch v1TableSearch;
500 // all instances of table headers
501 if (boost::regex_search(line, v1TableSearch, V1_TABLE_REG_EXP)) {
502 if (v1TableSearch.size() == 2) {
503 line = Strings::strip(v1TableSearch[1]);
505 std::move(tokenizer.begin(), tokenizer.end(), std::back_inserter(columnNames));
506 }
507 } else {
508 if (columnNames.empty()) // should never happen
509 throw Exception::FileError("file missing column names", filename);
510
511 line = Strings::strip(line);
513 std::vector<std::string> valuesAsStr;
514 std::move(tokenizer.begin(), tokenizer.end(), std::back_inserter(valuesAsStr));
515 if (valuesAsStr.size() < columnNames.size() + INFO_OFFSET_V1) {
516 std::stringstream msg;
517 msg << "Number of data columns (" << valuesAsStr.size() << ") not compatible with number of column labels ("
518 << (columnNames.size() + INFO_OFFSET_V1) << ")";
519 throw Exception::ParseError(msg.str(), filename, linenum);
520 }
521
522 const int rowIndex = findRow(wksp, valuesAsStr);
523
524 if (rowIndex >= 0) {
525 updateRow(wksp, static_cast<size_t>(rowIndex), columnNames, valuesAsStr);
526 } else {
527 // add the row
528 API::TableRow row = wksp->appendRow();
529 row << lexical_cast<double>(valuesAsStr[0], filename, linenum, "frequency");
530 row << lexical_cast<double>(valuesAsStr[1], filename, linenum, "wavelength");
531 row << boost::lexical_cast<int32_t>(1); // bank
532 row << valuesAsStr[2]; // vanadium
533 row << valuesAsStr[3]; // vanadium_background
534 row << "0"; // container
535 row << valuesAsStr[4]; // empty_environment
536 row << valuesAsStr[5]; // empty_instrument
537 row << "0"; // d_min
538 row << "0"; // d_max
539 row << 0.; // tof_min
540 row << 0.; // tof_max
541 row << 0.; // wavelength_min
542 row << 0.; // wavelength_max
543 // insert all the extras
544 for (size_t i = INFO_OFFSET_V1; i < valuesAsStr.size(); ++i) {
545 row << valuesAsStr[i];
546 }
547 }
548 }
549 // TODO need to get the extras line
550 }
551
552 file.close();
553}
554
560void PDLoadCharacterizations::readExpIni(const std::string &filename, API::ITableWorkspace_sptr &wksp) {
561 // don't bother if there isn't a filename
562 if (filename.empty())
563 return;
564
565 g_log.debug() << "readExpIni(" << filename << ", wksp)\n";
566
567 const size_t rowCount = wksp->rowCount();
568 if (rowCount == 0)
569 throw std::runtime_error("Characterizations file does not have any "
570 "characterizations information");
571
572 std::ifstream file(filename.c_str(), std::ios_base::binary);
573 if (!file.is_open()) {
574 throw Exception::FileError("Unable to open exp.ini file", filename);
575 }
576
577 // parse the file
578 for (std::string line = Strings::getLine(file); !file.eof(); Strings::getLine(file, line)) {
579 line = Strings::strip(line);
580 // skip empty lines and "comments"
581 if (line.empty())
582 continue;
583 if (line.substr(0, 1) == "#")
584 continue;
585
586 // split the line and see if it has something meaningful
587 std::vector<std::string> splitted;
588 boost::split(splitted, line, boost::is_any_of("\t "), boost::token_compress_on);
589 if (splitted.size() < 2)
590 continue;
591
592 // update the various charaterization runs in every row
593 for (size_t row = 0; row < rowCount; ++row) {
594 if (splitted[0] == EXP_INI_VAN_KEY) {
595 wksp->getRef<std::string>("vanadium", row) = splitted[1];
596 } else if (splitted[0] == EXP_INI_EMPTY_KEY) {
597 wksp->getRef<std::string>("vanadium_background", row) = splitted[1];
598 } else if (splitted[0] == EXP_INI_CAN_KEY) {
599 wksp->getRef<std::string>("container", row) = splitted[1];
600 }
601 }
602 }
603}
604
605} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
double value
The value of the point.
Definition: FitMW.cpp:51
double left
Definition: LineProfile.cpp:80
double right
Definition: LineProfile.cpp:81
#define fabs(x)
Definition: Matrix.cpp:22
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
@ OptionalLoad
to specify a file to read but the file doesn't have to exist
Definition: FileProperty.h:53
TableRow represents a row in a TableWorkspace.
Definition: TableRow.h:39
A property class for workspaces.
LoadPDCharacterizations : Load a characterization file used in Powder Diffraction Reduction.
void readExpIni(const std::string &filename, API::ITableWorkspace_sptr &wksp)
Parse the (optional) exp.ini file found on NOMAD.
const std::string name() const override
Algorithm's name for identification.
void readVersion1(const std::string &filename, API::ITableWorkspace_sptr &wksp)
void init() override
Initialize the algorithm's properties.
void readCharInfo(std::ifstream &file, API::ITableWorkspace_sptr &wksp, const std::string &filename, int linenum)
Parse the stream for the characterization file information.
void readVersion0(const std::string &filename, API::ITableWorkspace_sptr &wksp)
int readFocusInfo(std::ifstream &file, const std::string &filename)
Parse the stream for the focus positions and instrument parameter filename.
int version() const override
Algorithm's version for identification.
const std::string category() const override
Algorithm's category for identification.
std::vector< std::string > getFilenames()
This ignores the traditional interpretation of Mantid::API::MultipleFileProperty and flattens the arr...
Support for a property that holds an array of values.
Definition: ArrayProperty.h:28
Records the filename and the description of failure.
Definition: Exception.h:98
Records the filename, the description of failure and the line on which it happened.
Definition: Exception.h:115
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
Definition: Logger.cpp:114
void information(const std::string &msg)
Logs at information level.
Definition: Logger.cpp:105
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Iterator begin()
Iterator referring to first element in the container.
@ TOK_IGNORE_EMPTY
ignore empty tokens
Iterator end()
Iterator referring to the past-the-end element in the container.
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
Mantid::Kernel::StringTokenizer tokenizer
Definition: Expression.cpp:17
MANTID_KERNEL_DLL std::string strip(const std::string &A)
strip pre/post spaces
Definition: Strings.cpp:397
MANTID_KERNEL_DLL std::string peekLine(std::istream &fh)
Peek at a line without extracting it from the stream.
Definition: Strings.cpp:344
MANTID_KERNEL_DLL std::string getLine(std::istream &fh)
Get a line and strip comments Use only for a single call.
Definition: Strings.cpp:319
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition: EmptyValues.h:43
@ Output
An output workspace.
Definition: Property.h:54