Skip to content

Commit

Permalink
First implementation of changes
Browse files Browse the repository at this point in the history
 1. IDS mangling used for checksum is now inst name + sha1 of xml
 1.1. sha1 is computed after converitng to linux line endings and trim
 1. VTP file names changes to be same filename as IDS mangling
 1. VTP save directory moved to appdata/mantidproject/instrument/geometryCache
 1. VTP file saving simplified as files based on a checksum cannot be out of date
 1. unit tests updated to account for this
 1. unused methods removed from IDFObject
 1. InstrumentDefinitionParser changed to initialise during constructor
 1. XML parsing changed to lazy load rather than during initialisation.

Still to do:
 1. cache SHA1 checksum if needed
 1. Change the filename reported for nexus files
 1. Manually test
 1. Stop saving the filename to nexus files
 1. update documentation

re #11818
  • Loading branch information
NickDraper committed May 27, 2015
1 parent 03143a4 commit da16824
Show file tree
Hide file tree
Showing 14 changed files with 323 additions and 320 deletions.
3 changes: 3 additions & 0 deletions Code/Mantid/Framework/API/inc/MantidAPI/ExperimentInfo.h
Expand Up @@ -121,6 +121,7 @@ class MANTID_API_DLL ExperimentInfo {
virtual void loadExperimentInfoNexus(::NeXus::File *file, std::string &parameterStr);
/// Load the instrument from an open NeXus file.
virtual void loadInstrumentInfoNexus(::NeXus::File *file, std::string &parameterStr);

/// Load the sample and log info from an open NeXus file.
virtual void loadSampleAndLogInfoNexus(::NeXus::File *file);
/// Populate the parameter map given a string
Expand Down Expand Up @@ -164,6 +165,8 @@ class MANTID_API_DLL ExperimentInfo {
const Geometry::XMLInstrumentParameter &paramInfo,
const Run &runData);

//Loads the xml from an instrument file with some basic error handling
std::string loadInstrumentXML(const std::string& filename);
/// Detector grouping information
det2group_map m_detgroups;
/// Mutex to protect against cow_ptr copying
Expand Down
55 changes: 34 additions & 21 deletions Code/Mantid/Framework/API/src/ExperimentInfo.cpp
Expand Up @@ -1006,32 +1006,27 @@ void ExperimentInfo::loadInstrumentInfoNexus(::NeXus::File *file,
instrumentFilename = Strings::strip(instrumentFilename);
instrumentXml = Strings::strip(instrumentXml);
instrumentName = Strings::strip(instrumentName);
if (instrumentXml.empty() && !instrumentName.empty()) {
// XML was not included or was empty.
// Use the instrument name to find the file
try {
std::string filename =
getInstrumentFilename(instrumentName, getWorkspaceStartDate());
// And now load the contents
instrumentFilename = filename;
instrumentXml = Strings::loadFile(filename);
} catch (std::exception &e) {
g_log.error() << "Error loading instrument IDF file for '"
<< instrumentName << "'.\n";
g_log.debug() << e.what() << std::endl;
throw;
}
} else {
if (!instrumentFilename.empty())
instrumentFilename = ConfigService::Instance().getInstrumentDirectory() +
"/" + instrumentFilename;
if (!instrumentXml.empty()) {
// instrument xml is being loaded from the nxs file, set the instrumentFilename
// to identify the Nexus file as the source of the data
instrumentFilename = instrumentFilename;
g_log.debug() << "Using instrument IDF XML text contained in nexus file.\n";
}
else
{
// XML was not included or was empty
// Use the instrument name to find the file
std::string filename =
getInstrumentFilename(instrumentName, getWorkspaceStartDate());
// And now load the contents
instrumentFilename = filename;
instrumentXml = loadInstrumentXML(instrumentFilename);
}

// ---------- Now parse that XML to make the instrument -------------------
if (!instrumentXml.empty() && !instrumentName.empty()) {
InstrumentDefinitionParser parser;
parser.initialize(instrumentFilename, instrumentName, instrumentXml);
InstrumentDefinitionParser parser(instrumentFilename, instrumentName, instrumentXml);

std::string instrumentNameMangled = parser.getMangledName();
Instrument_sptr instr;
// Check whether the instrument is already in the InstrumentDataService
Expand All @@ -1049,6 +1044,24 @@ void ExperimentInfo::loadInstrumentInfoNexus(::NeXus::File *file,
}
}

//-------------------------------------------------------------------------------------------------
/** Loads the contents of a file and returns the string
* The file is assumed to be an IDF, and already checked that
* the path is correct.
*
* @param filename :: the path to the file
*/
std::string ExperimentInfo::loadInstrumentXML(const std::string &filename) {
try {
return Strings::loadFile(filename);
} catch (std::exception &e) {
g_log.error() << "Error loading instrument IDF file: "
<< filename << ".\n";
g_log.debug() << e.what() << std::endl;
throw;
}
}

//-------------------------------------------------------------------------------------------------
/** Parse the result of ParameterMap.asString() into the ParameterMap
* of the current instrument. The instrument needs to have been loaded
Expand Down
4 changes: 2 additions & 2 deletions Code/Mantid/Framework/DataHandling/src/LoadInstrument.cpp
Expand Up @@ -127,7 +127,7 @@ void LoadInstrument::exec() {
const PropertyWithValue<std::string> *xml =
dynamic_cast<const PropertyWithValue<std::string> *>(InstrumentXML);
if (xml) {
parser.initialize(m_filename, m_instName, *xml);
parser = InstrumentDefinitionParser(m_filename, m_instName, *xml);
} else {
throw std::invalid_argument("The instrument XML passed cannot be "
"casted to a standard string.");
Expand Down Expand Up @@ -165,7 +165,7 @@ void LoadInstrument::exec() {
m_instName = instrumentFile.substr(0, instrumentFile.find("_Def"));

// Initialize the parser with the the XML text loaded from the IDF file
parser.initialize(m_filename, m_instName, Strings::loadFile(m_filename));
parser = InstrumentDefinitionParser(m_filename, m_instName, Strings::loadFile(m_filename));
}

// Find the mangled instrument name that includes the modified date
Expand Down
3 changes: 1 addition & 2 deletions Code/Mantid/Framework/DataHandling/src/LoadMcStas.cpp
Expand Up @@ -187,9 +187,8 @@ void LoadMcStas::readEventData(

progInitial.report("Loading instrument");

Geometry::InstrumentDefinitionParser parser;
std::string instrumentName = "McStas";
parser.initialize(filename, instrumentName, instrumentXML);
Geometry::InstrumentDefinitionParser parser(filename, instrumentName, instrumentXML);
std::string instrumentNameMangled = parser.getMangledName();

// Check whether the instrument is already in the InstrumentDataService
Expand Down
Expand Up @@ -829,8 +829,7 @@ class LoadNexusProcessedTest: public CxxTest::TestSuite
// Loading a peaks workspace without a instrument from an IDF doesn't work ...
const std::string filename = FileFinder::Instance().getFullPath(
"IDFs_for_UNIT_TESTING/MINITOPAZ_Definition.xml");
InstrumentDefinitionParser parser;
parser.initialize(filename, "MINITOPAZ", Strings::loadFile(filename));
InstrumentDefinitionParser parser(filename, "MINITOPAZ", Strings::loadFile(filename));
auto instrument = parser.parseXML(NULL);
peaksTestWS->populateInstrumentParameters();
peaksTestWS->setInstrument(instrument);
Expand Down Expand Up @@ -872,8 +871,7 @@ class LoadNexusProcessedTest: public CxxTest::TestSuite
// Loading a peaks workspace without a instrument from an IDF doesn't work ...
const std::string filename = FileFinder::Instance().getFullPath(
"IDFs_for_UNIT_TESTING/MINITOPAZ_Definition.xml");
InstrumentDefinitionParser parser;
parser.initialize(filename, "MINITOPAZ", Strings::loadFile(filename));
InstrumentDefinitionParser parser(filename, "MINITOPAZ", Strings::loadFile(filename));
auto instrument = parser.parseXML(NULL);
peaksTestWS->populateInstrumentParameters();
peaksTestWS->setInstrument(instrument);
Expand Down
Expand Up @@ -5,7 +5,6 @@
#ifndef Q_MOC_RUN
#include <boost/shared_ptr.hpp>
#endif
#include <Poco/Timestamp.h>
#include <Poco/File.h>
#include <Poco/Path.h>
#include <stdexcept>
Expand Down Expand Up @@ -49,13 +48,11 @@ class DLLExport AbstractIDFObject {
public:
AbstractIDFObject() {}
static const std::string expectedExtension();
virtual const Poco::Path &getParentDirectory() const = 0;
virtual const Poco::Path getParentDirectory() const = 0;
virtual const Poco::Path &getFileFullPath() const = 0;
virtual const std::string &getFileFullPathStr() const = 0;
virtual std::string getFileNameOnly() const = 0;
virtual std::string getExtension() const = 0;
virtual Poco::Timestamp getLastModified() const = 0;
virtual std::string getFormattedLastModified() const = 0;
virtual std::string getMangledName() const = 0;
virtual bool exists() const = 0;
virtual ~AbstractIDFObject(){};
Expand All @@ -71,13 +68,11 @@ class DLLExport AbstractIDFObject {
class DLLExport IDFObject : public AbstractIDFObject {
public:
IDFObject(const std::string &fileName);
virtual const Poco::Path &getParentDirectory() const;
virtual const Poco::Path getParentDirectory() const;
virtual const Poco::Path &getFileFullPath() const;
virtual const std::string &getFileFullPathStr() const;
virtual std::string getFileNameOnly() const;
virtual std::string getExtension() const;
virtual Poco::Timestamp getLastModified() const;
virtual std::string getFormattedLastModified() const;
virtual std::string getMangledName() const;
virtual bool exists() const;
virtual ~IDFObject();
Expand All @@ -101,7 +96,7 @@ class DLLExport NullIDFObject : public AbstractIDFObject {

public:
NullIDFObject() : m_emptyResponse("") {}
virtual const Poco::Path &getParentDirectory() const {
virtual const Poco::Path getParentDirectory() const {
throw std::runtime_error("Not implemented on NullIDFObject");
}
virtual const Poco::Path &getFileFullPath() const {
Expand All @@ -112,12 +107,6 @@ class DLLExport NullIDFObject : public AbstractIDFObject {
}
virtual std::string getFileNameOnly() const { return m_emptyResponse; }
virtual std::string getExtension() const { return m_emptyResponse; }
virtual Poco::Timestamp getLastModified() const {
throw std::runtime_error("Not implemented on NullIDFObject");
}
virtual std::string getFormattedLastModified() const {
throw std::runtime_error("Not implemented on NullIDFObject");
}
virtual std::string getMangledName() const {
throw std::runtime_error("Not implemented on NullIDFObject");
}
Expand Down
Expand Up @@ -58,26 +58,22 @@ class Object;
class DLLExport InstrumentDefinitionParser {
public:
InstrumentDefinitionParser();
InstrumentDefinitionParser(const std::string &filename, const std::string &instName,
const std::string &xmlText);
InstrumentDefinitionParser(const IDFObject_const_sptr xmlFile,
const IDFObject_const_sptr expectedCacheFile,
const std::string& instName, const std::string& xmlText);
~InstrumentDefinitionParser();

/// Caching
enum CachingOption {
NoneApplied,
ReadAdjacent,
ReadGeomCache,
ReadFallBack,
WroteCacheAdjacent,
WroteGeomCache,
WroteCacheTemp
};

/// Set up parser
void initialize(const std::string &filename, const std::string &instName,
const std::string &xmlText);

/// Set up parser.
void initialize(IDFObject_const_sptr xmlFile,
IDFObject_const_sptr expectedCacheFile,
const std::string &instName, const std::string &xmlText);

/// Parse XML contents
boost::shared_ptr<Instrument> parseXML(Kernel::ProgressBase *prog);

Expand All @@ -104,7 +100,19 @@ class DLLExport InstrumentDefinitionParser {
/// Getter the the applied caching option.
CachingOption getAppliedCachingOption() const;

///creates a vtp filename from a given xml filename
const std::string createVTPFileName();

private:
///shared Constructor logic
void initialise(const std::string &filename,
const std::string &instName,
const std::string &xmlText,
const std::string &vtpFilename);

///lazy loads the document and returns a pointer
Poco::AutoPtr<Poco::XML::Document> getDocument();

/// Set location (position) of comp as specified in XML location element
void setLocation(Geometry::IComponent *comp, const Poco::XML::Element *pElem,
const double angleConvertConst,
Expand Down Expand Up @@ -210,22 +218,20 @@ class DLLExport InstrumentDefinitionParser {
/// notation for a sequence of \<location\> elements.
/// This method return this sequence as a xml string
std::string convertLocationsElement(const Poco::XML::Element *pElem);

public: // for testing
/// return absolute position of point which is set relative to the
/// coordinate system of the input component
Kernel::V3D getAbsolutPositionInCompCoorSys(Geometry::ICompAssembly *comp,
Kernel::V3D);

private:
/// Checks if the proposed cache file can be read from.
bool canUseProposedCacheFile(IDFObject_const_sptr cache) const;

/// Reads from a cache file.
void applyCache(IDFObject_const_sptr cacheToApply);

/// Write out a cache file.
CachingOption writeAndApplyCache(IDFObject_const_sptr usedCache);
CachingOption writeAndApplyCache(IDFObject_const_sptr firstChoiceCache,
IDFObject_const_sptr usedCache);

/// This method returns the parent appended which its child components and
/// also name of type of the last child component
Expand Down Expand Up @@ -259,10 +265,8 @@ class DLLExport InstrumentDefinitionParser {
/// Name of the instrument
std::string m_instName;

/// XML document loaded
Poco::AutoPtr<Poco::XML::Document> pDoc;
/// Root element of the parsed XML
Poco::XML::Element *pRootElem;
/// XML document is lazy loaded
Poco::AutoPtr<Poco::XML::Document> m_pDoc;

/** Holds all the xml elements that have a \<parameter\> child element.
* Added purely for the purpose of computing speed and is used in
Expand Down
19 changes: 1 addition & 18 deletions Code/Mantid/Framework/Geometry/src/Instrument/IDFObject.cpp
Expand Up @@ -33,7 +33,7 @@ IDFObject::~IDFObject() {}
Gets the parent directory of the file.
@return Parent directory path.
*/
const Poco::Path &IDFObject::getParentDirectory() const {
const Poco::Path IDFObject::getParentDirectory() const {
return m_cacheParentDirectory;
}

Expand Down Expand Up @@ -67,23 +67,6 @@ std::string IDFObject::getExtension() const {
return "." + ext;
}

/**
Gets the last modified timestamp of the file.
@return last modified timestamp.
*/
Poco::Timestamp IDFObject::getLastModified() const {
return m_defFile.getLastModified();
}

/**
Gets a formatted string of the last modified timestamp.
@return timestamp as a formatted string.
*/
std::string IDFObject::getFormattedLastModified() const {
return Poco::DateTimeFormatter::format(this->getLastModified(),
"%Y-%d-%mT%H:%M:%S");
}

/**
Gets the idf file as a mangled name.
@return the idf file as a mangled name.
Expand Down

0 comments on commit da16824

Please sign in to comment.