From b008a1348f9862f22722d7d42bb3edb6c61c60be Mon Sep 17 00:00:00 2001 From: Martyn Gigg <martyn.gigg@stfc.ac.uk> Date: Mon, 1 Jul 2013 16:12:57 +0100 Subject: [PATCH] Move the remaining loaders to the new scheme. Refs #7263 --- .../Crystal/inc/MantidCrystal/LoadIsawPeaks.h | 11 +- .../Framework/Crystal/src/LoadIsawPeaks.cpp | 129 +++++------ .../Crystal/test/LoadIsawPeaksTest.h | 11 +- .../inc/MantidDataHandling/Load.h | 36 ++- .../Framework/DataHandling/src/Load.cpp | 212 +++++++++--------- .../Kernel/inc/MantidKernel/Strings.h | 4 +- Code/Mantid/Framework/Kernel/src/Strings.cpp | 4 +- .../inc/MantidMDAlgorithms/LoadMD.h | 11 +- .../Framework/MDAlgorithms/src/LoadMD.cpp | 78 ++----- .../Framework/MDAlgorithms/test/LoadMDTest.h | 2 +- 10 files changed, 234 insertions(+), 264 deletions(-) diff --git a/Code/Mantid/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h b/Code/Mantid/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h index ac95259ebdb..54039d27d8c 100644 --- a/Code/Mantid/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h +++ b/Code/Mantid/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h @@ -2,9 +2,8 @@ #define MANTID_CRYSTAL_LOADISAWPEAKS_H_ #include "MantidKernel/System.h" -#include "MantidAPI/Algorithm.h" +#include "MantidAPI/IFileLoader.h" #include "MantidDataObjects/PeaksWorkspace.h" -#include "MantidAPI/IDataFileChecker.h" namespace Mantid { @@ -17,7 +16,7 @@ namespace Crystal * @author Janik Zikovsky, SNS * @date 2011-03-07 15:22:11.897153 */ - class DLLExport LoadIsawPeaks : public API::IDataFileChecker + class DLLExport LoadIsawPeaks : public API::IFileLoader { public: LoadIsawPeaks(); @@ -30,10 +29,8 @@ namespace Crystal /// Algorithm's category for identification virtual const std::string category() const { return "Crystal;DataHandling\\Isaw";} - /// do a quick check that this file can be loaded - bool quickFileCheck(const std::string& filePath,size_t nread,const file_header& header); - /// check the structure of the file and return a value between 0 and 100 of how much this file can be loaded - int fileCheck(const std::string& filePath); + /// Returns a confidence value that this algorithm can load a file + virtual int confidence(Kernel::FileDescriptor & descriptor) const; private: /// Sets documentation strings for this algorithm diff --git a/Code/Mantid/Framework/Crystal/src/LoadIsawPeaks.cpp b/Code/Mantid/Framework/Crystal/src/LoadIsawPeaks.cpp index a11db7af4c1..d2683170f8f 100644 --- a/Code/Mantid/Framework/Crystal/src/LoadIsawPeaks.cpp +++ b/Code/Mantid/Framework/Crystal/src/LoadIsawPeaks.cpp @@ -9,6 +9,7 @@ NOTE: The instrument used is determined by reading the 'Instrument:' and 'Date:' *WIKI*/ #include "MantidAPI/FileProperty.h" +#include "MantidAPI/RegisterFileLoader.h" #include "MantidCrystal/LoadIsawPeaks.h" #include "MantidDataObjects/PeaksWorkspace.h" #include "MantidGeometry/Crystal/OrientedLattice.h" @@ -29,7 +30,7 @@ NOTE: The instrument used is determined by reading the 'Instrument:' and 'Date:' #include <stdlib.h> #include <string> #include "MantidKernel/Unit.h" -#include "MantidAPI/LoadAlgorithmFactory.h" + using Mantid::Kernel::Strings::readToEndOfLine; using Mantid::Kernel::Strings::getWord; @@ -40,9 +41,7 @@ namespace Mantid namespace Crystal { - // Register the algorithm into the AlgorithmFactory - DECLARE_ALGORITHM(LoadIsawPeaks) - DECLARE_LOADALGORITHM(LoadIsawPeaks) + DECLARE_FILELOADER_ALGORITHM(LoadIsawPeaks); using namespace Mantid::Kernel; using namespace Mantid::API; @@ -64,6 +63,65 @@ namespace Crystal } + /** + * Return the confidence with with this algorithm can load the file + * @param descriptor A descriptor for the file + * @returns An integer specifying the confidence level. 0 indicates it will not be used + */ + int LoadIsawPeaks::confidence(Kernel::FileDescriptor & descriptor) const + { + const std::string & extn = descriptor.extension(); + // If the extension is peaks or integrate then give it a go + if(extn.compare(".peaks") != 0 && extn.compare(".integrate") != 0 ) return 0; + + int confidence(0); + try + { + auto &in = descriptor.data(); + // Read the header, load the instrument + std::string tag; + std::string r = getWord(in, false); + + if(r.length() < 1) + throw std::logic_error( std::string( "No first line of Peaks file" ) ); + + if(r.compare("Version:") != 0) + throw std::logic_error( + std::string( "No Version: on first line of Peaks file" ) ); + + std::string C_version = getWord( in , false ); + if( C_version.length() < 1 ) + throw std::logic_error( std::string( "No Version for Peaks file" ) ); + + getWord(in , false); //tag + // cppcheck-suppress unreadVariable + std::string C_Facility = getWord(in, false ); + + getWord(in , false ); //tag + std::string C_Instrument = getWord(in , false); + + if( C_Instrument.length() < 1 ) + throw std::logic_error( + std::string( "No Instrument for Peaks file" ) ); + + // Date: use the current date/time if not found + Kernel::DateAndTime C_experimentDate; + std::string date; + tag = getWord(in, false ); + if(tag.empty()) + date = Kernel::DateAndTime::getCurrentTime().toISO8601String(); + else if(tag == "Date:") + date = getWord(in, false ); + readToEndOfLine( in, true ); + confidence = 95; + } + catch (std::exception & ) + { + } + return confidence; + } + + //---------------------------------------------------------------------------------------------- /// Sets documentation strings for this algorithm void LoadIsawPeaks::initDocs() @@ -73,69 +131,6 @@ namespace Crystal } //---------------------------------------------------------------------------------------------- - /// @copydoc Mantid::API::IDataFileChecker::quickFileCheck - bool LoadIsawPeaks::quickFileCheck(const std::string& filePath,size_t nread,const file_header& header) - { - UNUSED_ARG(nread); - UNUSED_ARG(header); - - std::string ext = this->extension(filePath); - // If the extension is peaks or integrate then give it a go - if( ext.compare("peaks") == 0 ) return true; - else if( ext.compare("integrate") == 0 ) return true; - else return false; - } - - /// @copydoc Mantid::API::IDataFileChecker::fileCheck - int LoadIsawPeaks::fileCheck(const std::string& filePath) - { - int confidence(0); - try - { - // Open the file - std::ifstream in( filePath.c_str() ); - // Read the header, load the instrument - std::string tag; - std::string r = getWord( in , false ); - - if( r.length() < 1 ) - throw std::logic_error( std::string( "No first line of Peaks file" ) ); - - if( r.compare( std::string( "Version:" ) ) != 0 ) - throw std::logic_error( - std::string( "No Version: on first line of Peaks file" ) ); - - std::string C_version = getWord( in , false ); - if( C_version.length() < 1 ) - throw std::logic_error( std::string( "No Version for Peaks file" ) ); - - getWord( in , false ); //tag - // cppcheck-suppress unreadVariable - std::string C_Facility = getWord( in , false ); - - getWord( in , false ); //tag - std::string C_Instrument = getWord( in , false ); - - if( C_Instrument.length() < 1 ) - throw std::logic_error( - std::string( "No Instrument for Peaks file" ) ); - - // Date: use the current date/time if not found - Kernel::DateAndTime C_experimentDate; - std::string date; - tag = getWord( in , false ); - if(tag.empty()) - date = Kernel::DateAndTime::getCurrentTime().toISO8601String(); - else if(tag == "Date:") - date = getWord( in , false ); - readToEndOfLine( in , true ); - confidence = 95; - } - catch (std::exception & ) - { - } - return confidence; - } //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. diff --git a/Code/Mantid/Framework/Crystal/test/LoadIsawPeaksTest.h b/Code/Mantid/Framework/Crystal/test/LoadIsawPeaksTest.h index 4e7763ca5ef..29270d1dbd1 100644 --- a/Code/Mantid/Framework/Crystal/test/LoadIsawPeaksTest.h +++ b/Code/Mantid/Framework/Crystal/test/LoadIsawPeaksTest.h @@ -22,7 +22,16 @@ class LoadIsawPeaksTest : public CxxTest::TestSuite { public: - + void test_Confidence() + { + LoadIsawPeaks alg; + alg.initialize(); + alg.setPropertyValue("Filename", "TOPAZ_1241.integrate"); + + Mantid::Kernel::FileDescriptor descriptor(alg.getPropertyValue("Filename")); + TS_ASSERT_EQUALS(95, alg.confidence(descriptor)); + } + void test_Init() { LoadIsawPeaks alg; diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h index 51ff149b64d..0cd5b24d193 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h @@ -4,7 +4,7 @@ //---------------------------------------------------------------------- // Includes //---------------------------------------------------------------------- -#include "MantidAPI/IDataFileChecker.h" +#include "MantidAPI/Algorithm.h" #include <Poco/Mutex.h> #include <list> @@ -13,7 +13,7 @@ namespace Mantid { namespace DataHandling { - + /** Loads a workspace from a data file. The algorithm tries to determine the actual type of the file (raw, nxs, ...) and use the specialized loading algorith to load it. @@ -40,8 +40,8 @@ namespace Mantid File change history is stored at: <https://github.com/mantidproject/mantid>. Code Documentation is available at: <http://doxygen.mantidproject.org> - */ - class DLLExport Load : public API::IDataFileChecker + */ + class DLLExport Load : public API::Algorithm { public: /// Default constructor @@ -60,16 +60,12 @@ namespace Mantid private: /// Sets documentation strings for this algorithm virtual void initDocs(); - /// Quick file always returns false here - virtual bool quickFileCheck(const std::string& filePath,size_t nread,const file_header& header); - /// file check by looking at the structure of the data file - virtual int fileCheck(const std::string& filePath); /// This method returns shared pointer to a load algorithm which got /// the highest preference after file check. - API::IDataFileChecker_sptr getFileLoader(const std::string& filePath); + API::IAlgorithm_sptr getFileLoader(const std::string& filePath); /// Declare any additional input properties from the concrete loader - void declareLoaderProperties(const API::IDataFileChecker_sptr loader); - + void declareLoaderProperties(const API::IAlgorithm_sptr & loader); + /// Initialize the static base properties void init(); /// Execute @@ -83,16 +79,16 @@ namespace Mantid /// Overrides the cancel() method to call m_loader->cancel() void cancel(); /// Create the concrete instance use for the actual loading. - API::IDataFileChecker_sptr createLoader(const std::string & name, const double startProgress = -1.0, - const double endProgress=-1.0, const bool logging = true) const; + API::IAlgorithm_sptr createLoader(const std::string & name, const double startProgress = -1.0, + const double endProgress=-1.0, const bool logging = true) const; /// Set the loader option for use as a Child Algorithm. - void setUpLoader(API::IDataFileChecker_sptr loader, const double startProgress = -1.0, - const double endProgress=-1.0, const bool logging = true) const; + void setUpLoader(API::IAlgorithm_sptr & loader, const double startProgress = -1.0, + const double endProgress=-1.0, const bool logging = true) const; /// Set the output workspace(s) - void setOutputWorkspace(const API::IDataFileChecker_sptr & loader); + void setOutputWorkspace(const API::IAlgorithm_sptr & loader); /// Retrieve a pointer to the output workspace from the Child Algorithm API::Workspace_sptr getOutputWorkspace(const std::string & propName, - const API::IDataFileChecker_sptr & loader) const; + const API::IAlgorithm_sptr & loader) const; /// Load a file to a given workspace name. API::Workspace_sptr loadFileToWs(const std::string & fileName, const std::string & wsName); @@ -105,10 +101,12 @@ namespace Mantid /// The base properties std::set<std::string> m_baseProps; /// The actual loader - API::IDataFileChecker_sptr m_loader; + API::IAlgorithm_sptr m_loader; + /// The name of the property that will be passed the property from our Filename + std::string m_filenamePropName; /// Mutex for temporary fix for #5963 static Poco::Mutex m_mutex; - }; + }; } // namespace DataHandling } // namespace Mantid diff --git a/Code/Mantid/Framework/DataHandling/src/Load.cpp b/Code/Mantid/Framework/DataHandling/src/Load.cpp index 78077edd060..3c23011d23d 100644 --- a/Code/Mantid/Framework/DataHandling/src/Load.cpp +++ b/Code/Mantid/Framework/DataHandling/src/Load.cpp @@ -32,12 +32,15 @@ Loading multiple files is also possible with <code>Load</code>, as well as works // Includes //---------------------------------------------------------------------- #include "MantidDataHandling/Load.h" -#include "MantidAPI/MultipleFileProperty.h" +#include "MantidAPI/AlgorithmManager.h" +#include "MantidAPI/FileProperty.h" +#include "MantidAPI/FrameworkManager.h" #include "MantidAPI/IEventWorkspace.h" +#include "MantidAPI/IMDEventWorkspace.h" #include "MantidAPI/IWorkspaceProperty.h" -#include "MantidKernel/ArrayProperty.h" #include "MantidAPI/LoadAlgorithmFactory.h" -#include "MantidAPI/AlgorithmManager.h" +#include "MantidAPI/MultipleFileProperty.h" +#include "MantidKernel/ArrayProperty.h" #include "MantidKernel/FacilityInfo.h" #include <Poco/Path.h> @@ -47,7 +50,6 @@ Loading multiple files is also possible with <code>Load</code>, as well as works #include <functional> #include <numeric> #include <set> -#include "MantidAPI/IMDEventWorkspace.h" #include <cstdio> namespace @@ -164,7 +166,7 @@ namespace Mantid //-------------------------------------------------------------------------- /// Default constructor - Load::Load() : IDataFileChecker(), m_baseProps() + Load::Load() : Algorithm(), m_baseProps(), m_loader(), m_filenamePropName() { } @@ -177,7 +179,7 @@ namespace Mantid { // Call base class method in all cases. // For a filename property is deals with resolving the full path. - IDataFileChecker::setPropertyValue(name, value); + Algorithm::setPropertyValue(name, value); std::string NAME(name); std::transform(name.begin(),name.end(),NAME.begin(),toupper); @@ -186,21 +188,20 @@ namespace Mantid // Get back full path before passing to getFileLoader method, and also // find out whether this is a multi file load. std::vector<std::string> fileNames = flattenVecOfVec(getProperty("Filename")); - // If it's a single file load, then it's fine to change loader. + //If it's a single file load, then it's fine to change loader. if(fileNames.size() == 1) { - IDataFileChecker_sptr loader = getFileLoader(getPropertyValue(name)); + IAlgorithm_sptr loader = getFileLoader(getPropertyValue(name)); assert(loader); // (getFileLoader should throw if no loader is found.) declareLoaderProperties(loader); } - // Else we've got multiple files, and must enforce the rule that only one type of loader is allowed. // Allowing more than one would mean that "extra" properties defined by the class user (for example // "LoadLogFiles") are potentially ambiguous. else if(fileNames.size() > 1) { - IDataFileChecker_sptr loader = getFileLoader(fileNames[0]); - + IAlgorithm_sptr loader = getFileLoader(fileNames[0]); + // If the first file has a loader ... if( loader ) { @@ -226,109 +227,118 @@ namespace Mantid // Private methods //-------------------------------------------------------------------------- - /** - * Quick file always returns false here - * @param filePath :: File path - * @param nread :: Number of bytes read - * @param header :: A buffer containing the nread bytes - */ - bool Load::quickFileCheck(const std::string& filePath,size_t nread,const file_header& header) - { - (void)filePath; (void)nread; (void)header; - return false; - } - - /** - * File check by looking at the structure of the data file - * @param filePath :: The full file path - * @returns -1 - */ - int Load::fileCheck(const std::string& filePath) - { - (void)filePath; - return -1; - } - /** * Get a shared pointer to the load algorithm with highest preference for loading * @param filePath :: path of the file * @returns A shared pointer to the unmanaged algorithm */ - API::IDataFileChecker_sptr Load::getFileLoader(const std::string& filePath) + API::IAlgorithm_sptr Load::getFileLoader(const std::string& filePath) { - /* Open the file and read in the first bufferSize bytes - these will - * be used to determine the type of the file - */ - FILE* fp = fopen(filePath.c_str(), "rb"); - if (fp == NULL) +// /* Open the file and read in the first bufferSize bytes - these will +// * be used to determine the type of the file +// */ +// FILE* fp = fopen(filePath.c_str(), "rb"); +// if (fp == NULL) +// { +// throw Kernel::Exception::FileError("Unable to open the file:", filePath); +// } +// file_header header; +// size_t nread = fread(&header,sizeof(unsigned char), g_hdr_bytes, fp); +// // Ensure the character string is null terminated. +// header.full_hdr[g_hdr_bytes] = '\0'; +// +// if (fclose(fp) != 0) +// { +// throw std::runtime_error("Error while closing file \"" + filePath + "\""); +// } +// +// Poco::Mutex::ScopedLock lock( m_mutex ); +// +// // Iterate through all loaders and attempt to find the best qualified for the job. +// // Each algorithm has a quick and long file check. The long version returns an integer +// // giving its certainty about be able to load the file. The highest wins. +// std::vector<std::string> loaderNames = API::LoadAlgorithmFactory::Instance().getKeys(); +// int highestPref(0); +// API::IDataFileChecker_sptr winningLoader; +// std::vector<std::string>::const_iterator cend = loaderNames.end(); +// for( std::vector<std::string>::const_iterator citr = loaderNames.begin(); citr != cend; +// ++citr ) +// { +// IDataFileChecker_sptr loader = API::LoadAlgorithmFactory::Instance().create(*citr); +// try +// { +// if( loader->quickFileCheck(filePath, nread, header) ) +// { +// int pref = loader->fileCheck(filePath); +// // Can't just pick the first as there might be one later in the list with a higher +// // preference +// if( pref > highestPref ) +// { +// highestPref = pref; +// winningLoader = loader; +// } +// } +// } +// catch (std::exception & e) +// { +// g_log.debug() << "Error running file check of " << loader->name() << std::endl; +// g_log.debug() << e.what() << std::endl; +// +// } +// +// } +// +// if( !winningLoader ) +// { +// // Clear what may have been here previously +// setPropertyValue("LoaderName", ""); +// throw std::runtime_error("Cannot find an algorithm that is able to load \"" + filePath + "\".\n" +// "Check that the file is a supported type."); +// } +// g_log.debug() << "Winning loader is " << winningLoader->name() << std::endl; +// setPropertyValue("LoaderName", winningLoader->name()); +// winningLoader->initialize(); +// setUpLoader(winningLoader); +// return winningLoader; + std::string winningLoader; + try { - throw Kernel::Exception::FileError("Unable to open the file:", filePath); + CALLGRIND_START_INSTRUMENTATION; + winningLoader = API::FileLoaderRegistry::Instance().chooseLoader(filePath); + CALLGRIND_STOP_INSTRUMENTATION; } - file_header header; - size_t nread = fread(&header,sizeof(unsigned char), g_hdr_bytes, fp); - // Ensure the character string is null terminated. - header.full_hdr[g_hdr_bytes] = '\0'; - - if (fclose(fp) != 0) + catch(Exception::NotFoundError&) { - throw std::runtime_error("Error while closing file \"" + filePath + "\""); - } - - Poco::Mutex::ScopedLock lock( m_mutex ); - - // Iterate through all loaders and attempt to find the best qualified for the job. - // Each algorithm has a quick and long file check. The long version returns an integer - // giving its certainty about be able to load the file. The highest wins. - std::vector<std::string> loaderNames = API::LoadAlgorithmFactory::Instance().getKeys(); - int highestPref(0); - API::IDataFileChecker_sptr winningLoader; - std::vector<std::string>::const_iterator cend = loaderNames.end(); - for( std::vector<std::string>::const_iterator citr = loaderNames.begin(); citr != cend; - ++citr ) + // Clear what may have been here previously + setPropertyValue("LoaderName", ""); + throw std::runtime_error("Cannot find an algorithm that is able to load \"" + filePath + "\".\n" + "Check that the file is a supported type."); + } + const IAlgorithm_sptr loader = AlgorithmManager::Instance().create(winningLoader,-1); + loader->initialize(); + // Use the first file property as the main Filename + const auto & props = loader->getProperties(); + for(auto it = props.begin(); it != props.end(); ++it) { - IDataFileChecker_sptr loader = API::LoadAlgorithmFactory::Instance().create(*citr); - try + if(auto *fp = dynamic_cast<API::FileProperty*>(*it)) { - if( loader->quickFileCheck(filePath, nread, header) ) - { - int pref = loader->fileCheck(filePath); - // Can't just pick the first as there might be one later in the list with a higher - // preference - if( pref > highestPref ) - { - highestPref = pref; - winningLoader = loader; - } - } - } - catch (std::exception & e) - { - g_log.debug() << "Error running file check of " << loader->name() << std::endl; - g_log.debug() << e.what() << std::endl; - + m_filenamePropName = fp->name(); + break; } - } - - if( !winningLoader ) + if(m_filenamePropName.empty()) { - // Clear what may have been here previously setPropertyValue("LoaderName", ""); - throw std::runtime_error("Cannot find an algorithm that is able to load \"" + filePath + "\".\n" - "Check that the file is a supported type."); + throw std::runtime_error("Cannot find FileProperty on " + winningLoader + " algorithm."); } - g_log.debug() << "Winning loader is " << winningLoader->name() << std::endl; - setPropertyValue("LoaderName", winningLoader->name()); - winningLoader->initialize(); - setUpLoader(winningLoader); - return winningLoader; + return loader; } /** * Declare any additional properties of the concrete loader here * @param loader A pointer to the concrete loader */ - void Load::declareLoaderProperties(const IDataFileChecker_sptr loader) + void Load::declareLoaderProperties(const API::IAlgorithm_sptr & loader) { // If we have switch loaders then the concrete loader will have different properties // so take care of ensuring Load has the correct ones @@ -345,12 +355,11 @@ namespace Mantid } const std::vector<Property*> &loaderProps = loader->getProperties(); - const std::string filePropName(loader->filePropertyName()); size_t numProps(loaderProps.size()); for (size_t i = 0; i < numProps; ++i) { Property* loadProp = loaderProps[i]; - if( loadProp->name() == filePropName ) continue; + if( loadProp->name() == m_filenamePropName ) continue; try { Property * propClone = loadProp->clone(); @@ -447,7 +456,7 @@ namespace Mantid { m_loader->setPropertyValue(propName, getPropertyValue(propName)); } - else if( propName == m_loader->filePropertyName() ) + else if( propName == m_filenamePropName ) { m_loader->setPropertyValue(propName, getPropertyValue("Filename")); } @@ -554,11 +563,10 @@ namespace Mantid * algorithm where this child algorithm ends * @param logging :: Set to false to disable logging from the child algorithm */ - API::IDataFileChecker_sptr Load::createLoader(const std::string & name, const double startProgress, + API::IAlgorithm_sptr Load::createLoader(const std::string & name, const double startProgress, const double endProgress, const bool logging) const { - IDataFileChecker_sptr loader = boost::static_pointer_cast<IDataFileChecker>( - API::AlgorithmManager::Instance().createUnmanaged(name)); + API::IAlgorithm_sptr loader = API::AlgorithmManager::Instance().createUnmanaged(name); loader->initialize(); if( !loader ) { @@ -575,8 +583,8 @@ namespace Mantid * @param endProgress :: The end progress fraction * @param logging:: If true, enable logging */ - void Load::setUpLoader(API::IDataFileChecker_sptr loader, const double startProgress, - const double endProgress, const bool logging) const + void Load::setUpLoader(API::IAlgorithm_sptr & loader, const double startProgress, + const double endProgress, const bool logging) const { //Set as a child so that we are in control of output storage loader->setChild(true); @@ -604,7 +612,7 @@ namespace Mantid * Set the output workspace(s) if the load's return workspace has type API::Workspace * @param loader :: Shared pointer to load algorithm */ - void Load::setOutputWorkspace(const API::IDataFileChecker_sptr & loader) + void Load::setOutputWorkspace(const API::IAlgorithm_sptr & loader) { // Go through each OutputWorkspace property and check whether we need to make a counterpart here const std::vector<Property*> & loaderProps = loader->getProperties(); @@ -634,7 +642,7 @@ namespace Mantid * @returns A pointer to the OutputWorkspace property of the Child Algorithm */ API::Workspace_sptr Load::getOutputWorkspace(const std::string & propName, - const API::IDataFileChecker_sptr & loader) const + const API::IAlgorithm_sptr & loader) const { // @todo Need to try and find a better way using the getValue methods try diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Strings.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Strings.h index 834fa70f570..6ea32d2dfe0 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Strings.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Strings.h @@ -152,9 +152,9 @@ namespace Mantid float getVAXnum(const float A); /// Eat everything from the stream until the next EOL - MANTID_KERNEL_DLL void readToEndOfLine( std::ifstream& in , bool ConsumeEOL ); + MANTID_KERNEL_DLL void readToEndOfLine( std::istream& in , bool ConsumeEOL ); /// Returns the next word in the stream - MANTID_KERNEL_DLL std::string getWord( std::ifstream &in , bool consumeEOL ); + MANTID_KERNEL_DLL std::string getWord( std::istream &in , bool consumeEOL ); /// function parses a path, found in input string "path" and returns vector of the folders contributed into the path */ MANTID_KERNEL_DLL size_t split_path(const std::string &path, std::vector<std::string> &path_components); diff --git a/Code/Mantid/Framework/Kernel/src/Strings.cpp b/Code/Mantid/Framework/Kernel/src/Strings.cpp index 33a8de152f4..c2c1ba8b2b9 100644 --- a/Code/Mantid/Framework/Kernel/src/Strings.cpp +++ b/Code/Mantid/Framework/Kernel/src/Strings.cpp @@ -913,7 +913,7 @@ namespace Mantid * @param consumeEOL :: set to true to remove the new lines at the end of the line * @return a string with the word read in */ - std::string getWord( std::ifstream &in , bool consumeEOL ) + std::string getWord( std::istream &in , bool consumeEOL ) { std::string s; char c = 0; @@ -949,7 +949,7 @@ namespace Mantid * @param in :: stream input * @param ConsumeEOL :: set to true to remove the new lines at the end of the line */ - void readToEndOfLine( std::ifstream& in , bool ConsumeEOL ) + void readToEndOfLine( std::istream& in , bool ConsumeEOL ) { while( in.good() && getWord( in , false ).length() > 0 ) getWord( in , false ); diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h index e2cb4b745a6..9691fd76181 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h @@ -1,11 +1,10 @@ #ifndef MANTID_MDEVENTS_LOADMD_H_ #define MANTID_MDEVENTS_LOADMD_H_ -#include "MantidAPI/Algorithm.h" +#include "MantidAPI/IHDFFileLoader.h" #include "MantidAPI/IMDEventWorkspace.h" #include "MantidKernel/System.h" #include "MantidMDEvents/MDEventWorkspace.h" -#include "MantidAPI/IDataFileChecker.h" namespace Mantid { @@ -37,7 +36,7 @@ namespace MDAlgorithms File change history is stored at: <https://github.com/mantidproject/mantid> Code Documentation is available at: <http://doxygen.mantidproject.org> */ - class DLLExport LoadMD : public API::IDataFileChecker + class DLLExport LoadMD : public API::IHDFFileLoader { public: LoadMD(); @@ -50,10 +49,8 @@ namespace MDAlgorithms /// Algorithm's category for identification virtual const std::string category() const { return "MDAlgorithms";} - /// do a quick check that this file can be loaded - bool quickFileCheck(const std::string& filePath,size_t nread,const file_header& header); - /// check the structure of the file and return a value between 0 and 100 of how much this file can be loaded - int fileCheck(const std::string& filePath); + /// Returns a confidence value that this algorithm can load a file + int confidence(const Kernel::HDFDescriptor & descriptor) const; private: /// Sets documentation strings for this algorithm diff --git a/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp index 5d1fd2a973e..9bd468d27f8 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp @@ -21,7 +21,7 @@ and used by other algorithms, they should not be needed in daily use. #include "MantidAPI/ExperimentInfo.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/IMDEventWorkspace.h" -#include "MantidAPI/LoadAlgorithmFactory.h" +#include "MantidAPI/RegisterFileLoader.h" #include "MantidGeometry/MDGeometry/IMDDimension.h" #include "MantidGeometry/MDGeometry/IMDDimensionFactory.h" #include "MantidGeometry/MDGeometry/MDDimensionExtents.h" @@ -56,10 +56,7 @@ namespace Mantid namespace MDAlgorithms { - // Register the algorithm into the AlgorithmFactory - DECLARE_ALGORITHM(LoadMD); - DECLARE_LOADALGORITHM(LoadMD); - + DECLARE_HDF_FILELOADER_ALGORITHM(LoadMD); //---------------------------------------------------------------------------------------------- /** Constructor @@ -76,6 +73,26 @@ namespace Mantid } + /** + * Return the confidence with with this algorithm can load the file + * @param descriptor A descriptor for the file + * @returns An integer specifying the confidence level. 0 indicates it will not be used + */ + int LoadMD::confidence(const Kernel::HDFDescriptor & descriptor) const + { + int confidence(0); + const auto & rootPathNameType = descriptor.firstEntryNameType(); + if(rootPathNameType.second != "NXentry") return 0; + if(descriptor.pathExists("/" + rootPathNameType.first + "MDEventWorkspace") || + descriptor.pathExists("/" + rootPathNameType.first + "MDHistoWorkspace")) + { + return 95; + } + else return 0; + return confidence; + } + + //---------------------------------------------------------------------------------------------- /// Sets documentation strings for this algorithm void LoadMD::initDocs() @@ -113,57 +130,6 @@ namespace Mantid declareProperty(new WorkspaceProperty<IMDWorkspace>("OutputWorkspace","",Direction::Output), "Name of the output MDEventWorkspace."); } - - - //------------------------------------------------------------------------------------------------- - /** Do a quick file type check by looking at the first 100 bytes of the file - * @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 LoadMD::quickFileCheck(const std::string& filePath,size_t nread, const file_header& header) - { - std::string ext = this->extension(filePath); - // If the extension is nxs then give it a go - if( ext.compare("nxs") == 0 ) return true; - - // If not then let's see if it is a HDF file by checking for the magic cookie - if ( nread >= sizeof(int32_t) && (ntohl(header.four_bytes) == g_hdf_cookie) ) return true; - return false; - } - - //------------------------------------------------------------------------------------------------- - /** Checks the file by opening it and reading few lines - * @param filePath :: name of the file inluding its path - * @return an integer value how much this algorithm can load the file - */ - int LoadMD::fileCheck(const std::string& filePath) - { - int confidence(0); - typedef std::map<std::string,std::string> string_map_t; - try - { - ::NeXus::File file = ::NeXus::File(filePath); - string_map_t entries = file.getEntries(); - for(string_map_t::const_iterator it = entries.begin(); it != entries.end(); ++it) - { - if ( (it->second == "NXentry") && - ((it->first == "MDEventWorkspace") || (it->first == "MDHistoWorkspace")) ) - confidence = 95; - } - file.close(); - } - catch(::NeXus::Exception&) - { - } - return confidence; - } - - - - - //---------------------------------------------------------------------------------------------- /** Load the ExperimentInfo blocks, if any, in the NXS file * diff --git a/Code/Mantid/Framework/MDAlgorithms/test/LoadMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/LoadMDTest.h index d7da4227669..f325c38874f 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/LoadMDTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/LoadMDTest.h @@ -26,7 +26,7 @@ using namespace Mantid::Kernel; class LoadMDTest : public CxxTest::TestSuite { public: - + void test_Init() { LoadMD alg; -- GitLab