From 649cda83471c0f74fe0c95a74c09a85a09182da0 Mon Sep 17 00:00:00 2001 From: Alex Buts <Alex.Buts@stfc.ac.uk> Date: Fri, 11 Nov 2011 20:12:12 +0000 Subject: [PATCH] refs #3925 Possible Algorithm interface (will see if it is suitable for autogeneration) --- .../inc/MantidMDAlgorithms/ConvertToQ3DdE.h | 2 +- .../inc/MantidMDAlgorithms/ConvertToQNDany.h | 60 ++- .../MDAlgorithms/src/ConvertToQ3DdE.cpp | 16 +- .../MDAlgorithms/src/ConvertToQNDany.cpp | 356 +++++++++--------- .../MDAlgorithms/test/ConvertToQNDanyTest.h | 163 +++++++- 5 files changed, 392 insertions(+), 205 deletions(-) diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToQ3DdE.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToQ3DdE.h index 69a18eb3c8c..e30ee2923f2 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToQ3DdE.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToQ3DdE.h @@ -19,7 +19,7 @@ namespace MDAlgorithms /** ConvertToDiffractionMDWorkspace : * Transfrom processed inelastic workspace into MD(Event)Workspace with 3 components of momentum transfer plus energy transfer for Indirect?(should be expanded) geometry instrument * - * @author Alex Buts, ISIS + * @modyfier Alex Buts, ISIS; copypasted with minimal variatuions from ConvertToDiffractionMDWorkspace; @author Janik Zikovsky, SNS @date 2011-03-01 * @date 07-09-2011 Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToQNDany.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToQNDany.h index a8aa1a82653..7e03eb68158 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToQNDany.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToQNDany.h @@ -10,6 +10,7 @@ #include "MantidAPI/Progress.h" #include "MantidMDEvents/MDEventWorkspace.h" #include "MantidKernel/PhysicalConstants.h" +//#include <boost/function> namespace Mantid { @@ -17,9 +18,11 @@ namespace MDAlgorithms { /** ConvertToDiffractionMDWorkspace : - * Transfrom processed inelastic workspace into with components defined by user. - * - * @author Alex Buts, ISIS + * Transfrom a workspace into MD workspace with components defined by user. + * + * Gateway for number of subalgorithms, some are very important, some are questionable + * Intended to cover wide range of cases; + * @date 11-10-2011 Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory @@ -45,6 +48,21 @@ namespace MDAlgorithms class DLLExport ConvertToQNDany : public API::Algorithm { + protected: + // the enum counts the algorithms, which can be applied to workspace and differs + // additional switch would be direct/indirect mode . + enum known_algorithms + { + NoQND, // no Q just combine log values in ND workspace (simplest case -- irrelevant to any instruments) + modQdE, // specific algorithm -- 2D, powder + modQND, // ModQND -- good for powders + modQdEND, // inelastic powders plus something + Q3D, // specific algorithm -- diffraction + Q3DdE, // specific algorithn -- inelastic + Q3DND, // generic diffraction algorithm. + Q3DdEND, // generic algorithn -- inelastic + other dependencies + Unknow // if everything else failed + }; public: ConvertToQNDany(); ~ConvertToQNDany(); @@ -54,10 +72,7 @@ namespace MDAlgorithms /// Algorithm's version for identification virtual int version() const { return 1;}; /// Algorithm's category for identification - virtual const std::string category() const { return "Inelastic;MDAlgorithms";} - /// overload to the Algorithm property allowing to treat dependant properties; - virtual void setPropertyValue(const std::string &name, const std::string &value); - + virtual const std::string category() const { return "Inelastic;MDAlgorithms";} private: void init(); void exec(); @@ -73,20 +88,33 @@ namespace MDAlgorithms /// helper function which does exatly what it says void check_max_morethen_min(const std::vector<double> &min,const std::vector<double> &max); - - /// function generates input properties from defaults - bool build_default_properties(size_t max_nadd_dims=5); - /// functon generates properties to build N-dimensional workspace from user selected workspace properties - void build_ND_property_selector(size_t n_dims,const std::vector<std::string> & dim_ID_possible); - /// the variable which describes the number of the dimensions, currently used by algorithm. Changes in input properties can change this number; + /// the variable which describes the number of the dimensions, currently used by algorithm. Changes in input properties can change this number; size_t n_activated_dimensions; /// this variable describes default possible ID-s for Q-dimensions std::vector<std::string> Q_ID_possible; - protected: //for testing - /// function returns the list of names, which are possible dimensions for current matrix workspace + /** function returns the list of names, which can be possible dimensions for current matrix workspace */ std::vector<std::string > get_dimension_names(const std::vector<std::string> &default_prop,API::MatrixWorkspace_const_sptr inMatrixWS)const; - + /** function processes arguments entered by user and tries to istablish what algorithm should be deployed; */ + known_algorithms identify_requested_alg(const std::vector<std::string> &dim_names_availible,const std::string &Q_dim_requested, const std::vector<std::string> &other_dim_selected,size_t &nDims)const; + //NoQND + void processNoQ(); +// modQdE, // specific algorithm -- 2D, powder + void processModQdE(); +// modQND, // ModQND -- good for powders + void processModQND(); +// modQdEND, // inelastic powders plus something + void processModQdEND(); +// Q3D, // specific algorithm -- diffraction + void processQ3D(); +// Q3DdE, // specific algorithn -- inelastic + void processQ3DdE(); +// Q3DND, // generic diffraction algorithm. + void processQ3DND(); +// Q3DdEND, // generic algorithn -- inelastic + other dependencies + void processQ3DdEND(); + // + std::vector<boost::function<void (ConvertToQNDany*)> > alg_selector; }; diff --git a/Code/Mantid/Framework/MDAlgorithms/src/ConvertToQ3DdE.cpp b/Code/Mantid/Framework/MDAlgorithms/src/ConvertToQ3DdE.cpp index 25a034374f7..79d2f6be0de 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/ConvertToQ3DdE.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/ConvertToQ3DdE.cpp @@ -326,10 +326,8 @@ void ConvertToQ3DdE::exec(){ // size_t n_added_events(0); size_t SPLIT_LEVEL(1000); - // PARALLEL_FOR1(inWS2D) for (int64_t i = 0; i < int64_t(numSpec); ++i) { - // PARALLEL_START_INTERUPT_REGION const MantidVec& E_transfer = inWS2D->readX(i); const MantidVec& Signal = inWS2D->readY(i); const MantidVec& Error = inWS2D->readE(i); @@ -371,15 +369,13 @@ void ConvertToQ3DdE::exec(){ } //tp.joinAll(); progress.report(i); - // PARALLEL_END_INTERUPT_REGION } - // PARALLEL_CHECK_INTERUPT_REGION - if(n_added_events>0){ - ws->splitAllIfNeeded(NULL); - n_added_events=0; - } - ws->refreshCache(); - progress.report(); + if(n_added_events>0){ + ws->splitAllIfNeeded(NULL); + n_added_events=0; + } + ws->refreshCache(); + progress.report(); // Save the output diff --git a/Code/Mantid/Framework/MDAlgorithms/src/ConvertToQNDany.cpp b/Code/Mantid/Framework/MDAlgorithms/src/ConvertToQNDany.cpp index ccfff51f726..a97d72ed3c4 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/ConvertToQNDany.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/ConvertToQNDany.cpp @@ -24,6 +24,7 @@ #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/IPropertySettings.h" +#include <algorithm> #include <float.h> using namespace Mantid; @@ -38,86 +39,7 @@ namespace Mantid namespace MDAlgorithms { // the parameter, which specifies maximal default number of dimensions, the algorithm accepts (should be moved to configuration). - static int MAX_DIM_NUMBER=8; -// the class to verify and modify interconnected properties. -class PropChanger: public IPropertySettings -{ - // h specifies the workspace which has to be modified - std::string source_ws_name; - // the name of the property, which specifies the workspace which can contain single spectra to normalize by - std::string host_monws_name; - // the pointer to the main host algorithm. - const IPropertyManager * host_algo; - - // the string with log names, which can be used as dimension ID-s - mutable std::vector<std::string> possible_dim_ID; - // if the current dimension id is enabled - mutable bool is_enabled; - // auxiliary function to obtain list of monitor's ID-s (allowed_values) from the host workspace; - void monitor_id_reader()const; -public: - PropChanger(const IPropertyManager * algo,const std::string WSProperty,const std::string MonWSProperty): - host_ws_name(WSProperty),host_monws_name(MonWSProperty), host_algo(algo),is_enabled(true){} - // if input to " - bool isEnabled()const{ - API::MatrixWorkspace_const_sptr monitorsWS = host_algo->getProperty(host_monws_name); - if(monitorsWS){ - is_enabled = false; - }else{ - is_enabled = true; - } - return is_enabled; - } - // - bool isConditionChanged()const{ - if(!is_enabled)return false; - // read monitors list from the input workspace - monitor_id_reader(); - // if no monitors are associated with workspace -- ok -- you just have to use spectra_ID (may be not on an monitor) - if(possible_dim_ID.empty())return false; - //Kernel::Property *pProperty = host_algo->getPointerToProperty( - return true; - } - // function which modifies the allowed values for the list of monitors. - void applyChanges(Property *const pProp){ - PropertyWithValue<int>* piProp = dynamic_cast<PropertyWithValue<int>* >(pProp); - if(!piProp){ - throw(std::invalid_argument("modify allowed value has been called on wrong property")); - } - std::vector<int> ival(allowed_values.size()); - for(size_t i=0;i<ival.size();i++){ - ival[i]=boost::lexical_cast<int>(allowed_values[i]); - } - piProp->modify_validator(new ValidatorAnyList<int>(ival)); - - } - // interface needs it but if indeed proper clone used -- do not know. - virtual IPropertySettings* clone(){return new PropChanger(host_algo,host_ws_name,host_monws_name);} - - -}; -// read the monitors list from the workspace; -void -PropChanger::monitor_id_reader()const -{ - allowed_values.clear(); - API::MatrixWorkspace_const_sptr inputWS = host_algo->getProperty(host_ws_name); - if(!inputWS){ - return ; - } - - Geometry::Instrument_const_sptr pInstr = inputWS->getInstrument(); - if (!pInstr){ - return ; - } - std::vector<detid_t> mon = pInstr->getMonitors(); - allowed_values.resize(mon.size()); - for(size_t i=0;i<mon.size();i++){ - allowed_values[i]=boost::lexical_cast<std::string>(mon[i]); - } - return ; -} // logger for loading workspaces @@ -138,20 +60,29 @@ void ConvertToQNDany::initDocs() /** Constructor */ ConvertToQNDany::ConvertToQNDany(): -n_activated_dimensions(2), -Q_ID_possible(2) + Q_ID_possible(3) { Q_ID_possible[0]="|Q|"; - Q_ID_possible[1]="QxQyQz"; + Q_ID_possible[1]="QxQyQz"; + Q_ID_possible[2]=""; // no Q dimension (does it have any interest&relevance to ISIS/SNS?) + alg_selector.resize(ConvertToQNDany::Unknow); + + alg_selector[NoQND] = &ConvertToQNDany::processNoQ; + alg_selector[modQdE] = &ConvertToQNDany::processModQdE; + alg_selector[modQND] = &ConvertToQNDany::processModQND; + alg_selector[modQdEND]= &ConvertToQNDany::processModQdEND; + alg_selector[Q3D] = &ConvertToQNDany::processQ3D; + alg_selector[Q3DdE] = &ConvertToQNDany::processQ3DdE; + alg_selector[Q3DND] = &ConvertToQNDany::processQ3DND; + alg_selector[Q3DdEND] = &ConvertToQNDany::processQ3DdEND; } //---------------------------------------------------------------------------------------------- /** Destructor */ ConvertToQNDany::~ConvertToQNDany() -{ -} +{} // @@ -199,27 +130,32 @@ ConvertToQNDany::init() declareProperty(new WorkspaceProperty<MatrixWorkspace>("InputWorkspace","",Direction::Input,ws_valid), - "An input Matrix Workspace 2D, processed by Convert to energy (homer) algorithm and its x-axis has to be in the units of energy transfer with energy in mev."); - BoundedValidator<int> *min_nDim = new BoundedValidator<int>(); - + "An input Matrix Workspace 2D has to have units, which can be used as one of the dimensions "); + declareProperty(new WorkspaceProperty<IMDEventWorkspace>("OutputWorkspace","",Direction::Output), "Name of the output MDEventWorkspace. If the workspace already exists, then the events will be added to it."); - - declareProperty("QDimensions",Q_ID_possible[0],new ListValidator(Q_ID_possible), + + declareProperty("QDimensions",Q_ID_possible[0],new ListValidator(Q_ID_possible), "You can select mod(Q) (1 dimension) or QxQyQz (3 dimensions) in Q space",Direction::InOut); - min_nDim->setLower(0); - declareProperty(new PropertyWithValue<int>("NumAddDim",3,min_nDim,Direction::Input), - " Number of additional to Q (orthogonal) dimensions in the target workspace"); -// -------- Dynamic properties; - // build properties for possible additional dimensions - build_default_properties(8); + + declareProperty(new ArrayProperty<std::string>("OtherDimensions",Direction::Input), + " List(comma separated) of additional to Q (orthogonal) dimensions in the target workspace.\n" + " The names of these dimensions have to coinside with the log names in the source workspace"); -// declareProperty(new ArrayProperty<std::string>("dim1"), - // BoundedValidator<double> *minEn = new BoundedValidator<double>(); - // minEn->setLower(0); - // declareProperty("EnergyInput",0.000000001,minEn,"The value for the incident energy of the neutrons leaving the source (meV)",Direction::InOut); + declareProperty(new ArrayProperty<double>("MinValues"), + "An array of size 1+N_OtherDimensions if first dimension is equal |Q| or \n" + "3+N_OtherDimensions if first (3) dimensions QxQyQz containing minimal values for all dimensions" + " Momentum values expected to be in [A^-1] and energy transfer (if any) expressed in [meV]\n" + " All other values are in uints they are expressed in their log files\n" + " Values lower then the specified one will be ignored\n" + " If a minimal output workspace range is higer then specified, the workspace range will be used intstead)" ); + + declareProperty(new ArrayProperty<double>("MaxValues"), + "An array of the same size as MinValues array" + " Values higher then the specified by the array will be ignored\n" + " If a maximal output workspace ranges is lower, then one of specified, the workspace range will be used instead)" ); // // this property is mainly for subalgorithms to set-up as they have to identify //declareProperty(new PropertyWithValue<bool>("UsePreprocessedDetectors", true, Direction::Input), @@ -229,26 +165,132 @@ ConvertToQNDany::init() ////declareProperty(new ArrayProperty<double>("v"), "second base vecotors"); - // declareProperty(new ArrayProperty<double>("QdEValuesMin"), - // "An array containing minimal values for Q[A^-1] and energy transfer[meV] in a form qx_min,qy_min,qz_min, dE min\n" - // "(momentum and energy transfer values lower that this one will be ignored if this is set.\n" - // " If a minimal output workspace range is higer then specified, the workspace range will be used intstead)" ); + - // declareProperty(new ArrayProperty<double>("QdEValuesMax"), - // "An array containing maximal values for Q[A^-1] and energy transfer[meV] in a form qx_max,qy_max,qz_max, dE_max\n" - // "(momentum and energy transfer values higher that this one will be ignored if this is set.\n" - // " If a maximal output workspace ranges is lower, then one of specified, the workspace range will be used instead)" ); +} +void +ConvertToQNDany::check_max_morethen_min(const std::vector<double> &min,const std::vector<double> &max){ + for(size_t i=0; i<min.size();i++){ + if(max[i]<=min[i]){ + convert_log.error()<<" min value "<<min[i]<<" not less then max value"<<max[i]<<" in direction: "<<i<<std::endl; + throw(std::invalid_argument("min limit not smaller then max limit")); + } + } } -// -void -ConvertToQNDany::setPropertyValue(const std::string &name, const std::string &value){ - if(name.compare("Num_dimensions")){ + + + + //---------------------------------------------------------------------------------------------- + /* Execute the algorithm. */ +void ConvertToQNDany::exec(){ + // -------- Input workspace + MatrixWorkspace_sptr inMatrixWS = getProperty("InputWorkspace"); + Workspace2D_sptr inWS2D = boost::dynamic_pointer_cast<Workspace2D>(inMatrixWS); + + // Identify what dimension names we can obtain from the input workspace; + std::vector<std::string> dim_names_availible; + // assume that |Q| and QxQyQz availible from any workspace? + std::vector<std::string> wsNames(2); + wsNames[0]="|Q|"; + wsNames[1]="QxQyQz"; + +// get the X axis + NumericAxis *pXAxis = dynamic_cast<NumericAxis *>(inWS2D->getAxis(0)); + if(!pXAxis ) + { + convert_log.error()<<"Can not retrieve X axis from the source workspace: "<<inWS2D->getName()<<std::endl; + throw(std::invalid_argument("Input workspace has to have X-axis")); + } + std::string Dim1Name = pXAxis->unit()->unitID(); + wsNames.push_back(Dim1Name); + // + dim_names_availible = this->get_dimension_names(wsNames,inWS2D); + + + // get dim_names requested by user: + std::vector<std::string> dim_requested; + //a) by Q selector: + std::string Q_dim_requested = getProperty("QDimensions"); + //b) by other dim property; + std::vector<std::string> other_dim =getProperty("OtherDimensions"); + + + // Verify input parameters; + std::vector<std::string> dim_selected; + known_algorithms algo_id = identify_requested_alg(dim_names_availible, Q_dim_requested,other_dim,n_activated_dimensions); + + return; + +} + /** function processes input arguments and tries to istablish what algorithm should be deployed; + * + * @param dim_names_availible -- array of the names of the dimension (includeing default dimensiton) which can be obtained from input workspace + * @param Q_dim_requested -- what to do with Q-dimensions e.g. calculate either mod|Q| or Q3D; + * @param dim_selected -- vector of other dimension names requested by the algorithm + * + * @return known_algorithms -- enum identifying one of the known algorithms; if unknown, should fail. + */ +ConvertToQNDany::known_algorithms +ConvertToQNDany::identify_requested_alg(const std::vector<std::string> &dim_names_availible, const std::string &Q_dim_requested, const std::vector<std::string> &dim_requested, size_t &nDims)const +{ + + nDims = 0; + // verify if everything requested is availible: + for(size_t i=0;i<dim_requested.size();i++){ + if(std::find(dim_names_availible.begin(),dim_names_availible.end(),dim_requested[i])==dim_names_availible.end()){ + g_log.error()<<" The dimension: "<<dim_requested[i]<<" requested but can not be found in the list of availible parameters & data\n"; + throw(std::invalid_argument(" the data for availible dimension are not among the input data")); + } + } + // NoQND + if(Q_dim_requested.empty()){ + nDims = dim_requested.size(); + return ConvertToQNDany::NoQND; + } + // modQdE,modQND,modQdEND + if(Q_dim_requested.compare("|Q|")==0){ + if(std::find(dim_requested.begin(),dim_requested.end(),"DeltaE")!=dim_requested.end()){ // modQdE,modQdEND + if(dim_requested.size()==1){ // modQdE; + nDims = 2; + return ConvertToQNDany::modQdE; + }else{ + nDims = 1+dim_requested.size(); + return ConvertToQNDany::modQdEND; + } + }else{ // modQND + nDims= dim_requested.size()+1; + return ConvertToQNDany::modQND; } - API::Algorithm::PropertyManagerOwner::setProperty(name,value); -}; + } + + if(!(Q_dim_requested.compare("QxQyQz")==0)){ + g_log.error()<<" Q-value equal to: "<<Q_dim_requested<<" is not recognized\n"; + throw(std::invalid_argument(" invalid Q argument")); + } + //Q3D,Q3DdE,Q3DND,Q3DdEND + if(std::find(dim_requested.begin(),dim_requested.end(),"DeltaE")!=dim_requested.end()){ // modQdE,modQdEND + if(dim_requested.size()==1){ // Q3DdE,Q3DdEND; + nDims = 4; + return ConvertToQNDany::Q3DdE; + }else{ + nDims = 3+dim_requested.size(); + return ConvertToQNDany::Q3DdEND; + } + }else{ // Q3D,Q3DND + if(dim_requested.size()==0){ + nDims = 3; + return ConvertToQNDany::Q3D; + }else{ + nDims= dim_requested.size()+3; + return ConvertToQNDany::Q3DND; + } + } + + +} std::vector<std::string > ConvertToQNDany::get_dimension_names(const std::vector<std::string> &default_prop,MatrixWorkspace_const_sptr inMatrixWS)const{ @@ -281,72 +323,40 @@ ConvertToQNDany::get_dimension_names(const std::vector<std::string> &default_pro return prop_names; } -bool -ConvertToQNDany:: build_default_properties(size_t max_n_dims) -{ - // number of additional known dimensions: - // size_t n_add_dims =boost::lexical_cast<size_t>(getPropertyValue("NumAddDim")); - // number of total dimensions is also defined by the value of the Q -dimensions - std::string dim_id = getPropertyValue("QDimensions"); - // check if the number of dimensions have not changed and new input is needed - size_t n_dims; - if (dim_id.compare(Q_ID_possible[0])){ // |Q| -- 1 dimension - n_dims = 1; - }else{ // QxQyQz -- 3 dimensions - n_dims = 3; - } -// size_t n_dim_visible = n_dims+n_add_dims; -// size_t n_dim_invisible= max_n_dims-n_dim_visible; - - std::vector<std::string> dim_ID(max_n_dims); - dim_ID[0]=std::string("DeltaE"); - for(size_t i=1;i<max_n_dims;i++){ - std::string num = boost::lexical_cast<std::string>(i+1); - std::string dim_num = "dim_"+num; - dim_ID[i] = dim_num; - } - for(size_t i=0;i<max_n_dims;i++){ - if(this->existsProperty(dim_ID[i])) this->removeProperty(dim_ID[i]); - this->declareProperty(dim_ID[i],dim_ID[i],new ListValidator(dim_ID),"",Direction::InOut); - this->setPropertySettings(dim_ID[i], new EnabledWhenProperty(this, "NumAddDim", IS_MORE_OR_EQ, boost::lexical_cast<std::string>(i))); - } - return true; + +void ConvertToQNDany::processNoQ() +{ + throw(Kernel::Exception::NotImplementedError("")); } -// -void -ConvertToQNDany::build_ND_property_selector(size_t n_dims,const std::vector<std::string> & dim_ID) +void ConvertToQNDany::processModQdE() { - - if(dim_ID.size()<n_dims){ - convert_log.error()<<" number of dimensions requested="<<n_dims<<" and this has to be less or equal to the number of possible workspace variables"<<dim_ID.size()<<std::endl; - throw(std::invalid_argument(" nuber of dimensions exceed the possible dimension number")); - } - - + throw(Kernel::Exception::NotImplementedError("")); } - - - -void -ConvertToQNDany::check_max_morethen_min(const std::vector<double> &min,const std::vector<double> &max){ - for(size_t i=0; i<min.size();i++){ - if(max[i]<=min[i]){ - convert_log.error()<<" min value "<<min[i]<<" not less then max value"<<max[i]<<" in direction: "<<i<<std::endl; - throw(std::invalid_argument("min limit not smaller then max limit")); - } - } +void ConvertToQNDany::processModQND() +{ + throw(Kernel::Exception::NotImplementedError("")); } - - - - //---------------------------------------------------------------------------------------------- - /* Execute the algorithm. */ -void ConvertToQNDany::exec(){ - - return; - +void ConvertToQNDany::processModQdEND() +{ + throw(Kernel::Exception::NotImplementedError("")); +} +void ConvertToQNDany::processQ3D() +{ + throw(Kernel::Exception::NotImplementedError("")); +} +void ConvertToQNDany::processQ3DdE( ) +{ + throw(Kernel::Exception::NotImplementedError("")); } +void ConvertToQNDany::processQ3DND( ) +{ + throw(Kernel::Exception::NotImplementedError("")); +} +void ConvertToQNDany::processQ3DdEND() +{ + throw(Kernel::Exception::NotImplementedError("")); +} } // namespace Mantid } // namespace MDAlgorithms diff --git a/Code/Mantid/Framework/MDAlgorithms/test/ConvertToQNDanyTest.h b/Code/Mantid/Framework/MDAlgorithms/test/ConvertToQNDanyTest.h index 5773658375b..ea3c790249e 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/ConvertToQNDanyTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/ConvertToQNDanyTest.h @@ -30,8 +30,27 @@ public: default_properties[0]="DeltaE"; return ConvertToQNDany::get_dimension_names(default_properties,inMatrixWS); } -}; + ConvertToQNDany::known_algorithms identify_requested_alg(const std::vector<std::string> &dim_names_availible, const std::string &QOption,const std::vector<std::string> &dim_selected,size_t &nDims)const + { return ConvertToQNDany::identify_requested_alg( dim_names_availible,QOption,dim_selected,nDims); + } + + void run_algo(size_t n_mentod){ + alg_selector[n_mentod](this); + + } +}; +// helper function to provide list of names to test: +std::vector<std::string> dim_availible() +{ + std::string dns_ws[]={"DeltaE","T","alpha","beta","gamma"}; + std::vector<std::string> data_names_in_WS; + for(size_t i=0;i<5;i++){ + data_names_in_WS.push_back(dns_ws[i]); + } + return data_names_in_WS; +} +// class ConvertToQNDanyTest : public CxxTest::TestSuite { std::auto_ptr<Convert2AnyTestHelper> pAlg; @@ -44,11 +63,12 @@ void testInit(){ TS_ASSERT_THROWS_NOTHING( pAlg->initialize() ) TS_ASSERT( pAlg->isInitialized() ) -// TSM_ASSERT_EQUALS("algortithm should have 3 propeties",3,(size_t)(pAlg->getProperties().size())); + TSM_ASSERT_EQUALS("algortithm should have 6 propeties",6,(size_t)(pAlg->getProperties().size())); } void testGetDimNames(){ - Mantid::API::MatrixWorkspace_sptr ws2D =WorkspaceCreationHelper::createProcessedWorkspaceWithCylComplexInstrument(4,10,true); - + // get ws from the DS + Mantid::API::MatrixWorkspace_sptr ws2D = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("testWSProcessed")); + // check the privat function std::vector<std::string> dim_names = pAlg->get_dimension_names(ws2D); TSM_ASSERT_EQUALS("the algorithm for this workpace can choose from 4 properties",4,dim_names.size()); @@ -63,11 +83,144 @@ void testGetDimNames(){ } } +void testSetUpThrow() +{ + //TODO: check if wrong WS throws (should on validator) + + // get ws from the DS + Mantid::API::MatrixWorkspace_sptr ws2D = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("testWSProcessed")); + // give it to algorithm + TSM_ASSERT_THROWS_NOTHING("the inital ws is not in the units of energy transfer",pAlg->setPropertyValue("InputWorkspace", ws2D->getName())); + // target ws fine + TS_ASSERT_THROWS_NOTHING(pAlg->setPropertyValue("OutputWorkspace", "EnergyTransferND")); + // unknown Q-dimension trows + TS_ASSERT_THROWS(pAlg->setPropertyValue("QDimensions", "unknownQ"),std::invalid_argument); + // correct Q-dimension fine + TS_ASSERT_THROWS_NOTHING(pAlg->setPropertyValue("QDimensions", "|Q|")); + // additional dimensions requested -- fine + TS_ASSERT_THROWS_NOTHING(pAlg->setPropertyValue("OtherDimensions", "DeltaE,omega")); + +} +void testAlgoSelectorThrows() +{ + std::vector<std::string> data_names_in_WS = dim_availible(); + + std::vector<std::string> dim_requested(1); + dim_requested[0]="AA"; + size_t nDims; + TSM_ASSERT_THROWS("AA property is unavalible among ws parameters ",pAlg->identify_requested_alg(data_names_in_WS,"|Q|",dim_requested,nDims),std::invalid_argument); + + dim_requested[0]="DeltaE"; + TSM_ASSERT_THROWS("Invalid Q argument ",pAlg->identify_requested_alg(data_names_in_WS,"wrong",dim_requested,nDims),std::invalid_argument); +} + +void testAlgoSelector0() +{ + std::vector<std::string> data_names_in_WS = dim_availible(); + std::vector<std::string> dim_requested(1); + size_t nDims; + + dim_requested[0]="DeltaE"; + TSM_ASSERT_EQUALS("NoQND: ",0,(int)pAlg->identify_requested_alg(data_names_in_WS,"",dim_requested,nDims)); + TS_ASSERT_EQUALS(1,nDims); +} +void testAlgoSelector1() +{ + std::vector<std::string> data_names_in_WS = dim_availible(); + std::vector<std::string> dim_requested(1); + size_t nDims; + + dim_requested[0]="DeltaE"; + TSM_ASSERT_EQUALS("modQdE: ",1,(int)pAlg->identify_requested_alg(data_names_in_WS,"|Q|",dim_requested,nDims)); + TS_ASSERT_EQUALS(2,nDims); +} +void testAlgoSelector2() +{ + std::vector<std::string> data_names_in_WS = dim_availible(); + std::vector<std::string> dim_requested(2); + size_t nDims; + + dim_requested[0]="alpha"; + dim_requested[1]="beta"; + TSM_ASSERT_EQUALS("modQND: ",2,(int)pAlg->identify_requested_alg(data_names_in_WS,"|Q|",dim_requested,nDims)); + TS_ASSERT_EQUALS(3,nDims); +} +void testAlgoSelector3() +{ + std::vector<std::string> data_names_in_WS = dim_availible(); + std::vector<std::string> dim_requested(3); + size_t nDims; + + dim_requested[0]="alpha"; + dim_requested[1]="beta"; + dim_requested[2]="DeltaE"; + TSM_ASSERT_EQUALS("modQdEND: ",3,(int)pAlg->identify_requested_alg(data_names_in_WS,"|Q|",dim_requested,nDims)); + TS_ASSERT_EQUALS(4,nDims); +} +void testAlgoSelector4() +{ + std::vector<std::string> data_names_in_WS = dim_availible(); + std::vector<std::string> dim_requested; + size_t nDims; + + TSM_ASSERT_EQUALS("Q3D: ",4,(int)pAlg->identify_requested_alg(data_names_in_WS,"QxQyQz",dim_requested,nDims)); + TS_ASSERT_EQUALS(3,nDims); + +} +void testAlgoSelector5() +{ + std::vector<std::string> data_names_in_WS = dim_availible(); + std::vector<std::string> dim_requested(1); + size_t nDims; + dim_requested[0]="DeltaE"; + TSM_ASSERT_EQUALS("Q3DdE: ",5,(int)pAlg->identify_requested_alg(data_names_in_WS,"QxQyQz",dim_requested,nDims)); + TS_ASSERT_EQUALS(4,nDims); + +} +void testAlgoSelector6() +{ + std::vector<std::string> data_names_in_WS = dim_availible(); + std::vector<std::string> dim_requested(2); + size_t nDims; + + dim_requested[0]="alpha"; + dim_requested[1]="beta"; + TSM_ASSERT_EQUALS("Q3DND: ",6,(int)pAlg->identify_requested_alg(data_names_in_WS,"QxQyQz",dim_requested,nDims)); + TS_ASSERT_EQUALS(5,nDims); +} +void testAlgoSelector7() +{ + std::vector<std::string> data_names_in_WS = dim_availible(); + std::vector<std::string> dim_requested(3); + size_t nDims; + + dim_requested[0]="alpha"; + dim_requested[1]="beta"; + dim_requested[2]="DeltaE"; + TSM_ASSERT_EQUALS("Q3DdEND: ",7,(int)pAlg->identify_requested_alg(data_names_in_WS,"QxQyQz",dim_requested,nDims)); + TS_ASSERT_EQUALS(6,nDims); +} + + +void testFuncSelector() +{ + for(size_t i=0;i<8;i++){ + TSM_ASSERT_THROWS("f:"+boost::lexical_cast<std::string>(i),pAlg->run_algo(i),Kernel::Exception::NotImplementedError); + } +} + +void testExecSelection() +{ + + TS_ASSERT_THROWS_NOTHING(pAlg->execute()); +} ConvertToQNDanyTest(){ - pAlg = std::auto_ptr<Convert2AnyTestHelper>(new Convert2AnyTestHelper()); + pAlg = std::auto_ptr<Convert2AnyTestHelper>(new Convert2AnyTestHelper()); + Mantid::API::MatrixWorkspace_sptr ws2D =WorkspaceCreationHelper::createProcessedWorkspaceWithCylComplexInstrument(4,10,true); + AnalysisDataService::Instance().addOrReplace("testWSProcessed", ws2D); } }; -- GitLab