20#include <boost/algorithm/string.hpp>
27using namespace Kernel;
40 const std::string &filePath = descriptor.
filename();
41 const size_t filenameLength = filePath.size();
45 if (filenameLength > 12 ? (filePath.compare(filenameLength - 12, 12,
"_runinfo.xml") == 0)
46 :
false || filenameLength > 6 ? (filePath.compare(filenameLength - 6, 6,
".peaks") == 0)
47 :
false || filenameLength > 10 ? (filePath.compare(filenameLength - 10, 10,
".integrate") == 0)
50 }
else if (descriptor.
isAscii()) {
67 const int rowsToMatch(5);
71 int numCols(-1), matchingRows(0), row(0);
73 std::vector<double> values;
74 while (getline(file, line)) {
82 std::list<std::string> columns;
86 }
catch (boost::bad_lexical_cast &) {
91 if (lineCols == numCols) {
93 if (matchingRows == rowsToMatch)
105 file.clear(file.eofbit);
114 file.seekg(0, std::ios::beg);
116 numToSkip = row - rowsToMatch;
120 while (i < numToSkip && getline(file, line)) {
123 g_log.
information() <<
"Skipped " << numToSkip <<
" line(s) of header information()\n";
140 std::list<std::string> columns;
144 throw std::runtime_error(
"Invalid data format. Fewer than 2 columns found.");
146 size_t numSpectra(0);
147 bool haveErrors(
false);
148 bool haveXErrors(
false);
151 numSpectra = numCols / 2;
154 else if ((numCols - 1) % 2 == 0) {
155 numSpectra = (numCols - 1) / 2;
159 else if (numCols == 4) {
165 g_log.
error() <<
"LoadAscii requires the number of columns to be an even "
166 "multiple of either 2 or 3.";
167 throw std::runtime_error(
"Invalid data format.");
173 int numBins(0), lineNo(0);
174 std::vector<DataObjects::Histogram1D> spectra(
177 std::vector<double> dx;
178 std::vector<double> values(numCols, 0.);
186 if (lineCols != numCols) {
187 std::ostringstream ostr;
188 ostr <<
"Number of columns changed at line " << lineNo;
189 throw std::runtime_error(ostr.str());
194 }
catch (boost::bad_lexical_cast &) {
196 throw std::runtime_error(
"Invalid value encountered.");
199 for (
size_t i = 0; i < numSpectra; ++i) {
200 auto hist = spectra[i].histogram();
201 hist.resize(hist.size() + 1);
202 hist.mutableX().back() = values[0];
203 hist.mutableY().back() = values[i * 2 + 1];
205 hist.mutableE().back() = values[i * 2 + 2];
207 spectra[i].setHistogram(hist);
212 dx.emplace_back(values[3]);
215 }
while (getline(file, line));
216 auto sharedDx = Kernel::make_cow<HistogramData::HistogramDx>(dx);
217 for (
size_t i = 0; i < numSpectra; ++i) {
219 spectra[i].setSharedDx(sharedDx);
231 for (
size_t i = 0; i < numSpectra; ++i) {
232 localWorkspace->setHistogram(i, spectra[i].histogram());
235 localWorkspace->getSpectrum(i).setSpectrumNo(
static_cast<specnum_t>(i) + 1);
237 return localWorkspace;
259 boost::split(columns, str, boost::is_any_of(
m_columnSep), boost::token_compress_on);
260 return static_cast<int>(columns.size());
269 values.resize(columns.size());
271 for (
auto value : columns) {
273 boost::to_lower(
value);
277 double nan = std::numeric_limits<double>::quiet_NaN();
280 values[i] = boost::lexical_cast<double>(
value);
291 const std::vector<std::string> extensions{
".dat",
".txt",
".csv",
""};
293 "The name of the text file to read, including its full or "
294 "relative path. The file extension must be .txt, .dat, or "
297 "The name of the workspace that will be created, filled with "
298 "the read-in data and stored in the [[Analysis Data "
301 std::string spacers[6][6] = {{
"Automatic",
",\t:; "}, {
"CSV",
","}, {
"Tab",
"\t"},
302 {
"Space",
" "}, {
"Colon",
":"}, {
"SemiColon",
";"}};
304 std::array<std::string, 5> sepOptions;
305 for (
size_t i = 0; i < 5; ++i) {
306 const auto &option = spacers[i][0];
307 m_separatorIndex.insert(std::pair<std::string, std::string>(option, spacers[i][1]));
308 sepOptions[i] = option;
311 declareProperty(
"Separator",
"Automatic", std::make_shared<StringListValidator>(sepOptions),
312 "The separator between data columns in the data file. The possible "
313 "values are \"CSV\", \"Tab\", "
314 "\"Space\", \"SemiColon\", or \"Colon\" (default: Automatic selection).");
317 units.insert(units.begin(),
"Dimensionless");
318 declareProperty(
"Unit",
"Energy", std::make_shared<StringListValidator>(units),
319 "The unit to assign to the X axis (anything known to the "
320 "[[Unit Factory]] or \"Dimensionless\")");
322 auto mustBePosInt = std::make_shared<BoundedValidator<int>>();
323 mustBePosInt->setLower(0);
325 "If given, skip this number of lines at the start of the file.");
333 std::ifstream file(filename.c_str());
335 g_log.
error(
"Unable to open file: " + filename);
345 outputWS->mutableRun().addProperty(
"Filename", filename);
double value
The value of the point.
#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.
void useAlgorithm(const std::string &, const int version=-1)
The algorithm to use instead of this one.
@ Load
allowed here which will be passed to the algorithm
A property class for workspaces.
int splitIntoColumns(std::list< std::string > &columns, const std::string &str) const
Split the data into columns.
void peekLine(std::ifstream &is, std::string &str) const
Peek at a line without extracting it from the stream.
int confidence(Kernel::FileDescriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
void fillInputValues(std::vector< double > &values, const std::list< std::string > &columns) const
Fill the given vector with the data values.
std::string m_columnSep
The column separator.
void exec() override
Execute the algorithm.
LoadAscii()
Default constructor.
bool skipLine(const std::string &line) const
Return true if the line is to be skipped.
std::map< std::string, std::string > m_separatorIndex
Map the separator options to their string equivalents.
virtual void processHeader(std::ifstream &file) const
Process the header information within the file.
virtual API::Workspace_sptr readData(std::ifstream &file) const
Read the data from the file.
void init() override
Declare properties.
1D histogram implementation.
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.
const std::string & filename() const
Access the filename.
static bool isAscii(const std::string &filename, const size_t nbytes=256)
Returns true if the file is considered ascii.
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.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::unique_ptr< T > create(const P &parent, const IndexArg &indexArg, const HistArg &histArg)
This is the create() method that all the other create() methods call.
MANTID_KERNEL_DLL std::string peekLine(std::istream &fh)
Peek at a line without extracting it from the stream.
MANTID_KERNEL_DLL bool skipLine(const std::string &line)
Determines if a string starts with a #.
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
int32_t specnum_t
Typedef for a spectrum Number.
@ Output
An output workspace.