From b5b41a9ea2638b54dbbc37612d2a7c69c5fac5b2 Mon Sep 17 00:00:00 2001 From: Martyn Gigg <martyn.gigg@stfc.ac.uk> Date: Wed, 2 Feb 2011 16:13:11 +0000 Subject: [PATCH] This should be everything I need for the Framework to make using the Load algorithm much simpler (including from C++). Re #2329 --- .../API/inc/MantidAPI/AlgorithmProxy.h | 10 +- .../API/inc/MantidAPI/IFitFunction.h | 3 +- .../Framework/API/inc/MantidAPI/IFunctionMD.h | 10 - .../Framework/API/src/AlgorithmProxy.cpp | 48 ++- Code/Mantid/Framework/API/src/IFunctionMD.cpp | 11 +- .../Framework/API/test/AlgorithmProxyTest.h | 10 +- .../Framework/CurveFitting/src/Fit1D.cpp | 9 +- .../inc/MantidDataHandling/Load.h | 36 +- .../Framework/DataHandling/src/Load.cpp | 349 +++++++++--------- .../DataHandling/test/LoadDetectorInfoTest.h | 9 - .../test/LoadEmptyInstrumentTest.h | 8 +- .../Framework/DataHandling/test/LoadTest.h | 57 ++- .../inc/MantidKernel/IPropertyManager.h | 10 +- .../Kernel/inc/MantidKernel/PropertyManager.h | 4 +- .../inc/MantidKernel/PropertyManagerOwner.h | 6 + .../Framework/Kernel/src/PropertyManager.cpp | 28 +- .../Kernel/src/PropertyManagerOwner.cpp | 27 ++ .../Kernel/test/PropertyManagerTest.h | 24 ++ .../src/ComponentCreationHelper.cpp | 3 - 19 files changed, 391 insertions(+), 271 deletions(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/AlgorithmProxy.h b/Code/Mantid/Framework/API/inc/MantidAPI/AlgorithmProxy.h index 0caa70ffc41..3074a6b88fb 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/AlgorithmProxy.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/AlgorithmProxy.h @@ -87,6 +87,12 @@ namespace Mantid void setChild(const bool) {} ///< Do nothing void setRethrows(const bool rethrow); + /** @name PropertyManager methods */ + //@{ + /// Set the property value + void setPropertyValue(const std::string& name, const std::string &value); + //@} + void cancel() const; bool isRunningAsync(); bool isRunning(); @@ -112,7 +118,7 @@ namespace Mantid /// Private assignment operator: NO ASSIGNMENT ALLOWED AlgorithmProxy& operator=(const AlgorithmProxy&); - void createConcreteAlg(); + void createConcreteAlg(bool initOnly = false); void stopped(); void addObservers(); @@ -126,7 +132,7 @@ namespace Mantid std::string m_OptionalMessage; ///<Message to display in GUI const int m_version; ///< version of the real algorithm - Algorithm_sptr m_alg; ///< Pointer to the real algorithm, only defined when the algorithm is running + boost::shared_ptr<Algorithm> m_alg; ///< Shared pointer to a real algorithm. Created on demand bool m_isExecuted; ///< Executed flag bool m_isLoggingEnabled;///< is the logging of the underlying algorithm enabled bool m_rethrow; ///< Whether or not to rethrow exceptions. diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IFitFunction.h b/Code/Mantid/Framework/API/inc/MantidAPI/IFitFunction.h index b861c33ed8d..dbc07c47f94 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IFitFunction.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IFitFunction.h @@ -344,7 +344,7 @@ public: throw std::invalid_argument("Attribute "+attName+" not found in function "+this->name()); } /// Check if attribute attName exists - virtual bool hasAttribute(const std::string& attName)const{return false;} + virtual bool hasAttribute(const std::string& attName)const { (void)attName; return false;} /// Set a function handler void setHandler(FitFunctionHandler* handler); @@ -392,6 +392,7 @@ public: */ virtual void addNumberToColumn(const double& value, const int& iActiveP) { + (void)value; (void)iActiveP; // Avoid compiler warning throw Kernel::Exception::NotImplementedError("No addNumberToColumn() method of Jacobian provided"); } ///@endcond diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IFunctionMD.h b/Code/Mantid/Framework/API/inc/MantidAPI/IFunctionMD.h index 2dfbeb441b8..792d27484c9 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IFunctionMD.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IFunctionMD.h @@ -198,14 +198,4 @@ protected: } // namespace API } // namespace Mantid -/** - * Macro for declaring a new type of function to be used with the FunctionFactory - */ -//#define DECLARE_FUNCTION(classname) \ -// namespace { \ -// Mantid::Kernel::RegistrationHelper register_function_##classname( \ -// ((Mantid::API::FunctionFactory::Instance().subscribe<classname>(#classname)) \ -// , 0)); \ -// } - #endif /*MANTID_API_IFUNCTIONMD_H_*/ diff --git a/Code/Mantid/Framework/API/src/AlgorithmProxy.cpp b/Code/Mantid/Framework/API/src/AlgorithmProxy.cpp index 5ab3196a833..3dd1aa5c35f 100644 --- a/Code/Mantid/Framework/API/src/AlgorithmProxy.cpp +++ b/Code/Mantid/Framework/API/src/AlgorithmProxy.cpp @@ -13,7 +13,7 @@ namespace API { // Get a reference to the logger -Kernel::Logger& AlgorithmProxy::g_log = Kernel::Logger::get("AlgorithmProxyProxy"); +Kernel::Logger& AlgorithmProxy::g_log = Kernel::Logger::get("AlgorithmProxy"); //---------------------------------------------------------------------- // Public methods @@ -23,18 +23,17 @@ Kernel::Logger& AlgorithmProxy::g_log = Kernel::Logger::get("AlgorithmProxyProxy AlgorithmProxy::AlgorithmProxy(Algorithm_sptr alg) : PropertyManagerOwner(),_executeAsync(this,&AlgorithmProxy::executeAsyncImpl), m_name(alg->name()),m_category(alg->category()), - m_version(alg->version()), + m_version(alg->version()), m_alg(alg), m_isExecuted(),m_isLoggingEnabled(true), m_rethrow(false) { - Algorithm_sptr a = boost::dynamic_pointer_cast<Algorithm>(alg); - if (!a) + if (!alg) { g_log.error("Unable to create a proxy algorithm."); throw std::logic_error("Unable to create a proxy algorithm."); } - a->initialize(); - m_OptionalMessage = a->getOptionalMessage(); - copyPropertiesFrom(*a); + alg->initialize(); + m_OptionalMessage = alg->getOptionalMessage(); + copyPropertiesFrom(*alg); } /// Virtual destructor @@ -67,7 +66,6 @@ bool AlgorithmProxy::execute() } catch(...) { - // zero the pointer and rethrow m_alg.reset(); throw; } @@ -149,17 +147,42 @@ void AlgorithmProxy::setRethrows(const bool rethrow) if(m_alg) m_alg->setRethrows(rethrow); } +/** + * Override setPropertyValue + * @param name The name of the property + * @param value The value of the property as a string + */ +void AlgorithmProxy::setPropertyValue(const std::string &name, const std::string &value) +{ + createConcreteAlg(true); + const size_t numPropsAtStart = m_alg->propertyCount(); + m_alg->setPropertyValue(name, value); + if( numPropsAtStart != m_alg->propertyCount() ) + { + copyPropertiesFrom(*m_alg); + } + m_alg.reset(); +} + + //---------------------------------------------------------------------- // Private methods //---------------------------------------------------------------------- -/// Creates an unmanaged instance of the actual algorithm and sets its properties -void AlgorithmProxy::createConcreteAlg() +/** + * Creates an unmanaged instance of the actual algorithm and sets its properties + * @param initOenly If true then the algorithm will only having its init step run, otherwise observers will + * also be added and rethrows will be true + */ +void AlgorithmProxy::createConcreteAlg(bool initOnly) { m_alg = boost::dynamic_pointer_cast<Algorithm>(AlgorithmManager::Instance().createUnmanaged(name(),version())); m_alg->initializeFromProxy(*this); - m_alg->setRethrows(this->m_rethrow); - addObservers(); + if( !initOnly ) + { + m_alg->setRethrows(this->m_rethrow); + addObservers(); + } } /** @@ -168,7 +191,6 @@ void AlgorithmProxy::createConcreteAlg() void AlgorithmProxy::stopped() { m_isExecuted = m_alg->isExecuted(); - // Delete the actual algorithm m_alg.reset(); } diff --git a/Code/Mantid/Framework/API/src/IFunctionMD.cpp b/Code/Mantid/Framework/API/src/IFunctionMD.cpp index efad5e32fc6..9bfdbdadc06 100644 --- a/Code/Mantid/Framework/API/src/IFunctionMD.cpp +++ b/Code/Mantid/Framework/API/src/IFunctionMD.cpp @@ -30,6 +30,7 @@ namespace API */ void IFunctionMD::setWorkspace(boost::shared_ptr<Workspace> ws,const std::string& slicing) { + (void)slicing; //Avoid compiler warning try { m_workspace = boost::dynamic_pointer_cast<IMDWorkspace>(ws); @@ -198,7 +199,7 @@ namespace API m_dataSize(0) { std::vector<std::string> ids = ws->getDimensionIDs(); - for(int i = 0; i < ids.size(); ++i) + for(size_t i = 0; i < ids.size(); ++i) { m_dimensions.push_back(ws->getDimension(ids[i])); } @@ -227,7 +228,7 @@ namespace API if (m_dataSize == 0) { m_dataSize = 1; - for(int i = 0; i< m_dimensions.size(); ++i) + for(int i = 0; i< static_cast<int>(m_dimensions.size()); ++i) { m_dataSize *= m_dimensions[i]->getNBins(); } @@ -270,9 +271,9 @@ namespace API bool IFunctionMD::MDIterator::next() { bool overflow = false; - for(int i=0;i<m_index.size();++i) + for(size_t i=0;i<m_index.size();++i) { - int j = m_index[i] + 1; + size_t j = m_index[i] + 1; overflow = (j == m_dimensions[i]->getNBins()); if (overflow) { @@ -314,7 +315,7 @@ namespace API throw std::runtime_error("Method IFunctionMD::useAllDimensions() can only be called after setting the workspace"); } std::vector<std::string> ids = m_workspace->getDimensionIDs(); - for(int i = 0; i < ids.size(); ++ i) + for(size_t i = 0; i < ids.size(); ++ i) { useDimension(ids[i]); } diff --git a/Code/Mantid/Framework/API/test/AlgorithmProxyTest.h b/Code/Mantid/Framework/API/test/AlgorithmProxyTest.h index 159db50e494..5e7c8f3ae04 100644 --- a/Code/Mantid/Framework/API/test/AlgorithmProxyTest.h +++ b/Code/Mantid/Framework/API/test/AlgorithmProxyTest.h @@ -53,19 +53,19 @@ class TestProxyObserver: public AlgorithmObserver { public: bool start,progress,finish; - TestProxyObserver():AlgorithmObserver(),start(),progress(),finish(){} - TestProxyObserver(IAlgorithm_const_sptr alg):AlgorithmObserver(alg),start(),progress(),finish(){} - void startHandle(const IAlgorithm* alg) + TestProxyObserver():AlgorithmObserver(),start(false),progress(false),finish(false){} + TestProxyObserver(IAlgorithm_const_sptr alg):AlgorithmObserver(alg),start(false),progress(false),finish(false){} + void startHandle(const IAlgorithm*) { start = true; } - void progressHandle(const IAlgorithm* alg,double p,const std::string& msg) + void progressHandle(const IAlgorithm* ,double p,const std::string& msg) { progress = true; TS_ASSERT_EQUALS( p, 0.333 ); TS_ASSERT_EQUALS( msg, "Running" ); } - void finishHandle(const IAlgorithm* alg) + void finishHandle(const IAlgorithm* ) { finish = true; } diff --git a/Code/Mantid/Framework/CurveFitting/src/Fit1D.cpp b/Code/Mantid/Framework/CurveFitting/src/Fit1D.cpp index 5580e47b9bc..32094cd3b05 100644 --- a/Code/Mantid/Framework/CurveFitting/src/Fit1D.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/Fit1D.cpp @@ -199,6 +199,7 @@ static double gsl_costFunction(const gsl_vector * x, void *params) */ void Fit1D::functionDeriv(const double* in, Jacobian* out, const double* xValues, const int& nData) { + (void)in; (void)out; (void)xValues; (void)nData; //Avoid compiler warnings throw Exception::NotImplementedError("No derivative function provided"); } @@ -210,14 +211,18 @@ void Fit1D::functionDeriv(const double* in, Jacobian* out, const double* xValues * @param fittedParameter :: Values of fitting parameters in the order listed in declareParameters() */ void Fit1D::modifyInitialFittedParameters(std::vector<double>& fittedParameter) -{} +{ + (void)fittedParameter; //Avoid compiler warning +} /** If modifyInitialFittedParameters is overloaded this method must also be overloaded to reverse the effect of modifyInitialFittedParameters before outputting the results back to the user. * @param fittedParameter :: Values of fitting parameters in the order listed in declareParameters() */ void Fit1D::modifyFinalFittedParameters(std::vector<double>& fittedParameter) -{} +{ + (void)fittedParameter; //Avoid compiler warning +} /** Initialisation method */ diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h index 865baee8f04..048a7fdefd4 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h @@ -5,6 +5,7 @@ // Includes //---------------------------------------------------------------------- #include "MantidAPI/IDataFileChecker.h" +#include <list> namespace Mantid { @@ -37,9 +38,7 @@ namespace Mantid File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>. Code Documentation is available at: <http://doxygen.mantidproject.org> - */ - - + */ class DLLExport Load : public API::IDataFileChecker { public: @@ -51,34 +50,33 @@ namespace Mantid virtual int version() const { return 1; } /// Category virtual const std::string category() const { return "DataHandling"; } + /// Override setPropertyValue + virtual void setPropertyValue(const std::string &name, const std::string &value); private: /// 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::IAlgorithm_sptr getFileLoader(const std::string& filePath); + /// Declare any additional input properties from the concrete loader + void declareLoaderProperties(const API::IAlgorithm_sptr loader); - private: - ///init + /// Initialize the static base properties void init(); - /// execute + /// Execute void exec(); - /// This method returns shared pointer to load algorithm which got - /// the highest preference after file check. - API::IAlgorithm_sptr getFileLoader(const std::string& filePath); + /// Create the concrete instance use for the actual loading. + 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 output workspace(s) void setOutputWorkspace(API::IAlgorithm_sptr&); - /// intiliases the load algorithm with highest preference and sets this as a child algorithm - void initialiseLoadSubAlgorithm(API::IAlgorithm_sptr alg, const double startProgress, - const double endProgress, const bool enableLogging, const int& version); + private: - /// union used for identifying teh file type - unsigned char* m_header_buffer; -// union { -// unsigned u; -// unsigned long ul; -// unsigned char c[bufferSize+1]; -// } header_buffer_union; + /// A list of property names that have been dynamically set + std::list<std::string> m_loaderProps; }; } // namespace DataHandling diff --git a/Code/Mantid/Framework/DataHandling/src/Load.cpp b/Code/Mantid/Framework/DataHandling/src/Load.cpp index 2da25174f9e..dc48976c32f 100644 --- a/Code/Mantid/Framework/DataHandling/src/Load.cpp +++ b/Code/Mantid/Framework/DataHandling/src/Load.cpp @@ -6,8 +6,7 @@ #include "MantidKernel/ArrayProperty.h" #include "MantidDataObjects/Workspace2D.h" #include "MantidAPI/LoadAlgorithmFactory.h" -#include<algorithm> - +#include "MantidAPI/AlgorithmManager.h" namespace Mantid { @@ -19,17 +18,40 @@ namespace Mantid using namespace Kernel; using namespace API; + //-------------------------------------------------------------------------- + // Public methods + //-------------------------------------------------------------------------- + /// Default constructor - Load::Load() : IDataFileChecker(), m_header_buffer(NULL) + Load::Load() : IDataFileChecker(), m_loaderProps() { } /** - * Quick file always returns false here - * @param filePath File path - * @param nread Number of bytes read - * @param header_buffer A buffer containing the nread bytes - */ + * Override setPropertyValue + * @param name The name of the property + * @param value The value of the property as a string + */ + void Load::setPropertyValue(const std::string &name, const std::string &value) + { + IDataFileChecker::setPropertyValue(name, value); + if( name == "Filename" ) + { + IAlgorithm_sptr loader = getFileLoader(getPropertyValue(name)); + declareLoaderProperties(loader); + } + } + + //-------------------------------------------------------------------------- + // Private methods + //-------------------------------------------------------------------------- + + /** + * Quick file always returns false here + * @param filePath File path + * @param nread Number of bytes read + * @param header_buffer 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; @@ -47,132 +69,11 @@ namespace Mantid return -1; } - /// Initialisation method. - void Load::init() - { - - std::vector<std::string> exts; - exts.push_back(".raw"); - exts.push_back(".s*"); - exts.push_back(".add"); - - exts.push_back(".nxs"); - exts.push_back(".nx5"); - exts.push_back(".xml"); - exts.push_back(".n*"); - - exts.push_back(".dat"); - exts.push_back(".txt"); - exts.push_back(".csv"); - - exts.push_back(".spe"); - - declareProperty(new FileProperty("Filename", "", FileProperty::Load, exts), - "The name of the file to read, including its full or relative\n" - "path. (N.B. case sensitive if running on Linux)."); - declareProperty(new WorkspaceProperty<Workspace>("OutputWorkspace", "",Direction::Output, true), - "The name of the workspace that will be created, filled with the\n" - "read-in data and stored in the Analysis Data Service."); - BoundedValidator<int> *mustBePositive = new BoundedValidator<int>(); - mustBePositive->setLower(1); - declareProperty("SpectrumMin", 1, mustBePositive); - declareProperty("SpectrumMax", EMPTY_INT(), mustBePositive->clone()); - declareProperty(new ArrayProperty<int>("SpectrumList")); - declareProperty("EntryNumber", 0, - "Load a particular entry, if supported by the file format (default: Load all entries)"); - declareProperty("FindLoader", false, "If true the algorithm will only be run as\n" - "far as is necessary to discover the concrete Load algorithm to use"); - declareProperty("LoaderName", std::string(""), "A string containing the name of the concrete loader used", - Direction::Output); - } - - namespace - { - //@cond - /** - * Checks this property exists in the list of algorithm properties. - */ - struct hasProperty - { - /** constructor which takes 1 arguement. - *@param name :: name of the property - */ - hasProperty(const std::string name):m_name(name){} - - /**This method comapres teh property name - *@param prop :: shared pointer to property - *@return true if the property exists in the list of properties. - */ - bool operator()(Mantid::Kernel::Property* prop) - { - std::string name=prop->name(); - return (!name.compare(m_name)); - } - /// name of teh property - std::string m_name; - }; - - //@endcond - } - - /** - * Executes the algorithm. - */ - void Load::exec() - { - std::string fileName = getPropertyValue("Filename"); - std::string::size_type i = fileName.find_last_of('.'); - std::string ext = fileName.substr(i+1); - std::transform(ext.begin(),ext.end(),ext.begin(),tolower); - //get the shared pointer to the specialised load algorithm to execute - API::IAlgorithm_sptr loader = getFileLoader(fileName); - if( !loader ) - { - throw std::runtime_error("Cannot find a loader for \"" + fileName + "\""); - } - else - { - setPropertyValue("LoaderName", loader->name()); - } - - bool findOnly = getProperty("FindLoader"); - if( findOnly ) return; - - g_log.information()<<"The sub load algorithm created to execute is " - << loader->name() << " and it version is " - << loader->version() <<std::endl; - double startProgress(0.0), endProgress(1.0); - initialiseLoadSubAlgorithm(loader,startProgress,endProgress,true,-1); - - //get the list of properties for this algorithm - std::vector<Kernel::Property*> props=getProperties(); - ///get the list properties for the sub load algorithm - std::vector<Kernel::Property*>loader_props=loader->getProperties(); - - //loop through the properties of this algorithm - std::vector<Kernel::Property*>::iterator itr; - for (itr=props.begin();itr!=props.end();++itr) - { - std::vector<Mantid::Kernel::Property*>::iterator prop; - //if the load sub algorithm has the same property then set it. - prop=std::find_if(loader_props.begin(),loader_props.end(),hasProperty((*itr)->name())); - if(prop!=loader_props.end()) - { - - loader->setPropertyValue((*prop)->name(),getPropertyValue((*prop)->name())); - } - - } - // Execute the concrete loader - loader->execute(); - // Set the workspace. Deals with possible multiple periods - setOutputWorkspace(loader); - } - - /** Get a shared pointer to the load algorithm with highest preference for loading - *@param filePath :: path of the file - *@return filePath - path of the file - */ + /** + * 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::IAlgorithm_sptr Load::getFileLoader(const std::string& filePath) { /* Open the file and read in the first bufferSize bytes - these will @@ -183,8 +84,6 @@ namespace Mantid { throw Kernel::Exception::FileError("Unable to open the file:", filePath); } - //unsigned char* header_buffer = header_buffer_union.c; - //unsigned char * header_buffer = IDataFileChecker::g_hdr_buf.get(); file_header header; int nread = fread(&header,sizeof(unsigned char), g_hdr_bytes, fp); // Ensure the character string is null terminated. @@ -227,53 +126,166 @@ namespace Mantid { throw std::runtime_error("Cannot find a loader for \"" + filePath + "\""); } + setPropertyValue("LoaderName", winningLoader->name()); + winningLoader->initialize(); return winningLoader; } + + /** + * Declare any additional properties of the concrete loader here + * @param loader A pointer to the concrete loader + */ + void Load::declareLoaderProperties(const IAlgorithm_sptr loader) + { + if( !m_loaderProps.empty() ) + { + std::list<std::string>::const_iterator cend = m_loaderProps.end(); + for( std::list<std::string>::const_iterator citr = m_loaderProps.begin(); + citr != cend; ++citr ) + { + this->removeProperty(*citr); + } + m_loaderProps.clear(); + } + + + const std::vector<Property*> &loaderProps = loader->getProperties(); + size_t numProps(loaderProps.size()); + for (size_t i = 0; i < numProps; ++i) + { + Property* loadProp = loaderProps[i]; + try + { + declareProperty(loadProp->clone(), loadProp->documentation()); + } + catch(Exception::ExistsError&) + { + // Already exists as a static property + continue; + } + // Save just in case a this function is called again so that we + // can remove the dynamically generated properties + m_loaderProps.push_back(loadProp->name()); + } + } + + /// Initialisation method. + void Load::init() + { + + std::vector<std::string> exts; + exts.push_back(".raw"); + exts.push_back(".s*"); + exts.push_back(".add"); - /** This method set the algorithm as a child algorithm. - * @param alg :: The shared pointer to a algorithm - * @param startProgress :: The percentage progress value of the overall - * algorithm where this child algorithm starts - * @param endProgress :: The percentage progress value of the overall - * algorithm where this child algorithm ends - * @param enableLogging :: Set to false to disable logging from the child algorithm - * @param version :: The version of the child algorithm to create. - * By default gives the latest version. + exts.push_back(".nxs"); + exts.push_back(".nx5"); + exts.push_back(".xml"); + exts.push_back(".n*"); + + exts.push_back(".dat"); + exts.push_back(".txt"); + exts.push_back(".csv"); + + exts.push_back(".spe"); + + declareProperty(new FileProperty("Filename", "", FileProperty::Load, exts), + "The name of the file to read, including its full or relative\n" + "path. (N.B. case sensitive if running on Linux)."); + declareProperty(new WorkspaceProperty<Workspace>("OutputWorkspace", "",Direction::Output, true), + "The name of the workspace that will be created, filled with the\n" + "read-in data and stored in the Analysis Data Service."); + BoundedValidator<int> *mustBePositive = new BoundedValidator<int>(); + mustBePositive->setLower(1); + declareProperty("SpectrumMin", 1, mustBePositive); + declareProperty("SpectrumMax", EMPTY_INT(), mustBePositive->clone()); + declareProperty(new ArrayProperty<int>("SpectrumList")); + declareProperty("EntryNumber", 0, + "Load a particular entry, if supported by the file format (default: Load all entries)"); + declareProperty("LoaderName", std::string(""), "A string containing the name of the concrete loader used", + Direction::Output); + } + + /** + * Executes the algorithm. */ - void Load::initialiseLoadSubAlgorithm(API::IAlgorithm_sptr alg, - const double startProgress, const double endProgress, - const bool enableLogging, const int& version) + void Load::exec() { - (void) version; // Avoid compiler warning. - //Set as a child so that we are in control of output storage - alg->initialize(); - alg->setChild(true); - alg->setLogging(enableLogging); + const std::string loaderName = getPropertyValue("LoaderName"); + if( loaderName.empty() ) + { + throw std::invalid_argument("Cannot find loader, LoaderName property has not been set."); + } + + IAlgorithm_sptr loader = createLoader(loaderName); + g_log.information() << "Using " << loaderName << " version " << loader->version() << ".\n"; + // Get the list of properties for the Load algorithm + std::vector<Kernel::Property*> props = this->getProperties(); + ///get the list properties for the concrete loader load algorithm + std::vector<Kernel::Property*> loader_props = loader->getProperties(); + + //loop through the properties of this algorithm + std::vector<Kernel::Property*>::iterator itr; + for (itr = props.begin(); itr != props.end(); ++itr) + { + const std::string propName = (*itr)->name(); + if( loader->existsProperty(propName) ) + { + loader->setPropertyValue(propName, getPropertyValue(propName)); + } + } + // Execute the concrete loader + loader->execute(); + // Set the workspace. Deals with possible multiple periods + setOutputWorkspace(loader); + } + + /** + * Create the concrete instance use for the actual loading. + * @param name :: The name of the loader to instantiate + * @param startProgress :: The percentage progress value of the overall + * algorithm where this child algorithm starts + * @param endProgress :: The percentage progress value of the overall + * algorithm where this child algorithm ends + * @param logging :: Set to false to disable logging from the child algorithm + */ + API::IAlgorithm_sptr Load::createLoader(const std::string & name, const double startProgress, + const double endProgress, const bool logging) const + { + IAlgorithm_sptr loader = AlgorithmManager::Instance().createUnmanaged(name); + loader->initialize(); + if( !loader ) + { + throw std::runtime_error("Cannot create loader for \"" + getPropertyValue("Filename") + "\""); + } + + //Set as a child so that we are in control of output storage + loader->setChild(true); + loader->setLogging(logging); // If output workspaces are nameless, give them a temporary name to satisfy validator - const std::vector< Property*> &props = alg->getProperties(); + const std::vector< Property*> &props = loader->getProperties(); for (unsigned int i = 0; i < props.size(); ++i) { - if (props[i]->direction() == 1 && dynamic_cast<IWorkspaceProperty*>(props[i]) ) - { - if ( props[i]->value().empty() ) props[i]->setValue("LoadChildWorkspace"); - } + if (props[i]->direction() == Direction::Output && + dynamic_cast<IWorkspaceProperty*>(props[i]) ) + { + if ( props[i]->value().empty() ) props[i]->setValue("LoadChildWorkspace"); + } } - if (startProgress >= 0. && endProgress > startProgress && endProgress <= 1.) { - alg->addObserver(m_progressObserver); - alg->setChildStartProgress(startProgress); - alg->setChildEndProgress(endProgress); + loader->addObserver(m_progressObserver); + loader->setChildStartProgress(startProgress); + loader->setChildEndProgress(endProgress); } - + return loader; } /** - * Set the output workspace(s) if the load's return workspace - * has type API::Workspace - *@param load :: shared pointer to load algorithm - */ + * Set the output workspace(s) if the load's return workspace has type API::Workspace + * @param load :: Shared pointer to load algorithm + */ void Load::setOutputWorkspace(API::IAlgorithm_sptr& load) { try @@ -305,10 +317,7 @@ namespace Mantid MatrixWorkspace_sptr mws=load->getProperty("OutputWorkspace"); setProperty("OutputWorkspace",boost::dynamic_pointer_cast<Workspace>(mws)); } - - } - } // namespace DataHandling } // namespace Mantid diff --git a/Code/Mantid/Framework/DataHandling/test/LoadDetectorInfoTest.h b/Code/Mantid/Framework/DataHandling/test/LoadDetectorInfoTest.h index 087e0076bda..1cb53b2e78b 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadDetectorInfoTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadDetectorInfoTest.h @@ -189,17 +189,8 @@ public: // check the X-values for a sample of spectra avoiding the monitors const int firstIndex = 5, lastIndex = 690; - // you must uncomment this code and choose the appropiate test below to test Different Bins Same Offsets - // the next two are numbers picked at random for testing - const int alteredHist = 317, alteredBin = 133; - const double alteredAmount = 1e-4; - /* WS->dataX(alteredHist)[alteredBin] = - WS->dataX(alteredHist)[alteredBin] + alteredAmount;/**/ - grouper.setPropertyValue("Workspace", m_MariWS); - grouper.setPropertyValue("DataFilename", m_rawFile); - // grouper.setPropertyValue("DataFilename", "C:/mantid/Test/Data/merlin_detector.sca"); TS_ASSERT_THROWS_NOTHING( grouper.execute()); TS_ASSERT( grouper.isExecuted() ); diff --git a/Code/Mantid/Framework/DataHandling/test/LoadEmptyInstrumentTest.h b/Code/Mantid/Framework/DataHandling/test/LoadEmptyInstrumentTest.h index 02430ceeb80..1b18f610b21 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadEmptyInstrumentTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadEmptyInstrumentTest.h @@ -417,8 +417,6 @@ public: MatrixWorkspace_sptr ws; ws = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve(wsName)); - // get parameter map - ParameterMap& paramMap = ws->instrumentParameters(); boost::shared_ptr<IInstrument> i = ws->getInstrument(); // check if combined translation works @@ -754,9 +752,6 @@ public: MatrixWorkspace_sptr ws; ws = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve(wsName)); - // get parameter map - ParameterMap& paramMap = ws->instrumentParameters(); - IDetector_sptr det = ws->getDetector(1); TS_ASSERT_EQUALS( (det->getNumberParameter("number-of-x-pixels"))[0], 192); @@ -774,7 +769,7 @@ void testSANS2D() TS_ASSERT_THROWS_NOTHING(loader.initialize()); TS_ASSERT( loader.isInitialized() ); - loader.setPropertyValue("Filename", "SANS2D_Definition_mod.xml"); + loader.setPropertyValue("Filename", "SANS2D_Definition.xml"); wsName = "LoadEmptyInstrumentParaSans2dTest"; loader.setPropertyValue("OutputWorkspace", wsName); @@ -785,7 +780,6 @@ void testSANS2D() ws = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve(wsName)); // get parameter map - ParameterMap& paramMap = ws->instrumentParameters(); boost::shared_ptr<IInstrument> i = ws->getInstrument(); double pixelLength = 0.0051; diff --git a/Code/Mantid/Framework/DataHandling/test/LoadTest.h b/Code/Mantid/Framework/DataHandling/test/LoadTest.h index 0c2a15d72f4..d9a43f64af3 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadTest.h @@ -20,21 +20,24 @@ public: { Load loader; loader.initialize(); - loader.setPropertyValue("Filename","IRS38633.raw"); - const std::string outputName("LoadTest_IRS38633raw"); - loader.setPropertyValue("OutputWorkspace", outputName); - loader.setPropertyValue("FindLoader", "1"); - loader.setRethrows(true); - TS_ASSERT_THROWS_NOTHING(loader.execute()); +// const char * loadraw_props[5] = {"SpectrumMin", "SpectrumMax", "SpectrumList", "Cache", "LoadLogFiles"}; + const char * loadraw_props[2] = {"Cache", "LoadLogFiles"}; + const size_t numProps = (size_t)(sizeof(loadraw_props)/sizeof(const char*)); + // Basic load has no additional loader properties + for( size_t i = 0; i < numProps ; ++i ) + { + TS_ASSERT_EQUALS(loader.existsProperty(loadraw_props[i]), false); + } + //After setting the file property, the algorithm should have aquired the appropriate properties + TS_ASSERT_THROWS_NOTHING(loader.setPropertyValue("Filename","IRS38633.raw")); + // Now + for( size_t i = 0; i < numProps; ++i ) + { + TS_ASSERT_EQUALS(loader.existsProperty(loadraw_props[i]), true); + } // Did it find the right loader TS_ASSERT_EQUALS(loader.getPropertyValue("LoaderName"), "LoadRaw"); - AnalysisDataServiceImpl& dataStore = AnalysisDataService::Instance(); - TS_ASSERT_EQUALS(dataStore.doesExist(outputName), false); - if( dataStore.doesExist(outputName) ) - { - AnalysisDataService::Instance().remove(outputName); - } } void testRaw() @@ -43,12 +46,36 @@ public: loader.initialize(); loader.setPropertyValue("Filename","IRS38633.raw"); loader.setPropertyValue("OutputWorkspace","LoadTest_Output"); + loader.setRethrows(true); TS_ASSERT_THROWS_NOTHING(loader.execute()); MatrixWorkspace_sptr ws = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("LoadTest_Output")); TS_ASSERT(ws); AnalysisDataService::Instance().remove("LoadTest_Output"); } + void testRawWithOneSpectrum() + { + Load loader; + loader.initialize(); + loader.setPropertyValue("Filename","IRS38633.raw"); + const std::string outputName("LoadTest_IRS38633raw"); + loader.setPropertyValue("OutputWorkspace", outputName); + loader.setPropertyValue("SpectrumList", "1"); + loader.setRethrows(true); + TS_ASSERT_THROWS_NOTHING(loader.execute()); + TS_ASSERT_EQUALS(loader.isExecuted(), true); + + AnalysisDataServiceImpl& dataStore = AnalysisDataService::Instance(); + TS_ASSERT_EQUALS(dataStore.doesExist(outputName), true); + + MatrixWorkspace_sptr ws = boost::dynamic_pointer_cast<MatrixWorkspace>(dataStore.retrieve(outputName)); + if(!ws) TS_FAIL("Cannot retrieve workspace from the store"); + + // Check it only has 1 spectrum + TS_ASSERT_EQUALS( ws->getNumberHistograms(), 1 ); + AnalysisDataService::Instance().remove(outputName); + } + void testRaw1() { Load loader; @@ -130,11 +157,7 @@ public: { Load loader; loader.initialize(); - loader.setPropertyValue("Filename","hrpd_new_072_01.cal"); - loader.setPropertyValue("OutputWorkspace","LoadTest_Output"); - loader.setRethrows(true); - TS_ASSERT_THROWS(loader.execute(), std::runtime_error); - TS_ASSERT( !loader.isExecuted() ); + TS_ASSERT_THROWS(loader.setPropertyValue("Filename","hrpd_new_072_01.cal"), std::runtime_error); } void testSPE() diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/IPropertyManager.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/IPropertyManager.h index d4e835ea2fe..ffce45af39c 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/IPropertyManager.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/IPropertyManager.h @@ -76,7 +76,8 @@ public: /// Validates all the properties in the collection virtual bool validateProperties() const = 0; - + /// Returns the number of properties under management + virtual size_t propertyCount() const = 0; /// Get the value of a property as a string virtual std::string getPropertyValue(const std::string &name) const = 0; @@ -221,8 +222,11 @@ protected: */ template<typename T> T getValue(const std::string &name) const; - - + + /// Removes the property from management + virtual void removeProperty(const std::string &name) = 0; + /// Clears all properties under management + virtual void clear() = 0; /// Utility class that enables the getProperty() method to effectively be templated on the return type struct DLLExport TypedValue diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyManager.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyManager.h index d2d936da99d..1d81312cb82 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyManager.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyManager.h @@ -75,12 +75,14 @@ public: bool existsProperty(const std::string &name) const; bool validateProperties() const; - + size_t propertyCount() const; std::string getPropertyValue(const std::string &name) const; const std::vector< Property*>& getProperties() const; /// removes the property from properties map void removeProperty(const std::string &name); + /// Clears the whole property map + void clear(); /// Get the value of a property TypedValue getProperty(const std::string &name) const; diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyManagerOwner.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyManagerOwner.h index 7777ae3b224..a0c0925ec1b 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyManagerOwner.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyManagerOwner.h @@ -73,12 +73,18 @@ public: bool existsProperty(const std::string &name) const; bool validateProperties() const; + size_t propertyCount() const; std::string getPropertyValue(const std::string &name) const; const std::vector< Property*>& getProperties() const; /// Get the value of a property TypedValue getProperty(const std::string &name) const; + + /// Removes the property from management + void removeProperty(const std::string &name); + /// Clears all properties under management + void clear(); protected: diff --git a/Code/Mantid/Framework/Kernel/src/PropertyManager.cpp b/Code/Mantid/Framework/Kernel/src/PropertyManager.cpp index 44d926bffc3..64a8115f259 100644 --- a/Code/Mantid/Framework/Kernel/src/PropertyManager.cpp +++ b/Code/Mantid/Framework/Kernel/src/PropertyManager.cpp @@ -71,10 +71,7 @@ namespace Mantid /// Virtual destructor PropertyManager::~PropertyManager() { - for ( PropertyMap::iterator it = m_properties.begin(); it != m_properties.end(); ++it ) - { - delete it->second; - } + clear(); } @@ -324,6 +321,15 @@ namespace Mantid return allValid; } + //----------------------------------------------------------------------------------------------- + /** + * Count the number of properties under management + * @returns The number of properties being managed + */ + size_t PropertyManager::propertyCount() const + { + return m_orderedProperties.size(); + } //----------------------------------------------------------------------------------------------- /** Get the value of a property as a string @@ -438,5 +444,19 @@ namespace Mantid } } + //----------------------------------------------------------------------------------------------- + /** + * Clears the whole property map + */ + void PropertyManager::clear() + { + m_orderedProperties.clear(); + for ( PropertyMap::iterator it = m_properties.begin(); it != m_properties.end(); ++it ) + { + delete it->second; + } + m_properties.clear(); + } + } // namespace Kernel } // namespace Mantid diff --git a/Code/Mantid/Framework/Kernel/src/PropertyManagerOwner.cpp b/Code/Mantid/Framework/Kernel/src/PropertyManagerOwner.cpp index 739774db347..38f1c921f93 100644 --- a/Code/Mantid/Framework/Kernel/src/PropertyManagerOwner.cpp +++ b/Code/Mantid/Framework/Kernel/src/PropertyManagerOwner.cpp @@ -95,6 +95,15 @@ namespace Mantid return m_properties->validateProperties(); } + /** + * Count the number of properties under management + * @returns The number of properties being managed + */ + size_t PropertyManagerOwner::propertyCount() const + { + return m_properties->propertyCount(); + } + /** Get the value of a property as a string * @param name :: The name of the property (case insensitive) * @return The value of the named property @@ -153,5 +162,23 @@ namespace Mantid return m_properties->getProperty( name ); } + /** + * Removes the property from properties map. + * @param name :: Name of the property to be removed. + */ + void PropertyManagerOwner::removeProperty(const std::string &name) + { + m_properties->removeProperty(name); + } + + /** + * Clears all properties under management + */ + void PropertyManagerOwner::clear() + { + m_properties->clear(); + } + + } // namespace Kernel } // namespace Mantid diff --git a/Code/Mantid/Framework/Kernel/test/PropertyManagerTest.h b/Code/Mantid/Framework/Kernel/test/PropertyManagerTest.h index f4ac7699471..8087afaef0f 100644 --- a/Code/Mantid/Framework/Kernel/test/PropertyManagerTest.h +++ b/Code/Mantid/Framework/Kernel/test/PropertyManagerTest.h @@ -173,6 +173,17 @@ public: TS_ASSERT( ! mgr.validateProperties() ); } + void testPropertyCount() + { + PropertyManagerHelper mgr; + TS_ASSERT_EQUALS(mgr.propertyCount(), 0); + const std::string name("TestProperty"); + mgr.declareProperty(name, 10.0); + TS_ASSERT_EQUALS(mgr.propertyCount(), 1); + mgr.removeProperty(name); + TS_ASSERT_EQUALS(mgr.propertyCount(), 0); + } + void testGetPropertyValue() { TS_ASSERT( ! manager->getPropertyValue("APROP").compare("1") ); @@ -246,6 +257,19 @@ public: } + void testClear() + { + PropertyManagerHelper mgr; + const std::string name("TestProperty"); + TS_ASSERT_THROWS_NOTHING(mgr.declareProperty(name + "1", 10.0)); + TS_ASSERT_THROWS_NOTHING(mgr.declareProperty(name + "2", 15.0)); + TS_ASSERT_THROWS_NOTHING(mgr.declareProperty(name + "3", 14.0)); + + TS_ASSERT_EQUALS(mgr.propertyCount(), 3); + TS_ASSERT_THROWS_NOTHING(mgr.clear()); + TS_ASSERT_EQUALS(mgr.propertyCount(), 0); + + } //----------------------------------------------------------------------------------------------------------- /** Test of adding managers together (this will be used when diff --git a/Code/Mantid/Framework/TestHelpers/src/ComponentCreationHelper.cpp b/Code/Mantid/Framework/TestHelpers/src/ComponentCreationHelper.cpp index ddd340e45f0..eb1c76fb4ff 100644 --- a/Code/Mantid/Framework/TestHelpers/src/ComponentCreationHelper.cpp +++ b/Code/Mantid/Framework/TestHelpers/src/ComponentCreationHelper.cpp @@ -277,9 +277,6 @@ namespace ComponentCreationHelper // One object Object_sptr pixelShape = ComponentCreationHelper::createCappedCylinder(cylRadius, cylHeight, V3D(0.0,-cylHeight/2.0,0.0), V3D(0.,1.0,0.), "pixel-shape"); - //Just increment pixel ID's - int pixelID = 1; - for (int banknum=1; banknum <= num_banks; banknum++) { //Make a new bank -- GitLab