23#include <boost/algorithm/string.hpp>
24#include <boost/date_time/date_parsing.hpp>
25#include <boost/date_time/gregorian/gregorian.hpp>
26#include <boost/lexical_cast.hpp>
28#include <boost/regex.hpp>
41 std::string input = std::accumulate(codes.
begin(), codes.
end(), std::string(
""));
42 std::string reg(R
"(^[06][\w]+\([/ \w\^-]+\)$)");
43 boost::regex baseRegex(reg);
44 return boost::regex_match(input, baseRegex);
67void
LoadRKH::readLinesForRKH1D(
std::istream &stream,
int readStart,
int readEnd, HistogramData::Points &
x,
68 HistogramData::Counts &
y, HistogramData::CountStandardDeviations &ye,
69 HistogramData::PointStandardDeviations &xe,
Progress &prog,
bool readXError) {
71 std::vector<double> xData;
72 std::vector<double> yData;
73 std::vector<double> xError;
74 std::vector<double> yError;
76 xData.reserve(readEnd);
77 yData.reserve(readEnd);
78 xError.reserve(readEnd);
79 yError.reserve(readEnd);
83 getline(stream, fileline);
84 if (
index < readStart)
87 double xValue(0.), yValue(0.), yErrorValue(0.);
88 std::istringstream datastr(fileline);
89 datastr >> xValue >> yValue >> yErrorValue;
91 xData.emplace_back(xValue);
92 yData.emplace_back(yValue);
93 yError.emplace_back(yErrorValue);
97 double xErrorValue(0.);
98 datastr >> xErrorValue;
99 xError.emplace_back(xErrorValue);
121 auto &file = descriptor.
data();
122 std::string fileline;
128 std::getline(file, fileline);
130 if (boost::ifind_first(fileline,
"loq").empty() && boost::ifind_first(fileline,
"sans2d").empty())
134 static const char *MONTHS[12] = {
"-JAN-",
"-FEB-",
"-MAR-",
"-APR-",
"-MAY-",
"-JUN-",
135 "-JUL-",
"-AUG-",
"-SEP-",
"-OCT-",
"-NOV-",
"-DEC-"};
137 bool foundMonth(
false);
138 for (
auto &month : MONTHS) {
139 if (!boost::ifind_first(fileline, month).empty()) {
148 std::getline(file, fileline);
151 std::getline(file, fileline);
152 if (fileline.find(
"0 0 0 1") == std::string::npos)
156 std::getline(file, fileline);
157 if (fileline.find(
"0 0 0 0") == std::string::npos)
161 std::getline(file, fileline);
162 if (fileline.find(
"3 (F12.5,2E16.6)") == std::string::npos)
172 const std::vector<std::string> exts{
".txt",
".q",
".dat"};
174 "Name of the RKH file to load");
176 "The name to use for the output workspace");
178 std::vector<std::string> propOptions = Kernel::UnitFactory::Instance().getKeys();
179 m_unitKeys.insert(propOptions.begin(), propOptions.end());
189 declareProperty(
"FirstColumnValue",
"Wavelength", std::make_shared<Kernel::StringListValidator>(propOptions),
190 "Only used for 1D files, the units of the first column in the RKH "
191 "file (default Wavelength)");
206 g_log.
error(
"Unable to open file " + filename);
222 result->setDistribution(
true);
236 return isUnit(codes);
243 g_log.
information() <<
"file appears to contain 1D information, reading in 1D data mode\n";
248 int totalPoints(0), readStart(0), readEnd(0), buried(0);
249 std::string fileline;
252 std::istringstream is(fileline);
254 for (
int counter = 1; counter < 8; ++counter) {
271 g_log.
information() <<
"Total number of data points declared to be in the data file: " << totalPoints <<
"\n";
274 std::string firstColVal =
getProperty(
"FirstColumnValue");
275 bool colIsUnit(
true);
279 readEnd = totalPoints;
282 if (readStart < 1 || readEnd < 1 || readEnd < readStart || readStart > totalPoints || readEnd > totalPoints) {
285 throw std::invalid_argument(
"Invalid data range specfied.");
288 g_log.
information() <<
"Reading started on data line: " << readStart <<
"\n";
289 g_log.
information() <<
"Reading finished on data line: " << readEnd <<
"\n";
294 int pointsToRead = readEnd - readStart + 1;
296 HistogramData::Points columnOne;
297 HistogramData::Counts ydata;
298 HistogramData::PointStandardDeviations xError;
299 HistogramData::CountStandardDeviations errdata;
303 Progress prog(
this, 0.0, 1.0, readEnd);
309 assert(pointsToRead ==
static_cast<int>(columnOne.size()));
310 assert(pointsToRead ==
static_cast<int>(ydata.size()));
311 assert(pointsToRead ==
static_cast<int>(errdata.size()));
314 assert(pointsToRead ==
static_cast<int>(xError.size()));
320 localworkspace->getSpectrum(0).setDetectorID(
static_cast<detid_t>(1));
321 localworkspace->getAxis(0)->unit() = UnitFactory::Instance().create(firstColVal);
322 localworkspace->setPoints(0, columnOne);
323 localworkspace->setCounts(0, ydata);
324 localworkspace->setCountStandardDeviations(0, errdata);
326 localworkspace->setPointStandardDeviations(0, xError);
328 return localworkspace;
333 localworkspace->getSpectrum(
index).setSpectrumNo(
static_cast<int>(columnOne[
index]));
334 localworkspace->getSpectrum(
index).setDetectorID(
static_cast<detid_t>(
index + 1));
335 localworkspace->dataY(
index)[0] = ydata[
index];
336 localworkspace->dataE(
index)[0] = errdata[
index];
341 localworkspace->setPointStandardDeviations(0, 1, xError[
index]);
344 return localworkspace;
356 g_log.
information() <<
"file appears to contain 2D information, reading in 2D data mode\n";
361 const size_t nAxis1Values = outWrksp->getNumberHistograms();
364 auto toPass = Kernel::make_cow<HistogramData::HistogramX>(axis0Data);
365 for (
size_t i = 0; i < nAxis1Values; ++i) {
366 outWrksp->setX(i, toPass);
370 for (
double &
value : YOut) {
373 prog.
report(
"Loading Y data");
377 for (
size_t i = 0; i < nAxis1Values; ++i) {
379 for (
double &
value : EOut) {
382 prog.
report(
"Loading error estimates");
397 const std::string XUnit(
readUnit(initalLine));
399 std::string fileLine;
401 const std::string YUnit(
readUnit(fileLine));
404 const std::string intensityUnit(
readUnit(fileLine));
412 boost::trim(fileLine);
413 const auto nAxis0Boundaries = boost::lexical_cast<int>(fileLine);
414 axis0Data.resize(nAxis0Boundaries);
418 boost::trim(fileLine);
419 int nAxis1Boundaries;
421 nAxis1Boundaries = boost::lexical_cast<int>(fileLine);
422 }
catch (boost::bad_lexical_cast &) {
426 boost::trim(fileLine);
427 nAxis1Boundaries = boost::lexical_cast<int>(fileLine);
434 if (fileLine.size() < 5) {
439 if (wsDimensions.
count() < 2) {
442 const auto nAxis0Values = boost::lexical_cast<int>(wsDimensions[0]);
443 const auto nAxis1Values = boost::lexical_cast<int>(wsDimensions[1]);
445 Progress prog(
this, 0.05, 1.0, 2 * nAxis1Values);
449 for (
int i = 0; i < nAxis1Values; ++i) {
450 outWrksp->getSpectrum(i).setDetectorID(
static_cast<detid_t>(i + 1));
452 outWrksp->getAxis(0)->unit() = UnitFactory::Instance().create(XUnit);
453 outWrksp->setYUnitLabel(intensityUnit);
455 auto axis1 = std::make_unique<Mantid::API::NumericAxis>(nAxis1Boundaries);
456 auto axis1Raw = axis1.get();
457 axis1->unit() = Mantid::Kernel::UnitFactory::Instance().create(YUnit);
458 outWrksp->replaceAxis(1, std::move(axis1));
459 for (
int i = 0; i < nAxis1Boundaries; ++i) {
460 axis1Raw->setValue(i, axis1Data[i]);
463 outWrksp->setTitle(title);
477 output.resize(nEntries);
478 for (
int i = 0; i < nEntries; ++i) {
492 if (!isUnit(codes)) {
493 return "C++ no unit found";
496 if (codes.
count() < 1) {
497 return "C++ no unit found";
501 const std::string symbol(codes[0]);
503 auto itUnitsToken = codes.
cend() - 1;
504 const std::string unit(*itUnitsToken);
507 std::string theQuantity;
508 for (
auto current = codes.
cbegin() + 1; current != itUnitsToken; ++current) {
509 theQuantity += *current;
513 if (codes.
count() >= 3) {
517 if ((!unit.starts_with(
'(')) || (unit.find(
')') != unit.size())) {
519 if (symbol == qCode && theQuantity ==
"q" &&
520 (unit ==
"(1/Angstrom)" || unit ==
"(Angstrom^-1)")) {
522 return "MomentumTransfer";
525 if (symbol ==
"0" && theQuantity !=
"q") {
528 return theQuantity +
" " + unit;
533 return "C++ no unit found";
542 for (
int i = 0; i < nlines; ++i) {
543 getline(strm, buried);
560 auto containsXerror =
false;
561 auto currentPutLocation = stream.tellg();
563 getline(stream, line);
565 std::string
x,
y, yerr, xerr;
566 std::istringstream datastr(line);
567 datastr >>
x >>
y >> yerr >> xerr;
569 containsXerror =
true;
572 stream.seekg(currentPutLocation, stream.beg);
573 return containsXerror;
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
#define DECLARE_FILELOADER_ALGORITHM(classname)
DECLARE_FILELOADER_ALGORITHM should be used in place of the standard DECLARE_ALGORITHM macro when wri...
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
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.
@ Load
allowed here which will be passed to the algorithm
Helper class for reporting progress from algorithms.
A property class for workspaces.
Loads an RKH file into a Mantid 1D workspace.
int confidence(Kernel::FileDescriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
const API::MatrixWorkspace_sptr read1D()
Read a data file that contains only one spectrum into a workspace.
std::unordered_set< std::string > m_RKHKeys
Store the units added as options for this algorithm.
const std::string readUnit(const std::string &line)
Convert the units specification line from the RKH file into a Mantid unit name.
void init() override
Initialise the algorithm.
void readNumEntrys(const int nEntries, MantidVec &output)
Read the specified number of entries from input file into the the array that is passed.
void binCenter(const MantidVec &oldBoundaries, MantidVec &toCenter) const
PAss a vector of bin boundaries and get a vector of bin centers.
void exec() override
Execute the algorithm.
bool hasXerror(std::ifstream &stream)
Check if we the data set stores an X-Error values.
std::unordered_set< std::string > m_unitKeys
Store the units known to the UnitFactory.
const API::MatrixWorkspace_sptr read2D(const std::string &firstLine)
Reads from the third line of the input file to the end assuming it contains 2D data.
void readLinesForRKH1D(std::istream &stream, int readStart, int readEnd, HistogramData::Points &x, HistogramData::Counts &y, HistogramData::CountStandardDeviations &ye, HistogramData::PointStandardDeviations &xe, API::Progress &prog, bool readXError=false)
Read data from the RKH file.
API::Progress read2DHeader(const std::string &initalLine, API::MatrixWorkspace_sptr &outWrksp, MantidVec &axis0Data)
Reads the header information from a file containing 2D data.
std::ifstream m_fileIn
the input stream for the file being loaded
bool is2D(const std::string &testLine)
Determines if the file is 1D or 2D based on the first after the workspace's title.
void skipLines(std::istream &strm, int nlines)
Remove lines from an input stream.
@ Q_CODE
this is the integer code the RKH file format associates
Records the filename and the description of failure.
Exception for when an item is not found in a collection.
Defines a wrapper around an open file.
static bool isAscii(const std::string &filename, const size_t nbytes=256)
Returns true if the file is considered ascii.
std::istream & data()
Access the open file stream.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void error(const std::string &msg)
Logs at error level.
void information(const std::string &msg)
Logs at information level.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
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
@ TOK_TRIM
remove leading and trailing whitespace from tokens
Iterator end()
Iterator referring to the past-the-end element in the container.
ConstIterator cend() const
Const iterator referring to the past-the-end element in the container.
ConstIterator cbegin() const
Const iterator referring to first element in the container.
std::size_t count() const
Get the total number of tokens.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
void MANTID_KERNEL_DLL convertToBinCentre(const std::vector< double > &bin_edges, std::vector< double > &bin_centres)
Convert an array of bin boundaries to bin center values.
int32_t detid_t
Typedef for a detector ID.
std::vector< double > MantidVec
typedef for the data storage used in Mantid matrix workspaces
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Output
An output workspace.