Skip to content
Snippets Groups Projects
Commit 6ac1c250 authored by Peterson, Peter's avatar Peterson, Peter
Browse files

Merge remote-tracking branch 'origin/13632_SpeedUpLoadIsawPeaks'

parents 01ff6032 65bfc856
No related branches found
No related tags found
No related merge requests found
......@@ -8,7 +8,8 @@
namespace Mantid {
namespace Crystal {
/** LoadIsawPeaks : Load an ISAW-style .peaks file
/**
* Load an ISAW-style .peaks or .integrate file
* into a PeaksWorkspace
*
* @author Janik Zikovsky, SNS
......@@ -21,14 +22,16 @@ public:
virtual ~LoadIsawPeaks();
/// Algorithm's name for identification
virtual const std::string name() const { return "LoadIsawPeaks"; };
virtual const std::string name() const { return "LoadIsawPeaks"; }
/// Summary of algorithms purpose
virtual const std::string summary() const {
return "Load an ISAW-style .peaks file into a PeaksWorkspace.";
}
/// Algorithm's version for identification
virtual int version() const { return 1; };
virtual int version() const { return 1; }
/// Algorithm's category for identification
virtual const std::string category() const {
return "Crystal;DataHandling\\Isaw";
......@@ -36,26 +39,52 @@ public:
/// Returns a confidence value that this algorithm can load a file
virtual int confidence(Kernel::FileDescriptor &descriptor) const;
int findPixelID(Geometry::Instrument_const_sptr inst, std::string bankName,
int col, int row);
private:
/// Initialise the properties
void init();
/// Run the algorithm
void exec();
/// Reads calibration/detector section and returns first word of next line
std::string ApplyCalibInfo(std::ifstream &in, std::string startChar,
Geometry::Instrument_const_sptr instr_old,
Geometry::Instrument_const_sptr instr, double &T0);
/// Reads first line of peaks file and returns first word of next line
std::string readHeader(Mantid::DataObjects::PeaksWorkspace_sptr outWS,
std::ifstream &in, double &T0);
/// Read a single peak from peaks file
DataObjects::Peak readPeak(DataObjects::PeaksWorkspace_sptr outWS,
std::string &lastStr, std::ifstream &in,
int &seqNum, std::string bankName);
int findPixelID(Geometry::Instrument_const_sptr inst, std::string bankName,
int col, int row);
/// Read the header of a peak block section, returns first word of next line
std::string readPeakBlockHeader(std::string lastStr, std::ifstream &in,
int &run, int &detName, double &chi,
double &phi, double &omega, double &monCount);
/// Append peaks from given file to given workspace
void appendFile(Mantid::DataObjects::PeaksWorkspace_sptr outWS,
std::string filename);
/// Compare number of peaks in given file to given workspace
/// Throws std::length_error on mismatch
void checkNumberPeaks(Mantid::DataObjects::PeaksWorkspace_sptr outWS,
std::string filename);
/// Local cache of bank IComponents used in file
std::map<std::string, boost::shared_ptr<const Geometry::IComponent>> m_banks;
/// Retrieve cached bank (or load and cache for next time)
boost::shared_ptr<const Geometry::IComponent> getCachedBankByName(
std::string bankname,
const boost::shared_ptr<const Geometry::Instrument> &inst);
};
} // namespace Mantid
......
......@@ -29,8 +29,9 @@ LoadIsawPeaks::LoadIsawPeaks() {}
*/
LoadIsawPeaks::~LoadIsawPeaks() {}
//----------------------------------------------------------------------------------------------
/**
* Return the confidence with with this algorithm can load the file
* Determine the confidence with which this algorithm can load a given file
* @param descriptor A descriptor for the file
* @returns An integer specifying the confidence level. 0 indicates it will not
* be used
......@@ -78,12 +79,10 @@ int LoadIsawPeaks::confidence(Kernel::FileDescriptor &descriptor) const {
confidence = 95;
} catch (std::exception &) {
}
return confidence;
}
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
......@@ -99,6 +98,23 @@ void LoadIsawPeaks::init() {
"Name of the output workspace.");
}
//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void LoadIsawPeaks::exec() {
// Create the workspace
PeaksWorkspace_sptr ws(new PeaksWorkspace());
// This loads (appends) the peaks
this->appendFile(ws, getPropertyValue("Filename"));
// Save it in the output
setProperty("OutputWorkspace", boost::dynamic_pointer_cast<Workspace>(ws));
this->checkNumberPeaks(ws, getPropertyValue("Filename"));
}
//----------------------------------------------------------------------------------------------
std::string
LoadIsawPeaks::ApplyCalibInfo(std::ifstream &in, std::string startChar,
Geometry::Instrument_const_sptr instr_old,
......@@ -113,7 +129,6 @@ LoadIsawPeaks::ApplyCalibInfo(std::ifstream &in, std::string startChar,
startChar = getWord(in, false);
}
if (!(in.good())) {
// g_log.error()<<"Peaks file has no time shift and L0 info"<<std::endl;
throw std::invalid_argument("Peaks file has no time shift and L0 info");
}
std::string L1s = getWord(in, false);
......@@ -190,7 +205,7 @@ LoadIsawPeaks::ApplyCalibInfo(std::ifstream &in, std::string startChar,
}
bankName += SbankNum;
boost::shared_ptr<const Geometry::IComponent> bank =
instr_old->getComponentByName(bankName);
getCachedBankByName(bankName, instr_old);
if (!bank) {
g_log.error() << "There is no bank " << bankName << " in the instrument"
......@@ -291,15 +306,11 @@ std::string LoadIsawPeaks::readHeader(PeaksWorkspace_sptr outWS,
Geometry::Instrument_const_sptr instr(
new Geometry::Instrument(instr_old->baseInstrument(), map));
// std::string s;
std::string s = ApplyCalibInfo(in, "", instr_old, instr, T0);
outWS->setInstrument(instr);
// Now skip all lines on L1, detector banks, etc. until we get to a block of
// peaks. They start with 0.
// readToEndOfLine( in , true );
// readToEndOfLine( in , true );
// s = getWord(in, false);
while (s != "0" && in.good()) {
readToEndOfLine(in, true);
s = getWord(in, false);
......@@ -318,9 +329,10 @@ std::string LoadIsawPeaks::readHeader(PeaksWorkspace_sptr outWS,
* @param bankName :: the bank number from the ISAW file.
* @return the Peak the Peak object created
*/
Mantid::DataObjects::Peak readPeak(PeaksWorkspace_sptr outWS,
std::string &lastStr, std::ifstream &in,
int &seqNum, std::string bankName) {
DataObjects::Peak LoadIsawPeaks::readPeak(PeaksWorkspace_sptr outWS,
std::string &lastStr,
std::ifstream &in, int &seqNum,
std::string bankName) {
double h;
double k;
double l;
......@@ -387,9 +399,9 @@ Mantid::DataObjects::Peak readPeak(PeaksWorkspace_sptr outWS,
Instrument_const_sptr inst = outWS->getInstrument();
if (!inst)
throw std::runtime_error("No instrument in PeaksWorkspace!");
LoadIsawPeaks u;
int pixelID = u.findPixelID(inst, bankName, static_cast<int>(col),
static_cast<int>(row));
int pixelID =
findPixelID(inst, bankName, static_cast<int>(col), static_cast<int>(row));
// Create the peak object
Peak peak(outWS->getInstrument(), pixelID, wl);
......@@ -402,10 +414,12 @@ Mantid::DataObjects::Peak readPeak(PeaksWorkspace_sptr outWS,
return peak;
}
//----------------------------------------------------------------------------------------------
int LoadIsawPeaks::findPixelID(Instrument_const_sptr inst, std::string bankName,
int col, int row) {
boost::shared_ptr<const IComponent> parent =
inst->getComponentByName(bankName);
getCachedBankByName(bankName, inst);
if (parent->type().compare("RectangularDetector") == 0) {
boost::shared_ptr<const RectangularDetector> RDet =
boost::dynamic_pointer_cast<const RectangularDetector>(parent);
......@@ -441,9 +455,11 @@ int LoadIsawPeaks::findPixelID(Instrument_const_sptr inst, std::string bankName,
//-----------------------------------------------------------------------------------------------
/** Read the header of each peak block section */
std::string readPeakBlockHeader(std::string lastStr, std::ifstream &in,
int &run, int &detName, double &chi,
double &phi, double &omega, double &monCount) {
std::string LoadIsawPeaks::readPeakBlockHeader(std::string lastStr,
std::ifstream &in, int &run,
int &detName, double &chi,
double &phi, double &omega,
double &monCount) {
std::string s = lastStr;
if (s.length() < 1 && in.good()) // blank line
......@@ -491,6 +507,11 @@ void LoadIsawPeaks::appendFile(PeaksWorkspace_sptr outWS,
// Open the file
std::ifstream in(filename.c_str());
// Calculate filesize
in.seekg(0, in.end);
auto filelen = in.tellg();
in.seekg(0, in.beg);
// Read the header, load the instrument
double T0;
std::string s = readHeader(outWS, in, T0);
......@@ -514,8 +535,8 @@ void LoadIsawPeaks::appendFile(PeaksWorkspace_sptr outWS,
Mantid::Geometry::Goniometer uniGonio;
uniGonio.makeUniversalGoniometer();
// TODO: Can we find the number of peaks to get better progress reporting?
Progress prog(this, 0.0, 1.0, 100);
// Progress is reported based on how much of the file we've read
Progress prog(this, 0.0, 1.0, filelen);
while (in.good()) {
// Read the header if necessary
......@@ -565,9 +586,10 @@ void LoadIsawPeaks::appendFile(PeaksWorkspace_sptr outWS,
<< e.what() << std::endl;
}
prog.report();
prog.report(in.tellg());
}
}
//-----------------------------------------------------------------------------------------------
/** Count the peaks from a .peaks file and compare with the workspace
* @param outWS :: the workspace in which to place the information
......@@ -592,19 +614,29 @@ void LoadIsawPeaks::checkNumberPeaks(PeaksWorkspace_sptr outWS,
}
//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
/** Retrieves pointer to given bank from local cache.
*
* When the bank isn't in the local cache, it is loaded and
* added to the cache for later use. Lifetime of the cache
* is bound to the lifetime of this instance of the algorithm
* (typically, the instance should be destroyed once exec()
* finishes).
*
* Note that while this is used only for banks here, it would
* work for caching any component without modification.
*
* @param bankname :: the name of the requested bank
* @param inst :: the instrument from which to load the bank if it is not yet
*cached
* @return A shared pointer to the request bank (empty shared pointer if not
*found)
*/
void LoadIsawPeaks::exec() {
// Create the workspace
PeaksWorkspace_sptr ws(new PeaksWorkspace());
// This loads (appends) the peaks
this->appendFile(ws, getPropertyValue("Filename"));
// Save it in the output
setProperty("OutputWorkspace", boost::dynamic_pointer_cast<Workspace>(ws));
this->checkNumberPeaks(ws, getPropertyValue("Filename"));
boost::shared_ptr<const IComponent> LoadIsawPeaks::getCachedBankByName(
std::string bankname,
const boost::shared_ptr<const Geometry::Instrument> &inst) {
if (m_banks.count(bankname) == 0)
m_banks[bankname] = inst->getComponentByName(bankname);
return m_banks[bankname];
}
} // namespace Mantid
......
......@@ -865,34 +865,49 @@ int setValues(const std::string &Line, const std::vector<int> &Index,
* @return a string with the word read in
*/
std::string getWord(std::istream &in, bool consumeEOL) {
std::string s;
char c = 0;
if (in.good())
for (c = static_cast<char>(in.get()); c == ' ' && in.good();
c = static_cast<char>(in.get())) {
std::string ret;
char nextch = 0;
// Skip leading spaces
do {
nextch = static_cast<char>(in.get());
} while (nextch == ' ');
// Return an empty string on EOL; optionally consume it
if (nextch == '\n' || nextch == '\r') {
if (!consumeEOL) {
in.unget();
} else if ((nextch == '\n' && in.peek() == '\r') ||
(nextch == '\r' && in.peek() == '\n')) {
// Handle CRLF and LFCR on Unix by consuming both
in.ignore();
}
else
return std::string();
if (c == '\n') {
if (!consumeEOL)
in.putback(c);
return std::string();
return ret;
} else { // Non-EOL and non-space character
in.unget(); // Put it back on stream
}
s.push_back(c);
// Get next word if stream is still valid
if (in.good())
for (c = static_cast<char>(in.get());
in.good() && c != ' ' && c != '\n' && c != '\r';
c = static_cast<char>(in.get()))
s.push_back(c);
in >> ret;
// Optionally consume EOL character
if (consumeEOL) {
nextch = static_cast<char>(in.get());
if (((c == '\n') || (c == '\r')) && !consumeEOL)
in.putback(c);
// Handle CRLF and LFCR on Unix by consuming both
if (nextch == '\n' || nextch == '\r') {
if ((nextch == '\n' && in.peek() == '\r') ||
(nextch == '\r' && in.peek() == '\n')) {
in.ignore();
}
} else {
in.unget();
}
}
return s;
return ret;
}
//-----------------------------------------------------------------------------------------------
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment