Newer
Older
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidDataHandling/LoadSNSspec.h"
#include "MantidDataObjects/Workspace2D.h"
#include "MantidKernel/UnitFactory.h"
#include "MantidAPI/FileProperty.h"
Sofia Antony
committed
#include "MantidAPI/LoadAlgorithmFactory.h"
#include <fstream>
#include <cstring>
#include <boost/tokenizer.hpp>
namespace Mantid
{
namespace DataHandling
{
// Register the algorithm into the algorithm factory
DECLARE_ALGORITHM(LoadSNSspec)
Gigg, Martyn Anthony
committed
//register the algorithm into loadalgorithm factory
Sofia Antony
committed
DECLARE_LOADALGORITHM(LoadSNSspec)
Janik Zikovsky
committed
/// Sets documentation strings for this algorithm
void LoadSNSspec::initDocs()
{
this->setWikiSummary("Loads data from a text file and stores it in a 2D [[workspace]] ([[Workspace2D]] class). ");
this->setOptionalMessage("Loads data from a text file and stores it in a 2D workspace (Workspace2D class).");
}
using namespace Kernel;
using namespace API;
/// Empty constructor
Sofia Antony
committed
LoadSNSspec::LoadSNSspec() {}
/// Initialisation method.
void LoadSNSspec::init()
{
std::vector<std::string> exts;
exts.push_back(".dat");
exts.push_back(".txt");
declareProperty(new FileProperty("Filename", "", FileProperty::Load, exts),
"A SNS Spec Ascii file");
declareProperty(new WorkspaceProperty<>("OutputWorkspace",
"",Direction::Output), "The name of the workspace that will be created.");
std::vector<std::string> units = UnitFactory::Instance().getKeys();
declareProperty("Unit","Energy",new Kernel::ListValidator(units),
"The unit to assign to the X axis (default: Energy)");
}
/**
* Executes the algorithm.
*/
void LoadSNSspec::exec()
{
std::string filename = getProperty("Filename");
std::string separator = " "; //separator can be 1 or more spaces
std::ifstream file(filename.c_str());
file.seekg (0, std::ios::end);
Progress progress(this,0,1,static_cast<int>(file.tellg()));
file.seekg (0, std::ios::beg);
std::string str;
std::vector<DataObjects::Histogram1D> spectra;
Janik Zikovsky
committed
//size_t iLine=0; // line number
size_t ncols = 3; // number of columns
int nSpectra = 0;
int nBins = 0; //number of rows
std::string first_character;
std::string axes_infos;
Janik Zikovsky
committed
//bool numeric = true;
std::vector<double> input;
//determine the number of lines starting by #L
//as there is one per set of data
int spectra_nbr = 0;
while(getline(file,str))
{
Gigg, Martyn Anthony
committed
if (str.empty() ) continue;
if (str[0] == '#' && str[1] == 'L')
{
spectra_nbr++;
}
}
spectra.resize(spectra_nbr);
file.clear(); //end of file has been reached so we need to clear file state
file.seekg (0, std::ios::beg); //go back to beginning of file
int working_with_spectrum_nbr = -1; //spectrum number
while(getline(file,str))
{
progress.report(static_cast<int>(file.tellg()));
//line with data, need to be parsed by white spaces
if (!str.empty() && str[0] != '#')
{
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep(" ");
tokenizer tok(str, sep);
ncols = 0;
for (tokenizer::iterator beg=tok.begin(); beg!=tok.end(); ++beg)
{
std::stringstream ss;
ss << *beg;
double d;
ss >> d;
input.push_back(d);
}
}
if (str.empty())
{
if (working_with_spectrum_nbr != -1)
{
Janik Zikovsky
committed
for(int j=0; j<static_cast<int>(input.size()-1); j++)
{
spectra[working_with_spectrum_nbr].dataX().push_back(input[j]);
j++;
spectra[working_with_spectrum_nbr].dataY().push_back(input[j]);
j++;
spectra[working_with_spectrum_nbr].dataE().push_back(input[j]);
nBins = j/3;
}
}
working_with_spectrum_nbr++;
input.clear();
}
} //end of read file
try
{
if (spectra_nbr == 0)
throw "Undefined number of spectra";
if (working_with_spectrum_nbr == (spectra_nbr-1))
{
Janik Zikovsky
committed
for(int j=0; j<static_cast<int>(input.size()-1); j++)
{
spectra[working_with_spectrum_nbr].dataX().push_back(input[j]);
j++;
spectra[working_with_spectrum_nbr].dataY().push_back(input[j]);
j++;
spectra[working_with_spectrum_nbr].dataE().push_back(input[j]);
nBins = j/3;
}
}
}
catch (...)
{
}
try
{
nSpectra = spectra_nbr;
MatrixWorkspace_sptr localWorkspace = boost::dynamic_pointer_cast<MatrixWorkspace>
(WorkspaceFactory::Instance().create("Workspace2D",nSpectra,nBins,nBins));
localWorkspace->getAxis(0)->unit() = UnitFactory::Instance().create(getProperty("Unit"));
{
localWorkspace->dataX(i) = spectra[i].dataX();
localWorkspace->dataY(i) = spectra[i].dataY();
localWorkspace->dataE(i) = spectra[i].dataE();
// Just have spectrum number start at 1 and count up
localWorkspace->getAxis(1)->spectraNo(i) = i+1;
}
setProperty("OutputWorkspace",localWorkspace);
}
catch (Exception::NotFoundError &)
{
// Asked for dimensionless workspace (obviously not in unit factory)
}
}
Gigg, Martyn Anthony
committed
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/**This method does a quick file check by checking the no.of bytes read nread params and header buffer
* @param filePath- path of the file including name.
* @param nread :: no.of bytes read
* @param header :: The first 100 bytes of the file as a union
* @return true if the given file is of type which can be loaded by this algorithm
*/
bool LoadSNSspec::quickFileCheck(const std::string& filePath,size_t nread,const file_header& header)
{
std::string extn=extension(filePath);
bool bascii(false);
(!extn.compare("txt"))?bascii=true:bascii=false;
bool is_ascii (true);
for(size_t i=0; i<nread; i++)
{
if (!isascii(header.full_hdr[i]))
is_ascii =false;
}
return(is_ascii|| bascii?true:false);
}
/**checks the file by opening it and reading few lines
* @param filePath :: name of the file including its path
* @return an integer value how much this algorithm can load the file
*/
int LoadSNSspec::fileCheck(const std::string& filePath)
{
std::ifstream file(filePath.c_str());
if (!file)
{
g_log.error("Unable to open file: " + filePath);
throw Exception::FileError("Unable to open file: " , filePath);
}
int bret=0;
int axiscols=0;
int datacols=0;
std::string str;
Sofia Antony
committed
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep(" ");
Gigg, Martyn Anthony
committed
bool bsnsspec(false);
while(!file.eof())
{
//read line
std::getline(file,str);
if(str.empty())
{
continue;
}
try
{
//if it's comment line
if (str.at(0)=='#' )
{
if(str.at(1) =='L')
{
tokenizer tok(str, sep);
Sofia Antony
committed
for (tokenizer::iterator beg=tok.begin(); beg!=tok.end(); ++beg)
{
Gigg, Martyn Anthony
committed
}
//if the file contains a comment line starting with "#L" followed
//by three columns this could be loadsnsspec file
if(axiscols>2)
{
bsnsspec=true;
}
}
}
else
{
//check first data line is a 3 column line
Sofia Antony
committed
tokenizer tok(str, sep);
for (tokenizer::iterator beg=tok.begin(); beg!=tok.end(); ++beg)
{
Gigg, Martyn Anthony
committed
}
break;
}
}
catch(std::out_of_range& )
{
}
}
if(bsnsspec && datacols==3 )//three column data
{
bret=80;
}
return bret;
Sofia Antony
committed
}
} // namespace DataHandling
} // namespace Mantid