diff --git a/Code/Mantid/Build/CMake/CommonSetup.cmake b/Code/Mantid/Build/CMake/CommonSetup.cmake index eb212611218ed18fe096838d942754ec49be0686..5e1bb820719404315623cd365d031d4a74f6edae 100644 --- a/Code/Mantid/Build/CMake/CommonSetup.cmake +++ b/Code/Mantid/Build/CMake/CommonSetup.cmake @@ -186,11 +186,6 @@ else() message (STATUS "Could NOT find PyUnitTest - unit testing of python not available" ) endif() -########################################################################### -# Allow binaries to be put into subdirectories. -########################################################################### -include(OutputBinaryTo) - ########################################################################### # Set a flag to indicate that this script has been called ########################################################################### diff --git a/Code/Mantid/Build/CMake/MantidUtils.cmake b/Code/Mantid/Build/CMake/MantidUtils.cmake index 2b734bdf08fb95e3bcd19abfe4e456fdd80ee823..cf8ab87e6c9d61f7719cd08e72b5d7a4c6c09aec 100644 --- a/Code/Mantid/Build/CMake/MantidUtils.cmake +++ b/Code/Mantid/Build/CMake/MantidUtils.cmake @@ -28,8 +28,8 @@ function( SET_TARGET_OUTPUT_DIRECTORY TARGET OUTPUT_DIR ) ${OUTPUT_DIR} ) add_custom_command ( TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E echo - "Moving \"$(TargetName)${LIB_EXT}\" to ${OUTPUT_DIR}/$(TargetName)${LIB_EXT}" - COMMAND ${CMAKE_COMMAND} ARGS -E rename + "Copying \"$(TargetName)${LIB_EXT}\" to ${OUTPUT_DIR}/$(TargetName)${LIB_EXT}" + COMMAND ${CMAKE_COMMAND} ARGS -E copy ${SRC_DIR}/$(TargetName)${LIB_EXT} ${OUTPUT_DIR}/$(TargetName)${LIB_EXT} ) # Clean up diff --git a/Code/Mantid/Build/CMake/OutputBinaryTo.cmake b/Code/Mantid/Build/CMake/OutputBinaryTo.cmake deleted file mode 100644 index 8d92b623834fe244dd547f0c7a14a9aff4212856..0000000000000000000000000000000000000000 --- a/Code/Mantid/Build/CMake/OutputBinaryTo.cmake +++ /dev/null @@ -1,30 +0,0 @@ -# Put the binaries in a subfolder of the usual bin directory -function(output_binary_to LIB_NAME SUB_DIR_NAME) - - # Change the destination of the target as Qt expects this in a directory called "SUB_DIR_NAME" - if ( MSVC ) - # For some reason when the generator is MSVC 10 it ignores the LIBRARY_OUTPUT_DIRECTORY - # property so we have to do something slightly different - set ( LIB_EXTS ".dll" ) - set ( SRC_DIR ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR} ) - set ( DEST_DIR ${SRC_DIR}/${SUB_DIR_NAME} ) - add_custom_command( TARGET ${LIB_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} ARGS -E make_directory - ${DEST_DIR} ) - foreach ( LIB_EXT ${LIB_EXTS} ) - add_custom_command ( TARGET ${LIB_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} ARGS -E echo - "Moving \"${LIB_NAME}${LIB_EXT}\" to ${SUB_DIR_NAME} directory." - COMMAND ${CMAKE_COMMAND} ARGS -E copy - ${SRC_DIR}/${LIB_NAME}${LIB_EXT} - ${DEST_DIR}/${LIB_NAME}${LIB_EXT} ) - endforeach ( LIB_EXT ) - # Clean up - set ( LIB_EXTS ) - set ( SRC_DIR ) - set ( DEST_DIR ) - else () - set_target_properties ( ${LIB_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY - ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${SUB_DIR_NAME} ) - endif ( MSVC ) -endfunction(output_binary_to) \ No newline at end of file diff --git a/Code/Mantid/Build/wiki_maker.py b/Code/Mantid/Build/wiki_maker.py index a0b01a1e40284afc93e0dece32f1d778f269868e..42be069f33f6643cb2fcaa54be8c900d3cf491ae 100755 --- a/Code/Mantid/Build/wiki_maker.py +++ b/Code/Mantid/Build/wiki_maker.py @@ -63,6 +63,7 @@ def make_property_table_line(propnum, p): defaultstr = str(default) # Replace the ugly default values with "optional" if (defaultstr == "8.9884656743115785e+307") or \ + (defaultstr == "1.7976931348623157e+308") or \ (defaultstr == "2147483647"): defaultstr = "Optional" diff --git a/Code/Mantid/Framework/API/CMakeLists.txt b/Code/Mantid/Framework/API/CMakeLists.txt index 5444683168bd684a208b16eb2ed2e80b204f3121..d2762c03d9b2ddc002179a01ded037f5c8a9c278 100644 --- a/Code/Mantid/Framework/API/CMakeLists.txt +++ b/Code/Mantid/Framework/API/CMakeLists.txt @@ -35,6 +35,7 @@ set ( SRC_FILES src/IFunctionMD.cpp src/IFunctionMW.cpp src/IMDEventWorkspace.cpp + src/IMDHistoWorkspace.cpp src/IMDIterator.cpp src/IMDWorkspace.cpp src/IPeak.cpp @@ -137,6 +138,7 @@ set ( INC_FILES inc/MantidAPI/IFunctionWithLocation.h inc/MantidAPI/ILocatedData.h inc/MantidAPI/IMDEventWorkspace.h + inc/MantidAPI/IMDHistoWorkspace.h inc/MantidAPI/IMDIterator.h inc/MantidAPI/IMDWorkspace.h inc/MantidAPI/IPeak.h diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/EnabledWhenWorkspaceIsType.h b/Code/Mantid/Framework/API/inc/MantidAPI/EnabledWhenWorkspaceIsType.h index 43acd72cc6134ee24ddffe63f0537ff403e3d2a6..b3a60d1f00b3f14b399eb91be82e320c4dd6b623 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/EnabledWhenWorkspaceIsType.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/EnabledWhenWorkspaceIsType.h @@ -126,8 +126,7 @@ namespace API EnabledWhenWorkspaceIsType * out = new EnabledWhenWorkspaceIsType<T>(this->m_propertyManager, m_otherPropName, m_enabledSetting); return out; } - - protected: + protected: /// Name of the OTHER property that we will check. std::string m_otherPropName; /// Set Enabled to this. diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IMDHistoWorkspace.h b/Code/Mantid/Framework/API/inc/MantidAPI/IMDHistoWorkspace.h new file mode 100644 index 0000000000000000000000000000000000000000..c4cc492decce16f9a43ab2b2a691139c1601c1c2 --- /dev/null +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IMDHistoWorkspace.h @@ -0,0 +1,87 @@ +#ifndef MANTID_API_IMDHISTOWORKSPACE_H_ +#define MANTID_API_IMDHISTOWORKSPACE_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/IMDWorkspace.h" + + +namespace Mantid +{ +namespace API +{ + + /** Abstract interface to MDHistoWorkspace, + for use in exposing to Python. + + @date 2011-11-09 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + 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 IMDHistoWorkspace : public IMDWorkspace + { + public: + IMDHistoWorkspace(); + virtual ~IMDHistoWorkspace(); + + /// See the MDHistoWorkspace definition for descriptions of these + virtual coord_t getInverseVolume() const = 0; + virtual signal_t * getSignalArray() = 0; + virtual signal_t * getErrorSquaredArray() = 0; + virtual void setTo(signal_t signal, signal_t errorSquared) = 0; + virtual Mantid::Kernel::VMD getCenter(size_t linearIndex) const = 0; + virtual void setSignalAt(size_t index, signal_t value) = 0; + virtual void setErrorSquaredAt(size_t index, signal_t value) = 0; + virtual signal_t getErrorAt(size_t index) const = 0; + virtual signal_t getErrorAt(size_t index1, size_t index2) const = 0; + virtual signal_t getErrorAt(size_t index1, size_t index2, size_t index3) const = 0; + virtual signal_t getErrorAt(size_t index1, size_t index2, size_t index3, size_t index4) const = 0; + virtual signal_t getSignalAt(size_t index) const = 0; + virtual signal_t getSignalAt(size_t index1, size_t index2) const = 0; + virtual signal_t getSignalAt(size_t index1, size_t index2, size_t index3) const = 0; + virtual signal_t getSignalAt(size_t index1, size_t index2, size_t index3, size_t index4) const = 0; + virtual signal_t getSignalNormalizedAt(size_t index) const = 0; + virtual signal_t getSignalNormalizedAt(size_t index1, size_t index2) const = 0; + virtual signal_t getSignalNormalizedAt(size_t index1, size_t index2, size_t index3) const = 0; + virtual signal_t getSignalNormalizedAt(size_t index1, size_t index2, size_t index3, size_t index4) const = 0; + virtual signal_t getErrorNormalizedAt(size_t index) const = 0; + virtual signal_t getErrorNormalizedAt(size_t index1, size_t index2) const = 0; + virtual signal_t getErrorNormalizedAt(size_t index1, size_t index2, size_t index3) const = 0; + virtual signal_t getErrorNormalizedAt(size_t index1, size_t index2, size_t index3, size_t index4) const = 0; + + virtual signal_t & errorSquaredAt(size_t index) = 0; + virtual signal_t & signalAt(size_t index) = 0; + virtual size_t getLinearIndex(size_t index1, size_t index2) const = 0; + virtual size_t getLinearIndex(size_t index1, size_t index2, size_t index3) const = 0; + virtual size_t getLinearIndex(size_t index1, size_t index2, size_t index3, size_t index4) const = 0; + + virtual double & operator [](const size_t & index) = 0; + }; + + /// Shared pointer to the IMDWorkspace base class + typedef boost::shared_ptr<IMDHistoWorkspace> IMDHistoWorkspace_sptr; + /// Shared pointer to the IMDWorkspace base class (const version) + typedef boost::shared_ptr<const IMDHistoWorkspace> IMDHistoWorkspace_const_sptr; + + +} // namespace API +} // namespace Mantid + +#endif /* MANTID_API_IMDHISTOWORKSPACE_H_ */ diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IMDWorkspace.h b/Code/Mantid/Framework/API/inc/MantidAPI/IMDWorkspace.h index 40d9810e29de7e5bde65af8d2561dda08b22cbfd..a687e43ac0d4d81e02d7b5f7be6f1858d02351a1 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IMDWorkspace.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IMDWorkspace.h @@ -87,9 +87,9 @@ namespace Mantid }; - /// Shared pointer to the matrix workspace base class + /// Shared pointer to the IMDWorkspace base class typedef boost::shared_ptr<IMDWorkspace> IMDWorkspace_sptr; - /// Shared pointer to the matrix workspace base class (const version) + /// Shared pointer to the IMDWorkspace base class (const version) typedef boost::shared_ptr<const IMDWorkspace> IMDWorkspace_const_sptr; } } diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IPeak.h b/Code/Mantid/Framework/API/inc/MantidAPI/IPeak.h index f0e02b8a9c7f166e2fd4108bed2a0a9fa5b7f224..4168f93c7428a9f58b0b9fdf69b2a6a6de9af5c8 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IPeak.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IPeak.h @@ -52,6 +52,7 @@ namespace API virtual void setWavelength(double wavelength) = 0; virtual double getWavelength() const = 0; + virtual double getScattering() const = 0; virtual double getDSpacing() const = 0; virtual double getTOF() const = 0; diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/WorkspaceProperty.h b/Code/Mantid/Framework/API/inc/MantidAPI/WorkspaceProperty.h index 60a7c0ccf033a9eebc9725802a5d4cacdb860331..0ec88670092387abb0d29185f435dde7bafc4de1 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/WorkspaceProperty.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/WorkspaceProperty.h @@ -67,7 +67,7 @@ namespace Mantid * @param validator :: The (optional) validator to use for this property * @throw std::out_of_range if the direction argument is not a member of the Direction enum (i.e. 0-2) */ - WorkspaceProperty( const std::string &name, const std::string &wsName, const unsigned int direction, + explicit WorkspaceProperty( const std::string &name, const std::string &wsName, const unsigned int direction, Kernel::IValidator<boost::shared_ptr<TYPE> > *validator = new Kernel::NullValidator<boost::shared_ptr<TYPE> > ) : Kernel::PropertyWithValue <boost::shared_ptr<TYPE> >( name, boost::shared_ptr<TYPE>( ), validator, direction ), m_workspaceName( wsName ), m_initialWSName( wsName ), m_optional(false) @@ -341,22 +341,32 @@ namespace Mantid std::string memberWsName = *it; boost::shared_ptr<Workspace> memberWs = AnalysisDataService::Instance().retrieve(memberWsName); - // ... and if it is a workspace of incorrect type, exclude the group by returning an error. - if( NULL == boost::dynamic_pointer_cast<TYPE>(memberWs) ) + // Table Workspaces are ignored + if ("TableWorkspace" == memberWs->id()) { - error = "Workspace " + memberWsName + " is not of type " + Kernel::PropertyWithValue< boost::shared_ptr<TYPE> >::type() + "."; - + error = "Workspace " + memberWsName + " is of type TableWorkspace and will therefore be ignored as part of the GroupedWorkspace."; + g_log.debug() << error << std::endl; - - return error; } - // If it is of the correct type, it may still be invalid. Check. else { - Mantid::API::WorkspaceProperty<TYPE> memberWsProperty(*this); - std::string memberError = memberWsProperty.setValue(memberWsName); - if( !memberError.empty() ) - return memberError; // Since if this member is invalid, then the whole group is invalid. + // ... and if it is a workspace of incorrect type, exclude the group by returning an error. + if( NULL == boost::dynamic_pointer_cast<TYPE>(memberWs) ) + { + error = "Workspace " + memberWsName + " is not of type " + Kernel::PropertyWithValue< boost::shared_ptr<TYPE> >::type() + "."; + + g_log.debug() << error << std::endl; + + return error; + } + // If it is of the correct type, it may still be invalid. Check. + else + { + Mantid::API::WorkspaceProperty<TYPE> memberWsProperty(*this); + std::string memberError = memberWsProperty.setValue(memberWsName); + if( !memberError.empty() ) + return memberError; // Since if this member is invalid, then the whole group is invalid. + } } } diff --git a/Code/Mantid/Framework/API/src/Algorithm.cpp b/Code/Mantid/Framework/API/src/Algorithm.cpp index db1ef3a864a28797d5cac247cb55d0d606da549c..b95a2d0f08feb1c7c60e4bdbe3f13e7ba59c3dcd 100644 --- a/Code/Mantid/Framework/API/src/Algorithm.cpp +++ b/Code/Mantid/Framework/API/src/Algorithm.cpp @@ -856,80 +856,85 @@ namespace Mantid std::vector<std::string>::const_iterator wsItr=inputWSNames.begin(); for(;wsItr!=inputWSNames.end();++wsItr) { //set properties - std::vector<Mantid::Kernel::Property*>::const_iterator itr; - for (itr=props.begin();itr!=props.end();++itr) + + if (API::AnalysisDataService::Instance().retrieve(*wsItr)->id() != "TableWorkspace") { - int outWSCount=0; - - if(isWorkspaceProperty(*itr) ) - { - if(isInputWorkspaceProperty(*itr)) - { + // Do the rest of the for loop + std::vector<Mantid::Kernel::Property*>::const_iterator itr; + for (itr=props.begin();itr!=props.end();++itr) + { + int outWSCount=0; - if(!setInputWSProperties(alg,*itr,*wsItr)) + if(isWorkspaceProperty(*itr) ) + { + if(isInputWorkspaceProperty(*itr)) { - throw std::runtime_error("Invalid value found for the property " +(*itr)->name()+ " when executing the algorithm"+this->name()); - } - } - if(isOutputWorkspaceProperty(*itr)) - { - ++outWSCount; - //create a group and pass that to setOutputWSProperties - if(outWSCount==1) - { - if( bnewGoup1) - { - wsgrp1_sptr= WorkspaceGroup_sptr(new WorkspaceGroup); - bnewGoup1=false; - } - if(!setOutputWSProperties(alg,*itr,nPeriod,*wsItr,wsgrp1_sptr,bSimilarNames,bequal)) + if(!setInputWSProperties(alg,*itr,*wsItr)) { throw std::runtime_error("Invalid value found for the property " +(*itr)->name()+ " when executing the algorithm"+this->name()); } } - if(outWSCount==2) + if(isOutputWorkspaceProperty(*itr)) { - if( bnewGoup2) - { - wsgrp2_sptr= WorkspaceGroup_sptr(new WorkspaceGroup); - bnewGoup2=false; + ++outWSCount; + //create a group and pass that to setOutputWSProperties + if(outWSCount==1) + { + if( bnewGoup1) + { + wsgrp1_sptr= WorkspaceGroup_sptr(new WorkspaceGroup); + bnewGoup1=false; + } + if(!setOutputWSProperties(alg,*itr,nPeriod,*wsItr,wsgrp1_sptr,bSimilarNames,bequal)) + { + throw std::runtime_error("Invalid value found for the property " +(*itr)->name()+ " when executing the algorithm"+this->name()); + } + } - if(!setOutputWSProperties(alg,*itr,nPeriod,*wsItr,wsgrp2_sptr,bSimilarNames,bequal)) + if(outWSCount==2) { - throw std::runtime_error("Invalid value found for the property " +(*itr)->name()+ " when executing the algorithm"+this->name()); + if( bnewGoup2) + { + wsgrp2_sptr= WorkspaceGroup_sptr(new WorkspaceGroup); + bnewGoup2=false; + } + if(!setOutputWSProperties(alg,*itr,nPeriod,*wsItr,wsgrp2_sptr,bSimilarNames,bequal)) + { + throw std::runtime_error("Invalid value found for the property " +(*itr)->name()+ " when executing the algorithm"+this->name()); + } } - } - }//end of isOutputWorkspaceProperty + }//end of isOutputWorkspaceProperty - }// end of isWorkspaceProperty - else - { - this->setOtherProperties(alg,(*itr)->name(),(*itr)->value(),nPeriod); + }// end of isWorkspaceProperty + else + { + this->setOtherProperties(alg,(*itr)->name(),(*itr)->value(),nPeriod); + } + }//end of for loop for setting properties + //resetting the previous properties at the end of each execution + prevPropName=""; + // execute the algorithm + bool bStatus = false; + if ( alg->validateProperties() ) + {bStatus = alg->execute(); + } + // status of each execution is checking + bgroupPassed=bgroupPassed&&bStatus; + bgroupFailed=bgroupFailed||bStatus; + execPercentage+=10; + progress(double((execPercentage)/execTotal)); + //if a workspace execution fails + if(!bStatus) + { + throw std::runtime_error("execution failed for the input workspace "+(*wsItr)); } - }//end of for loop for setting properties - //resetting the previous properties at the end of each execution - prevPropName=""; - // execute the algorithm - bool bStatus = false; - if ( alg->validateProperties() ) - {bStatus = alg->execute(); - } - // status of each execution is checking - bgroupPassed=bgroupPassed&&bStatus; - bgroupFailed=bgroupFailed||bStatus; - execPercentage+=10; - progress(double((execPercentage)/execTotal)); - //if a workspace execution fails - if(!bStatus) - { - throw std::runtime_error("execution failed for the input workspace "+(*wsItr)); } //increment count for outworkpsace name nPeriod++; - + }//end of for loop for input workspace group members processing //if all passed if(bgroupPassed) diff --git a/Code/Mantid/Framework/API/src/IMDHistoWorkspace.cpp b/Code/Mantid/Framework/API/src/IMDHistoWorkspace.cpp new file mode 100644 index 0000000000000000000000000000000000000000..41e584e19722a902486690a6cfdb8bc99dd3e761 --- /dev/null +++ b/Code/Mantid/Framework/API/src/IMDHistoWorkspace.cpp @@ -0,0 +1,74 @@ +#include "MantidAPI/IMDHistoWorkspace.h" +#include "MantidKernel/System.h" +#include "MantidKernel/Exception.h" +#include "MantidKernel/IPropertyManager.h" + +using namespace Mantid::Kernel; +using namespace Mantid::API; + +namespace Mantid +{ +namespace API +{ + + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + IMDHistoWorkspace::IMDHistoWorkspace() + { + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + IMDHistoWorkspace::~IMDHistoWorkspace() + { + } + + + +} // namespace Mantid +} // namespace API + + +namespace Mantid +{ +namespace Kernel +{ + /** In order to be able to cast PropertyWithValue classes correctly a definition for the PropertyWithValue<IMDEventWorkspace> is required */ + template<> MANTID_API_DLL + Mantid::API::IMDHistoWorkspace_sptr IPropertyManager::getValue<Mantid::API::IMDHistoWorkspace_sptr>(const std::string &name) const + { + PropertyWithValue<Mantid::API::IMDHistoWorkspace_sptr>* prop = + dynamic_cast<PropertyWithValue<Mantid::API::IMDHistoWorkspace_sptr>*>(getPointerToProperty(name)); + if (prop) + { + return *prop; + } + else + { + std::string message = "Attempt to assign property "+ name +" to incorrect type. Expected IMDHistoWorkspace."; + throw std::runtime_error(message); + } + } + + /** In order to be able to cast PropertyWithValue classes correctly a definition for the PropertyWithValue<IMDWorkspace_const_sptr> is required */ + template<> MANTID_API_DLL + Mantid::API::IMDHistoWorkspace_const_sptr IPropertyManager::getValue<Mantid::API::IMDHistoWorkspace_const_sptr>(const std::string &name) const + { + PropertyWithValue<Mantid::API::IMDHistoWorkspace_sptr>* prop = + dynamic_cast<PropertyWithValue<Mantid::API::IMDHistoWorkspace_sptr>*>(getPointerToProperty(name)); + if (prop) + { + return prop->operator()(); + } + else + { + std::string message = "Attempt to assign property "+ name +" to incorrect type. Expected const IMDHistoWorkspace."; + throw std::runtime_error(message); + } + } + +} // namespace Kernel +} // namespace Mantid diff --git a/Code/Mantid/Framework/API/src/WorkspaceOpOverloads.cpp b/Code/Mantid/Framework/API/src/WorkspaceOpOverloads.cpp index 0a03dd5a5ff915c6fc2f31fe4c33786b7f0cbd3e..bea36963f8ad7e6c48b8efdcd406090318fb10e3 100644 --- a/Code/Mantid/Framework/API/src/WorkspaceOpOverloads.cpp +++ b/Code/Mantid/Framework/API/src/WorkspaceOpOverloads.cpp @@ -10,6 +10,8 @@ #include "MantidAPI/WorkspaceFactory.h" #include "MantidAPI/SpectraAxis.h" #include <numeric> +#include "MantidAPI/IMDWorkspace.h" +#include "MantidAPI/IMDHistoWorkspace.h" namespace Mantid { @@ -41,7 +43,6 @@ namespace OperatorOverloads { alg->setProperty<LHSType>("LHSWorkspace",lhs); alg->setProperty<RHSType>("RHSWorkspace",rhs); - alg->setProperty<bool>("AllowDifferentNumberSpectra",false); // Have to set a text name for the output workspace if the algorithm is a child even // though it will not be used. alg->setPropertyValue("OutputWorkspace","��NotApplicable"); @@ -55,7 +56,6 @@ namespace OperatorOverloads { alg->setPropertyValue("LHSWorkspace",lhs->getName()); alg->setPropertyValue("RHSWorkspace",rhs->getName()); - alg->setProperty<bool>("AllowDifferentNumberSpectra",false); if( lhsAsOutput ) { alg->setPropertyValue("OutputWorkspace",lhs->getName()); @@ -104,6 +104,25 @@ namespace OperatorOverloads template DLLExport WorkspaceGroup_sptr executeBinaryOperation(const std::string &, const MatrixWorkspace_sptr, const WorkspaceGroup_sptr, bool, bool, const std::string &, bool); + template DLLExport IMDWorkspace_sptr executeBinaryOperation(const std::string &, const IMDWorkspace_sptr, const IMDWorkspace_sptr, bool, + bool, const std::string &, bool); + template DLLExport WorkspaceGroup_sptr executeBinaryOperation(const std::string &, const WorkspaceGroup_sptr, const IMDWorkspace_sptr, bool, + bool, const std::string &, bool); + template DLLExport WorkspaceGroup_sptr executeBinaryOperation(const std::string &, const IMDWorkspace_sptr, const WorkspaceGroup_sptr, bool, + bool, const std::string &, bool); + + template DLLExport IMDWorkspace_sptr executeBinaryOperation(const std::string &, const IMDWorkspace_sptr, const MatrixWorkspace_sptr, bool, + bool, const std::string &, bool); + template DLLExport IMDWorkspace_sptr executeBinaryOperation(const std::string &, const MatrixWorkspace_sptr, const IMDWorkspace_sptr, bool, + bool, const std::string &, bool); + + template DLLExport IMDHistoWorkspace_sptr executeBinaryOperation(const std::string &, const IMDHistoWorkspace_sptr, const IMDHistoWorkspace_sptr, bool, + bool, const std::string &, bool); + template DLLExport IMDHistoWorkspace_sptr executeBinaryOperation(const std::string &, const IMDHistoWorkspace_sptr, const MatrixWorkspace_sptr, bool, + bool, const std::string &, bool); + template DLLExport IMDHistoWorkspace_sptr executeBinaryOperation(const std::string &, const MatrixWorkspace_sptr, const IMDHistoWorkspace_sptr, bool, + bool, const std::string &, bool); + } // namespace OperatorOverloads diff --git a/Code/Mantid/Framework/Algorithms/CMakeLists.txt b/Code/Mantid/Framework/Algorithms/CMakeLists.txt index 53562ed099b836c6e7e12df313358e3683351023..9de8132408ed75b98b3d8449c7e74d2dbaea3e98 100644 --- a/Code/Mantid/Framework/Algorithms/CMakeLists.txt +++ b/Code/Mantid/Framework/Algorithms/CMakeLists.txt @@ -3,6 +3,7 @@ set ( SRC_FILES src/AbsorptionCorrection.cpp src/AddLogDerivative.cpp src/AddSampleLog.cpp + src/AlignDetectorInTOF.cpp src/AlignDetectors.cpp src/AlphaCalc.cpp src/AnyShapeAbsorption.cpp @@ -158,7 +159,7 @@ set ( SRC_FILES src/SumSpectra.cpp src/TOFSANSResolution.cpp src/Transpose.cpp - src/UnGroupWorkspaces.cpp + src/UnGroupWorkspace.cpp src/UnaryOperation.cpp src/Unwrap.cpp src/UnwrapMonitor.cpp @@ -172,6 +173,7 @@ set ( INC_FILES inc/MantidAlgorithms/AbsorptionCorrection.h inc/MantidAlgorithms/AddLogDerivative.h inc/MantidAlgorithms/AddSampleLog.h + inc/MantidAlgorithms/AlignDetectorInTOF.h inc/MantidAlgorithms/AlignDetectors.h inc/MantidAlgorithms/AlphaCalc.h inc/MantidAlgorithms/AnyShapeAbsorption.h @@ -328,7 +330,7 @@ set ( INC_FILES inc/MantidAlgorithms/SumSpectra.h inc/MantidAlgorithms/TOFSANSResolution.h inc/MantidAlgorithms/Transpose.h - inc/MantidAlgorithms/UnGroupWorkspaces.h + inc/MantidAlgorithms/UnGroupWorkspace.h inc/MantidAlgorithms/UnaryOperation.h inc/MantidAlgorithms/Unwrap.h inc/MantidAlgorithms/UnwrapMonitor.h @@ -340,6 +342,7 @@ set ( INC_FILES set ( TEST_FILES test/AddLogDerivativeTest.h test/AddSampleLogTest.h + test/AlignDetectorInTOFTest.h test/AlignDetectorsTest.h test/AlphaCalcTest.h test/AnyShapeAbsorptionTest.h @@ -479,7 +482,7 @@ set ( TEST_FILES test/SumRowColumnTest.h test/SumSpectraTest.h test/TransposeTest.h - test/UnGroupWorkspacesTest.h + test/UnGroupWorkspaceTest.h test/UnaryOperationTest.h test/UnwrapSNSTest.h test/UnwrapTest.h diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectorInTOF.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectorInTOF.h new file mode 100644 index 0000000000000000000000000000000000000000..6090e7ef0371b291485de468103d222c514fecd5 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectorInTOF.h @@ -0,0 +1,66 @@ +#ifndef MANTID_ALGORITHMS_ALIGNDETECTORINTOF_H_ +#define MANTID_ALGORITHMS_ALIGNDETECTORINTOF_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidDataObjects/EventWorkspace.h" + +namespace Mantid +{ +namespace Algorithms +{ + + /** AlignDetectorInTOF : TODO: DESCRIPTION + + @date 2011-11-08 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + 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 AlignDetectorInTOF : public API::Algorithm + { + public: + AlignDetectorInTOF(); + virtual ~AlignDetectorInTOF(); + + /// Algorithm's name for identification overriding a virtual method + virtual const std::string name() const { return "AlignDetectorsInTOF";}; + /// Algorithm's version for identification overriding a virtual method + virtual int version() const { return 1;}; + /// Algorithm's category for identification overriding a virtual method + virtual const std::string category() const { return "Diffraction";} + + private: + /// Sets documentation strings for this algorithm + virtual void initDocs(); + // Implement abstract Algorithm methods + void init(); + + void exec(); + + void execTOFEvent(std::string calfilename, Mantid::API::MatrixWorkspace_const_sptr inputWS); + + }; + + +} // namespace Algorithms +} // namespace Mantid + +#endif /* MANTID_ALGORITHMS_ALIGNDETECTORINTOF_H_ */ diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectors.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectors.h index dc3bda45496d12201dab056441ea7d15bfb4f657..f9d9199adcfb642431f07b8804bf01086c0ff4e4 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectors.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectors.h @@ -71,7 +71,7 @@ private: void execEvent(); - void execTOFEvent(std::string calfilename, Mantid::API::MatrixWorkspace_const_sptr inputWS); + // void execTOFEvent(std::string calfilename, Mantid::API::MatrixWorkspace_const_sptr inputWS); /// Pointer for an event workspace Mantid::DataObjects::EventWorkspace_const_sptr eventW; diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/GroupWorkspaces.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/GroupWorkspaces.h index 1066f944f696d8f6625cb8eae4d442cbda9650cc..aab72cac4b0e2fdb58003f7f7127dcc409d82e9b 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/GroupWorkspaces.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/GroupWorkspaces.h @@ -63,11 +63,9 @@ private: /// overridden execute method void exec(); /// method to check the input workspaces are of same types - bool isCompatibleWorkspaces(const std::string & firstWS,const std::string& newWStoAdd ); + bool isCompatibleWorkspaces(const std::string & wsName,std::string& firstWs); /// add member workspace to the groupworkspace - void addworkspacetoGroup(Mantid::API::WorkspaceGroup_sptr outgrp_sptr,const std::string &wsName); - - + void addworkspacetoGroup(Mantid::API::WorkspaceGroup_sptr outgrp_sptr,const std::string &wsName, std::string& firstWs); }; } // namespace Algorithm diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/SmoothNeighbours.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/SmoothNeighbours.h index 9f67e39cbec5ac42603f2a7588d9857b0dedfc88..dcc9069dbfa28fcab3655e12b61e62548c4f308c 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/SmoothNeighbours.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/SmoothNeighbours.h @@ -62,7 +62,7 @@ private: void execEvent(Mantid::DataObjects::EventWorkspace_sptr ws); void findNeighboursRectangular(); - void findNeighboursRadius(); + void findNeighboursUbiqutious(); /// Pixels in the detector int XPixels; diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/UnGroupWorkspaces.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/UnGroupWorkspace.h similarity index 100% rename from Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/UnGroupWorkspaces.h rename to Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/UnGroupWorkspace.h diff --git a/Code/Mantid/Framework/Algorithms/src/AlignDetectorInTOF.cpp b/Code/Mantid/Framework/Algorithms/src/AlignDetectorInTOF.cpp new file mode 100644 index 0000000000000000000000000000000000000000..69b450a78141c8b1c3eeb4a3dee928148cd60277 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/src/AlignDetectorInTOF.cpp @@ -0,0 +1,263 @@ +/*WIKI* + + +The offsets are a correction to the TOF values and are applied to each TOF event as follows: + +:<math> d = \frac{h}{2m_N} \frac{t.o.f.}{L_{tot} sin \theta} (1+ \rm{offset})</math> + +The detector offsets can be obtained from either: an [[OffsetsWorkspace]] where each pixel has one value, the offset; or a .cal file (in the form created by the ARIEL software). + +'''Note:''' the workspace that this algorithms outputs is a [[Ragged Workspace]]. + +==== Restrictions on the input workspace ==== +The input workspace must contain histogram or event data where the X unit is time-of-flight and the Y data is raw counts. The [[instrument]] associated with the workspace must be fully defined because detector, source & sample position are needed. + + +*WIKI*/ +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- +#include "MantidAlgorithms/AlignDetectorInTOF.h" +#include "MantidAPI/FileProperty.h" +#include "MantidAPI/SpectraDetectorMap.h" +#include "MantidAPI/WorkspaceValidators.h" +#include "MantidDataObjects/EventWorkspace.h" +#include "MantidDataObjects/OffsetsWorkspace.h" +#include "MantidKernel/V3D.h" +#include "MantidKernel/PhysicalConstants.h" +#include "MantidKernel/UnitFactory.h" +#include <fstream> +#include <sstream> + +using namespace Mantid::Kernel; +using namespace Mantid::API; +using namespace Mantid::Geometry; +using namespace Mantid::DataObjects; +using Mantid::DataObjects::OffsetsWorkspace; + +using namespace Mantid::Kernel; +using namespace Mantid::API; + +namespace Mantid +{ +namespace Algorithms +{ + + // Register the algorithm into the algorithm factory + DECLARE_ALGORITHM(AlignDetectorInTOF) + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + AlignDetectorInTOF::AlignDetectorInTOF() + { + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + AlignDetectorInTOF::~AlignDetectorInTOF() + { + } + + + /// Sets documentation strings for this algorithm + void AlignDetectorInTOF::initDocs() + { + this->setWikiSummary("Performs correction on TOF value on each TOF. "); + this->setOptionalMessage("Performs correction on TOF value on each TOF."); + } + + void AlignDetectorInTOF::init() + { + /* + CompositeWorkspaceValidator<> *wsValidator = new CompositeWorkspaceValidator<>; + //Workspace unit must be TOF. + wsValidator->add(new WorkspaceUnitValidator<>("TOF")); + wsValidator->add(new RawCountValidator<>); + wsValidator->add(new InstrumentValidator<>); + + declareProperty( new WorkspaceProperty<API::MatrixWorkspace>("InputWorkspace","",Direction::Input,wsValidator), + "A workspace with units of TOF" ); + */ + + //Input workspace must be in dSpacing and be an inputWorkspace + API::CompositeWorkspaceValidator<EventWorkspace> *wsValidator2 = new API::CompositeWorkspaceValidator<EventWorkspace>; + wsValidator2->add(new API::WorkspaceUnitValidator<EventWorkspace>("TOF")); + + declareProperty( new WorkspaceProperty<DataObjects::EventWorkspace>("InputWorkspace","",Direction::Input,wsValidator2), + "An EventWorkspace with units of TOF" ); + + + declareProperty( new WorkspaceProperty<API::MatrixWorkspace>("OutputWorkspace","",Direction::Output), + "The name to use for the output workspace" ); + + std::vector<std::string> exts; + exts.push_back(".cal"); + exts.push_back(".dat"); + declareProperty(new FileProperty("CalibrationFile", "", FileProperty::OptionalLoad, exts), + "Optional: The .cal file containing the position correction factors. Either this or OffsetsWorkspace needs to be specified."); + + } + + //----------------------------------------------------------------------- + /** Executes the algorithm + * @throw Exception::FileError If the calibration file cannot be opened and read successfully + * @throw Exception::InstrumentDefinitionError If unable to obtain the source-sample distance + */ + void AlignDetectorInTOF::exec() + { + // Get the input workspace + MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); + + // Read in the calibration data + const std::string calFileName = getProperty("CalibrationFile"); + progress(0.0,"Reading calibration file"); + if (calFileName.empty()) + throw std::invalid_argument("You must specify CalibrationFile."); + + if (calFileName.empty()){ + throw std::invalid_argument("Must use Ke's calibration file in TOF"); + } + + this->execTOFEvent(calFileName, inputWS); + + return; + } + + /* + * Compute TOF with Offset + * @params + * + */ + void AlignDetectorInTOF::execTOFEvent(std::string calfilename, Mantid::API::MatrixWorkspace_const_sptr inputWS){ + + g_log.debug() << "Processing in TOF only!" << std::endl; + + // 1. Read spectral - offset file + std::map<detid_t, double> specmap; + + std::ifstream calfile(calfilename.c_str()); + if (!calfile){ + g_log.error() << "File " << calfilename << " is not readable" << std::endl; + } + std::string line; + detid_t specid; + double offset; + while(getline(calfile, line)){ + std::istringstream ss(line); + ss >> specid >> offset; + specmap.insert(std::make_pair(specid, offset)); + } + + // 2. Convert to Eventworkspace and generate a new workspace for output + EventWorkspace_const_sptr eventWS = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS); + if (!eventWS){ + g_log.error() << "Input Worskspace is not EventWorkspace!" << std::endl; + throw std::invalid_argument("Input Workspace is not EventWorkspace"); + } + + API::MatrixWorkspace_sptr outputMatrixWS = this->getProperty("OutputWorkspace"); + EventWorkspace_sptr outputWS; + if (outputMatrixWS == inputWS){ + outputWS = boost::dynamic_pointer_cast<EventWorkspace>(outputMatrixWS); + } else { + outputWS = boost::dynamic_pointer_cast<EventWorkspace>( + API::WorkspaceFactory::Instance().create("EventWorkspace", eventWS->getNumberHistograms(), 2, 1)); + API::WorkspaceFactory::Instance().initializeFromParent(eventWS, outputWS, false); + outputWS->copyDataFrom((*eventWS)); + + outputMatrixWS = boost::dynamic_pointer_cast<MatrixWorkspace>(outputWS); + this->setProperty("OutputWorkspace", outputMatrixWS); + } + + // 3. Convert! + for (int ispec = 0; ispec < static_cast<int>(outputWS->getNumberHistograms()); ispec ++){ + // For each spectrum + + EventList events = outputWS->getEventList(ispec); + std::set<detid_t> detectorids = eventWS->getSpectrum(size_t(ispec))->getDetectorIDs(); + + // a) Check! There is only one possible detector ID in the set + if (detectorids.size() != 1){ + g_log.error() << "Spectrum " << ispec << " Detectors = " << detectorids.size() << std::endl; + } + + std::set<detid_t>::iterator setiter; + double shiftfactor = 1.0; + detid_t detid = 0; + for (setiter=detectorids.begin(); setiter != detectorids.end(); ++setiter){ + + detid = *setiter; + std::map<detid_t, double>::iterator mapiter = specmap.find(detid); + if (mapiter == specmap.end()){ + // No match + g_log.error() << "Detector (ID) = " << detid << " Has No Entry In Calibration File" << std::endl; + } else { + // Matched + // i) Inner-module offset + double offset1 = mapiter->second; + + // ii) Inter-module offset + detid_t index2 = detid_t(detid/1250)*1250+1250-2; + std::map<detid_t, double>::iterator itermodule = specmap.find(index2); + if (itermodule == specmap.end()){ + throw std::invalid_argument("Inter-module offset cannot be found"); + } + double offset2 = itermodule->second; + + // iii) Inter-stack offset + detid_t index3 = index2 + 1; + std::map<detid_t, double>::iterator iterstack = specmap.find(index3); + if (iterstack == specmap.end()){ + throw std::invalid_argument("Inter-stack offset cannot be found"); + } + double offset3 = iterstack->second; + + // iv) overall factor + shiftfactor = pow(10.0, -(offset1+offset2+offset3)); + + /* + if (ispec < 30){ + g_log.notice() << "Detector " << detid << " Shift Factor = " << shiftfactor << " Inner-module = " << offset1 << std::endl; + } + */ + } + + } // for one and only one detector + if (ispec < 30){ + g_log.notice() << "Detector " << detid << " Shift Factor = " << shiftfactor << " Number of events = " << events.getNumberEvents() << std::endl; + } + + /* + if (ispec == 11){ + std::vector<double> tofs; + outputWS->getEventList(ispec).getTofs(tofs); + // events.getTofs(tofs); + g_log.notice() << "Before: TOF[0] = " << tofs[0] << std::endl; + } + */ + outputWS->getEventList(ispec).convertTof(shiftfactor, 0.0); + /* + if (ispec == 11){ + std::vector<double> tofs; + events.getTofs(tofs); + g_log.notice() << "After: TOF[0] = " << tofs[0] << std::endl; + } + */ + + } // for spec + + // Another check + /* + EventList checklist = outputWS->getEventList(11); + std::vector<double> tofs; + checklist.getTofs(tofs); + g_log.notice() << "Final Check: TOF[11][0]" << tofs[0] << std::endl; + */ + + return; + } + +} // namespace Mantid +} // namespace Algorithms diff --git a/Code/Mantid/Framework/Algorithms/src/AlignDetectors.cpp b/Code/Mantid/Framework/Algorithms/src/AlignDetectors.cpp index db56b14dc053ab8a88b6b9e96ffc5ac8970ad566..445c2fdc16e186a007df818ed45540103bc91efd 100644 --- a/Code/Mantid/Framework/Algorithms/src/AlignDetectors.cpp +++ b/Code/Mantid/Framework/Algorithms/src/AlignDetectors.cpp @@ -168,15 +168,12 @@ void AlignDetectors::init() std::vector<std::string> exts; exts.push_back(".cal"); - exts.push_back(".dat"); declareProperty(new FileProperty("CalibrationFile", "", FileProperty::OptionalLoad, exts), "Optional: The .cal file containing the position correction factors. Either this or OffsetsWorkspace needs to be specified."); declareProperty(new WorkspaceProperty<OffsetsWorkspace>("OffsetsWorkspace", "", Direction::Input, true), "Optional: A OffsetsWorkspace containing the calibration offsets. Either this or CalibrationFile needs to be specified."); - declareProperty("InTOFOnly", false, "Working in TOF space only"); - } @@ -200,18 +197,6 @@ void AlignDetectors::exec() if (!offsetsWS && calFileName.empty()) throw std::invalid_argument("You must specify either CalibrationFile or OffsetsWorkspace."); - bool intofonly = getProperty("InTOFOnly"); - - if (intofonly){ - if (calFileName.empty()){ - throw std::invalid_argument("Must use Ke's calibration file in TOF"); - } - - this->execTOFEvent(calFileName, inputWS); - - return; - } - if (!calFileName.empty()) { // Load the .cal file @@ -288,134 +273,6 @@ void AlignDetectors::exec() } -/* - * Compute TOF with Offset - */ -void AlignDetectors::execTOFEvent(std::string calfilename, Mantid::API::MatrixWorkspace_const_sptr inputWS){ - - g_log.notice() << "Processing in TOF only!" << std::endl; - - // 1. Read spectral - offset file - std::map<detid_t, double> specmap; - - std::ifstream calfile(calfilename.c_str()); - if (!calfile){ - g_log.error() << "File " << calfilename << " is not readable" << std::endl; - } - std::string line; - detid_t specid; - double offset; - while(getline(calfile, line)){ - std::istringstream ss(line); - ss >> specid >> offset; - specmap.insert(std::make_pair(specid, offset)); - } - - // 2. Convert to Eventworkspace and generate a new workspace for output - EventWorkspace_const_sptr eventWS = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS); - - API::MatrixWorkspace_sptr outputMatrixWS = this->getProperty("OutputWorkspace"); - EventWorkspace_sptr outputWS; - if (outputMatrixWS == inputWS){ - outputWS = boost::dynamic_pointer_cast<EventWorkspace>(outputMatrixWS); - } else { - outputWS = boost::dynamic_pointer_cast<EventWorkspace>( - API::WorkspaceFactory::Instance().create("EventWorkspace", eventWS->getNumberHistograms(), 2, 1)); - API::WorkspaceFactory::Instance().initializeFromParent(eventWS, outputWS, false); - outputWS->copyDataFrom((*eventWS)); - - outputMatrixWS = boost::dynamic_pointer_cast<MatrixWorkspace>(outputWS); - this->setProperty("OutputWorkspace", outputMatrixWS); - } - - // 3. Convert! - for (int ispec = 0; ispec < static_cast<int>(outputWS->getNumberHistograms()); ispec ++){ - // For each spectrum - - EventList events = outputWS->getEventList(ispec); - std::set<detid_t> detectorids = eventWS->getSpectrum(size_t(ispec))->getDetectorIDs(); - - // a) Check! There is only one possible detector ID in the set - if (detectorids.size() != 1){ - g_log.error() << "Spectrum " << ispec << " Detectors = " << detectorids.size() << std::endl; - } - - std::set<detid_t>::iterator setiter; - double shiftfactor = 1.0; - detid_t detid = 0; - for (setiter=detectorids.begin(); setiter != detectorids.end(); ++setiter){ - - detid = *setiter; - std::map<detid_t, double>::iterator mapiter = specmap.find(detid); - if (mapiter == specmap.end()){ - // No match - g_log.error() << "Detector (ID) = " << detid << " Has No Entry In Calibration File" << std::endl; - } else { - // Matched - // i) Inner-module offset - double offset1 = mapiter->second; - - // ii) Inter-module offset - detid_t index2 = detid_t(detid/1250)*1250+1250-2; - std::map<detid_t, double>::iterator itermodule = specmap.find(index2); - if (itermodule == specmap.end()){ - throw std::invalid_argument("Inter-module offset cannot be found"); - } - double offset2 = itermodule->second; - - // iii) Inter-stack offset - detid_t index3 = index2 + 1; - std::map<detid_t, double>::iterator iterstack = specmap.find(index3); - if (iterstack == specmap.end()){ - throw std::invalid_argument("Inter-stack offset cannot be found"); - } - double offset3 = iterstack->second; - - // iv) overall factor - shiftfactor = pow(10.0, -(offset1+offset2+offset3)); - - /* - if (ispec < 30){ - g_log.notice() << "Detector " << detid << " Shift Factor = " << shiftfactor << " Inner-module = " << offset1 << std::endl; - } - */ - } - - } // for one and only one detector - if (ispec < 30){ - g_log.notice() << "Detector " << detid << " Shift Factor = " << shiftfactor << " Number of events = " << events.getNumberEvents() << std::endl; - } - - /* - if (ispec == 11){ - std::vector<double> tofs; - outputWS->getEventList(ispec).getTofs(tofs); - // events.getTofs(tofs); - g_log.notice() << "Before: TOF[0] = " << tofs[0] << std::endl; - } - */ - outputWS->getEventList(ispec).convertTof(shiftfactor, 0.0); - /* - if (ispec == 11){ - std::vector<double> tofs; - events.getTofs(tofs); - g_log.notice() << "After: TOF[0] = " << tofs[0] << std::endl; - } - */ - - } // for spec - - // Another check - /* - EventList checklist = outputWS->getEventList(11); - std::vector<double> tofs; - checklist.getTofs(tofs); - g_log.notice() << "Final Check: TOF[11][0]" << tofs[0] << std::endl; - */ - - return; -} - //----------------------------------------------------------------------- /** * Execute the align detectors algorithm for an event workspace. diff --git a/Code/Mantid/Framework/Algorithms/src/ConvertToEventWorkspace.cpp b/Code/Mantid/Framework/Algorithms/src/ConvertToEventWorkspace.cpp index fcadeed9327246ca7b436cf3964b70156e5983cd..da15c7a3d792510be5662bc1a99992ec9d143e50 100644 --- a/Code/Mantid/Framework/Algorithms/src/ConvertToEventWorkspace.cpp +++ b/Code/Mantid/Framework/Algorithms/src/ConvertToEventWorkspace.cpp @@ -14,6 +14,7 @@ If the GenerateMultipleEvents option is set, then instead of a single event per #include "MantidDataObjects/Workspace2D.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/Events.h" +#include <limits> using namespace Mantid::Kernel; using namespace Mantid::API; @@ -86,6 +87,10 @@ namespace Algorithms //Copy geometry, etc. over. API::WorkspaceFactory::Instance().initializeFromParent(inWS, outWS, false); + // Cached values for later checks + double inf = std::numeric_limits<double>::infinity(); + double ninf = -inf; + Progress prog(this, 0.0, 1.0, inWS->getNumberHistograms()); PARALLEL_FOR1(inWS) for (int iwi=0; iwi<int(inWS->getNumberHistograms()); iwi++) @@ -109,46 +114,52 @@ namespace Algorithms for (size_t i=0; i<X.size()-1; i++) { double weight = Y[i]; - if (weight != 0.0) + if ((weight != 0.0) && (weight == weight) /*NAN check*/ + && (weight != inf) && (weight != ninf)) { - if (GenerateMultipleEvents) + double error = E[i]; + // Also check that the error is not a bad number + if ((error == error) /*NAN check*/ + && (error != inf) && (error != ninf)) { - // --------- Multiple events per bin ---------- - double errorSquared = E[i]; - errorSquared *= errorSquared; - // Find how many events to fake - double val = weight / E[i]; - val *= val; - // Convert to int with slight rounding up. This is to avoid rounding errors - int numEvents = int(val + 0.2); - if (numEvents < 1) numEvents = 1; - if (numEvents > MaxEventsPerBin) numEvents = MaxEventsPerBin; - // Scale the weight and error for each - weight /= numEvents; - errorSquared /= numEvents; - - // Spread the TOF. e.g. 2 events = 0.25, 0.75. - double tofStep = (X[i+1] - X[i]) / (numEvents); - for (size_t j=0; j<size_t(numEvents); j++) + if (GenerateMultipleEvents) + { + // --------- Multiple events per bin ---------- + double errorSquared = error * error; + // Find how many events to fake + double val = weight / E[i]; + val *= val; + // Convert to int with slight rounding up. This is to avoid rounding errors + int numEvents = int(val + 0.2); + if (numEvents < 1) numEvents = 1; + if (numEvents > MaxEventsPerBin) numEvents = MaxEventsPerBin; + // Scale the weight and error for each + weight /= numEvents; + errorSquared /= numEvents; + + // Spread the TOF. e.g. 2 events = 0.25, 0.75. + double tofStep = (X[i+1] - X[i]) / (numEvents); + for (size_t j=0; j<size_t(numEvents); j++) + { + double tof = X[i] + tofStep * (0.5 + double(j)); + // Create and add the event + el.addEventQuickly( WeightedEventNoTime(tof, weight, errorSquared) ); + } + } + else { - double tof = X[i] + tofStep * (0.5 + double(j)); + // --------- Single event per bin ---------- + // TOF = midpoint of the bin + double tof = (X[i] + X[i+1]) / 2.0; + // Error squared is carried in the event + double errorSquared = E[i]; + errorSquared *= errorSquared; // Create and add the event el.addEventQuickly( WeightedEventNoTime(tof, weight, errorSquared) ); } - } - else - { - // --------- Single event per bin ---------- - // TOF = midpoint of the bin - double tof = (X[i] + X[i+1]) / 2.0; - // Error squared is carried in the event - double errorSquared = E[i]; - errorSquared *= errorSquared; - // Create and add the event - el.addEventQuickly( WeightedEventNoTime(tof, weight, errorSquared) ); - } - } - } + } // error is nont NAN or infinite + } // weight is non-zero, not NAN, and non-infinite + } // (each bin) // Set the X binning parameters el.setX( inSpec->ptrX() ); diff --git a/Code/Mantid/Framework/Algorithms/src/CreateWorkspace.cpp b/Code/Mantid/Framework/Algorithms/src/CreateWorkspace.cpp index 85643f5a83d54425bfad2442acf3a3dbc1162744..19784083535b759ac57f199d6f1589b2711426c9 100644 --- a/Code/Mantid/Framework/Algorithms/src/CreateWorkspace.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CreateWorkspace.cpp @@ -136,7 +136,7 @@ void CreateWorkspace::exec() } - const bool dataE_provided(static_cast<bool>(dataE.size())); + const bool dataE_provided = !dataE.empty(); if ( dataE_provided && dataY.size() != dataE.size() ) { throw std::runtime_error("DataE (if provided) must be the same size as DataY"); diff --git a/Code/Mantid/Framework/Algorithms/src/DiffractionEventCalibrateDetectors.cpp b/Code/Mantid/Framework/Algorithms/src/DiffractionEventCalibrateDetectors.cpp index e60af440eed826a85549ba8bdd5f9e59954ff225..8fc0bd3d120842b5005115cde038830a253e5191 100644 --- a/Code/Mantid/Framework/Algorithms/src/DiffractionEventCalibrateDetectors.cpp +++ b/Code/Mantid/Framework/Algorithms/src/DiffractionEventCalibrateDetectors.cpp @@ -269,7 +269,7 @@ namespace Algorithms void DiffractionEventCalibrateDetectors::init() { declareProperty( - new WorkspaceProperty<EventWorkspace>("InputWorkspace","",Direction::Input,new InstrumentValidator<>), + new WorkspaceProperty<EventWorkspace>("InputWorkspace","",Direction::Input, new InstrumentValidator<EventWorkspace>), "The workspace containing the geometry to be calibrated." ); declareProperty("Params", "", diff --git a/Code/Mantid/Framework/Algorithms/src/FindPeaks.cpp b/Code/Mantid/Framework/Algorithms/src/FindPeaks.cpp index 2623ac6176ca4661d9e80280dbd8b1439a196359..881fc2dd8794e02afa4bda9b506858b54df13944 100644 --- a/Code/Mantid/Framework/Algorithms/src/FindPeaks.cpp +++ b/Code/Mantid/Framework/Algorithms/src/FindPeaks.cpp @@ -523,8 +523,8 @@ void FindPeaks::fitPeak(const API::MatrixWorkspace_sptr &input, const int spectr const MantidVec &X = input->readX(spectrum); const MantidVec &Y = input->readY(spectrum); - g_log.information() << "Fit Peak @ " << X[i4] << " of Spectrum " << spectrum << " "; - g_log.information() << "Peak In Range " << X[i0] << ", " << X[i2] << " Peak @ " << X[i4] << std::endl; + g_log.debug() << "Fit Peak @ " << X[i4] << " of Spectrum " << spectrum << " "; + g_log.debug() << "Peak In Range " << X[i0] << ", " << X[i2] << " Peak @ " << X[i4] << std::endl; // Get the initial estimate of the width, in # of bins const int fitWidth = i0-i2; @@ -537,7 +537,7 @@ void FindPeaks::fitPeak(const API::MatrixWorkspace_sptr &input, const int spectr if (i_min<1) i_min=1; if (i_max>=Y.size()-1) i_max=static_cast<unsigned int>(Y.size()-2); // TODO this is dangerous - g_log.information() << "Background + Peak -- Bounds = " << X[i_min] << ", " << X[i_max] << std::endl; + g_log.debug() << "Background + Peak -- Bounds = " << X[i_min] << ", " << X[i_max] << std::endl; // Estimate height, boundary, and etc for fitting const double bg_lowerSum = Y[i_min-1] + Y[i_min] + Y[i_min+1]; @@ -596,7 +596,7 @@ void FindPeaks::fitPeak(const API::MatrixWorkspace_sptr &input, const int spectr throw std::invalid_argument("Background type is not supported in FindPeak.cpp"); } std::string function = ss.str(); - g_log.information() << "Background Type = " << backgroundtype << " Function: " << function << std::endl; + g_log.debug() << "Background Type = " << backgroundtype << " Function: " << function << std::endl; // d) complete fit fit->setProperty("StartX", (X[i0] - 5 * (X[i0] - X[i2]))); @@ -664,7 +664,7 @@ void FindPeaks::fitPeak(const API::MatrixWorkspace_sptr &input, const int spectr } else { - g_log.information() << "Peak Fitted. Centre=" << centre << ", Sigma=" << width + g_log.debug() << "Peak Fitted. Centre=" << centre << ", Sigma=" << width << ", Height=" << height << ", Background slope=" << bgslope << ", Background intercept=" << bgintercept << std::endl; API::TableRow t = m_peaks->appendRow(); @@ -675,7 +675,7 @@ void FindPeaks::fitPeak(const API::MatrixWorkspace_sptr &input, const int spectr } // if SUCCESS else { - g_log.information() << "Fit Status = " << fitStatus << std::endl; + g_log.debug() << "Fit Status = " << fitStatus << std::endl; } // if FAILED } @@ -689,7 +689,7 @@ void FindPeaks::fitPeak(const API::MatrixWorkspace_sptr &input, const int spectr } // if high background - g_log.information() << "Fit Peak Over" << std::endl; + g_log.debug() << "Fit Peak Over" << std::endl; return; @@ -812,7 +812,7 @@ void FindPeaks::fitPeakHighBackground(const API::MatrixWorkspace_sptr &input, co throw std::invalid_argument("Background type is not supported in FindPeak.cpp"); } std::string function = ss.str(); - g_log.information() << "Background Type = " << backgroundtype << " Function: " << function << std::endl; + g_log.debug() << "Background Type = " << backgroundtype << " Function: " << function << std::endl; // d) complete fit fit->setProperty("StartX", (X[i0] - 5 * (X[i0] - X[i2]))); @@ -839,7 +839,7 @@ void FindPeaks::fitPeakHighBackground(const API::MatrixWorkspace_sptr &input, co if (backgroundtype.compare("Quadratic")==0){ a2 = params[2]; } - g_log.notice() << "Backgound parameters: a0 = " << a0 << " a1 = " << a1 << " a2 = " << a2 << std::endl; + g_log.debug() << "Backgound parameters: a0 = " << a0 << " a1 = " << a1 << " a2 = " << a2 << std::endl; // f) Create theoretic background workspace and thus peak workspace // TODO theortic background workspace will be removed when the code is matured @@ -918,7 +918,7 @@ void FindPeaks::fitPeakHighBackground(const API::MatrixWorkspace_sptr &input, co gfit->setProperty("CostFunction", "Least squares"); gfit->setProperty("Function", function); - g_log.notice() << "Function: " << function << " From " << (X[i4] - 5 * (X[i0] - X[i2])) << " to " << (X[i4] + 5 * (X[i0] - X[i2])) << std::endl; + g_log.debug() << "Function: " << function << " From " << (X[i4] - 5 * (X[i0] - X[i2])) << " to " << (X[i4] + 5 * (X[i0] - X[i2])) << std::endl; // e) Fit and get result gfit->executeAsSubAlg(); @@ -952,7 +952,7 @@ void FindPeaks::fitPeakHighBackground(const API::MatrixWorkspace_sptr &input, co std::string outputstatus = gfit->getProperty("OutputStatus"); if (fheight <= 0 || fsigma <= 0){ - g_log.information() << "Wrong Fit!!!" << std::endl; + g_log.debug() << "Wrong Fit!!!" << std::endl; } else { if (chi2 < mincost){ bestheight = fheight; @@ -960,7 +960,7 @@ void FindPeaks::fitPeakHighBackground(const API::MatrixWorkspace_sptr &input, co bestsigma = fsigma; } } - g_log.information() << "Status: " << outputstatus << " Cost = " << chi2 << " Height, Center, Sigma = " << fheight << ", " << fcenter << ", " << fsigma << std::endl; + g_log.debug() << "Status: " << outputstatus << " Cost = " << chi2 << " Height, Center, Sigma = " << fheight << ", " << fcenter << ", " << fsigma << std::endl; } // ENDFOR @@ -998,7 +998,7 @@ void FindPeaks::fitPeakHighBackground(const API::MatrixWorkspace_sptr &input, co throw std::invalid_argument("Background type is not supported in FindPeak.cpp"); } function = ss2.str(); - g_log.information() << "Final Fit Function: " << function << std::endl; + g_log.debug() << "Final Fit Function: " << function << std::endl; // d) complete fit lastfit->setProperty("StartX", (X[i4] - 2 * (X[i0] - X[i2]))); diff --git a/Code/Mantid/Framework/Algorithms/src/GroupWorkspaces.cpp b/Code/Mantid/Framework/Algorithms/src/GroupWorkspaces.cpp index c997e70ec2b29ff9c326cae61e12aa1141a10697..1c73c0397aab5bd5fad56ca0a78ce68d0e9d6488 100644 --- a/Code/Mantid/Framework/Algorithms/src/GroupWorkspaces.cpp +++ b/Code/Mantid/Framework/Algorithms/src/GroupWorkspaces.cpp @@ -50,6 +50,7 @@ void GroupWorkspaces::exec() std::string outputWorkspace = "OutputWorkspace"; int count = 0; std::vector<std::string>::const_iterator citr; + std::string firstWs(""); // iterate through the input workspaces for (citr = inputworkspaces.begin(); citr != inputworkspaces.end(); ++citr) { @@ -73,9 +74,8 @@ void GroupWorkspaces::exec() declareProperty(new WorkspaceProperty<Workspace> (outws, wsName, Direction::Output)); setProperty(outws, ws_sptr); - //add to output group - addworkspacetoGroup(outgrp_sptr, (*itr)); + addworkspacetoGroup(outgrp_sptr, (*itr), firstWs); } inws_sptr.reset(); ingrp_sptr.reset(); @@ -94,9 +94,8 @@ void GroupWorkspaces::exec() declareProperty(new WorkspaceProperty<Workspace> (outws, wsName, Direction::Output)); setProperty(outws, ws_sptr); //add to output group - addworkspacetoGroup(outgrp_sptr, (*citr)); + addworkspacetoGroup(outgrp_sptr, *citr, firstWs); } - }//end of for loop for input workspaces // Notify listeners that a new grop has been created @@ -105,62 +104,56 @@ void GroupWorkspaces::exec() } -/** checks the input workspaces are of same types - * @param firstWS :: first workspace added to group vector - * @param newWStoAdd :: new workspace to add to group - * @retval boolean true if two workspaces are of same types else false - */ -bool GroupWorkspaces::isCompatibleWorkspaces(const std::string & firstWS, const std::string& newWStoAdd) +///** checks the input workspaces are of same types +// * @param wsName :: name of the workspace to be added +// * @param firstWs :: the first workspace type (not including table workspaces) +// * @retval boolean true if two workspaces are of same types else false +// */ +bool GroupWorkspaces::isCompatibleWorkspaces(const std::string &wsName, std::string& firstWs) { - bool bStatus = 0; - try + bool bStatus(true); + Workspace_sptr ws = AnalysisDataService::Instance().retrieve(wsName); + //check to see if compatible with each other (exception for TableWorkspaces.) + if ( ws->id() != "TableWorkspace" ) { - std::string firstWSTypeId; - - Workspace_sptr wsSptr1 = Mantid::API::AnalysisDataService::Instance().retrieve(firstWS); - firstWSTypeId = wsSptr1->id(); - - //check the typeid of the next workspace - std::string wsTypeId(""); - Workspace_sptr wsSptr = Mantid::API::AnalysisDataService::Instance().retrieve(newWStoAdd); - if (wsSptr) + if (firstWs == "") { - wsTypeId = wsSptr->id(); + firstWs = ws->id(); + } + else + { + if (ws->id() != firstWs) + { + bStatus = false; + } } - (firstWSTypeId == wsTypeId) ? (bStatus = true) : (bStatus = false); - } catch (Kernel::Exception::NotFoundError& e) - { - g_log.error() << e.what() << std::endl; - bStatus = false; } - return bStatus; } -/** add workspace to groupworkspace - * @param outgrp_sptr :: shared pointer to groupworkspace - * @param wsName :: name of the workspace to add to group - */ -void GroupWorkspaces::addworkspacetoGroup(WorkspaceGroup_sptr outgrp_sptr, const std::string &wsName) +///** add workspace to groupworkspace +// * @param outgrp_sptr :: shared pointer to groupworkspace +// * @param wsName :: name of the workspace to add to group +// * @param firstWs :: the first workspace type (not including table workspaces) +// */ +void GroupWorkspaces::addworkspacetoGroup(WorkspaceGroup_sptr outgrp_sptr, const std::string &wsName, std::string &firstWs) { std::vector<std::string> groupVec = outgrp_sptr->getNames(); if (groupVec.size() > 0) { - std::string firstws = groupVec[0]; - if (isCompatibleWorkspaces(firstws, wsName)) + if( isCompatibleWorkspaces( wsName, firstWs ) ) { outgrp_sptr->add(wsName); } else { throw std::runtime_error("Selected workspaces are not of same Types.\n" - "Check the selected workspaces and ensure that they are of same types to group"); + "Check the selected workspaces and ensure that they are of same types to group"); } } else { outgrp_sptr->add(wsName); - } } diff --git a/Code/Mantid/Framework/Algorithms/src/NormaliseToMonitor.cpp b/Code/Mantid/Framework/Algorithms/src/NormaliseToMonitor.cpp index 3ae88add816ecc20a127e62911691575c8058d45..c35c6ae4836670cd6a26af22442d5359922df4ec 100644 --- a/Code/Mantid/Framework/Algorithms/src/NormaliseToMonitor.cpp +++ b/Code/Mantid/Framework/Algorithms/src/NormaliseToMonitor.cpp @@ -38,11 +38,97 @@ In both cases, the [[Divide]] algorithm is used to perform the normalisation. #include "MantidAPI/SpectraAxis.h" #include "MantidAPI/WorkspaceOpOverloads.h" #include "MantidKernel/VectorHelper.h" +#include "MantidKernel/ValidatorAnyList.h" #include <cfloat> #include <iomanip> namespace Mantid { + +// +namespace Kernel { + +// the class to verify and modify interconnected properties. +class PropChanger: public IPropertySettings +{ + // the name of the property, which specifies the workspace which has to be modified + std::string host_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 allowed monitors indexes + mutable std::vector<std::string> allowed_values; + // if the monitors id input string 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(allowed_values.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 ; +} + +} // end Kernel Namespace; + namespace Algorithms { @@ -84,6 +170,9 @@ void NormaliseToMonitor::init() // Can either set a spectrum within the workspace to be the monitor spectrum..... declareProperty("MonitorSpectrum",-1, "The spectrum number of the monitor spectrum within the InputWorkspace"); + // set up the validator, which would verify if spectrum is correct + setPropertySettings("MonitorSpectrum",new PropChanger(this,"InputWorkspace","MonitorWorkspace")); + // ...or provide it in a separate workspace (note: optional WorkspaceProperty) declareProperty(new WorkspaceProperty<>("MonitorWorkspace","",Direction::Input,true,val->clone()), "A single-spectrum workspace containing the monitor spectrum"); @@ -132,7 +221,7 @@ void NormaliseToMonitor::checkProperties(API::MatrixWorkspace_sptr inputWorkspac { // Check where the monitor spectrum should come from Property* monSpec = getProperty("MonitorSpectrum"); - Property* monWS = getProperty("MonitorWorkspace"); + Property* monWS = getProperty("MonitorWorkspace"); // Is the monitor spectrum within the main input workspace const bool inWS = !monSpec->isDefault(); // Or is it in a separate workspace @@ -187,7 +276,7 @@ API::MatrixWorkspace_sptr NormaliseToMonitor::getInWSMonitorSpectrum(API::Matrix const SpectraAxis* axis = dynamic_cast<const SpectraAxis*>(inputWorkspace->getAxis(1)); if ( ! axis) { - throw std::runtime_error("Cannot retrieve monitor spectrum - spectrum numbers no attached to workspace"); + throw std::runtime_error("Cannot retrieve monitor spectrum - spectrum numbers not attached to workspace"); } axis->getSpectraIndexMap(specs); if ( ! specs.count(monitorSpec) ) diff --git a/Code/Mantid/Framework/Algorithms/src/Q1D2.cpp b/Code/Mantid/Framework/Algorithms/src/Q1D2.cpp index c557f5b64f2655225f3df03e095cf5c9c0f0ec48..74967152be82c0b28321c6ee13d361d15a193e9b 100644 --- a/Code/Mantid/Framework/Algorithms/src/Q1D2.cpp +++ b/Code/Mantid/Framework/Algorithms/src/Q1D2.cpp @@ -64,7 +64,7 @@ void Q1D2::init() mustBePositive->setLower(0.0); declareProperty("RadiusCut", 0.0, mustBePositive, "To increase resolution some wavelengths are excluded within this distance from\n" - "the beam center (m)"); + "the beam center (mm)"); declareProperty("WaveCut", 0.0, mustBePositive->clone(), "To increase resolution by starting to remove some wavelengths below this" "freshold (angstrom)"); diff --git a/Code/Mantid/Framework/Algorithms/src/Qhelper.cpp b/Code/Mantid/Framework/Algorithms/src/Qhelper.cpp index 6f9143122620eadc1af1f3f323f3a90d1c856d6c..5bdd7f90d8a6c38ce1db1062b79146cfc6383532 100644 --- a/Code/Mantid/Framework/Algorithms/src/Qhelper.cpp +++ b/Code/Mantid/Framework/Algorithms/src/Qhelper.cpp @@ -82,7 +82,7 @@ void Qhelper::examineInput(API::MatrixWorkspace_const_sptr dataWS, /** Finds the first index number of the first wavelength bin that should included based on the * the calculation: W = Wcut (Rcut-R)/Rcut * @param dataWS data workspace -* @param RCut the radius cut off, should be value of the property RadiusCut +* @param RCut the radius cut off, should be value of the property RadiusCut (unit is mm) * @param WCut this wavelength cut off, should be equal to the value WaveCut * @param specInd spectrum that is being analysed * @return index number of the first bin to include in the calculation @@ -91,11 +91,12 @@ size_t Qhelper::waveLengthCutOff(API::MatrixWorkspace_const_sptr dataWS, const d const size_t specInd) const { double l_WCutOver = 0.0; - double l_RCut = 0.0; + double l_RCut = 0.0; // locally we store RCut in units of meters if ( RCut > 0 && WCut > 0 ) { - l_WCutOver = WCut/RCut; - l_RCut = RCut; + l_RCut = RCut / 1000.0; // convert to meters + //l_RCut = RCut; // convert to meters + l_WCutOver = WCut/l_RCut; } if ( !(l_RCut > 0) ) diff --git a/Code/Mantid/Framework/Algorithms/src/Qxy.cpp b/Code/Mantid/Framework/Algorithms/src/Qxy.cpp index ccb3aea03d04969f820dc839bd573b1b82bf9263..342058a0d794edbe49b8f98b9af7d91a3ab80c06 100644 --- a/Code/Mantid/Framework/Algorithms/src/Qxy.cpp +++ b/Code/Mantid/Framework/Algorithms/src/Qxy.cpp @@ -67,7 +67,7 @@ void Qxy::init() mustBePositive2->setLower(0.0); declareProperty("RadiusCut", 0.0, mustBePositive2, "To increase resolution some wavelengths are excluded within this distance from\n" - "the beam center (m)"); + "the beam center (mm)"); declareProperty("WaveCut", 0.0, mustBePositive2->clone(), "To increase resolution by starting to remove some wavelengths below this" "freshold (angstrom)"); diff --git a/Code/Mantid/Framework/Algorithms/src/SmoothNeighbours.cpp b/Code/Mantid/Framework/Algorithms/src/SmoothNeighbours.cpp index 9f7be26560553179c06bf75c09d0a511800cfc60..3ec99a9a6f2a1bb7f36cdd5ba17c6b737b9fa16e 100644 --- a/Code/Mantid/Framework/Algorithms/src/SmoothNeighbours.cpp +++ b/Code/Mantid/Framework/Algorithms/src/SmoothNeighbours.cpp @@ -81,22 +81,33 @@ void SmoothNeighbours::init() new WorkspaceProperty<MatrixWorkspace>("OutputWorkspace","",Direction::Output), "The name of the workspace to be created as the output of the algorithm." ); + declareProperty("ProvideRadius", true, "Provide the radius for the search. Otherwise will need to specify number of neighbours"); + //Unsigned double BoundedValidator<double> *mustBePositiveDouble = new BoundedValidator<double>(); mustBePositiveDouble->setLower(0.0); + + //Unsigned int. + BoundedValidator<int> *mustBePositive = new BoundedValidator<int>(); + mustBePositive->setLower(0); + declareProperty("Radius", 0.0, mustBePositiveDouble, "The radius around a pixel to look for nearest neighbours to average. \n" "If 0, will use the AdjX and AdjY parameters for rectangular detectors instead." ); + setPropertySettings("Radius", new EnabledWhenProperty(this, "ProvideRadius", IS_DEFAULT)); + + declareProperty("NumberOfNeighbours", 8, mustBePositive->clone(), "Number of nearest neighbouring pixels.\n" + "Alternative to providing the radius. The default is 8."); + setPropertySettings("NumberOfNeighbours", new EnabledWhenProperty(this, "ProvideRadius", IS_NOT_DEFAULT)); declareProperty("WeightedSum", true, "Adjust the weight of neighboring pixels when summing them, based on their distance."); - + setPropertySettings("WeightedSum", new EnabledWhenProperty(this, "ProvideRadius", IS_DEFAULT)); //Weighted sum needs the radius for the calculation. + // As the property takes ownership of the validator pointer, have to take care to pass in a unique // pointer to each property. - BoundedValidator<int> *mustBePositive = new BoundedValidator<int>(); - mustBePositive->setLower(0); - declareProperty("AdjX", 1, mustBePositive, + declareProperty("AdjX", 1, mustBePositive->clone(), "The number of X (horizontal) adjacent pixels to average together. Only for instruments with RectangularDetectors. " ); setPropertySettings("AdjX", new EnabledWhenProperty(this, "Radius", IS_DEFAULT) ); @@ -256,7 +267,7 @@ void SmoothNeighbours::findNeighboursRectangular() //-------------------------------------------------------------------------------------------- /** Use NearestNeighbours to find the neighbours for any instrument */ -void SmoothNeighbours::findNeighboursRadius() +void SmoothNeighbours::findNeighboursUbiqutious() { m_prog->resetNumSteps(inWS->getNumberHistograms(), 0.2, 0.5); this->progress(0.2, "Building Neighbour Map"); @@ -266,13 +277,34 @@ void SmoothNeighbours::findNeighboursRadius() // Resize the vector we are setting m_neighbours.resize(inWS->getNumberHistograms()); - + //Get the use radius flag. + bool useRadius = getProperty("ProvideRadius"); + int nNeighbours = getProperty("NumberOfNeighbours"); + IDetector_const_sptr det; // Go through every input workspace pixel for (size_t wi=0; wi < inWS->getNumberHistograms(); wi++) { - specid_t inSpec = inWS->getSpectrum(wi)->getSpectrumNo(); - std::map<specid_t, double> neighbSpectra = inWS->getNeighbours(inSpec, Radius); + // We want to skip monitors + try + { + det = inWS->getDetector(wi); + if( det->isMonitor() ) continue; //skip monitor + } + catch(Kernel::Exception::NotFoundError&) + { + continue; //skip missing detector + } + specid_t inSpec = inWS->getSpectrum(wi)->getSpectrumNo(); + std::map<specid_t, double> neighbSpectra; + if(useRadius) + { + neighbSpectra = inWS->getNeighbours(inSpec, Radius); + } + else + { + neighbSpectra = inWS->getNeighboursExact(inSpec, nNeighbours); + } // Force the central pixel to always be there // There seems to be a bug in nearestNeighbours, returns distance != 0.0 for the central pixel. So we force distance = 0 neighbSpectra[inSpec] = 0.0; @@ -338,15 +370,16 @@ void SmoothNeighbours::exec() // Get the input workspace inWS = getProperty("InputWorkspace"); - + // Progress reporting, first for the sorting m_prog = new Progress(this, 0.0, 0.2, inWS->getNumberHistograms()); // Collect the neighbours with either method. - if (Radius <= 0.0) + bool useRadius = getProperty("ProvideRadius"); + if (Radius <= 0.0 && useRadius) findNeighboursRectangular(); else - findNeighboursRadius(); + findNeighboursUbiqutious(); // Find the right method to exec EventWorkspace_sptr wsEvent = boost::dynamic_pointer_cast<EventWorkspace>(inWS); @@ -371,6 +404,7 @@ void SmoothNeighbours::execWorkspace2D(Mantid::API::MatrixWorkspace_sptr ws) //Get some stuff from the input workspace const size_t numberOfSpectra = inWS->getNumberHistograms(); + const size_t YLength = inWS->blocksize(); MatrixWorkspace_sptr outWS; @@ -393,6 +427,8 @@ void SmoothNeighbours::execWorkspace2D(Mantid::API::MatrixWorkspace_sptr ws) MantidVec & outY = outSpec->dataY(); // We will temporarily carry the squared error MantidVec & outE = outSpec->dataE(); + // tmp to carry the X Data. + MantidVec & outX = outSpec->dataX(); // Which are the neighbours? std::vector< weightedNeighbour > & neighbours = m_neighbours[outWI]; @@ -404,6 +440,7 @@ void SmoothNeighbours::execWorkspace2D(Mantid::API::MatrixWorkspace_sptr ws) const MantidVec & inY = ws->readY(inWI); const MantidVec & inE = ws->readE(inWI); + const MantidVec & inX = ws->readX(inWI); for (size_t i=0; i<YLength; i++) { @@ -414,6 +451,11 @@ void SmoothNeighbours::execWorkspace2D(Mantid::API::MatrixWorkspace_sptr ws) errorSquared *= errorSquared; errorSquared *= weight; outE[i] += errorSquared; + outX[i] = inX[i]; + } + if(ws->isHistogramData()) + { + outX[YLength] = inX[YLength]; } } //(each neighbour) diff --git a/Code/Mantid/Framework/Algorithms/src/SumNeighbours.cpp b/Code/Mantid/Framework/Algorithms/src/SumNeighbours.cpp index 7be427cb3631cfdb7fec2304ae41c409dbdf44c2..b9eb1163afd2135202545b3d3b405e4931051c4b 100644 --- a/Code/Mantid/Framework/Algorithms/src/SumNeighbours.cpp +++ b/Code/Mantid/Framework/Algorithms/src/SumNeighbours.cpp @@ -51,7 +51,7 @@ using namespace DataObjects; */ void SumNeighbours::init() { - declareProperty(new WorkspaceProperty<EventWorkspace>("InputWorkspace","",Direction::Input,new InstrumentValidator<>), + declareProperty(new WorkspaceProperty<EventWorkspace>("InputWorkspace","",Direction::Input,new InstrumentValidator<EventWorkspace>), "A workspace containing one or more rectangular area detectors. Each spectrum needs to correspond to only one pixelID (e.g. no grouping or previous calls to SumNeighbours)." ); declareProperty( diff --git a/Code/Mantid/Framework/Algorithms/src/UnGroupWorkspaces.cpp b/Code/Mantid/Framework/Algorithms/src/UnGroupWorkspace.cpp similarity index 91% rename from Code/Mantid/Framework/Algorithms/src/UnGroupWorkspaces.cpp rename to Code/Mantid/Framework/Algorithms/src/UnGroupWorkspace.cpp index 38aaebf802288340d99d8841605912ffdde1ac94..4ed41ade7e342996cb4897d8712c66d8a172ff05 100644 --- a/Code/Mantid/Framework/Algorithms/src/UnGroupWorkspaces.cpp +++ b/Code/Mantid/Framework/Algorithms/src/UnGroupWorkspace.cpp @@ -1,7 +1,10 @@ -//---------------------------------------------------------------------- -// Includes -//---------------------------------------------------------------------- -#include "MantidAlgorithms/UnGroupWorkspaces.h" +/*WIKI* + +Takes a [[WorkspaceGroup]] as input and ungroups it into several workspaces. +You can perform this from the MantidPlot GUI by selecting the WorkspaceGroup and clicking "Ungroup". + +*WIKI*/ +#include "MantidAlgorithms/UnGroupWorkspace.h" namespace Mantid { diff --git a/Code/Mantid/Framework/Algorithms/test/.gitignore b/Code/Mantid/Framework/Algorithms/test/.gitignore index a154d0b10d434ad25d8de93704cf20b62789a25e..2eac291d276e131a3915ad3b3ac57b3733a4ffdf 100644 --- a/Code/Mantid/Framework/Algorithms/test/.gitignore +++ b/Code/Mantid/Framework/Algorithms/test/.gitignore @@ -2,3 +2,4 @@ DivideTest.h MinusTest.h MultiplyTest.h PlusTest.h +*.cpp diff --git a/Code/Mantid/Framework/Algorithms/test/AlignDetectorInTOFTest.h b/Code/Mantid/Framework/Algorithms/test/AlignDetectorInTOFTest.h new file mode 100644 index 0000000000000000000000000000000000000000..a12a532807c288a76e49ae65882f383615864ffb --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/test/AlignDetectorInTOFTest.h @@ -0,0 +1,33 @@ +#ifndef MANTID_ALGORITHMS_ALIGNDETECTORINTOFTEST_H_ +#define MANTID_ALGORITHMS_ALIGNDETECTORINTOFTEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidKernel/Timer.h" +#include "MantidKernel/System.h" +#include <iostream> +#include <iomanip> + +#include "MantidAlgorithms/AlignDetectorInTOF.h" + +using namespace Mantid; +using namespace Mantid::Algorithms; +using namespace Mantid::API; + +class AlignDetectorInTOFTest : public CxxTest::TestSuite +{ +public: + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static AlignDetectorInTOFTest *createSuite() { return new AlignDetectorInTOFTest(); } + static void destroySuite( AlignDetectorInTOFTest *suite ) { delete suite; } + + + void test_Something() + { + } + + +}; + + +#endif /* MANTID_ALGORITHMS_ALIGNDETECTORINTOFTEST_H_ */ \ No newline at end of file diff --git a/Code/Mantid/Framework/Algorithms/test/ConvertToEventWorkspaceTest.h b/Code/Mantid/Framework/Algorithms/test/ConvertToEventWorkspaceTest.h index 16a73e4ff464d1ce568dea9a46aad8d9bb1f1116..5a1ef3c8d2725894f95177d69e4ffd9029ec682c 100644 --- a/Code/Mantid/Framework/Algorithms/test/ConvertToEventWorkspaceTest.h +++ b/Code/Mantid/Framework/Algorithms/test/ConvertToEventWorkspaceTest.h @@ -138,6 +138,55 @@ public: } + /// Workspace with infinity or NAN = don't create events there. + void test_with_nan_and_inf() + { + // Create the input + Workspace2D_sptr inWS = WorkspaceCreationHelper::Create2DWorkspace(1, 10); + + double nan = std::numeric_limits<double>::quiet_NaN(); + double inf = std::numeric_limits<double>::infinity(); + double ninf = -inf; + + inWS->dataY(0)[0] = 1.0; + inWS->dataE(0)[0] = 1.0; + + // But nan or inf in either Y or error + inWS->dataY(0)[1] = nan; + inWS->dataE(0)[2] = nan; + inWS->dataY(0)[3] = inf; + inWS->dataE(0)[4] = inf; + inWS->dataY(0)[5] = ninf; + inWS->dataE(0)[6] = ninf; + + for (size_t i=7; i<10; i++) + { + inWS->dataY(0)[i] = 0; + inWS->dataE(0)[i] = 0; + } + + // Name of the output workspace. + std::string outWSName("ConvertToEventWorkspaceTest_OutputWS"); + + ConvertToEventWorkspace alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + TS_ASSERT_THROWS_NOTHING( alg.setProperty("InputWorkspace", inWS) ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("GenerateMultipleEvents", false) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) ); + TS_ASSERT_THROWS_NOTHING( alg.execute(); ); + TS_ASSERT( alg.isExecuted() ); + + // Retrieve the workspace from data service. + EventWorkspace_sptr outWS; + TS_ASSERT_THROWS_NOTHING( outWS = boost::dynamic_pointer_cast<EventWorkspace>(AnalysisDataService::Instance().retrieve(outWSName)) ); + TS_ASSERT(outWS); + if (!outWS) return; + + // Only 1 bin had a valid weight/error, so it should have 1 event + TS_ASSERT_EQUALS( outWS->getNumberEvents(), 1); + } + }; diff --git a/Code/Mantid/Framework/Algorithms/test/GroupWorkspacesTest.h b/Code/Mantid/Framework/Algorithms/test/GroupWorkspacesTest.h index 75d07b77fd4bbbf92393068a63bf7c69cc7b9c3f..2b2c62b39bbd3e738677616ec995bb183f19e3e8 100644 --- a/Code/Mantid/Framework/Algorithms/test/GroupWorkspacesTest.h +++ b/Code/Mantid/Framework/Algorithms/test/GroupWorkspacesTest.h @@ -198,7 +198,7 @@ public: AnalysisDataService::Instance().remove("CSP79590_2"); AnalysisDataService::Instance().remove("LOQ48098"); } - void testExecGroupTwoIncompatibleWorkspaces() + void testExecGroupWithDifferentWorkspaces() { LoadRaw3 alg; alg.initialize(); @@ -209,9 +209,14 @@ public: Mantid::DataHandling::LoadNexusProcessed loader; loader.initialize(); + loader.setProperty("Filename","focussed.nxs"); loader.setProperty("OutputWorkspace","peaksWS"); - TS_ASSERT_THROWS_NOTHING(loader.execute()); + TS_ASSERT_THROWS_NOTHING(loader.execute()); + + loader.setProperty("Filename","LOQ49886.nxs"); + loader.setProperty("OutputWorkspace","LOQ49886"); + TS_ASSERT_THROWS_NOTHING(loader.execute()); Mantid::Algorithms::FindPeaks finder; finder.initialize(); @@ -227,11 +232,11 @@ public: std::vector<std::string >input; input.push_back("LOQ48094"); input.push_back("foundpeaks"); + input.push_back("LOQ49886"); TS_ASSERT_THROWS_NOTHING( grpwsalg.setProperty("InputWorkspaces",input)); TS_ASSERT_THROWS_NOTHING( grpwsalg.setProperty("OutputWorkspace","NewGroup")); TS_ASSERT_THROWS_NOTHING( grpwsalg.execute()); TS_ASSERT( !grpwsalg.isExecuted() ); - } private: diff --git a/Code/Mantid/Framework/Algorithms/test/Q1D2Test.h b/Code/Mantid/Framework/Algorithms/test/Q1D2Test.h index b691d081252af82e984b5e079a602aeb9908f304..fb93c42f075bdf6d31f0a19f7da834d55c431f3e 100644 --- a/Code/Mantid/Framework/Algorithms/test/Q1D2Test.h +++ b/Code/Mantid/Framework/Algorithms/test/Q1D2Test.h @@ -175,7 +175,7 @@ public: Q1D.setProperty("PixelAdj", m_pixel); Q1D.setPropertyValue("OutputWorkspace", outputWS); Q1D.setPropertyValue("OutputBinning", "0.1,-0.02,0.5"); - Q1D.setProperty("RadiusCut", 0.22); + Q1D.setProperty("RadiusCut", 220.0); Q1D.setProperty("WaveCut", 8.0); ) //#default is don't correct for gravity @@ -218,7 +218,7 @@ public: Q1D.setPropertyValue("OutputWorkspace", outputWS); Q1D.setPropertyValue("OutputBinning", "0.1,-0.02,0.5"); //this raduis is too small to exclude anything - Q1D.setProperty("RadiusCut", 0.05); + Q1D.setProperty("RadiusCut", 50.0); //this is the entire wavelength range Q1D.setProperty("WaveCut", 30.0); ) diff --git a/Code/Mantid/Framework/Algorithms/test/SmoothNeighboursTest.h b/Code/Mantid/Framework/Algorithms/test/SmoothNeighboursTest.h index c08751526fc2f1f11db430b30d99d7beb203d520..ceb36a29ffb414360b2686ba1b4a009fe1b47c51 100644 --- a/Code/Mantid/Framework/Algorithms/test/SmoothNeighboursTest.h +++ b/Code/Mantid/Framework/Algorithms/test/SmoothNeighboursTest.h @@ -2,6 +2,7 @@ #define SmoothNeighboursTEST_H_ #include "MantidAlgorithms/SmoothNeighbours.h" +#include "MantidAlgorithms/CheckWorkspacesMatch.h" #include <cxxtest/TestSuite.h> #include "MantidKernel/Timer.h" #include "MantidKernel/System.h" @@ -108,6 +109,64 @@ public: AnalysisDataService::Instance().remove("testEW"); } + void testWithUnsignedNumberOfNeighbours() + { + SmoothNeighbours alg; + alg.initialize(); + TSM_ASSERT_THROWS("Cannot have number of neighbours < 1",alg.setProperty("NumberOfNeighbours", -1), std::invalid_argument); + } + + void testWithNonIntegerNumberOfNeighbours() + { + SmoothNeighbours alg; + alg.initialize(); + TSM_ASSERT_THROWS("Cannot have non-integer number of neighbours",alg.setProperty("NumberOfNeighbours", 1.1), std::invalid_argument); + } + + void testWithValidNumberOfNeighbours() + { + SmoothNeighbours alg; + alg.initialize(); + TSM_ASSERT_THROWS_NOTHING("A single neighbour is valid",alg.setProperty("NumberOfNeighbours", 1)); + int value = alg.getProperty("NumberOfNeighbours"); + TS_ASSERT_EQUALS(1, value); + } + + void testWithNumberOfNeighbours() + { + MatrixWorkspace_sptr inWS = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(100, 10); + + SmoothNeighbours alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ); + TS_ASSERT( alg.isInitialized() ); + alg.setProperty("InputWorkspace", inWS); + alg.setProperty("OutputWorkspace", "testMW"); + alg.setProperty("PreserveEvents", false); + alg.setProperty("WeightedSum", false); + alg.setProperty("ProvideRadius", false); + alg.setProperty("NumberOfNeighbours", 8); + TS_ASSERT_THROWS_NOTHING( alg.execute(); ); + TS_ASSERT( alg.isExecuted() ); + + MatrixWorkspace_sptr outWS; + TS_ASSERT_THROWS_NOTHING(outWS = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("testMW")) ); + + //Some basic checks + TSM_ASSERT_EQUALS("Wrong number of histograms", inWS->getNumberHistograms(), outWS->getNumberHistograms()); + TSM_ASSERT_EQUALS("Wrong number of bins", inWS->readX(0).size(), outWS->readX(0).size()); + + //Check that the workspaces are identical, including x and y values. + CheckWorkspacesMatch* checkAlg = new CheckWorkspacesMatch; + checkAlg->initialize(); + checkAlg->setProperty("Workspace1", inWS); + checkAlg->setProperty("Workspace2", outWS); + checkAlg->setProperty("Tolerance", 0.001); + checkAlg->execute(); + std::string result = checkAlg->getProperty("Result"); + TS_ASSERT_EQUALS("Success!", result); + + } + void test_event_WEIGHTED() { double expectedY[9] = {2, 2, 2, 2.3636, 2.5454, 2.3636, 2, 2, 2}; diff --git a/Code/Mantid/Framework/Algorithms/test/UnGroupWorkspacesTest.h b/Code/Mantid/Framework/Algorithms/test/UnGroupWorkspaceTest.h similarity index 96% rename from Code/Mantid/Framework/Algorithms/test/UnGroupWorkspacesTest.h rename to Code/Mantid/Framework/Algorithms/test/UnGroupWorkspaceTest.h index 4dcc0eafdb7543e8af98981cb03142e34f7c7f77..9e1c4ff90f3559a6f657ae109efd32e1c7dce697 100644 --- a/Code/Mantid/Framework/Algorithms/test/UnGroupWorkspacesTest.h +++ b/Code/Mantid/Framework/Algorithms/test/UnGroupWorkspaceTest.h @@ -2,7 +2,7 @@ #define UNGROUPWORKSPACESTEST_H_ #include <cxxtest/TestSuite.h> -#include "MantidAlgorithms/UnGroupWorkspaces.h" +#include "MantidAlgorithms/UnGroupWorkspace.h" #include "MantidDataHandling/LoadRaw3.h" using namespace Mantid::API; @@ -10,7 +10,7 @@ using namespace Mantid::Kernel; using namespace Mantid::DataHandling; using namespace Mantid::Algorithms; -class UnGroupWorkspacesTest : public CxxTest::TestSuite +class UnGroupWorkspaceTest : public CxxTest::TestSuite { public: void testName() diff --git a/Code/Mantid/Framework/Crystal/CMakeLists.txt b/Code/Mantid/Framework/Crystal/CMakeLists.txt index 363d5d1f89a5be8ab771dabebe8795697f2cd9cd..962bf8f951cab0a2476dfba7a1730f96004c0f9b 100644 --- a/Code/Mantid/Framework/Crystal/CMakeLists.txt +++ b/Code/Mantid/Framework/Crystal/CMakeLists.txt @@ -1,6 +1,7 @@ set ( SRC_FILES src/AnvredCorrection.cpp src/CalculateUMatrix.cpp + src/CentroidPeaks.cpp src/FindUBUsingIndexedPeaks.cpp src/FindUBUsingLatticeParameters.cpp src/FindUBUsingMinMaxD.cpp @@ -23,6 +24,7 @@ set ( SRC_UNITY_IGNORE_FILES ) set ( INC_FILES inc/MantidCrystal/AnvredCorrection.h inc/MantidCrystal/CalculateUMatrix.h + inc/MantidCrystal/CentroidPeaks.h inc/MantidCrystal/FindUBUsingIndexedPeaks.h inc/MantidCrystal/FindUBUsingLatticeParameters.h inc/MantidCrystal/FindUBUsingMinMaxD.h diff --git a/Code/Mantid/Framework/Crystal/inc/MantidCrystal/CentroidPeaks.h b/Code/Mantid/Framework/Crystal/inc/MantidCrystal/CentroidPeaks.h new file mode 100644 index 0000000000000000000000000000000000000000..d7af07c86bdb8ae5ee1ea639d280d4c32af7a212 --- /dev/null +++ b/Code/Mantid/Framework/Crystal/inc/MantidCrystal/CentroidPeaks.h @@ -0,0 +1,59 @@ +#ifndef MANTID_CRYSTAL_CENTROIDPEAKS_H_ +#define MANTID_CRYSTAL_CENTROIDPEAKS_H_ +/*WIKI* + +This algorithm starts with a PeaksWorkspace containing the expected positions of peaks in reciprocal space. It calculates the centroid of the peak by calculating the average of the coordinates of all events within a given radius of the peak, weighted by the weight (signal) of the event. + + +*WIKI*/ + +#include "MantidAPI/Algorithm.h" +#include "MantidDataObjects/PeaksWorkspace.h" +#include "MantidKernel/System.h" +#include "MantidDataObjects/EventWorkspace.h" + +namespace Mantid +{ +namespace Crystal +{ + + /** Find the centroid of single-crystal peaks in a 2D Workspace, in order to refine their positions. + * + * @author Janik Zikovsky + * @date 2011-06-01 + */ + class DLLExport CentroidPeaks : public API::Algorithm + { + public: + CentroidPeaks(); + ~CentroidPeaks(); + + /// Algorithm's name for identification + virtual const std::string name() const { return "CentroidPeaks";}; + /// Algorithm's version for identification + virtual int version() const { return 1;}; + /// Algorithm's category for identification + virtual const std::string category() const { return "General";} + + private: + /// Sets documentation strings for this algorithm + virtual void initDocs(); + /// Initialise the properties + void init(); + /// Run the algorithm + void exec(); + void integrate(); + void integrateEvent(); + + /// Input 2D Workspace + API::MatrixWorkspace_sptr inWS; + DataObjects::EventWorkspace_sptr eventW; + Mantid::detid2index_map * wi_to_detid_map; + + }; + + +} // namespace Mantid +} // namespace Crystal + +#endif /* MANTID_CRYSTAL_CENTROIDPEAKS_H_ */ diff --git a/Code/Mantid/Framework/Crystal/src/CentroidPeaks.cpp b/Code/Mantid/Framework/Crystal/src/CentroidPeaks.cpp new file mode 100644 index 0000000000000000000000000000000000000000..26576110fa530ca46d4763e44c65088ae7b0f30b --- /dev/null +++ b/Code/Mantid/Framework/Crystal/src/CentroidPeaks.cpp @@ -0,0 +1,379 @@ +#include "MantidDataObjects/PeaksWorkspace.h" +#include "MantidKernel/System.h" +#include "MantidCrystal/CentroidPeaks.h" +#include "MantidGeometry/Instrument/RectangularDetector.h" +#include "MantidKernel/VectorHelper.h" + +using Mantid::DataObjects::PeaksWorkspace; + +namespace Mantid +{ +namespace Crystal +{ + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(CentroidPeaks) + + using namespace Mantid::API; + using namespace Mantid::DataObjects; + using namespace Mantid::Geometry; + using namespace Mantid::Kernel; + using namespace Mantid::Crystal; + + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + CentroidPeaks::CentroidPeaks() + { + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + CentroidPeaks::~CentroidPeaks() + { + } + + + //---------------------------------------------------------------------------------------------- + /// Sets documentation strings for this algorithm + void CentroidPeaks::initDocs() + { + this->setWikiSummary("Find the centroid of single-crystal peaks in a 2D Workspace, in order to refine their positions."); + this->setOptionalMessage("Find the centroid of single-crystal peaks in a 2D Workspace, in order to refine their positions."); + } + + //---------------------------------------------------------------------------------------------- + /** Initialize the algorithm's properties. + */ + void CentroidPeaks::init() + { + declareProperty(new WorkspaceProperty<PeaksWorkspace>("InPeaksWorkspace","",Direction::Input), + "A PeaksWorkspace containing the peaks to centroid."); + + declareProperty(new WorkspaceProperty<>("InputWorkspace","",Direction::Input), "An input 2D Workspace."); + + declareProperty(new PropertyWithValue<int>("PeakRadius",10,Direction::Input), + "Fixed radius around each peak position in which to calculate the centroid."); + + declareProperty(new PropertyWithValue<int>("EdgePixels",0,Direction::Input), + "The number of pixels where peaks are removed at edges. Only for instruments with RectangularDetectors. " ); + + declareProperty(new WorkspaceProperty<PeaksWorkspace>("OutPeaksWorkspace","",Direction::Output), + "The output PeaksWorkspace will be a copy of the input PeaksWorkspace " + "with the peaks' positions modified by the new found centroids."); + } + + //---------------------------------------------------------------------------------------------- + /** Integrate the peaks of the workspace using parameters saved in the algorithm class + * @param inWS :: 2D Workspace to integrate + */ + void CentroidPeaks::integrate() + { + + /// Peak workspace to centroid + Mantid::DataObjects::PeaksWorkspace_sptr inPeakWS = getProperty("InPeaksWorkspace"); + + /// Output peaks workspace, create if needed + Mantid::DataObjects::PeaksWorkspace_sptr peakWS = getProperty("OutPeaksWorkspace"); + if (peakWS != inPeakWS) + peakWS = inPeakWS->clone(); + + + /// Radius to use around peaks + int PeakRadius = getProperty("PeakRadius"); + + PARALLEL_FOR2(inWS,peakWS) + for (int i=0; i < int(peakWS->getNumberPeaks()); ++i) + { + PARALLEL_START_INTERUPT_REGION + // Get a direct ref to that peak. + IPeak & peak = peakWS->getPeak(i); + int col = peak.getCol(); + int row = peak.getRow(); + double TOFPeakd = peak.getTOF(); + Geometry::Instrument_const_sptr Iptr = peak.getInstrument(); + std::string bankName = peak.getBankName(); + + boost::shared_ptr<const IComponent> parent = Iptr->getComponentByName(bankName); + + if (parent->type().compare("RectangularDetector") != 0) + { + + std::cout<<" getPanel C type="<<parent->type()<<std::endl; + throw std::runtime_error("Improper Peak Argument"); + } + boost::shared_ptr<const RectangularDetector> RDet = boost::shared_dynamic_cast< + const RectangularDetector>(parent); + double intensity = 0.0; + double chancentroid = 0.0; + boost::shared_ptr<Detector> pixel = RDet->getAtXY(col, row); + Mantid::detid2index_map::iterator it; + it = (*wi_to_detid_map).find(pixel->getID()); + size_t workspaceIndex = (it->second); + + Mantid::MantidVec X = inWS->readX(workspaceIndex); + Mantid::MantidVec histogram = inWS->readY(workspaceIndex); + + int chan = Kernel::VectorHelper::getBinIndex(X, TOFPeakd); + int chanstart = std::max(0,chan-PeakRadius); + int chanend = std::min(static_cast<int>(X.size()),chan+PeakRadius); + double rowcentroid = 0.0; + int roinWStart = std::max(0,row-PeakRadius); + int rowend = std::min(RDet->ypixels()-1,row+PeakRadius); + double colcentroid = 0.0; + int colstart = std::max(0,col-PeakRadius); + int colend = std::min(RDet->xpixels()-1,col+PeakRadius); + for (int ichan=chanstart; ichan<=chanend; ++ichan) + { + for (int irow=roinWStart; irow<=rowend; ++irow) + { + for (int icol=colstart; icol<=colend; ++icol) + { + boost::shared_ptr<Detector> pixel = RDet->getAtXY(icol, irow); + Mantid::detid2index_map::iterator it; + it = (*wi_to_detid_map).find(pixel->getID()); + size_t workspaceIndex = (it->second); + + Mantid::MantidVec X = inWS->readX(workspaceIndex); + Mantid::MantidVec histogram = inWS->readY(workspaceIndex); + + intensity += histogram[ichan]; + rowcentroid += irow*histogram[ichan]; + colcentroid += icol*histogram[ichan]; + chancentroid += ichan*histogram[ichan]; + } + } + } + // Set pixelID to change row and col + row = std::min(RDet->ypixels()-1,int(rowcentroid/intensity)); + row = std::max(0,row); + col = std::min(RDet->xpixels()-1,int(colcentroid/intensity)); + col = std::max(0,col); + pixel = RDet->getAtXY(col, row); + peak.setDetectorID(pixel->getID()); + // Set wavelength to change tof for peak object + it = (*wi_to_detid_map).find(pixel->getID()); + workspaceIndex = (it->second); + + X = inWS->readX(workspaceIndex); + histogram = inWS->readY(workspaceIndex); + + chan = int(chancentroid/intensity); + chan = std::max(0,chan); + chan = std::min(static_cast<int>(X.size()),chan); + Mantid::Kernel::Units::Wavelength wl; + std::vector<double> timeflight; + timeflight.push_back(X[chan]); + double scattering = peak.getScattering(); + double L1 = peak.getL1(); + double L2 = peak.getL2(); + wl.fromTOF(timeflight, timeflight, L1, L2, scattering, 0, 0, 0); + const double lambda = timeflight[0]; + timeflight.clear(); + + peak.setWavelength(lambda); + peak.setBinCount(histogram[chan]); + PARALLEL_END_INTERUPT_REGION + } + PARALLEL_CHECK_INTERUPT_REGION + + for (int i= int(peakWS->getNumberPeaks())-1; i>=0; --i) + { + // Get a direct ref to that peak. + IPeak & peak = peakWS->getPeak(i); + int col = peak.getCol(); + int row = peak.getRow(); + Geometry::Instrument_const_sptr Iptr = peak.getInstrument(); + std::string bankName = peak.getBankName(); + + boost::shared_ptr<const IComponent> parent = Iptr->getComponentByName(bankName); + + if (parent->type().compare("RectangularDetector") != 0) + { + + std::cout<<" getPanel C type="<<parent->type()<<std::endl; + throw std::runtime_error("Improper Peak Argument"); + } + boost::shared_ptr<const RectangularDetector> RDet = boost::shared_dynamic_cast< + const RectangularDetector>(parent); + int Edge = getProperty("EdgePixels"); + if (col < Edge || col > (RDet->xpixels()-Edge) || row < Edge || row > (RDet->ypixels()-Edge)) + { + peakWS->removePeak(i); + } + } + // Save the output + setProperty("OutPeaksWorkspace", peakWS); + + } + + //---------------------------------------------------------------------------------------------- + /** Integrate the peaks of the workspace using parameters saved in the algorithm class + * @param inWS :: 2D Workspace to integrate + */ + void CentroidPeaks::integrateEvent() + { + + /// Peak workspace to centroid + Mantid::DataObjects::PeaksWorkspace_sptr inPeakWS = getProperty("InPeaksWorkspace"); + + /// Output peaks workspace, create if needed + Mantid::DataObjects::PeaksWorkspace_sptr peakWS = getProperty("OutPeaksWorkspace"); + if (peakWS != inPeakWS) + peakWS = inPeakWS->clone(); + + + /// Radius to use around peaks + int PeakRadius = getProperty("PeakRadius"); + + PARALLEL_FOR2(inWS,peakWS) + for (int i=0; i < int(peakWS->getNumberPeaks()); ++i) + { + PARALLEL_START_INTERUPT_REGION + // Get a direct ref to that peak. + IPeak & peak = peakWS->getPeak(i); + int col = peak.getCol(); + int row = peak.getRow(); + double TOFPeakd = peak.getTOF(); + Geometry::Instrument_const_sptr Iptr = peak.getInstrument(); + std::string bankName = peak.getBankName(); + + boost::shared_ptr<const IComponent> parent = Iptr->getComponentByName(bankName); + + if (parent->type().compare("RectangularDetector") != 0) + { + + std::cout<<" getPanel C type="<<parent->type()<<std::endl; + throw std::runtime_error("Improper Peak Argument"); + } + boost::shared_ptr<const RectangularDetector> RDet = boost::shared_dynamic_cast< + const RectangularDetector>(parent); + double intensity = 0.0; + double chancentroid = 0.0; + boost::shared_ptr<Detector> pixel = RDet->getAtXY(col, row); + Mantid::detid2index_map::iterator it; + it = (*wi_to_detid_map).find(pixel->getID()); + size_t workspaceIndex = (it->second); + + Mantid::MantidVec X = inWS->readX(workspaceIndex); + Mantid::MantidVec histogram = inWS->readY(workspaceIndex); + + int chan = Kernel::VectorHelper::getBinIndex(X, TOFPeakd); + int chanstart = std::max(0,chan-PeakRadius); + int chanend = std::min(static_cast<int>(X.size()),chan+PeakRadius); + double rowcentroid = 0.0; + int roinWStart = std::max(0,row-PeakRadius); + int rowend = std::min(RDet->ypixels()-1,row+PeakRadius); + double colcentroid = 0.0; + int colstart = std::max(0,col-PeakRadius); + int colend = std::min(RDet->xpixels()-1,col+PeakRadius); + for (int ichan=chanstart; ichan<=chanend; ++ichan) + { + for (int irow=roinWStart; irow<=rowend; ++irow) + { + for (int icol=colstart; icol<=colend; ++icol) + { + boost::shared_ptr<Detector> pixel = RDet->getAtXY(icol, irow); + Mantid::detid2index_map::iterator it; + it = (*wi_to_detid_map).find(pixel->getID()); + size_t workspaceIndex = (it->second); + + Mantid::MantidVec X = inWS->readX(workspaceIndex); + Mantid::MantidVec histogram = inWS->readY(workspaceIndex); + + intensity += histogram[ichan]; + rowcentroid += irow*histogram[ichan]; + colcentroid += icol*histogram[ichan]; + chancentroid += ichan*histogram[ichan]; + } + } + } + // Set pixelID to change row and col + row = std::min(RDet->ypixels()-1,int(rowcentroid/intensity)); + row = std::max(0,row); + col = std::min(RDet->xpixels()-1,int(colcentroid/intensity)); + col = std::max(0,col); + pixel = RDet->getAtXY(col, row); + peak.setDetectorID(pixel->getID()); + // Set wavelength to change tof for peak object + it = (*wi_to_detid_map).find(pixel->getID()); + workspaceIndex = (it->second); + + X = inWS->readX(workspaceIndex); + histogram = inWS->readY(workspaceIndex); + + chan = int(chancentroid/intensity); + chan = std::max(0,chan); + chan = std::min(static_cast<int>(X.size()),chan); + Mantid::Kernel::Units::Wavelength wl; + std::vector<double> timeflight; + timeflight.push_back(X[chan]); + double scattering = peak.getScattering(); + double L1 = peak.getL1(); + double L2 = peak.getL2(); + wl.fromTOF(timeflight, timeflight, L1, L2, scattering, 0, 0, 0); + const double lambda = timeflight[0]; + timeflight.clear(); + + peak.setWavelength(lambda); + peak.setBinCount(histogram[chan]); + PARALLEL_END_INTERUPT_REGION + } + PARALLEL_CHECK_INTERUPT_REGION + + for (int i= int(peakWS->getNumberPeaks())-1; i>=0; --i) + { + // Get a direct ref to that peak. + IPeak & peak = peakWS->getPeak(i); + int col = peak.getCol(); + int row = peak.getRow(); + Geometry::Instrument_const_sptr Iptr = peak.getInstrument(); + std::string bankName = peak.getBankName(); + + boost::shared_ptr<const IComponent> parent = Iptr->getComponentByName(bankName); + + if (parent->type().compare("RectangularDetector") != 0) + { + + std::cout<<" getPanel C type="<<parent->type()<<std::endl; + throw std::runtime_error("Improper Peak Argument"); + } + boost::shared_ptr<const RectangularDetector> RDet = boost::shared_dynamic_cast< + const RectangularDetector>(parent); + int Edge = getProperty("EdgePixels"); + if (col < Edge || col > (RDet->xpixels()-Edge) || row < Edge || row > (RDet->ypixels()-Edge)) + { + peakWS->removePeak(i); + } + } + // Save the output + setProperty("OutPeaksWorkspace", peakWS); + + } + + //---------------------------------------------------------------------------------------------- + /** Execute the algorithm. + */ + void CentroidPeaks::exec() + { + inWS = getProperty("InputWorkspace"); + + // For quickly looking up workspace index from det id + wi_to_detid_map = inWS->getDetectorIDToWorkspaceIndexMap(true); + + eventW = boost::dynamic_pointer_cast<EventWorkspace>( inWS ); + if(eventW) + { + eventW->sortAll(TOF_SORT, NULL); + this->integrateEvent(); + } + else + { + this->integrate(); + } + } + +} // namespace Mantid +} // namespace Crystal diff --git a/Code/Mantid/Framework/DataHandling/src/LoadEventNexus.cpp b/Code/Mantid/Framework/DataHandling/src/LoadEventNexus.cpp index 4872f48853fc8ff48b8d5eb238974d9d19a7ff0f..a58f19546629184f9d6de2be08bf9726ef725ad7 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadEventNexus.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadEventNexus.cpp @@ -1094,7 +1094,8 @@ void LoadEventNexus::loadEvents(API::Progress * const prog, const bool monitors) } //Info reporting - g_log.information() << "Read " << WS->getNumberEvents() << " events" + const std::size_t eventsLoaded = WS->getNumberEvents(); + g_log.information() << "Read " << eventsLoaded << " events" << ". Shortest TOF: " << shortest_tof << " microsec; longest TOF: " << longest_tof << " microsec." << std::endl; @@ -1105,9 +1106,12 @@ void LoadEventNexus::loadEvents(API::Progress * const prog, const bool monitors) //Now, create a default X-vector for histogramming, with just 2 bins. Kernel::cow_ptr<MantidVec> axis; MantidVec& xRef = axis.access(); - xRef.resize(2); - xRef[0] = shortest_tof - 1; //Just to make sure the bins hold it all - xRef[1] = longest_tof + 1; + xRef.resize(2,0.0); + if ( eventsLoaded > 0) + { + xRef[0] = shortest_tof - 1; //Just to make sure the bins hold it all + xRef[1] = longest_tof + 1; + } //Set the binning axis using this. WS->setAllX(axis); @@ -1221,7 +1225,7 @@ bool LoadEventNexus::runLoadInstrument(const std::string &nexusfilename, MatrixW instrument = nxfile.getStrData(); alg->getLogger().debug() << "Instrument name read from NeXus file is " << instrument << std::endl; } - catch ( ::NeXus::Exception & e) + catch ( ::NeXus::Exception &) { // Get the instrument name from the file instead size_t n = nexusfilename.rfind('/'); diff --git a/Code/Mantid/Framework/DataHandling/src/LoadMaskingFile.cpp b/Code/Mantid/Framework/DataHandling/src/LoadMaskingFile.cpp index fa6ba46107902759cd36055446106613a62f2657..ae017111307ecbc60d7b52e0d6ad175af61414ba 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadMaskingFile.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadMaskingFile.cpp @@ -363,8 +363,10 @@ namespace DataHandling */ void LoadMaskingFile::initializeXMLParser(const std::string & filename) { - // const std::string instName; + // const std::string instName + std::cout << "Load File " << filename << std::endl; const std::string xmlText = Kernel::Strings::loadFile(filename); + std::cout << "Successfully Load XML File " << std::endl; // Set up the DOM parser and parse xml file DOMParser pParser; diff --git a/Code/Mantid/Framework/DataHandling/src/LoadNexusLogs.cpp b/Code/Mantid/Framework/DataHandling/src/LoadNexusLogs.cpp index 86cb079cc672fb99fb5357ec02b68335efa065cd..018fddb975f60ce8ed4a01a115254a39bc9b2b69 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadNexusLogs.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadNexusLogs.cpp @@ -135,7 +135,7 @@ namespace Mantid file.openPath("/" + entry_name + "/" + eventEntry + "/event_frame_number"); file.getData(event_frame_number); } - catch(const ::NeXus::Exception& exc) + catch(const ::NeXus::Exception&) { this->getLogger().warning() << "Unable to load event_frame_number - filtering events by time will not work " << std::endl; } diff --git a/Code/Mantid/Framework/DataHandling/src/SaveToSNSHistogramNexus.cpp b/Code/Mantid/Framework/DataHandling/src/SaveToSNSHistogramNexus.cpp index 0c19c55871f704e689f33600ede682dc3d8cc0a9..6048e30c20d2319b8eb439564bdacccf11dbb015 100644 --- a/Code/Mantid/Framework/DataHandling/src/SaveToSNSHistogramNexus.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SaveToSNSHistogramNexus.cpp @@ -41,6 +41,8 @@ In addition, this only works for instruments that use [[RectangularDetector]]s ( #include <string.h> #include <time.h> + + namespace Mantid { namespace DataHandling @@ -471,7 +473,7 @@ namespace DataHandling // Give a 50% margin of error in allocating the memory memory_available = memory_available/2; - if (memory_available > 5e9) memory_available = 5e9; + if (memory_available > (size_t)5e9) memory_available = (size_t)5e9; if (memory_available < memory_required) { diff --git a/Code/Mantid/Framework/DataHandling/test/CreateSampleShapeTest.h b/Code/Mantid/Framework/DataHandling/test/CreateSampleShapeTest.h index 667e509e62b58d7bdc243a1d20c99e196fe9e401..5af69e44629f78f54bea013cd1b3d93a5836463f 100644 --- a/Code/Mantid/Framework/DataHandling/test/CreateSampleShapeTest.h +++ b/Code/Mantid/Framework/DataHandling/test/CreateSampleShapeTest.h @@ -79,11 +79,11 @@ public: if( inside ) { - TS_ASSERT_EQUALS( sample.isValid(point), 1); + TS_ASSERT_EQUALS( sample.isValid(point), true); } else { - TS_ASSERT_EQUALS( sample.isValid(point), 0); + TS_ASSERT_EQUALS( sample.isValid(point), false); } TS_ASSERT_THROWS_NOTHING( Mantid::API::AnalysisDataService::Instance().remove("TestWorkspace") ); diff --git a/Code/Mantid/Framework/DataHandling/test/LoadEventNexusTest.h b/Code/Mantid/Framework/DataHandling/test/LoadEventNexusTest.h index 05b4d593ebe20015d1e508ce80740f6afa190324..50df523abbc6fa4c9a08f97c5c7e0c6663f2a47f 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadEventNexusTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadEventNexusTest.h @@ -362,6 +362,22 @@ public: }; +//------------------------------------------------------------------------------ +// Performance test +//------------------------------------------------------------------------------ + +class LoadEventNexusTestPerformance : public CxxTest::TestSuite +{ +public: + void testDefaultLoad() + { + LoadEventNexus loader; + loader.initialize(); + loader.setPropertyValue("Filename", "CNCS_7860_event.nxs"); + loader.setPropertyValue("OutputWorkspace", "ws"); + TS_ASSERT( loader.execute() ); + } +}; #endif /*LOADEVENTNEXUSTEST_H_*/ diff --git a/Code/Mantid/Framework/DataHandling/test/LoadEventPreNexusTest.h b/Code/Mantid/Framework/DataHandling/test/LoadEventPreNexusTest.h index ae4c58975c89a58b2eef79d7c5dbd946c03f01db..d23303a8a27d952dd22e30fe46b6948968cc889d 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadEventPreNexusTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadEventPreNexusTest.h @@ -293,7 +293,7 @@ public: EventWorkspace_sptr chunk1 = boost::dynamic_pointer_cast<EventWorkspace> (AnalysisDataService::Instance().retrieve("chunk1")); - // Load chunk 2 of 10 + // Load chunk 2 of 2 eventLoader->setPropertyValue("EventFilename", "CNCS_7860_neutron_event.dat"); eventLoader->setPropertyValue("ChunkNumber","2"); eventLoader->setPropertyValue("TotalChunks","2"); @@ -309,5 +309,22 @@ public: }; +//------------------------------------------------------------------------------ +// Performance test +//------------------------------------------------------------------------------ + +class LoadEventPreNexusTestPerformance : public CxxTest::TestSuite +{ +public: + void testDefaultLoad() + { + LoadEventPreNexus loader; + loader.initialize(); + loader.setPropertyValue("EventFilename", "CNCS_7860_neutron_event.dat"); + loader.setPropertyValue("OutputWorkspace", "ws"); + TS_ASSERT( loader.execute() ); + } +}; + #endif /* LOADEVENTPRENEXUSTEST_H_ */ diff --git a/Code/Mantid/Framework/DataHandling/test/LoadISISNexusTest.h b/Code/Mantid/Framework/DataHandling/test/LoadISISNexusTest.h index 3540831d564b1854be3c42cc9b9119d7e2b85380..415771469362c660445e27aee26eeb306931cd9e 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadISISNexusTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadISISNexusTest.h @@ -179,4 +179,21 @@ public: } }; +//------------------------------------------------------------------------------ +// Performance test +//------------------------------------------------------------------------------ + +class LoadISISNexusTestPerformance : public CxxTest::TestSuite +{ +public: + void testDefaultLoad() + { + LoadISISNexus2 loader; + loader.initialize(); + loader.setPropertyValue("Filename", "LOQ49886.nxs"); + loader.setPropertyValue("OutputWorkspace", "ws"); + TS_ASSERT( loader.execute() ); + } +}; + #endif /*LOADISISNEXUSTEST_H_*/ diff --git a/Code/Mantid/Framework/DataHandling/test/LoadMaskingFileTest.h b/Code/Mantid/Framework/DataHandling/test/LoadMaskingFileTest.h index e89456feca3c091194cea2851156033157791a77..67536037a3046091ff32cab0577c16997c309c5e 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadMaskingFileTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadMaskingFileTest.h @@ -8,6 +8,7 @@ #include <iomanip> #include "MantidDataHandling/LoadMaskingFile.h" +#include "MantidDataObjects/SpecialWorkspace2D.h" using namespace Mantid; using namespace Mantid::DataHandling; @@ -22,10 +23,80 @@ public: static void destroySuite( LoadMaskingFileTest *suite ) { delete suite; } - void test_Something() + void test_LoadXML() { - } + LoadMaskingFile loadfile; + loadfile.initialize(); + loadfile.setProperty("Instrument", "POWGEN"); + loadfile.setProperty("InputFile", "testmasking.xml"); + loadfile.setProperty("OutputWorkspace", "PG3Mask"); + + try + { + TS_ASSERT_EQUALS(loadfile.execute(), true); + DataObjects::SpecialWorkspace2D_sptr maskws = + boost::dynamic_pointer_cast<DataObjects::SpecialWorkspace2D>(AnalysisDataService::Instance().retrieve("PG3Mask")); + } + catch(std::runtime_error e) + { + TS_FAIL(e.what()); + } + } // test_LoadXML + + void test_BinaryOperation() + { + // 1. Generate Mask Workspace + LoadMaskingFile loadfile; + loadfile.initialize(); + + loadfile.setProperty("Instrument", "POWGEN"); + loadfile.setProperty("InputFile", "testmasking.xml"); + loadfile.setProperty("OutputWorkspace", "PG3Mask"); + + TS_ASSERT_EQUALS(loadfile.execute(),true); + DataObjects::SpecialWorkspace2D_sptr maskws = + boost::dynamic_pointer_cast<DataObjects::SpecialWorkspace2D>(AnalysisDataService::Instance().retrieve("PG3Mask")); + + // 2. Generate Region of Interest Workspace + LoadMaskingFile loadfile2; + loadfile2.initialize(); + + loadfile2.setProperty("Instrument", "POWGEN"); + loadfile2.setProperty("InputFile", "regionofinterest.xml"); + loadfile2.setProperty("OutputWorkspace", "PG3Interest"); + + TS_ASSERT_EQUALS(loadfile2.execute(), true); + DataObjects::SpecialWorkspace2D_sptr interestws = + boost::dynamic_pointer_cast<DataObjects::SpecialWorkspace2D>(AnalysisDataService::Instance().retrieve("PG3Interest")); + + // 3. Check + size_t sizemask = maskws->getNumberHistograms(); + size_t sizeinterest = interestws->getNumberHistograms(); + TS_ASSERT_EQUALS(sizemask==sizeinterest, true); + + if (sizemask == sizeinterest){ + size_t number1 = 0; + size_t number0 = 0; + for (size_t ih = 0; ih < maskws->getNumberHistograms(); ih ++){ + double v1 = maskws->dataY(ih)[0]; + double v2 = interestws->dataY(ih)[0]; + if (v1 < 0.5){ + number0 ++; + } + if (v2 > 0.5){ + number1 ++; + } + TS_ASSERT_EQUALS(v1+v2<1.5, true); + TS_ASSERT_EQUALS(v1+v2>0.5, true); + } + + TS_ASSERT_EQUALS(number0 > 0, true); + TS_ASSERT_EQUALS(number1 > 0, true); + TS_ASSERT_EQUALS(number1-number0, 0); + } + + } // test_Openfile }; diff --git a/Code/Mantid/Framework/DataHandling/test/LoadMuonNexus2Test.h b/Code/Mantid/Framework/DataHandling/test/LoadMuonNexus2Test.h index 4dd5e9ee79060f2b92d9bbaa213492b02999ac64..56df0e8e4523aec9cb6ff62d097c931e469373e6 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadMuonNexus2Test.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadMuonNexus2Test.h @@ -448,4 +448,22 @@ public: } }; + +//------------------------------------------------------------------------------ +// Performance test +//------------------------------------------------------------------------------ + +class LoadMuonNexus2TestPerformance : public CxxTest::TestSuite +{ +public: + void testDefaultLoad() + { + LoadMuonNexus2 loader; + loader.initialize(); + loader.setPropertyValue("Filename", "emu00006475.nxs"); + loader.setPropertyValue("OutputWorkspace", "ws"); + TS_ASSERT( loader.execute() ); + } +}; + #endif /*LOADMUONNEXUS2TEST_H_*/ diff --git a/Code/Mantid/Framework/DataHandling/test/LoadNexusProcessedTest.h b/Code/Mantid/Framework/DataHandling/test/LoadNexusProcessedTest.h index d63149c10f5464b49f788fa099cdafde8cd691d3..9177f8b72d107bc7b714c5fc9a2154246e0d16d0 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadNexusProcessedTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadNexusProcessedTest.h @@ -448,4 +448,21 @@ private: std::string testFile, output_ws; }; +//------------------------------------------------------------------------------ +// Performance test +//------------------------------------------------------------------------------ + +class LoadNexusProcessedTestPerformance : public CxxTest::TestSuite +{ +public: + void testHistogramWorkspace() + { + LoadNexusProcessed loader; + loader.initialize(); + loader.setPropertyValue("Filename", "PG3_733_focussed.nxs"); + loader.setPropertyValue("OutputWorkspace", "ws"); + TS_ASSERT( loader.execute() ); + } +}; + #endif /*LOADNEXUSPROCESSEDTESTRAW_H_*/ diff --git a/Code/Mantid/Framework/DataHandling/test/LoadRaw3Test.h b/Code/Mantid/Framework/DataHandling/test/LoadRaw3Test.h index 9237e855fa77ab4839320a2862c26a2530791dd7..83be0ba6b775051c503287bcca1da75fabd26d4e 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadRaw3Test.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadRaw3Test.h @@ -869,4 +869,23 @@ private: std::string outputSpace; }; +//------------------------------------------------------------------------------ +// Performance test +//------------------------------------------------------------------------------ + +class LoadRaw3TestPerformance : public CxxTest::TestSuite +{ +public: + void testDefaultLoad() + { + LoadRaw3 loader; + loader.initialize(); + loader.setPropertyValue("Filename", "HET15869.raw"); + loader.setPropertyValue("OutputWorkspace", "ws"); + TS_ASSERT( loader.execute() ); + } +}; + + + #endif /*LoadRaw3TEST_H_*/ diff --git a/Code/Mantid/Framework/DataHandling/test/LoadTOFRawNexusTest.h b/Code/Mantid/Framework/DataHandling/test/LoadTOFRawNexusTest.h index ab7021b6c25b47834d75d1dd2775baf7b8cc7efe..16f15f0fdf2c9b0787794f6dea2975d0c16d6e26 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadTOFRawNexusTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadTOFRawNexusTest.h @@ -244,4 +244,21 @@ public: }; }; +//------------------------------------------------------------------------------ +// Performance test +//------------------------------------------------------------------------------ + +class LoadTOFRawNexusTestPerformance : public CxxTest::TestSuite +{ +public: + void testDefaultLoad() + { + LoadTOFRawNexus loader; + loader.initialize(); + loader.setPropertyValue("Filename", "REF_L_32035.nxs"); + loader.setPropertyValue("OutputWorkspace", "ws"); + TS_ASSERT( loader.execute() ); + } +}; + #endif /*LOADTOFRAWNEXUSTEST_H_*/ diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/Peak.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/Peak.h index c13a3c8e9f77e91af3f22906ff93e0236960f216..ea7728618b69d9c3eedb6cc182efe0c45b781b6c 100644 --- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/Peak.h +++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/Peak.h @@ -67,6 +67,7 @@ namespace DataObjects void setWavelength(double wavelength); double getWavelength() const; + double getScattering() const; double getDSpacing() const; double getTOF() const; diff --git a/Code/Mantid/Framework/DataObjects/src/CompressedWorkspace2D.cpp b/Code/Mantid/Framework/DataObjects/src/CompressedWorkspace2D.cpp index b0c969809912757e415abeb11744c66e82e1cd1d..17f1d69fc386111a6cc7b575ba437b08d3be38a4 100644 --- a/Code/Mantid/Framework/DataObjects/src/CompressedWorkspace2D.cpp +++ b/Code/Mantid/Framework/DataObjects/src/CompressedWorkspace2D.cpp @@ -156,9 +156,9 @@ CompressedWorkspace2D::CompressedPointer CompressedWorkspace2D::compressBlock(Ma j += m_YLength; } - uLongf nBuff = m_outBuffer.size(); + uLongf nBuff = static_cast<uLongf>(m_outBuffer.size()); - compress2(&m_outBuffer[0],&nBuff,reinterpret_cast<Bytef*>(&m_inBuffer[0]),m_vectorSize*m_vectorsPerBlock,1); + compress2(&m_outBuffer[0],&nBuff,reinterpret_cast<Bytef*>(&m_inBuffer[0]),static_cast<uLong>(m_vectorSize*m_vectorsPerBlock),1); Bytef* tmp = new Bytef[nBuff]; memcpy(tmp,&m_outBuffer[0],nBuff); @@ -172,10 +172,9 @@ CompressedWorkspace2D::CompressedPointer CompressedWorkspace2D::compressBlock(Ma */ void CompressedWorkspace2D::uncompressBlock(ManagedDataBlock2D* block,size_t startIndex)const { - //std::cerr<<"uncompress "<<startIndex<<'\n'; - uLongf nBuff = m_outBuffer.size(); + uLongf nBuff = static_cast<uLongf>(m_outBuffer.size()); CompressedPointer p = m_compressedData[startIndex]; - int status = uncompress (&m_outBuffer[0], &nBuff, p.first, p.second); + int status = uncompress (&m_outBuffer[0], &nBuff, p.first, static_cast<uLong>(p.second)); if (status == Z_MEM_ERROR) throw std::runtime_error("There is not enough memory to complete the uncompress operation."); diff --git a/Code/Mantid/Framework/DataObjects/src/Peak.cpp b/Code/Mantid/Framework/DataObjects/src/Peak.cpp index 322db67af2c6f5deb727724b5c833b5438eb194a..fcb1bdc4c24a7ececf6d616fb4eb8d66b0c458d9 100644 --- a/Code/Mantid/Framework/DataObjects/src/Peak.cpp +++ b/Code/Mantid/Framework/DataObjects/src/Peak.cpp @@ -314,6 +314,17 @@ namespace DataObjects return tof * 1e6; } + // ------------------------------------------------------------------------------------- + /** Calculate the scattering angle of the peak */ + double Peak::getScattering() const + { + // The detector is at 2 theta scattering angle + V3D beamDir = samplePos - sourcePos; + V3D detDir = detPos - samplePos; + + return detDir.angle(beamDir); + } + // ------------------------------------------------------------------------------------- /** Calculate the d-spacing of the peak, in 1/Angstroms */ double Peak::getDSpacing() const diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h index 5c66af557966f744c2964fcbd3bdd61ed57b017a..beb88a4dd30df54ccc413ca37259e4e8286a19a3 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h @@ -65,6 +65,9 @@ namespace Geometry /// get name of location element static std::string getNameOfLocationElement(Poco::XML::Element* pElem); + /// Save DOM tree to xml file + void saveDOM_Tree(std::string& outFilename); + private: /// Static reference to the logger class static Kernel::Logger& g_log; diff --git a/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp b/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp index 9a93c91809b83a8847ffb1e38ba781a96b215ec0..2f94d61534bb2c1edd88061e247ae2757fb44939 100644 --- a/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp +++ b/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp @@ -21,6 +21,7 @@ #include <iostream> #include <Poco/DOM/Document.h> #include <Poco/DOM/DOMParser.h> +#include <Poco/DOM/DOMWriter.h> #include <Poco/DOM/Element.h> #include <Poco/DOM/NodeFilter.h> #include <Poco/DOM/NodeIterator.h> @@ -341,7 +342,24 @@ namespace Geometry return m_instrument; } + //----------------------------------------------------------------------------------------------------------------------- + /** Save DOM tree to xml file. This method was initially added for testing purpose + * but may be useful for other purposes. During the parsing of the DOM tree + * in parseXML() the tree may be modified, e.g. if <combine-components-into-one-shape> + * is used. + * + * @param outFilename :: Output filename + */ + void InstrumentDefinitionParser::saveDOM_Tree(std::string& outFilename) + { + Poco::XML::DOMWriter writer; + writer.setNewLine("\n"); + writer.setOptions(Poco::XML::XMLWriter::PRETTY_PRINT); + std::ofstream outFile(outFilename.c_str()); + writer.writeNode(outFile, pDoc); + outFile.close(); + } //----------------------------------------------------------------------------------------------------------------------- /** Set location (position) of comp as specified in XML location element. diff --git a/Code/Mantid/Framework/Kernel/CMakeLists.txt b/Code/Mantid/Framework/Kernel/CMakeLists.txt index 87227b4793bc7e2a333baff3247406a7d052f594..9c8ca56828aac803d6bcf3045164cac708b684bf 100644 --- a/Code/Mantid/Framework/Kernel/CMakeLists.txt +++ b/Code/Mantid/Framework/Kernel/CMakeLists.txt @@ -1,6 +1,7 @@ set ( SRC_FILES src/ANN_complete.cpp src/ArrayBoundedValidator.cpp + src/ArrayLengthValidator.cpp src/ArrayProperty.cpp src/Atom.cpp src/BinFinder.cpp @@ -91,6 +92,7 @@ set ( INC_FILES inc/MantidKernel/ANN/ANNperf.h inc/MantidKernel/ANN/ANNx.h inc/MantidKernel/ArrayBoundedValidator.h + inc/MantidKernel/ArrayLengthValidator.h inc/MantidKernel/ArrayProperty.h inc/MantidKernel/Atom.h inc/MantidKernel/BinFinder.h @@ -183,11 +185,13 @@ set ( INC_FILES inc/MantidKernel/VectorHelper.h inc/MantidKernel/VisibleWhenProperty.h inc/MantidKernel/cow_ptr.h - inc/MantidKernel/ValidatorSignalChange.h + inc/MantidKernel/ValidatorSignalChange.h + inc/MantidKernel/ValidatorAnyList.h ) set ( TEST_FILES test/ArrayBoundedValidatorTest.h + test/ArrayLengthValidatorTest.h test/ArrayPropertyTest.h test/AtomTest.h test/BinFinderTest.h @@ -256,9 +260,10 @@ set ( TEST_FILES test/V2DTest.h test/V3DTest.h test/VMDTest.h + test/ValidatorSignalChangeTest.h test/VectorHelperTest.h test/VisibleWhenPropertyTest.h - test/ValidatorSignalChangeTest.h + test/ValidatorAnyListTest.h ) if(UNITY_BUILD) diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ArrayLengthValidator.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ArrayLengthValidator.h new file mode 100644 index 0000000000000000000000000000000000000000..2a903bd4c5dc645a6a37e9f3cc00a9493bafe503 --- /dev/null +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ArrayLengthValidator.h @@ -0,0 +1,66 @@ +#ifndef MANTID_KERNEL_ARRAYLENGTHVALIDATOR_H_ +#define MANTID_KERNEL_ARRAYLENGTHVALIDATOR_H_ + +#include "MantidKernel/IValidator.h" +#include <vector> + + +namespace Mantid +{ +namespace Kernel +{ + + /** ArrayLenghtValidator : Validate lenghth of an array property + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + template <typename TYPE> + class MANTID_KERNEL_DLL ArrayLengthValidator: public IValidator<std::vector<TYPE> > + { + public: + ArrayLengthValidator(); + ArrayLengthValidator(const size_t len); + virtual ~ArrayLengthValidator(); + + IValidator<std::vector<TYPE> >* clone(); + + std::string isValid(const std::vector<TYPE> &value) const; + + /// Return if it has a length + bool hasLength() const; + /// Return the legth + const size_t& getLength() const; + /// Set lower bound value + void setLength( const size_t& value ); + /// Clear the length + void clearLength(); + + private: + std::string checkValidity( const std::vector<TYPE> &value ) const; + size_t m_arraySize; + bool m_hasArraySize; + }; + + +} // namespace Kernel +} // namespace Mantid + +#endif /* MANTID_KERNEL_ARRAYLENGTHVALIDATOR_H_ */ diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/CompositeValidator.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/CompositeValidator.h index 7601e98e537df1aa9de3e1a709422a0e7be1652c..dc148ef3c7a3c99e29f37f323e1f9d4abaaecc8b 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/CompositeValidator.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/CompositeValidator.h @@ -111,6 +111,10 @@ namespace Kernel m_children.push_back(child); } + virtual void modify_validator(IValidator<TYPE> *pNewValidator) + { + UNUSED_ARG(pNewValidator); + } private: /// Private Copy constructor: NO DIRECT COPY ALLOWED CompositeValidator(const CompositeValidator&); diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/EnabledWhenProperty.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/EnabledWhenProperty.h index 74bf83904e0e77d342c24a196664e758899901af..dd0b95b00bce2f27cd93fa8462c8ce88aa99d4ee 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/EnabledWhenProperty.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/EnabledWhenProperty.h @@ -145,7 +145,8 @@ namespace Kernel { return true; } - + /// does nothing in this case and put here to satisfy the interface. + void modify_allowed_values(Property * const){} //-------------------------------------------------------------------------------------------- /// Make a copy of the present type of validator virtual IPropertySettings * clone() diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/IPropertySettings.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/IPropertySettings.h index d1a3d07db43102c7b2638ff14de896a7a810069e..fd95ca39938dc342456347dc2aee5cc9e0856063 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/IPropertySettings.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/IPropertySettings.h @@ -11,6 +11,7 @@ namespace Kernel // Forward Declaration //---------------------------------------------------------------------- class IPropertyManager; +class Property; /** Interface for modifiers to Property's that specify * if they should be enabled or in a GUI. @@ -61,7 +62,24 @@ class IPropertyManager; /** Is the property to be shown in the GUI? Default true. */ virtual bool isVisible() const { return true; } - + /** to verify if the properties, this one depends on have changed + or other special condition occurs which needs the framework to react to */ + virtual bool isConditionChanged()const + {return false;} + /** The function user have to overload it in his custom code to modify the property + according to the changes to other properties. + * + * Currently it has been tested to modify the property values as function of other properties + * + * Allowed property valies are obtrained from property's allowedValues function, and the purpose the + * function interfaced here is to modify its output. + * + * allowedValues function on propertyWithValue class obtains its data from a validator, so in the case of + * simple PropertyWithValue, this function has to replace the validator. + * For WorkspaceProperty, which obtains its values from dataservice and filters them by validators, + * a new validator has to be a new filter */ + virtual void applyChanges(Property * const){}; + //------------------------------------------------------------------------------------------------------------ /** Set the property manager (i.e. algorithm) containing the other properties to use to validate * @param propertyManager :: pointer */ @@ -78,7 +96,9 @@ class IPropertyManager; /** Pointer to the property manager (i.e. algorithm) containing the other properties to use to validate */ const IPropertyManager * m_propertyManager; - + private: + // non-copyable directly + IPropertySettings(const IPropertySettings &){} }; diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/IValidator.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/IValidator.h index 94d0b6439251f76d522455e2b631f5ea24105e57..0b7f95981baf5ff79cbe8af11aa9fbeac6d12969 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/IValidator.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/IValidator.h @@ -71,6 +71,7 @@ public: /// Make a copy of the present type of validator virtual IValidator* clone() = 0; + protected: /** Checks the value based on the validator's rules * diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ListValidator.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ListValidator.h index 4e2c5cd1456bd664591c895d17255367fc3acbeb..b52ee901db4afb398285b842442375f59717ffb9 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ListValidator.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ListValidator.h @@ -6,6 +6,7 @@ //---------------------------------------------------------------------- #include "IValidator.h" #include <vector> +#include <set> namespace Mantid { diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Property.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Property.h index ed85c1acacb5b1d63ab1cf1f575085babcc8d328..561f4ad2777cc7ff7a8091d5e5bd0a9a1b9068a4 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Property.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Property.h @@ -115,6 +115,12 @@ public: if (m_settings) return m_settings->isVisible(); else return true; } + /// function reports if the property limits have changed and property widgets have to be reset in GUI + virtual bool isConditionChanged()const + { + if(m_settings) return m_settings->isConditionChanged(); + else return false; + } /** Set the PropertySettings determining when this property is visible/enabled */ void setSettings(IPropertySettings * settings) diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h index 8f66d3fa5a6dbd7c59b48ebae07fe6b2ef6efff7..feb4d3d74dfc375bb91d1783c8a4ea810e76fce4 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h @@ -10,12 +10,14 @@ #include "MantidKernel/Logger.h" #include "MantidKernel/IValidator.h" #include "MantidKernel/NullValidator.h" +#include "MantidKernel/CompositeValidator.h" #include <boost/lexical_cast.hpp> #include <boost/shared_ptr.hpp> #include <Poco/StringTokenizer.h> #include <vector> #include "MantidKernel/IPropertySettings.h" + namespace Mantid { @@ -417,7 +419,42 @@ public: { return m_validator->allowedValues(); } - + /** function modyfies validator e.g. replaces it by the new one if the old and new validator types are equivalent. + * + * if existing validator is a composite validator, it looks through all memeber validators and replaces the first, + * which has the same type as the new. + * if the validator types are different, a composite validator consising of old and new validator is created + *@param *pNewValidator -- new validator + *@param just_replace -- if set to true, the old validator is just replaced by the new one regardless of their types. + */ + virtual void modify_validator(IValidator<TYPE> *pNewValidator,bool just_replace=false) + { + // temporary + UNUSED_ARG(just_replace); + if(!pNewValidator)return; + // + // if(just_replace){ + delete m_validator; + m_validator = pNewValidator; + return; + // } + //// need to build composite validator, combining new and old validators + //CompositeValidator<TYPE> *compo_val = dynamic_cast<CompositeValidator<TYPE>* >(m_validator); + //if(compo_val ){ + // compo_val->modify_validator(pNewValidator); + // return; + //} + //// the validator is just replacement for the old one; + //if(typeid(m_validator)==typeid(pNewValidator)){ + // delete m_validator; + // m_validator = pNewValidator; + //}else{ // build composite validator + // CompositeValidator<TYPE> *new_val = new CompositeValidator<TYPE>(); + // new_val->add(m_validator); + // new_val->add(pNewValidator); + // m_validator = new_val; + //} + } protected: /// The value of the property TYPE m_value; diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ValidatorAnyList.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ValidatorAnyList.h new file mode 100644 index 0000000000000000000000000000000000000000..a35c3be2184c67192a4a7b31f86790c8e00c8f03 --- /dev/null +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ValidatorAnyList.h @@ -0,0 +1,108 @@ +#ifndef MANTID_KERNEL_VALIDATOR_ANYLIST_H_ +#define MANTID_KERNEL_VALIDATOR_ANYLIST_H_ + +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- +#include "IValidator.h" +#include <vector> +#include <set> +#include <boost/lexical_cast.hpp> + +namespace Mantid +{ +namespace Kernel +{ +/** ValidatorAnyList is a validator that requires the value of a property to be one of a defined list + of possibilities. boost::lexical_cast has to be allowed for conversion betweed the list values and the strings + + Example of applications :: to validate the list of detectors ID-s (integer numbers), which are availible for selection; + + @date 18/06/2008 + + Copyright © 2008-9 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>. + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +/// a list validator, which allows to validate the lists of different types, e.g. set of integers; +template<typename TYPE> +class ValidatorAnyList : public IValidator<TYPE> +{ +public: + /// Default constructor. Sets up an empty list of valid values. + ValidatorAnyList(): IValidator<TYPE>(), m_allowedValues(){}; + /** Constructor + * @param values :: A set of values consisting of the valid values */ + explicit ValidatorAnyList(const std::set<TYPE>& values): + IValidator<TYPE>(), m_allowedValues(values){} + + /** Constructor + * @param values :: A vector of the valid values */ + explicit ValidatorAnyList(const std::vector<TYPE>& values): + IValidator<TYPE>(), m_allowedValues(values.begin(),values.end()){} + + /// Destructor + virtual ~ValidatorAnyList(){}; + + /// Returns the set of valid values + std::set<std::string> allowedValues() const + { + std::set<std::string> rez; + typename std::set<TYPE >::const_iterator it=m_allowedValues.begin(); + for(;it!=m_allowedValues.end();it++){ + rez.insert(rez.end(),boost::lexical_cast<std::string>(*it)); + } + return rez; + } + /* /// Adds the argument to the set of valid values + void addAllowedValue(const std::string &value) + { + TYPE rVal = boost::lexical_cast<TYPE>(value); + m_allowedValues.insert(rVal); + }*/ + /// Adds the argument to the set of valid values + void addAllowedValue(const TYPE &value) + { + m_allowedValues.insert(value); + } + + IValidator<TYPE>* clone() { return new ValidatorAnyList<TYPE>(*this); } + + private: + /** Checks if the string passed is in the list + * @param value :: The value to test + * @return "" if the value is on the list, or "The value is not in the list of allowed values" */ + std::string checkValidity(const TYPE &value) const + { + if ( m_allowedValues.count(value) ){ + return ""; + }else{ + //if ( value.empty() ) return "Select a value"; + return "The value \"" + boost::lexical_cast<std::string>(value) + "\" is not in the list of allowed values"; + } + } + + /// The set of valid values + std::set<TYPE> m_allowedValues; +}; + +} // namespace Kernel +} // namespace Mantid + +#endif /*MANTID_KERNEL_LISTVALIDATOR_H_*/ diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ValidatorSignalChange.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ValidatorSignalChange.h index 6f5450bdac0e9dacd5d0b8e6ab56a52daa466981..21ed897a8c8cb7c2eda67951ccd65c7c70fb8ceb 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ValidatorSignalChange.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ValidatorSignalChange.h @@ -18,7 +18,7 @@ namespace Kernel /** ValidatorSignalChange is a validator, which connects to a property and signals to subscribers that this property has changed - @author Alex Buts + DO NOT USE -- it is currently the concept, which has memory leak. @date 03/11/2011 Copyright © 2007-9 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory diff --git a/Code/Mantid/Framework/Kernel/src/ArrayLengthValidator.cpp b/Code/Mantid/Framework/Kernel/src/ArrayLengthValidator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1768fb67c398e268c86dcde495d3f576e5e468f7 --- /dev/null +++ b/Code/Mantid/Framework/Kernel/src/ArrayLengthValidator.cpp @@ -0,0 +1,81 @@ +#include "MantidKernel/ArrayLengthValidator.h" +#include "MantidKernel/System.h" + +using namespace Mantid::Kernel; + +namespace Mantid +{ +namespace Kernel +{ + + + //---------------------------------------------------------------------------------------------- + /** No arg constructor + */ + template <typename TYPE> + ArrayLengthValidator<TYPE>::ArrayLengthValidator():IValidator<std::vector<TYPE> >(),m_arraySize(size_t(0)),m_hasArraySize(false) + { + } + //---------------------------------------------------------------------------------------------- + /** Constructor + * @param len:: the legth of the array + */ + template <typename TYPE> + ArrayLengthValidator<TYPE>::ArrayLengthValidator(const size_t len):IValidator<std::vector<TYPE> >(),m_arraySize(size_t(len)),m_hasArraySize(true) + { + } + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + template <typename TYPE> + ArrayLengthValidator<TYPE>::~ArrayLengthValidator() + { + } + template <typename TYPE> + bool ArrayLengthValidator<TYPE>::hasLength() const + { + return this->m_hasArraySize; + } + template <typename TYPE> + const size_t& ArrayLengthValidator<TYPE>:: getLength() const + { + return this->m_arraySize; + } + template <typename TYPE> + void ArrayLengthValidator<TYPE>::setLength(const size_t &value) + { + this->m_hasArraySize=true; + this->m_arraySize=value; + } + template <typename TYPE> + void ArrayLengthValidator<TYPE>::clearLength() + { + this->m_hasArraySize=false; + this->m_arraySize=size_t(0); + } + template <typename TYPE> + IValidator<std::vector <TYPE> >* ArrayLengthValidator<TYPE>::clone() + { + return new ArrayLengthValidator(*this); + } + + template <typename TYPE> + std::string ArrayLengthValidator<TYPE>::isValid(const std::vector<TYPE> &value ) const + { + return this->checkValidity(value); + } + + template <typename TYPE> + std::string ArrayLengthValidator<TYPE>::checkValidity( const std::vector<TYPE> &value ) const + { + if (value.size()==this->m_arraySize ) + { + return ""; + } + else return"Incorrect size"; + } + // Required explicit instantiations + template class ArrayLengthValidator<double>; + template class ArrayLengthValidator<int>; +} // namespace Mantid +} // namespace Kernel diff --git a/Code/Mantid/Framework/Kernel/src/DateAndTime.cpp b/Code/Mantid/Framework/Kernel/src/DateAndTime.cpp index 22c5f954ba9bac2ae6f994a18e1cd77f463687b0..e61c4eecb0d8fb74b4fdf827803f03ca5dccd8d0 100644 --- a/Code/Mantid/Framework/Kernel/src/DateAndTime.cpp +++ b/Code/Mantid/Framework/Kernel/src/DateAndTime.cpp @@ -502,7 +502,7 @@ void DateAndTime::set_from_ISO8601_string(const std::string str) //The timezone is - so we need to ADD the hours this->set_from_ptime( boost::posix_time::time_from_string(time) + tz_offset ); } - catch (boost::bad_lexical_cast & e) + catch (boost::bad_lexical_cast &) { // Re-throw a more helpful error message throw std::invalid_argument("Error interpreting string '" + time + "' as a date/time."); diff --git a/Code/Mantid/Framework/Kernel/src/Property.cpp b/Code/Mantid/Framework/Kernel/src/Property.cpp index 2f8a8ce99d6ff065687a6d491c89d176d662e31e..e12632065b26e21debcdc17915c07958caf8d481 100644 --- a/Code/Mantid/Framework/Kernel/src/Property.cpp +++ b/Code/Mantid/Framework/Kernel/src/Property.cpp @@ -209,6 +209,7 @@ namespace API class IMDEventWorkspace; class IMDWorkspace; class IEventWorkspace; + class IMDHistoWorkspace; } namespace DataObjects { @@ -274,6 +275,8 @@ std::string getUnmangledTypeName(const std::type_info& type) string("OffsetsWorkspace"))); typestrings.insert(make_pair(typeid(boost::shared_ptr<SpecialWorkspace2D>).name(), string("SpecialWorkspace2D"))); + typestrings.insert(make_pair(typeid(boost::shared_ptr<IMDHistoWorkspace>).name(), + string("IMDHistoWorkspace"))); } diff --git a/Code/Mantid/Framework/Kernel/test/ArrayLengthValidatorTest.h b/Code/Mantid/Framework/Kernel/test/ArrayLengthValidatorTest.h new file mode 100644 index 0000000000000000000000000000000000000000..de64a94a268e4d6d7daa689158c92686dde66744 --- /dev/null +++ b/Code/Mantid/Framework/Kernel/test/ArrayLengthValidatorTest.h @@ -0,0 +1,67 @@ +#ifndef MANTID_KERNEL_ARRAYLENGTHVALIDATORTEST_H_ +#define MANTID_KERNEL_ARRAYLENGTHVALIDATORTEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidKernel/Timer.h" +#include "MantidKernel/System.h" +#include <iostream> +#include <iomanip> +#include <vector> + +#include "MantidKernel/ArrayLengthValidator.h" + +using namespace Mantid; +using namespace Mantid::Kernel; + +class ArrayLengthValidatorTest : public CxxTest::TestSuite +{ +public: + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static ArrayLengthValidatorTest *createSuite() { return new ArrayLengthValidatorTest(); } + static void destroySuite( ArrayLengthValidatorTest *suite ) { delete suite; } + + + void testConstructor() + { + ArrayLengthValidator<int> av1,av2(3); + TS_ASSERT_EQUALS(av1.hasLength(),false); + TS_ASSERT_EQUALS(av2.hasLength(),true); + TS_ASSERT_EQUALS(av2.getLength(),3); + } + + void testClone() + { + ArrayLengthValidator<int> *vi= new ArrayLengthValidator<int>; + IValidator<std::vector<int> > *vvi = vi->clone(); + TS_ASSERT_DIFFERS( vi, vvi ); + delete vi; + delete vvi; + } + + void testSetClear() + { + ArrayLengthValidator<int> av1; + TS_ASSERT_EQUALS(av1.hasLength(),false); + av1.setLength(4); + TS_ASSERT_EQUALS(av1.hasLength(),true); + TS_ASSERT_EQUALS(av1.getLength(),4); + av1.clearLength(); + TS_ASSERT_EQUALS(av1.hasLength(),false); + TS_ASSERT_EQUALS(av1.getLength(),0); + } + + void testValidator() + { + ArrayLengthValidator<int> vi(3); + std::vector<int> a; + a.push_back(3); + TS_ASSERT_DIFFERS(vi.isValid(a).length(),0); + a.push_back(-1); + a.push_back(11); + TS_ASSERT_EQUALS(vi.isValid(a).length(),0); + } +}; + + +#endif /* MANTID_KERNEL_ARRAYLENGTHVALIDATORTEST_H_ */ diff --git a/Code/Mantid/Framework/Kernel/test/ValidatorAnyListTest.h b/Code/Mantid/Framework/Kernel/test/ValidatorAnyListTest.h new file mode 100644 index 0000000000000000000000000000000000000000..bc2dd45e8d02e192627c1f5fd296ee8da105b3c4 --- /dev/null +++ b/Code/Mantid/Framework/Kernel/test/ValidatorAnyListTest.h @@ -0,0 +1,100 @@ +#ifndef VALIDATOR_ANYLIST_TEST_H_ +#define VALIDATOR_ANYLIST_TEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidKernel/ValidatorAnyList.h" + +using namespace Mantid::Kernel; + +class ValidatorAnyListTest : public CxxTest::TestSuite +{ +public: + void testEmptyConstructor() + { + ValidatorAnyList<int> v; + TS_ASSERT( v.allowedValues().empty() ) + } + + void testVectorConstructor() + { + std::vector<std::string> vec; + vec.push_back("one"); + vec.push_back("two"); + vec.push_back("three"); + ValidatorAnyList<std::string> v(vec); + TS_ASSERT_EQUALS( v.allowedValues().size(), 3 ) + } + void testVectorConstructor2() + { + std::vector<int> vec; + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + ValidatorAnyList<int> v(vec); + TS_ASSERT_EQUALS( v.allowedValues().size(), 3 ) + } + + void testIsValid() + { + ValidatorAnyList<int> v; + //TS_ASSERT_EQUALS( v.isValid(""), "Select a value" ) + + TS_ASSERT_EQUALS( v.isValid(1), + "The value \"1\" is not in the list of allowed values") + + v.addAllowedValue(1); + // TS_ASSERT_EQUALS( v.isValid(""), + // "Select a value" ) + TS_ASSERT_EQUALS( v.isValid(1), "" ) + TS_ASSERT_EQUALS( v.isValid(2), + "The value \"2\" is not in the list of allowed values") + } + + void testAllowedValues() + { + ValidatorAnyList<int> v; + v.addAllowedValue(1); + v.addAllowedValue(2); + std::set<std::string> s; + TS_ASSERT_THROWS_NOTHING( s = v.allowedValues() ) + TS_ASSERT_EQUALS( s.size(), 2 ) + TS_ASSERT( s.count("1") ) + TS_ASSERT( s.count("2") ) + TS_ASSERT( ! s.count("3") ) + } + + void testAddAllowedValue() + { + ValidatorAnyList<int> v; + TS_ASSERT( v.allowedValues().empty() ) + TS_ASSERT_THROWS_NOTHING( v.addAllowedValue(10) ) + TS_ASSERT_EQUALS( v.allowedValues().size(), 1 ) + TS_ASSERT_EQUALS( v.isValid(10), "" ) + // Try adding again just to make sure the instruction is ignored, but doesn't throw + TS_ASSERT_THROWS_NOTHING( v.addAllowedValue(10) ) + TS_ASSERT_EQUALS( v.allowedValues().size(), 1 ) + TS_ASSERT_EQUALS( v.isValid(10), "" ) + } + + void testClone() + { + IValidator<int> *v = new ValidatorAnyList<int>(); + IValidator<int> *vv = v->clone(); + TS_ASSERT_DIFFERS( v, vv ) + TS_ASSERT( dynamic_cast<ValidatorAnyList<int> *>(vv) ) + delete v; + delete vv; + } + + void testCast() + { + IValidator<int> *v = new ValidatorAnyList<int>(); + TS_ASSERT( dynamic_cast<IValidator<int>*>(v) ) + TS_ASSERT( ! dynamic_cast<IValidator<double>*>(v) ) + delete v; + } + +}; + +#endif /*LISTVALIDATORTEST_H_*/ diff --git a/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt b/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt index b4d00155a7baa0448bade521d870da98f924677a..6888fae77523976a974e67b4cd53cae304a983d5 100644 --- a/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt +++ b/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt @@ -1,7 +1,9 @@ # GLOBs should be replaced with explicit listings set ( SRC_FILES # src/CreateMDFitWorkspace.cpp + src/AndMD.cpp src/BinaryOperationMD.cpp + src/BooleanBinaryOperationMD.cpp src/CobaltSpinWaveDSHO.cpp src/CompositeFunctionBuilder.cpp src/CompositeImplicitFunction.cpp @@ -9,20 +11,30 @@ set ( SRC_FILES src/ConvertToQ3DdE.cpp src/ConvertToQNDany.cpp src/DivideMD.cpp + src/EqualToMD.cpp + src/ExponentialMD.cpp + src/GreaterThanMD.cpp src/IDynamicRebinning.cpp src/InvalidParameter.cpp src/InvalidParameterParser.cpp + src/LessThanMD.cpp + src/LogarithmMD.cpp src/MinusMD.cpp src/MultiplyMD.cpp + src/NotMD.cpp src/NullImplicitFunction.cpp + src/OrMD.cpp src/PlusMD.cpp + src/PowerMD.cpp src/QuadEnBackground.cpp src/RunParam.cpp + src/SetMDUsingMask.cpp src/SimulateMDD.cpp src/SimulateResolution.cpp src/TobyFitSimulate.cpp src/UnaryOperationMD.cpp src/Vector3DParameterParser.cpp + src/XorMD.cpp ) #set ( SRC_UNITY_IGNORE_FILES src/IDynamicRebinning.cpp @@ -30,7 +42,9 @@ set ( SRC_FILES set ( INC_FILES # inc/MantidMDAlgorithms/CreateMDFitWorkspace.h + inc/MantidMDAlgorithms/AndMD.h inc/MantidMDAlgorithms/BinaryOperationMD.h + inc/MantidMDAlgorithms/BooleanBinaryOperationMD.h inc/MantidMDAlgorithms/CobaltSpinWaveDSHO.h inc/MantidMDAlgorithms/CompositeFunctionBuilder.h inc/MantidMDAlgorithms/CompositeImplicitFunction.h @@ -38,21 +52,31 @@ set ( INC_FILES inc/MantidMDAlgorithms/ConvertToQ3DdE.h inc/MantidMDAlgorithms/ConvertToQNDany.h inc/MantidMDAlgorithms/DivideMD.h + inc/MantidMDAlgorithms/EqualToMD.h + inc/MantidMDAlgorithms/ExponentialMD.h + inc/MantidMDAlgorithms/GreaterThanMD.h inc/MantidMDAlgorithms/IDynamicRebinning.h inc/MantidMDAlgorithms/InvalidParameter.h inc/MantidMDAlgorithms/InvalidParameterParser.h + inc/MantidMDAlgorithms/LessThanMD.h + inc/MantidMDAlgorithms/LogarithmMD.h inc/MantidMDAlgorithms/MinusMD.h inc/MantidMDAlgorithms/MultiplyMD.h + inc/MantidMDAlgorithms/NotMD.h inc/MantidMDAlgorithms/NullImplicitFunction.h + inc/MantidMDAlgorithms/OrMD.h inc/MantidMDAlgorithms/PlusMD.h + inc/MantidMDAlgorithms/PowerMD.h inc/MantidMDAlgorithms/QuadEnBackground.h inc/MantidMDAlgorithms/RunParam.h + inc/MantidMDAlgorithms/SetMDUsingMask.h inc/MantidMDAlgorithms/SimulateMDD.h inc/MantidMDAlgorithms/SimulateResolution.h inc/MantidMDAlgorithms/TobyFitSimulate.h inc/MantidMDAlgorithms/UnaryOperationMD.h inc/MantidMDAlgorithms/Vector3DParameter.h inc/MantidMDAlgorithms/Vector3DParameterParser.h + inc/MantidMDAlgorithms/XorMD.h ) # Test files. Other source files required. @@ -61,18 +85,30 @@ set ( TEST_FILES #test/CobaltSWDTest.h #test/CreateMDFitWorkspaceTest.h #test/QuadEnBackgroundTest.h + test/AndMDTest.h + test/BooleanBinaryOperationMDTest.h test/ConvertToQ3DdETest.h test/ConvertToQNDanyTest.h test/DivideMDTest.h + test/EqualToMDTest.h + test/ExponentialMDTest.h + test/GreaterThanMDTest.h test/InvalidParameterParserTest.h test/InvalidParameterTest.h + test/LessThanMDTest.h + test/LogarithmMDTest.h test/MinusMDTest.h test/MultiplyMDTest.h + test/NotMDTest.h + test/OrMDTest.h test/PlusMDTest.h + test/PowerMDTest.h test/RunParamTest.h + test/SetMDUsingMaskTest.h test/SimulateMDDTest.h test/TobyFitSimulateTest.h test/UnaryOperationMDTest.h + test/XorMDTest.h ) set ( GMOCK_TEST_FILES diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AndMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AndMD.h new file mode 100644 index 0000000000000000000000000000000000000000..a58af4e1d1825576c9abd135f78bcf240a380bce --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AndMD.h @@ -0,0 +1,55 @@ +#ifndef MANTID_MDALGORITHMS_ANDMD_H_ +#define MANTID_MDALGORITHMS_ANDMD_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidMDAlgorithms/BinaryOperationMD.h" +#include "MantidMDAlgorithms/BooleanBinaryOperationMD.h" + +namespace Mantid +{ +namespace MDAlgorithms +{ + + /** AndMD : Perform the And boolean operation on two MDHistoWorkspaces + + @date 2011-11-08 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + 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 AndMD : public BooleanBinaryOperationMD + { + public: + AndMD(); + virtual ~AndMD(); + + virtual const std::string name() const; + virtual int version() const; + + private: + void execHistoHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::MDEvents::MDHistoWorkspace_const_sptr operand); + }; + + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_ANDMD_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BinaryOperationMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BinaryOperationMD.h index bd1f587357111d054a75abdce128eba1fa42d3ad..8b08ef4d0bb56e796ec7f1161e65962066ef752e 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BinaryOperationMD.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BinaryOperationMD.h @@ -78,6 +78,7 @@ namespace MDAlgorithms virtual std::string outputPropName() const { return "OutputWorkspace";} void init(); + virtual void initExtraProperties(); virtual void exec(); /// LHS workspace diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BooleanBinaryOperationMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BooleanBinaryOperationMD.h new file mode 100644 index 0000000000000000000000000000000000000000..2bfe5c9042f23c81683c653ded4a78852deb3ce7 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BooleanBinaryOperationMD.h @@ -0,0 +1,67 @@ +#ifndef MANTID_MDALGORITHMS_BOOLEANBINARYOPERATIONMD_H_ +#define MANTID_MDALGORITHMS_BOOLEANBINARYOPERATIONMD_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidMDAlgorithms/BinaryOperationMD.h" + +namespace Mantid +{ +namespace MDAlgorithms +{ + + /** BooleanBinaryOperationMD : base class for boolean-type operations on MDHistoWorkspaces + + @date 2011-11-08 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + 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 BooleanBinaryOperationMD : public BinaryOperationMD + { + public: + BooleanBinaryOperationMD(); + virtual ~BooleanBinaryOperationMD(); + + virtual const std::string name() const; + virtual int version() const; + + protected: + /// Return true if the algorithm can operate on a scalar. + virtual bool acceptScalar() const + { return true; } + virtual bool commutative() const; + + virtual void initDocs(); + void checkInputs(); + void execEvent(); + virtual void execHistoScalar(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::DataObjects::WorkspaceSingleValue_const_sptr scalar); + + /// Run the algorithm with a MDHisotWorkspace as output and operand + virtual void execHistoHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::MDEvents::MDHistoWorkspace_const_sptr operand) = 0; + + + }; + + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_BOOLEANBINARYOPERATIONMD_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EqualToMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EqualToMD.h new file mode 100644 index 0000000000000000000000000000000000000000..09f77b1fb31081360de3143a0c4e1841e6dc728f --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EqualToMD.h @@ -0,0 +1,58 @@ +#ifndef MANTID_MDALGORITHMS_EQUALTOMD_H_ +#define MANTID_MDALGORITHMS_EQUALTOMD_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidMDAlgorithms/BooleanBinaryOperationMD.h" + +namespace Mantid +{ +namespace MDAlgorithms +{ + + /** EqualToMD : boolean operation on MDHistoWorkspaces + + @date 2011-11-08 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + 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 EqualToMD : public BooleanBinaryOperationMD + { + public: + EqualToMD(); + virtual ~EqualToMD(); + + virtual const std::string name() const; + virtual int version() const; + + private: + void initExtraProperties(); + bool acceptScalar() { return true; } + void execHistoHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::MDEvents::MDHistoWorkspace_const_sptr operand); + void execHistoScalar(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::DataObjects::WorkspaceSingleValue_const_sptr scalar); + + }; + + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_EQUALTOMD_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ExponentialMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ExponentialMD.h new file mode 100644 index 0000000000000000000000000000000000000000..6707f0b5cf386c3917e0cfb8d5260a1b77405a5c --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ExponentialMD.h @@ -0,0 +1,65 @@ +#ifndef MANTID_MDALGORITHMS_EXPONENTIALMD_H_ +#define MANTID_MDALGORITHMS_EXPONENTIALMD_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidMDAlgorithms/UnaryOperationMD.h" + +namespace Mantid +{ +namespace MDAlgorithms +{ + + /** ExponentialMD : exponential function on MDHistoWorkspace + + @date 2011-11-08 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + 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 ExponentialMD : public UnaryOperationMD + { + public: + ExponentialMD(); + virtual ~ExponentialMD(); + + virtual const std::string name() const; + virtual int version() const; + + private: + virtual void initDocs(); + + /// Check the inputs and throw if the algorithm cannot be run + void checkInputs(); + + /// Run the algorithm on a MDEventWorkspace + void execEvent(Mantid::API::IMDEventWorkspace_sptr out); + + /// Run the algorithm with a MDHistoWorkspace + void execHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out); + + + }; + + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_EXPONENTIALMD_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/GreaterThanMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/GreaterThanMD.h new file mode 100644 index 0000000000000000000000000000000000000000..3f7b66ace30a0b9d283c294b92ceb77e06adcdbd --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/GreaterThanMD.h @@ -0,0 +1,59 @@ +#ifndef MANTID_MDALGORITHMS_GREATERTHANMD_H_ +#define MANTID_MDALGORITHMS_GREATERTHANMD_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidMDAlgorithms/BooleanBinaryOperationMD.h" + +namespace Mantid +{ +namespace MDAlgorithms +{ + + /** GreaterThanMD : boolean operation on MDHistoWorkspaces + + @date 2011-11-08 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + 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 GreaterThanMD : public BooleanBinaryOperationMD + { + public: + GreaterThanMD(); + virtual ~GreaterThanMD(); + + virtual const std::string name() const; + virtual int version() const; + + private: + bool acceptScalar() const { return true; } + bool commutative() const { return false; } + + void execHistoHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::MDEvents::MDHistoWorkspace_const_sptr operand); + void execHistoScalar(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::DataObjects::WorkspaceSingleValue_const_sptr scalar); + + }; + + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_GREATERTHANMD_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LessThanMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LessThanMD.h new file mode 100644 index 0000000000000000000000000000000000000000..d9610f6d341829198676175b0f6897568f7c597c --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LessThanMD.h @@ -0,0 +1,60 @@ +#ifndef MANTID_MDALGORITHMS_LESSTHANMD_H_ +#define MANTID_MDALGORITHMS_LESSTHANMD_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidMDAlgorithms/BooleanBinaryOperationMD.h" + +namespace Mantid +{ +namespace MDAlgorithms +{ + + /** LessThanMD : boolean operation on MDHistoWorkspaces + + @date 2011-11-08 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + 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 LessThanMD : public BooleanBinaryOperationMD + { + public: + LessThanMD(); + virtual ~LessThanMD(); + + virtual const std::string name() const; + virtual int version() const; + + private: + bool acceptScalar() const { return true; } + bool commutative() const { return false; } + + void execHistoHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::MDEvents::MDHistoWorkspace_const_sptr operand); + void execHistoScalar(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::DataObjects::WorkspaceSingleValue_const_sptr scalar); + + + }; + + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_LESSTHANMD_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LogarithmMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LogarithmMD.h new file mode 100644 index 0000000000000000000000000000000000000000..36f55af5a26600092d78fef6b5ca358b7e4fbd82 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LogarithmMD.h @@ -0,0 +1,66 @@ +#ifndef MANTID_MDALGORITHMS_LOGARITHMMD_H_ +#define MANTID_MDALGORITHMS_LOGARITHMMD_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidMDAlgorithms/UnaryOperationMD.h" + +namespace Mantid +{ +namespace MDAlgorithms +{ + + /** LogarithmMD : natural logarithm of a MDHistoWorkspace + + @date 2011-11-08 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + 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 LogarithmMD : public UnaryOperationMD + { + public: + LogarithmMD(); + virtual ~LogarithmMD(); + + virtual const std::string name() const; + virtual int version() const; + + private: + virtual void initDocs(); + virtual void initExtraProperties(); + + /// Check the inputs and throw if the algorithm cannot be run + void checkInputs(); + + /// Run the algorithm on a MDEventWorkspace + void execEvent(Mantid::API::IMDEventWorkspace_sptr out); + + /// Run the algorithm with a MDHistoWorkspace + void execHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out); + + + }; + + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_LOGARITHMMD_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/NotMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/NotMD.h new file mode 100644 index 0000000000000000000000000000000000000000..3f5aa470fc90435dec1d1c2f2cf2d0894af070d4 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/NotMD.h @@ -0,0 +1,64 @@ +#ifndef MANTID_MDALGORITHMS_NOTMD_H_ +#define MANTID_MDALGORITHMS_NOTMD_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidMDAlgorithms/UnaryOperationMD.h" + +namespace Mantid +{ +namespace MDAlgorithms +{ + + /** NotMD : boolean negation of a MDHistoWorkspace + + @date 2011-11-08 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + 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 NotMD : public UnaryOperationMD + { + public: + NotMD(); + virtual ~NotMD(); + + virtual const std::string name() const; + virtual int version() const; + + private: + virtual void initDocs(); + + /// Check the inputs and throw if the algorithm cannot be run + void checkInputs(); + + /// Run the algorithm on a MDEventWorkspace + void execEvent(Mantid::API::IMDEventWorkspace_sptr out); + + /// Run the algorithm with a MDHistoWorkspace + void execHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out); + + }; + + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_NOTMD_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/OrMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/OrMD.h new file mode 100644 index 0000000000000000000000000000000000000000..290b3cb90ba4ee257572f1eaab1fa38d7f0d8c9f --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/OrMD.h @@ -0,0 +1,56 @@ +#ifndef MANTID_MDALGORITHMS_ORMD_H_ +#define MANTID_MDALGORITHMS_ORMD_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidMDAlgorithms/BooleanBinaryOperationMD.h" + +namespace Mantid +{ +namespace MDAlgorithms +{ + + /** OrMD : boolean operation on MDHistoWorkspaces + + @date 2011-11-08 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + 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 OrMD : public BooleanBinaryOperationMD + { + public: + OrMD(); + virtual ~OrMD(); + + virtual const std::string name() const; + virtual int version() const; + + private: + void execHistoHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::MDEvents::MDHistoWorkspace_const_sptr operand); + + + }; + + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_ORMD_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PowerMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PowerMD.h new file mode 100644 index 0000000000000000000000000000000000000000..1d9b7c5edea82babcb823601e75d23eee72e9aea --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PowerMD.h @@ -0,0 +1,65 @@ +#ifndef MANTID_MDALGORITHMS_POWERMD_H_ +#define MANTID_MDALGORITHMS_POWERMD_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidMDAlgorithms/UnaryOperationMD.h" + +namespace Mantid +{ +namespace MDAlgorithms +{ + + /** PowerMD : raise a MDHistoWorkspace to a power. + + @date 2011-11-08 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + 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 PowerMD : public UnaryOperationMD + { + public: + PowerMD(); + virtual ~PowerMD(); + + virtual const std::string name() const; + virtual int version() const; + + private: + virtual void initDocs(); + virtual void initExtraProperties(); + + /// Check the inputs and throw if the algorithm cannot be run + void checkInputs(); + + /// Run the algorithm on a MDEventWorkspace + void execEvent(Mantid::API::IMDEventWorkspace_sptr out); + + /// Run the algorithm with a MDHistoWorkspace + void execHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out); + + }; + + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_POWERMD_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SetMDUsingMask.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SetMDUsingMask.h new file mode 100644 index 0000000000000000000000000000000000000000..d07e8321ee67c10819f59d463aa130e41bd01974 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SetMDUsingMask.h @@ -0,0 +1,58 @@ +#ifndef MANTID_MDALGORITHMS_SETMDUSINGMASK_H_ +#define MANTID_MDALGORITHMS_SETMDUSINGMASK_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" + +namespace Mantid +{ +namespace MDAlgorithms +{ + + /** Algorithm to set a MDHistoWorkspace in points determined by a mask boolean MDHistoWorkspace. + + @date 2011-11-10 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + 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 SetMDUsingMask : public API::Algorithm + { + public: + SetMDUsingMask(); + virtual ~SetMDUsingMask(); + + virtual const std::string name() const; + virtual int version() const; + virtual const std::string category() const; + + private: + virtual void initDocs(); + void init(); + void exec(); + + + }; + + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_SETMDUSINGMASK_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/UnaryOperationMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/UnaryOperationMD.h index 4553b7e77d84de2987307d47677d8ced59fbe3b7..5dfa1abbc1c7b759de5f447066b00fea33dfd1c1 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/UnaryOperationMD.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/UnaryOperationMD.h @@ -52,6 +52,7 @@ namespace MDAlgorithms virtual const std::string outputPropName() const { return "OutputWorkspace";} void init(); + virtual void initExtraProperties(); void exec(); /// Check the inputs and throw if the algorithm cannot be run diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/XorMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/XorMD.h new file mode 100644 index 0000000000000000000000000000000000000000..41f66bd1427bdc38978e5d078063d2c57d67f2e3 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/XorMD.h @@ -0,0 +1,56 @@ +#ifndef MANTID_MDALGORITHMS_XORMD_H_ +#define MANTID_MDALGORITHMS_XORMD_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidMDAlgorithms/BooleanBinaryOperationMD.h" + +namespace Mantid +{ +namespace MDAlgorithms +{ + + /** XorMD : boolean operation on MDHistoWorkspaces + + @date 2011-11-08 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + 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 XorMD : public BooleanBinaryOperationMD + { + public: + XorMD(); + virtual ~XorMD(); + + virtual const std::string name() const; + virtual int version() const; + + private: + void execHistoHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::MDEvents::MDHistoWorkspace_const_sptr operand); + + + }; + + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_XORMD_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/src/AndMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/AndMD.cpp new file mode 100644 index 0000000000000000000000000000000000000000..42c580ccd8fd64dfda0430a77f5089211ee8eda1 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/src/AndMD.cpp @@ -0,0 +1,58 @@ +/*WIKI* + +Perform the And boolean operation on two MDHistoWorkspaces. +The && operation is performed element-by-element. +A signal of 0.0 means "false" and any non-zero signal is "true". + +== Usage == + + C = A & B + A &= B + +See [[MDHistoWorkspace#Boolean_Operations|this page]] for examples on using boolean operations. + +*WIKI*/ + +#include "MantidMDAlgorithms/AndMD.h" +#include "MantidKernel/System.h" + +using namespace Mantid::Kernel; +using namespace Mantid::API; + +namespace Mantid +{ +namespace MDAlgorithms +{ + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(AndMD) + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + AndMD::AndMD() + { } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + AndMD::~AndMD() + { } + + //---------------------------------------------------------------------------------------------- + /// Algorithm's name for identification. @see Algorithm::name + const std::string AndMD::name() const { return "AndMD";}; + + /// Algorithm's version for identification. @see Algorithm::version + int AndMD::version() const { return 1;}; + + //---------------------------------------------------------------------------------------------- + /// Run the algorithm with a MDHisotWorkspace as output and operand + void AndMD::execHistoHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::MDEvents::MDHistoWorkspace_const_sptr operand) + { + out->operator &=(*operand); + } + + +} // namespace Mantid +} // namespace MDAlgorithms diff --git a/Code/Mantid/Framework/MDAlgorithms/src/BinaryOperationMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/BinaryOperationMD.cpp index bdec78d1708dec5564d4baff3146798d65e5c5bd..c8bbde2296acbd2ffe92ee49fd5a935d6c6ccf5f 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/BinaryOperationMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/BinaryOperationMD.cpp @@ -59,6 +59,13 @@ namespace MDAlgorithms "An MDEventWorkspace, MDHistoWorkspace or WorkspaceSingleValue as the right-hand side of the operation."); declareProperty(new WorkspaceProperty<IMDWorkspace>(outputPropName(),"",Direction::Output), "Name of the output MDEventWorkspace or MDHistoWorkspace."); + this->initExtraProperties(); + } + + + /// Optional extra properties + void BinaryOperationMD::initExtraProperties() + { } //---------------------------------------------------------------------------------------------- diff --git a/Code/Mantid/Framework/MDAlgorithms/src/BooleanBinaryOperationMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/BooleanBinaryOperationMD.cpp new file mode 100644 index 0000000000000000000000000000000000000000..553f3dbe74e02a7a4367d85f6d504a2b4203cab6 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/src/BooleanBinaryOperationMD.cpp @@ -0,0 +1,75 @@ + +#include "MantidMDAlgorithms/BooleanBinaryOperationMD.h" +#include "MantidKernel/System.h" + +using namespace Mantid::Kernel; +using namespace Mantid::API; + +namespace Mantid +{ +namespace MDAlgorithms +{ + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + BooleanBinaryOperationMD::BooleanBinaryOperationMD() + { } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + BooleanBinaryOperationMD::~BooleanBinaryOperationMD() + { } + + //---------------------------------------------------------------------------------------------- + /// Algorithm's name for identification. @see Algorithm::name + const std::string BooleanBinaryOperationMD::name() const { return "BooleanBinaryOperationMD";}; + + /// Algorithm's version for identification. @see Algorithm::version + int BooleanBinaryOperationMD::version() const { return 1;}; + + //---------------------------------------------------------------------------------------------- + /// Sets documentation strings for this algorithm + void BooleanBinaryOperationMD::initDocs() + { + std::string algo = this->name(); + algo = algo.substr(0, algo.size()-2); + this->setWikiSummary("Perform the " + algo + " boolean operation on two MDHistoWorkspaces"); + this->setOptionalMessage("Perform the " + algo + " boolean operation on two MDHistoWorkspaces"); + } + + //---------------------------------------------------------------------------------------------- + /// Is the operation commutative? + bool BooleanBinaryOperationMD::commutative() const + { return true; } + + //---------------------------------------------------------------------------------------------- + /// Check the inputs and throw if the algorithm cannot be run + void BooleanBinaryOperationMD::checkInputs() + { + if (m_lhs_event || m_rhs_event) + throw std::runtime_error("Cannot perform the " + this->name() + " operation on a MDEventWorkspace."); + if (!acceptScalar() && (m_lhs_scalar || m_rhs_scalar)) + throw std::runtime_error("Cannot perform the " + this->name() + " operation on a WorkspaceSingleValue."); + if (!this->commutative() && m_lhs_scalar) + throw std::runtime_error("Cannot perform the " + this->name() + " operation with a scalar on the left-hand side."); + } + + //---------------------------------------------------------------------------------------------- + /// Run the algorithm with an MDEventWorkspace as output + void BooleanBinaryOperationMD::execEvent() + { + throw std::runtime_error("Cannot perform the " + this->name() + " operation on a MDEventWorkspace."); + } + + //---------------------------------------------------------------------------------------------- + /// Run the algorithm with a MDHisotWorkspace as output, scalar and operand + void BooleanBinaryOperationMD::execHistoScalar(Mantid::MDEvents::MDHistoWorkspace_sptr /*out*/, Mantid::DataObjects::WorkspaceSingleValue_const_sptr /*scalar*/) + { + throw std::runtime_error("Cannot perform the " + this->name() + " operation on a WorkspaceSingleValue."); + } + + +} // namespace Mantid +} // namespace MDAlgorithms diff --git a/Code/Mantid/Framework/MDAlgorithms/src/DivideMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/DivideMD.cpp index e0212163fd2528b0702d51c2fd9902b6e5df7cbc..f4926337a2278f13db2ae24f3b7cf110ebd995bf 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/DivideMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/DivideMD.cpp @@ -12,6 +12,15 @@ The error of <math> f = a / b </math> is propagated with <math> df^2 = f^2 * (da * '''[[MDEventWorkspace]]'s''' ** This operation is not supported, as it is not clear what its meaning would be. +== Usage == + + C = A / B + C = A / 123.4 + A /= B + A /= 123.4 + +See [[MDHistoWorkspace#Arithmetic_Operations|this page]] for examples on using arithmetic operations. + *WIKI*/ #include "MantidMDAlgorithms/DivideMD.h" diff --git a/Code/Mantid/Framework/MDAlgorithms/src/EqualToMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/EqualToMD.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4b4ffcddeeca7f830bf19c842994200da6b7f915 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/src/EqualToMD.cpp @@ -0,0 +1,75 @@ +/*WIKI* + +Perform the == (equals to) boolean operation on two MDHistoWorkspaces or a MDHistoWorkspace and a scalar. +The output workspace has a signal of 0.0 to mean "false" and a signal of 1.0 to mean "true". Errors are 0. + +For two MDHistoWorkspaces, the operation is performed element-by-element. Only the signal is compared. + +For a MDHistoWorkspace and a scalar, the operation is performed on each element of the output. + +== Usage == + +See [[MDHistoWorkspace#Boolean_Operations|this page]] for examples on using boolean operations. + +*WIKI*/ + +#include "MantidMDAlgorithms/EqualToMD.h" +#include "MantidKernel/System.h" + +using namespace Mantid::Kernel; +using namespace Mantid::API; + +namespace Mantid +{ +namespace MDAlgorithms +{ + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(EqualToMD) + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + EqualToMD::EqualToMD() + { } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + EqualToMD::~EqualToMD() + { } + + //---------------------------------------------------------------------------------------------- + /// Algorithm's name for identification. @see Algorithm::name + const std::string EqualToMD::name() const { return "EqualToMD";}; + + /// Algorithm's version for identification. @see Algorithm::version + int EqualToMD::version() const { return 1;}; + + //---------------------------------------------------------------------------------------------- + /// Extra properties + void EqualToMD::initExtraProperties() + { + declareProperty("Tolerance", 1e-5, + "Tolerance when performing the == comparison. Default 10^-5."); + } + + //---------------------------------------------------------------------------------------------- + /// Run the algorithm with a MDHisotWorkspace as output and operand + void EqualToMD::execHistoHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::MDEvents::MDHistoWorkspace_const_sptr operand) + { + double tolerance = getProperty("Tolerance"); + out->equalTo(*operand, tolerance); + } + + //---------------------------------------------------------------------------------------------- + /// Run the algorithm with a MDHisotWorkspace as output and a scalar on the RHS + void EqualToMD::execHistoScalar(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::DataObjects::WorkspaceSingleValue_const_sptr scalar) + { + double tolerance = getProperty("Tolerance"); + out->equalTo(scalar->dataY(0)[0], tolerance); + } + + +} // namespace Mantid +} // namespace MDAlgorithms diff --git a/Code/Mantid/Framework/MDAlgorithms/src/ExponentialMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/ExponentialMD.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ad9ccfeb3fdfd643cda3413991c647f00dede1c5 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/src/ExponentialMD.cpp @@ -0,0 +1,79 @@ +/*WIKI* + +This executes the exponential function on a MDHistoWorkspace. + +The signal <math>a</math> becomes <math> f = e^a </math> + +The error <math>da</math> becomes <math> df^2 = f^2 * da^2 </math> + +This algorithm cannot be run on a [[MDEventWorkspace]]. Its equivalent on a [[MatrixWorkspace]] is called [[Exponential]]. + +*WIKI*/ + +#include "MantidMDAlgorithms/ExponentialMD.h" +#include "MantidKernel/System.h" + +using namespace Mantid::Kernel; +using namespace Mantid::API; + +namespace Mantid +{ +namespace MDAlgorithms +{ + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(ExponentialMD) + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + ExponentialMD::ExponentialMD() + { } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + ExponentialMD::~ExponentialMD() + { } + + //---------------------------------------------------------------------------------------------- + /// Algorithm's name for identification. @see Algorithm::name + const std::string ExponentialMD::name() const { return "ExponentialMD";}; + + /// Algorithm's version for identification. @see Algorithm::version + int ExponentialMD::version() const { return 1;}; + + //---------------------------------------------------------------------------------------------- + /// Sets documentation strings for this algorithm + void ExponentialMD::initDocs() + { + this->setWikiSummary("Applies the exponential function on a [[MDHistoWorkspace]]."); + this->setOptionalMessage("Applies the exponential function on a MDHistoWorkspace."); + } + + //---------------------------------------------------------------------------------------------- + /// Check the inputs and throw if the algorithm cannot be run + void ExponentialMD::checkInputs() + { + if (!m_in_histo) + throw std::runtime_error(this->name() + " can only be run on a MDHistoWorkspace."); + } + + //---------------------------------------------------------------------------------------------- + /// Run the algorithm on a MDEventWorkspace + void ExponentialMD::execEvent(Mantid::API::IMDEventWorkspace_sptr /*out*/) + { + throw std::runtime_error(this->name() + " can only be run on a MDHistoWorkspace."); + } + + //---------------------------------------------------------------------------------------------- + /// ExponentialMD::Run the algorithm with a MDHistoWorkspace + void ExponentialMD::execHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out) + { + out->exp(); + } + + + +} // namespace Mantid +} // namespace MDAlgorithms diff --git a/Code/Mantid/Framework/MDAlgorithms/src/GreaterThanMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/GreaterThanMD.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d158e54c4a7dcc4f997102288b535e432052df9e --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/src/GreaterThanMD.cpp @@ -0,0 +1,70 @@ +/*WIKI* + +Perform the > (greater-than) boolean operation on two MDHistoWorkspaces or a MDHistoWorkspace and a scalar. +The output workspace has a signal of 0.0 to mean "false" and a signal of 1.0 to mean "true". Errors are 0. + +For two MDHistoWorkspaces, the operation is performed element-by-element. + +For a MDHistoWorkspace and a scalar, the operation is performed on each element of the output. + +== Usage == + + # Compare two workspaces, element-by-element + C = A < B + # Compare a workspace and a number, element-by-element + C = A < 123.4 + +See [[MDHistoWorkspace#Boolean_Operations|this page]] for examples on using boolean operations. + +*WIKI*/ + +#include "MantidMDAlgorithms/GreaterThanMD.h" +#include "MantidKernel/System.h" + +using namespace Mantid::Kernel; +using namespace Mantid::API; + +namespace Mantid +{ +namespace MDAlgorithms +{ + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(GreaterThanMD) + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + GreaterThanMD::GreaterThanMD() + { } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + GreaterThanMD::~GreaterThanMD() + { } + + //---------------------------------------------------------------------------------------------- + /// Algorithm's name for identification. @see Algorithm::name + const std::string GreaterThanMD::name() const { return "GreaterThanMD";}; + + /// Algorithm's version for identification. @see Algorithm::version + int GreaterThanMD::version() const { return 1;}; + + //---------------------------------------------------------------------------------------------- + /// Run the algorithm with a MDHisotWorkspace as output and operand + void GreaterThanMD::execHistoHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::MDEvents::MDHistoWorkspace_const_sptr operand) + { + out->greaterThan(*operand); + } + + //---------------------------------------------------------------------------------------------- + /// Run the algorithm with a MDHisotWorkspace as output and a scalar on the RHS + void GreaterThanMD::execHistoScalar(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::DataObjects::WorkspaceSingleValue_const_sptr scalar) + { + out->greaterThan(scalar->dataY(0)[0]); + } + + +} // namespace Mantid +} // namespace MDAlgorithms diff --git a/Code/Mantid/Framework/MDAlgorithms/src/LessThanMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/LessThanMD.cpp new file mode 100644 index 0000000000000000000000000000000000000000..45273240764190ddc6198a336d9955737a9ab252 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/src/LessThanMD.cpp @@ -0,0 +1,70 @@ +/*WIKI* + +Perform the < (less-than) boolean operation on two MDHistoWorkspaces or a MDHistoWorkspace and a scalar. +The output workspace has a signal of 0.0 to mean "false" and a signal of 1.0 to mean "true". Errors are 0. + +For two MDHistoWorkspaces, the operation is performed element-by-element. + +For a MDHistoWorkspace and a scalar, the operation is performed on each element of the output. + +== Usage == + + # Compare two workspaces, element-by-element + C = A > B + # Compare a workspace and a number, element-by-element + C = A > 123.4 + +See [[MDHistoWorkspace#Boolean_Operations|this page]] for examples on using boolean operations. + +*WIKI*/ + +#include "MantidMDAlgorithms/LessThanMD.h" +#include "MantidKernel/System.h" + +using namespace Mantid::Kernel; +using namespace Mantid::API; + +namespace Mantid +{ +namespace MDAlgorithms +{ + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(LessThanMD) + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + LessThanMD::LessThanMD() + { } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + LessThanMD::~LessThanMD() + { } + + //---------------------------------------------------------------------------------------------- + /// Algorithm's name for identification. @see Algorithm::name + const std::string LessThanMD::name() const { return "LessThanMD";}; + + /// Algorithm's version for identification. @see Algorithm::version + int LessThanMD::version() const { return 1;}; + + //---------------------------------------------------------------------------------------------- + /// Run the algorithm with a MDHisotWorkspace as output and operand + void LessThanMD::execHistoHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::MDEvents::MDHistoWorkspace_const_sptr operand) + { + out->lessThan(*operand); + } + + //---------------------------------------------------------------------------------------------- + /// Run the algorithm with a MDHisotWorkspace as output and a scalar on the RHS + void LessThanMD::execHistoScalar(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::DataObjects::WorkspaceSingleValue_const_sptr scalar) + { + out->lessThan(scalar->dataY(0)[0]); + } + + +} // namespace Mantid +} // namespace MDAlgorithms diff --git a/Code/Mantid/Framework/MDAlgorithms/src/LogarithmMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/LogarithmMD.cpp new file mode 100644 index 0000000000000000000000000000000000000000..19a52ba318010514ac06f180160e8dd7647e5275 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/src/LogarithmMD.cpp @@ -0,0 +1,100 @@ +/*WIKI* + +This executes the natural logarithm operation on a MDHistoWorkspace. + +The signal <math>a</math> becomes <math> f = log(a) </math> + +The error <math>da</math> becomes <math> df^2 = a^2 / da^2 </math> + +This algorithm cannot be run on a [[MDEventWorkspace]]. Its equivalent on a [[MatrixWorkspace]] is called [[Logarithm]]. + +*WIKI*/ + +#include "MantidMDAlgorithms/LogarithmMD.h" +#include "MantidKernel/System.h" + +using namespace Mantid::Kernel; +using namespace Mantid::API; + +namespace Mantid +{ +namespace MDAlgorithms +{ + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(LogarithmMD) + + + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + LogarithmMD::LogarithmMD() + { + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + LogarithmMD::~LogarithmMD() + { + } + + + //---------------------------------------------------------------------------------------------- + /// Algorithm's name for identification. @see Algorithm::name + const std::string LogarithmMD::name() const { return "LogarithmMD";}; + + /// Algorithm's version for identification. @see Algorithm::version + int LogarithmMD::version() const { return 1;}; + + //---------------------------------------------------------------------------------------------- + /// Sets documentation strings for this algorithm + void LogarithmMD::initDocs() + { + this->setWikiSummary("Perform a natural logarithm of a [[MDHistoWorkspace]]."); + this->setOptionalMessage("Perform a natural logarithm of a MDHistoWorkspace."); + } + + //---------------------------------------------------------------------------------------------- + /// Optional method to be subclassed to add properties + void LogarithmMD::initExtraProperties() + { + declareProperty("Filler", 0.0, + "Some values in a workspace can normally be zeros or may get negative values after transformations\n" + "log(x) is not defined for such values, so here is the value, that will be placed as the result of log(x<=0) operation\n" + "Default value is 0"); + declareProperty("Natural",true,"Switch to choose between natural or base 10 logarithm. Default true (natural)."); + } + + //---------------------------------------------------------------------------------------------- + /// Check the inputs and throw if the algorithm cannot be run + void LogarithmMD::checkInputs() + { + if (!m_in_histo) + throw std::runtime_error(this->name() + " can only be run on a MDHistoWorkspace."); + } + + //---------------------------------------------------------------------------------------------- + /// Run the algorithm on a MDEventWorkspace + void LogarithmMD::execEvent(Mantid::API::IMDEventWorkspace_sptr /*out*/) + { + throw std::runtime_error(this->name() + " can only be run on a MDHistoWorkspace."); + } + + //---------------------------------------------------------------------------------------------- + /// LogarithmMD::Run the algorithm with a MDHistoWorkspace + void LogarithmMD::execHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out) + { + bool natural = getProperty("Natural"); + double filler = getProperty("Filler"); + if (natural) + out->log(filler); + else + out->log10(filler); + } + + + +} // namespace Mantid +} // namespace MDAlgorithms diff --git a/Code/Mantid/Framework/MDAlgorithms/src/MinusMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/MinusMD.cpp index 913f01e6bb27dafcd2cb3e8d071feab5ac50df41..cf759ba0cfe0a2c70e0400b761041e388af9172c 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/MinusMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/MinusMD.cpp @@ -10,6 +10,15 @@ Subtract two [[MDHistoWorkspace]]'s or a MDHistoWorkspace and a scalar. * '''[[MDEventWorkspace]]'s''' ** This is not currently supported, but it could be in the future. +== Usage == + + C = A - B + C = A - 123.4 + A -= B + A -= 123.4 + +See [[MDHistoWorkspace#Arithmetic_Operations|this page]] for examples on using arithmetic operations. + *WIKI*/ #include "MantidMDAlgorithms/MinusMD.h" diff --git a/Code/Mantid/Framework/MDAlgorithms/src/MultiplyMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/MultiplyMD.cpp index a281e98b8fea11cf64008786aebd3c4fdce4dde3..42b232ce831e654cc8b5bb24c7c8013ad597893c 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/MultiplyMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/MultiplyMD.cpp @@ -10,6 +10,15 @@ The error of <math> f = a * b </math> is propagated with <math>df^2 = f^2 * (da^ * '''[[MDEventWorkspace]]'s''' ** This operation is not supported, as it is not clear what its meaning would be. +== Usage == + + C = A * B + C = A * 123.4 + A *= B + A *= 123.4 + +See [[MDHistoWorkspace#Arithmetic_Operations|this page]] for examples on using arithmetic operations. + *WIKI*/ #include "MantidMDAlgorithms/MultiplyMD.h" diff --git a/Code/Mantid/Framework/MDAlgorithms/src/NotMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/NotMD.cpp new file mode 100644 index 0000000000000000000000000000000000000000..31a9dadc94de586dfefd0e44fb8a5d32013226d3 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/src/NotMD.cpp @@ -0,0 +1,83 @@ +/*WIKI* + +Perform the Not (negation) boolean operation on a [[MDHistoWorkspace]]. +The not operation is performed element-by-element. +Any 0.0 signal is changed to 1.0 (meaning true). +Any non-zero signal is changed to 0.0 (meaning false). + +== Usage == + + B = ~A + A = ~A + +See [[MDHistoWorkspace#Boolean_Operations|this page]] for examples on using boolean operations. + +*WIKI*/ + +#include "MantidMDAlgorithms/NotMD.h" +#include "MantidKernel/System.h" + +using namespace Mantid::Kernel; +using namespace Mantid::API; + +namespace Mantid +{ +namespace MDAlgorithms +{ + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(NotMD) + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + NotMD::NotMD() + { } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + NotMD::~NotMD() + { } + + //---------------------------------------------------------------------------------------------- + /// Algorithm's name for identification. @see Algorithm::name + const std::string NotMD::name() const { return "NotMD";}; + + /// Algorithm's version for identification. @see Algorithm::version + int NotMD::version() const { return 1;}; + + //---------------------------------------------------------------------------------------------- + /// Sets documentation strings for this algorithm + void NotMD::initDocs() + { + this->setWikiSummary("Performs a boolean negation on a [[MDHistoWorkspace]]."); + this->setOptionalMessage("Performs a boolean negation on a MDHistoWorkspace."); + } + + //---------------------------------------------------------------------------------------------- + /// Check the inputs and throw if the algorithm cannot be run + void NotMD::checkInputs() + { + if (!m_in_histo) + throw std::runtime_error(this->name() + " can only be run on a MDHistoWorkspace."); + } + + //---------------------------------------------------------------------------------------------- + /// Run the algorithm on a MDEventWorkspace + void NotMD::execEvent(Mantid::API::IMDEventWorkspace_sptr /*out*/) + { + throw std::runtime_error(this->name() + " can only be run on a MDHistoWorkspace."); + } + + //---------------------------------------------------------------------------------------------- + /// NotMD::Run the algorithm with a MDHistoWorkspace + void NotMD::execHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out) + { + out->operatorNot(); + } + + + +} // namespace Mantid +} // namespace MDAlgorithms diff --git a/Code/Mantid/Framework/MDAlgorithms/src/OrMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/OrMD.cpp new file mode 100644 index 0000000000000000000000000000000000000000..af5c6bc7524de9cdd40f2b6c051e4c73089c4aaa --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/src/OrMD.cpp @@ -0,0 +1,58 @@ +/*WIKI* + +Perform the Or boolean operation on two MDHistoWorkspaces. +The || operation is performed element-by-element. +A signal of 0.0 means "false" and any non-zero signal is "true". + +== Usage == + + C = A | B + A |= B + +See [[MDHistoWorkspace#Boolean_Operations|this page]] for examples on using boolean operations. + +*WIKI*/ + +#include "MantidMDAlgorithms/OrMD.h" +#include "MantidKernel/System.h" + +using namespace Mantid::Kernel; +using namespace Mantid::API; + +namespace Mantid +{ +namespace MDAlgorithms +{ + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(OrMD) + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + OrMD::OrMD() + { } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + OrMD::~OrMD() + { } + + //---------------------------------------------------------------------------------------------- + /// Algorithm's name for identification. @see Algorithm::name + const std::string OrMD::name() const { return "OrMD";}; + + /// Algorithm's version for identification. @see Algorithm::version + int OrMD::version() const { return 1;}; + + //---------------------------------------------------------------------------------------------- + /// Run the algorithm with a MDHisotWorkspace as output and operand + void OrMD::execHistoHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::MDEvents::MDHistoWorkspace_const_sptr operand) + { + out->operator |=(*operand); + } + + +} // namespace Mantid +} // namespace MDAlgorithms diff --git a/Code/Mantid/Framework/MDAlgorithms/src/PlusMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/PlusMD.cpp index 8193ccf7b0ecfd9d7203e6b2a7fc6e9264f02093..0368b4ed64ba940b2be6bd89e2d2efc9bc071aab 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/PlusMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/PlusMD.cpp @@ -24,6 +24,15 @@ See [[CloneMDWorkspace]] for details, but note that a file-backed [[MDEventWorks Also, be aware that events added to a MDEventWorkspace are currently added '''in memory''' and are not cached to file until [[SaveMD]] or another algorithm requiring it is called. The workspace is marked as 'requiring file update'. +== Usage == + + C = A + B + C = A + 123.4 + A += B + A += 123.4 + +See [[MDHistoWorkspace#Arithmetic_Operations|this page]] for examples on using arithmetic operations. + *WIKI*/ #include "MantidAPI/IMDEventWorkspace.h" diff --git a/Code/Mantid/Framework/MDAlgorithms/src/PowerMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/PowerMD.cpp new file mode 100644 index 0000000000000000000000000000000000000000..43d42749f24e35c22709e1387e0b7740afde7540 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/src/PowerMD.cpp @@ -0,0 +1,88 @@ +/*WIKI* + +This executes the power function on a MDHistoWorkspace. + +The signal <math>a</math> becomes <math> f = a^b </math> + +The error <math>da</math> becomes <math> df^2 = f^2 * b^2 * (da^2 / a^2) </math> + +This algorithm cannot be run on a [[MDEventWorkspace]]. Its equivalent on a [[MatrixWorkspace]] is called [[Power]]. + +*WIKI*/ + +#include "MantidMDAlgorithms/PowerMD.h" +#include "MantidKernel/System.h" + +using namespace Mantid::Kernel; +using namespace Mantid::API; + +namespace Mantid +{ +namespace MDAlgorithms +{ + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(PowerMD) + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + PowerMD::PowerMD() + { } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + PowerMD::~PowerMD() + { } + + //---------------------------------------------------------------------------------------------- + /// Algorithm's name for identification. @see Algorithm::name + const std::string PowerMD::name() const { return "PowerMD";}; + + /// Algorithm's version for identification. @see Algorithm::version + int PowerMD::version() const { return 1;}; + + //---------------------------------------------------------------------------------------------- + /// Sets documentation strings for this algorithm + void PowerMD::initDocs() + { + this->setWikiSummary("Raise a [[MDHistoWorkspace]] to a power."); + this->setOptionalMessage("Raise a MDHistoWorkspace to a power"); + } + + //---------------------------------------------------------------------------------------------- + /// Optional method to be subclassed to add properties + void PowerMD::initExtraProperties() + { + declareProperty("Exponent", 2.0, + "Power to which to raise the values. Default 2.0."); + } + + //---------------------------------------------------------------------------------------------- + /// Check the inputs and throw if the algorithm cannot be run + void PowerMD::checkInputs() + { + if (!m_in_histo) + throw std::runtime_error(this->name() + " can only be run on a MDHistoWorkspace."); + } + + //---------------------------------------------------------------------------------------------- + /// Run the algorithm on a MDEventWorkspace + void PowerMD::execEvent(Mantid::API::IMDEventWorkspace_sptr /*out*/) + { + throw std::runtime_error(this->name() + " can only be run on a MDHistoWorkspace."); + } + + //---------------------------------------------------------------------------------------------- + /// PowerMD::Run the algorithm with a MDHistoWorkspace + void PowerMD::execHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out) + { + double exponent = getProperty("Exponent"); + out->power(exponent); + } + + + +} // namespace Mantid +} // namespace MDAlgorithms diff --git a/Code/Mantid/Framework/MDAlgorithms/src/SetMDUsingMask.cpp b/Code/Mantid/Framework/MDAlgorithms/src/SetMDUsingMask.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2d5ebec01af9e7850091e283adfff67774b33151 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/src/SetMDUsingMask.cpp @@ -0,0 +1,158 @@ +/*WIKI* + +This algorithm is used to replace values in a [[MDHistoWorkspace]] but only at particular points. + +A mask MDHistoWorkspace is provided, where non-zero values indicate 'true'. +At these points, the corresponding value in the ValueWorkspace will be set. +Any 'false' points in the MaskWorkspace are skipped. + +If ValueWorkspace is not specified, the you must specify Value, which is a a simple number to set. + +In matlab, the equivalent function call would be WS[mask] = OtherWS[mask] + +See [[MDHistoWorkspace#Boolean_Operations| this page on boolean operations]] for examples of how to create a mask. + +== Usage (Python) == + + # This will zero-out any values below the threshold of 123 + MaskWS = WS < 123 + ModifiedWS = SetMDUsingMask(InputWorkspace=WS, Value="0", MaskWorkspace=MaskWS) + +*WIKI*/ + +#include "MantidMDAlgorithms/SetMDUsingMask.h" +#include "MantidKernel/System.h" +#include "MantidAPI/IMDWorkspace.h" +#include "MantidAPI/IMDHistoWorkspace.h" +#include "MantidMDEvents/MDHistoWorkspace.h" +#include <float.h> + +using namespace Mantid::Kernel; +using namespace Mantid::API; +using namespace Mantid::MDEvents; + +namespace Mantid +{ +namespace MDAlgorithms +{ + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(SetMDUsingMask) + + + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + SetMDUsingMask::SetMDUsingMask() + { + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + SetMDUsingMask::~SetMDUsingMask() + { + } + + + //---------------------------------------------------------------------------------------------- + /// Algorithm's name for identification. @see Algorithm::name + const std::string SetMDUsingMask::name() const { return "SetMDUsingMask";}; + + /// Algorithm's version for identification. @see Algorithm::version + int SetMDUsingMask::version() const { return 1;}; + + /// Algorithm's category for identification. @see Algorithm::category + const std::string SetMDUsingMask::category() const { return "Arithmetic";} + + //---------------------------------------------------------------------------------------------- + /// Sets documentation strings for this algorithm + void SetMDUsingMask::initDocs() + { + this->setWikiSummary("Algorithm to set a [[MDHistoWorkspace]] in points determined by a mask boolean MDHistoWorkspace."); + this->setOptionalMessage("Algorithm to set a MDHistoWorkspace in points determined by a mask boolean MDHistoWorkspace."); + } + + //---------------------------------------------------------------------------------------------- + /** Initialize the algorithm's properties. + */ + void SetMDUsingMask::init() + { + declareProperty(new WorkspaceProperty<IMDHistoWorkspace>("InputWorkspace","",Direction::Input), + "An input MDHistoWorkspace."); + declareProperty(new WorkspaceProperty<IMDHistoWorkspace>("MaskWorkspace","",Direction::Input), + "A mask MDHistoWorkspace, where true indicates where to set the value."); + + declareProperty(new WorkspaceProperty<IMDHistoWorkspace>("ValueWorkspace","",Direction::Input, true), + "Workspace to copy to the output workspace over the input. Optional - specify this or Value."); + + declareProperty("Value", DBL_MAX, + "Single number to set in the output workspace. Optional - specify this or ValueWorkspace"); + + declareProperty(new WorkspaceProperty<IMDHistoWorkspace>("OutputWorkspace","",Direction::Output), + "An output MDHistoWorkspace."); + } + + //---------------------------------------------------------------------------------------------- + /** Execute the algorithm. + */ + void SetMDUsingMask::exec() + { + IMDHistoWorkspace_sptr inIWS = getProperty("InputWorkspace"); + IMDHistoWorkspace_sptr maskIWS = getProperty("MaskWorkspace"); + IMDHistoWorkspace_sptr outIWS = getProperty("OutputWorkspace"); + IMDHistoWorkspace_sptr valueIWS = getProperty("ValueWorkspace"); + double value = getProperty("Value"); + + bool useValueWS = (value == DBL_MAX); + + if (useValueWS && !valueIWS) + throw std::invalid_argument("You must specify either ValueWorkspace or Value."); + if (!useValueWS && valueIWS) + throw std::invalid_argument("You must specify either ValueWorkspace or Value, not both!"); + + if (maskIWS->getNumDims() != inIWS->getNumDims()) + throw std::invalid_argument("Input and Mask workspace need to have the same number of dimensions."); + if (maskIWS->getNPoints() != inIWS->getNPoints()) + throw std::invalid_argument("Input and Mask workspace need to have the same number of points."); + if (valueIWS) + { + if (maskIWS->getNumDims() != valueIWS->getNumDims()) + throw std::invalid_argument("Input and Value workspace need to have the same number of dimensions."); + if (maskIWS->getNPoints() != valueIWS->getNPoints()) + throw std::invalid_argument("Input and Value workspace need to have the same number of points."); + } + + if (outIWS != inIWS) + { + // Not in-place. So clone the input to the output + IAlgorithm_sptr clone = this->createSubAlgorithm("CloneMDWorkspace", 0.0, 0.5, true); + clone->setProperty("InputWorkspace", boost::dynamic_pointer_cast<IMDWorkspace>(inIWS)); + clone->setPropertyValue("OutputWorkspace", getPropertyValue("OutputWorkspace")); + clone->executeAsSubAlg(); + IMDWorkspace_sptr temp = clone->getProperty("OutputWorkspace"); + outIWS = boost::dynamic_pointer_cast<IMDHistoWorkspace>(temp); + } + + MDHistoWorkspace_sptr outWS = boost::dynamic_pointer_cast<MDHistoWorkspace>(outIWS); + MDHistoWorkspace_sptr maskWS = boost::dynamic_pointer_cast<MDHistoWorkspace>(maskIWS); + MDHistoWorkspace_sptr valueWS = boost::dynamic_pointer_cast<MDHistoWorkspace>(valueIWS); + + if (!outWS || !maskWS) + throw std::runtime_error("Error creating output workspace."); + + // Set either using the WS or the single value + if (useValueWS) + outWS->setUsingMask(*maskWS, *valueWS); + else + outWS->setUsingMask(*maskWS, value, 0.0 /* assume zero error */ ); + + // Save the output + setProperty("OutputWorkspace", outIWS); + } + + + +} // namespace Mantid +} // namespace MDAlgorithms diff --git a/Code/Mantid/Framework/MDAlgorithms/src/UnaryOperationMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/UnaryOperationMD.cpp index 0d1f19df2a1bcecf6d852d80d368ff87466d0cc8..71afdba1d0c393e650efaff844ea0e31d6fe843e 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/UnaryOperationMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/UnaryOperationMD.cpp @@ -49,6 +49,13 @@ namespace Mantid "A MDEventWorkspace or MDHistoWorkspace on which to apply the operation."); declareProperty(new WorkspaceProperty<IMDWorkspace>(outputPropName(),"",Direction::Output), "Name of the output MDEventWorkspace or MDHistoWorkspace."); + this->initExtraProperties(); + } + + //---------------------------------------------------------------------------------------------- + /// Optional method to be subclassed to add properties + void UnaryOperationMD::initExtraProperties() + { } //---------------------------------------------------------------------------------------------- diff --git a/Code/Mantid/Framework/MDAlgorithms/src/XorMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/XorMD.cpp new file mode 100644 index 0000000000000000000000000000000000000000..10f8fd7d711c45deb6187792bafa5e5420057fff --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/src/XorMD.cpp @@ -0,0 +1,58 @@ +/*WIKI* + +Perform the Xor (exclusive-or) boolean operation on two MDHistoWorkspaces. +The xor operation is performed element-by-element. +A signal of 0.0 means "false" and any non-zero signal is "true". + +== Usage == + + C = A ^ B + A ^= B + +See [[MDHistoWorkspace#Boolean_Operations|this page]] for examples on using boolean operations. + +*WIKI*/ + +#include "MantidMDAlgorithms/XorMD.h" +#include "MantidKernel/System.h" + +using namespace Mantid::Kernel; +using namespace Mantid::API; + +namespace Mantid +{ +namespace MDAlgorithms +{ + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(XorMD) + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + XorMD::XorMD() + { } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + XorMD::~XorMD() + { } + + //---------------------------------------------------------------------------------------------- + /// Algorithm's name for identification. @see Algorithm::name + const std::string XorMD::name() const { return "XorMD";}; + + /// Algorithm's version for identification. @see Algorithm::version + int XorMD::version() const { return 1;}; + + //---------------------------------------------------------------------------------------------- + /// Run the algorithm with a MDHisotWorkspace as output and operand + void XorMD::execHistoHisto(Mantid::MDEvents::MDHistoWorkspace_sptr out, Mantid::MDEvents::MDHistoWorkspace_const_sptr operand) + { + out->operator ^=(*operand); + } + + +} // namespace Mantid +} // namespace MDAlgorithms diff --git a/Code/Mantid/Framework/MDAlgorithms/test/AndMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/AndMDTest.h new file mode 100644 index 0000000000000000000000000000000000000000..edf6430fc4e4b2c340913675ecbe65ecf7608fb9 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/test/AndMDTest.h @@ -0,0 +1,49 @@ +#ifndef MANTID_MDALGORITHMS_ANDMDTEST_H_ +#define MANTID_MDALGORITHMS_ANDMDTEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidKernel/Timer.h" +#include "MantidKernel/System.h" +#include <iostream> +#include <iomanip> + +#include "MantidMDAlgorithms/AndMD.h" +#include "MantidTestHelpers/BinaryOperationMDTestHelper.h" +#include "MantidMDEvents/MDHistoWorkspace.h" + +using namespace Mantid; +using namespace Mantid::MDAlgorithms; +using namespace Mantid::API; +using Mantid::MDEvents::MDHistoWorkspace_sptr; + +class AndMDTest : public CxxTest::TestSuite +{ +public: + + void test_Init() + { + AndMD alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_histo_histo() + { + MDHistoWorkspace_sptr out; + out = BinaryOperationMDTestHelper::doTest("AndMD", "histo_A", "histo_zero", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 0.0, 1e-5); + out = BinaryOperationMDTestHelper::doTest("AndMD", "histo_A", "histo_B", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 1.0, 1e-5); + } + + void test_scalar_or_event_fails() + { + BinaryOperationMDTestHelper::doTest("AndMD", "histo_A", "scalar", "out", false /*fails*/); + BinaryOperationMDTestHelper::doTest("AndMD", "event_A", "event_B", "out", false /*fails*/); + } + + +}; + + +#endif /* MANTID_MDALGORITHMS_ANDMDTEST_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/test/BooleanBinaryOperationMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/BooleanBinaryOperationMDTest.h new file mode 100644 index 0000000000000000000000000000000000000000..adcdb43bfa543e0e19a2bd570733b415599cf96b --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/test/BooleanBinaryOperationMDTest.h @@ -0,0 +1,42 @@ +#ifndef MANTID_MDALGORITHMS_BOOLEANBINARYOPERATIONMDTEST_H_ +#define MANTID_MDALGORITHMS_BOOLEANBINARYOPERATIONMDTEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidKernel/Timer.h" +#include "MantidKernel/System.h" +#include <iostream> +#include <iomanip> +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include "MantidMDAlgorithms/BooleanBinaryOperationMD.h" + +using namespace Mantid; +using namespace Mantid::MDAlgorithms; +using namespace Mantid::API; +using namespace testing; + +class MockBooleanBinaryOperationMD : public BooleanBinaryOperationMD +{ +public: + MOCK_METHOD0(initExtraProperties, void()); + MOCK_METHOD2(execHistoHisto, void(Mantid::MDEvents::MDHistoWorkspace_sptr, Mantid::MDEvents::MDHistoWorkspace_const_sptr)); +}; + + +class BooleanBinaryOperationMDTest : public CxxTest::TestSuite +{ +public: + + void test_basics() + { + MockBooleanBinaryOperationMD alg; + EXPECT_CALL(alg, initExtraProperties()).Times(1); + alg.initialize(); + TSM_ASSERT("Algorithm methods were called as expected", testing::Mock::VerifyAndClearExpectations(&alg)); + } + + +}; + + +#endif /* MANTID_MDALGORITHMS_BOOLEANBINARYOPERATIONMDTEST_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/test/EqualToMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/EqualToMDTest.h new file mode 100644 index 0000000000000000000000000000000000000000..a84cf543682fe1aae8ea429f0d5aa104ed59030d --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/test/EqualToMDTest.h @@ -0,0 +1,66 @@ +#ifndef MANTID_MDALGORITHMS_EQUALTOMDTEST_H_ +#define MANTID_MDALGORITHMS_EQUALTOMDTEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidKernel/Timer.h" +#include "MantidKernel/System.h" +#include <iostream> +#include <iomanip> + +#include "MantidMDAlgorithms/EqualToMD.h" +#include "MantidTestHelpers/BinaryOperationMDTestHelper.h" +#include "MantidMDEvents/MDHistoWorkspace.h" + +using namespace Mantid; +using namespace Mantid::MDAlgorithms; +using namespace Mantid::API; +using Mantid::MDEvents::MDHistoWorkspace_sptr; + +class EqualToMDTest : public CxxTest::TestSuite +{ +public: + void test_Init() + { + EqualToMD alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_histo_histo() + { + MDHistoWorkspace_sptr out; + out = BinaryOperationMDTestHelper::doTest("EqualToMD", "histo_A", "histo_B", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 0.0, 1e-5); + out = BinaryOperationMDTestHelper::doTest("EqualToMD", "histo_B", "histo_B", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 1.0, 1e-5); + } + + void test_histo_scalar() + { + MDHistoWorkspace_sptr out; + out = BinaryOperationMDTestHelper::doTest("EqualToMD", "histo_A", "scalar", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 0.0, 1e-5); + out = BinaryOperationMDTestHelper::doTest("EqualToMD", "scalar", "histo_B", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 1.0, 1e-5); + } + + void test_event_fails() + { + BinaryOperationMDTestHelper::doTest("EqualToMD", "event_A", "scalar", "out", false /*fails*/); + BinaryOperationMDTestHelper::doTest("EqualToMD", "event_A", "event_B", "out", false /*fails*/); + } + + void test_Tolerance() + { + MDHistoWorkspace_sptr out; + out = BinaryOperationMDTestHelper::doTest("EqualToMD", "histo_A", "histo_B", "out", true, "Tolerance", "1.5"); + // Large enough tolerance to say that 2 == 3 (give or take 1.5) + TS_ASSERT_DELTA( out->getSignalAt(0), 1.0, 1e-5); + } + + + +}; + + +#endif /* MANTID_MDALGORITHMS_EQUALTOMDTEST_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/test/ExponentialMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/ExponentialMDTest.h new file mode 100644 index 0000000000000000000000000000000000000000..83fc8d93cf7b32f559c6d872ec55fca167e851d3 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/test/ExponentialMDTest.h @@ -0,0 +1,45 @@ +#ifndef MANTID_MDALGORITHMS_EXPONENTIALMDTEST_H_ +#define MANTID_MDALGORITHMS_EXPONENTIALMDTEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidKernel/Timer.h" +#include "MantidKernel/System.h" +#include <iostream> +#include <iomanip> + +#include "MantidMDAlgorithms/ExponentialMD.h" +#include "MantidTestHelpers/BinaryOperationMDTestHelper.h" +#include "MantidMDEvents/MDHistoWorkspace.h" + +using namespace Mantid; +using namespace Mantid::MDAlgorithms; +using namespace Mantid::API; +using Mantid::MDEvents::MDHistoWorkspace_sptr; + +class ExponentialMDTest : public CxxTest::TestSuite +{ +public: + void test_Init() + { + ExponentialMD alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_histo() + { + MDHistoWorkspace_sptr out; + out = UnaryOperationMDTestHelper::doTest("ExponentialMD", "histo", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), exp(2.0), 1e-5); + } + + void test_event_fails() + { + UnaryOperationMDTestHelper::doTest("ExponentialMD", "event", "out", false /* fails*/); + } + + +}; + + +#endif /* MANTID_MDALGORITHMS_EXPONENTIALMDTEST_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/test/GreaterThanMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/GreaterThanMDTest.h new file mode 100644 index 0000000000000000000000000000000000000000..c96946af1b01def928b3fe4fd84d97f6e405b3b1 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/test/GreaterThanMDTest.h @@ -0,0 +1,61 @@ +#ifndef MANTID_MDALGORITHMS_GREATERTHANMDTEST_H_ +#define MANTID_MDALGORITHMS_GREATERTHANMDTEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidKernel/Timer.h" +#include "MantidKernel/System.h" +#include <iostream> +#include <iomanip> + +#include "MantidMDAlgorithms/GreaterThanMD.h" +#include "MantidTestHelpers/BinaryOperationMDTestHelper.h" +#include "MantidMDEvents/MDHistoWorkspace.h" + +using namespace Mantid; +using namespace Mantid::MDAlgorithms; +using namespace Mantid::API; +using Mantid::MDEvents::MDHistoWorkspace_sptr; + +class GreaterThanMDTest : public CxxTest::TestSuite +{ +public: + void test_Init() + { + GreaterThanMD alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_histo_histo() + { + MDHistoWorkspace_sptr out; + out = BinaryOperationMDTestHelper::doTest("GreaterThanMD", "histo_A", "histo_B", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 0.0, 1e-5); + out = BinaryOperationMDTestHelper::doTest("GreaterThanMD", "histo_B", "histo_A", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 1.0, 1e-5); + } + + void test_histo_scalar() + { + MDHistoWorkspace_sptr out; + out = BinaryOperationMDTestHelper::doTest("GreaterThanMD", "histo_A", "scalar", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 0.0, 1e-5); + } + + void test_event_fails() + { + BinaryOperationMDTestHelper::doTest("GreaterThanMD", "event_A", "scalar", "out", false /*fails*/); + BinaryOperationMDTestHelper::doTest("GreaterThanMD", "event_A", "event_B", "out", false /*fails*/); + } + + void test_scalar_histo_fails() + { + BinaryOperationMDTestHelper::doTest("GreaterThanMD", "scalar", "histo_A", "out", false /*fails*/); + } + + + +}; + + +#endif /* MANTID_MDALGORITHMS_GREATERTHANMDTEST_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/test/LessThanMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/LessThanMDTest.h new file mode 100644 index 0000000000000000000000000000000000000000..4706f2dfd804f7844fa51e41a58607c262d5d1c3 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/test/LessThanMDTest.h @@ -0,0 +1,61 @@ +#ifndef MANTID_MDALGORITHMS_LESSTHANMDTEST_H_ +#define MANTID_MDALGORITHMS_LESSTHANMDTEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidKernel/Timer.h" +#include "MantidKernel/System.h" +#include <iostream> +#include <iomanip> + +#include "MantidMDAlgorithms/LessThanMD.h" +#include "MantidTestHelpers/BinaryOperationMDTestHelper.h" +#include "MantidMDEvents/MDHistoWorkspace.h" + +using namespace Mantid; +using namespace Mantid::MDAlgorithms; +using namespace Mantid::API; +using Mantid::MDEvents::MDHistoWorkspace_sptr; + +class LessThanMDTest : public CxxTest::TestSuite +{ +public: + + void test_Init() + { + LessThanMD alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_histo_histo() + { + MDHistoWorkspace_sptr out; + out = BinaryOperationMDTestHelper::doTest("LessThanMD", "histo_A", "histo_B", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 1.0, 1e-5); + out = BinaryOperationMDTestHelper::doTest("LessThanMD", "histo_B", "histo_A", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 0.0, 1e-5); + } + + void test_histo_scalar() + { + MDHistoWorkspace_sptr out; + out = BinaryOperationMDTestHelper::doTest("LessThanMD", "histo_A", "scalar", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 1.0, 1e-5); + } + + void test_event_fails() + { + BinaryOperationMDTestHelper::doTest("LessThanMD", "event_A", "scalar", "out", false /*fails*/); + BinaryOperationMDTestHelper::doTest("LessThanMD", "event_A", "event_B", "out", false /*fails*/); + } + + void test_scalar_histo_fails() + { + BinaryOperationMDTestHelper::doTest("LessThanMD", "scalar", "histo_A", "out", false /*fails*/); + } + + +}; + + +#endif /* MANTID_MDALGORITHMS_LESSTHANMDTEST_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/test/LogarithmMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/LogarithmMDTest.h new file mode 100644 index 0000000000000000000000000000000000000000..ad0dd5d378832d577e81ed8facb5d33763a19823 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/test/LogarithmMDTest.h @@ -0,0 +1,53 @@ +#ifndef MANTID_MDALGORITHMS_LOGARITHMMDTEST_H_ +#define MANTID_MDALGORITHMS_LOGARITHMMDTEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidKernel/Timer.h" +#include "MantidKernel/System.h" +#include <iostream> +#include <iomanip> + +#include "MantidMDAlgorithms/LogarithmMD.h" +#include "MantidMDEvents/MDHistoWorkspace.h" +#include "MantidTestHelpers/BinaryOperationMDTestHelper.h" + +using namespace Mantid; +using namespace Mantid::MDAlgorithms; +using namespace Mantid::API; +using Mantid::MDEvents::MDHistoWorkspace_sptr; + +class LogarithmMDTest : public CxxTest::TestSuite +{ +public: + void test_Init() + { + LogarithmMD alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_histo() + { + MDHistoWorkspace_sptr out; + out = UnaryOperationMDTestHelper::doTest("LogarithmMD", "histo", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), std::log(2.0), 1e-5); + } + + void test_histo_with_not_Natural() + { + MDHistoWorkspace_sptr out; + out = UnaryOperationMDTestHelper::doTest("LogarithmMD", "histo", "out", true, "Natural", "0"); + TS_ASSERT_DELTA( out->getSignalAt(0), std::log10(2.0), 1e-5); + } + + void test_event_fails() + { + UnaryOperationMDTestHelper::doTest("LogarithmMD", "event", "out", false /* fails*/); + } + + + +}; + + +#endif /* MANTID_MDALGORITHMS_LOGARITHMMDTEST_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/test/NotMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/NotMDTest.h new file mode 100644 index 0000000000000000000000000000000000000000..e4ea5e62514fdae84c7c9a152853b2322c118a79 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/test/NotMDTest.h @@ -0,0 +1,45 @@ +#ifndef MANTID_MDALGORITHMS_NOTMDTEST_H_ +#define MANTID_MDALGORITHMS_NOTMDTEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidKernel/Timer.h" +#include "MantidKernel/System.h" +#include <iostream> +#include <iomanip> + +#include "MantidMDAlgorithms/NotMD.h" +#include "MantidTestHelpers/BinaryOperationMDTestHelper.h" +#include "MantidMDEvents/MDHistoWorkspace.h" + +using namespace Mantid; +using namespace Mantid::MDAlgorithms; +using namespace Mantid::API; +using Mantid::MDEvents::MDHistoWorkspace_sptr; + +class NotMDTest : public CxxTest::TestSuite +{ +public: + void test_Init() + { + NotMD alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_histo() + { + MDHistoWorkspace_sptr out; + out = UnaryOperationMDTestHelper::doTest("NotMD", "histo", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 0.0, 1e-5); + } + + void test_event_fails() + { + UnaryOperationMDTestHelper::doTest("NotMD", "event", "out", false /* fails*/); + } + + +}; + + +#endif /* MANTID_MDALGORITHMS_NOTMDTEST_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/test/OrMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/OrMDTest.h new file mode 100644 index 0000000000000000000000000000000000000000..bb1427ea3f87ede4349841b5c4d68ada9ef97e5f --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/test/OrMDTest.h @@ -0,0 +1,49 @@ +#ifndef MANTID_MDALGORITHMS_ORMDTEST_H_ +#define MANTID_MDALGORITHMS_ORMDTEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidKernel/Timer.h" +#include "MantidKernel/System.h" +#include <iostream> +#include <iomanip> + +#include "MantidMDAlgorithms/OrMD.h" +#include "MantidTestHelpers/BinaryOperationMDTestHelper.h" +#include "MantidMDEvents/MDHistoWorkspace.h" + +using namespace Mantid; +using namespace Mantid::MDAlgorithms; +using namespace Mantid::API; +using Mantid::MDEvents::MDHistoWorkspace_sptr; + +class OrMDTest : public CxxTest::TestSuite +{ +public: + + void test_Init() + { + OrMD alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_histo_histo() + { + MDHistoWorkspace_sptr out; + out = BinaryOperationMDTestHelper::doTest("OrMD", "histo_A", "histo_zero", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 1.0, 1e-5); + out = BinaryOperationMDTestHelper::doTest("OrMD", "histo_zero", "histo_zero", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 0.0, 1e-5); + } + + void test_scalar_or_event_fails() + { + BinaryOperationMDTestHelper::doTest("OrMD", "histo_A", "scalar", "out", false /*fails*/); + BinaryOperationMDTestHelper::doTest("OrMD", "event_A", "event_B", "out", false /*fails*/); + } + + +}; + + +#endif /* MANTID_MDALGORITHMS_ORMDTEST_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/test/PlusMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/PlusMDTest.h index 8b474c467853bc6b50fe0dcd00c8bbe5d6e5ea7c..eb1b2032098b0a82cfc70bacd1336a8bc2dcc2f9 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/PlusMDTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/PlusMDTest.h @@ -119,7 +119,6 @@ public: void test_mem_plus_file_inPlace() { do_test(false, true, 1); } -//FIXME: Test fails on Windows7 build server. http://trac.mantidproject.org/mantid/ticket/4028 void test_file_plus_file() { do_test(true, true, 0); } diff --git a/Code/Mantid/Framework/MDAlgorithms/test/PowerMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/PowerMDTest.h new file mode 100644 index 0000000000000000000000000000000000000000..86cdbbab9e37ea56bda38cc649a5f63819075707 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/test/PowerMDTest.h @@ -0,0 +1,53 @@ +#ifndef MANTID_MDALGORITHMS_POWERMDTEST_H_ +#define MANTID_MDALGORITHMS_POWERMDTEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidKernel/Timer.h" +#include "MantidKernel/System.h" +#include <iostream> +#include <iomanip> + +#include "MantidMDAlgorithms/PowerMD.h" +#include "MantidTestHelpers/BinaryOperationMDTestHelper.h" +#include "MantidMDEvents/MDHistoWorkspace.h" + +using namespace Mantid; +using namespace Mantid::MDAlgorithms; +using namespace Mantid::API; +using Mantid::MDEvents::MDHistoWorkspace_sptr; + +class PowerMDTest : public CxxTest::TestSuite +{ +public: + void test_Init() + { + PowerMD alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_histo() + { + MDHistoWorkspace_sptr out; + out = UnaryOperationMDTestHelper::doTest("PowerMD", "histo", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 4.0, 1e-5); + } + + void test_histo_with_Exponent() + { + MDHistoWorkspace_sptr out; + out = UnaryOperationMDTestHelper::doTest("PowerMD", "histo", "out", true, "Exponent", "-3.0"); + TS_ASSERT_DELTA( out->getSignalAt(0), 1./8., 1e-5); + } + + void test_event_fails() + { + UnaryOperationMDTestHelper::doTest("PowerMD", "event", "out", false /* fails*/); + } + + + +}; + + +#endif /* MANTID_MDALGORITHMS_POWERMDTEST_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/test/SetMDUsingMaskTest.h b/Code/Mantid/Framework/MDAlgorithms/test/SetMDUsingMaskTest.h new file mode 100644 index 0000000000000000000000000000000000000000..75c8b797f19ee5fd2aa2868d1a84c665fc9b6d40 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/test/SetMDUsingMaskTest.h @@ -0,0 +1,110 @@ +#ifndef MANTID_MDALGORITHMS_SETMDUSINGMASKTEST_H_ +#define MANTID_MDALGORITHMS_SETMDUSINGMASKTEST_H_ + +#include "MantidAPI/AnalysisDataService.h" +#include "MantidAPI/IMDHistoWorkspace.h" +#include "MantidKernel/System.h" +#include "MantidKernel/Timer.h" +#include "MantidMDAlgorithms/SetMDUsingMask.h" +#include "MantidMDEvents/MDHistoWorkspace.h" +#include "MantidTestHelpers/MDEventsTestHelper.h" +#include <cxxtest/TestSuite.h> +#include <iomanip> +#include <iostream> + +using namespace Mantid; +using namespace Mantid::MDAlgorithms; +using namespace Mantid::API; +using namespace Mantid::MDEvents; + +class SetMDUsingMaskTest : public CxxTest::TestSuite +{ +public: + void test_Init() + { + SetMDUsingMask alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void do_test(std::string InputWorkspace, std::string MaskWorkspace, + std::string ValueWorkspace, std::string Value, + std::string OutputWorkspace, + double expectedSignal, double expectedError, + bool succeeds=true) + { + MDHistoWorkspace_sptr histo_A = MDEventsTestHelper::makeFakeMDHistoWorkspace(2.0, 2, 5, 10.0, 2.0); + MDHistoWorkspace_sptr histo_B = MDEventsTestHelper::makeFakeMDHistoWorkspace(3.0, 2, 5, 10.0, 3.0); + MDHistoWorkspace_sptr histo_diff = MDEventsTestHelper::makeFakeMDHistoWorkspace(2.0, 2, 4, 10.0, 2.0); + MDHistoWorkspace_sptr mask_0 = MDEventsTestHelper::makeFakeMDHistoWorkspace(0.0, 2, 5, 10.0, 0.0); + MDHistoWorkspace_sptr mask_1 = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 2, 5, 10.0, 0.0); + AnalysisDataService::Instance().addOrReplace("histo_A", histo_A); + AnalysisDataService::Instance().addOrReplace("histo_B", histo_B); + AnalysisDataService::Instance().addOrReplace("histo_diff", histo_diff); + AnalysisDataService::Instance().addOrReplace("mask_0", mask_0); + AnalysisDataService::Instance().addOrReplace("mask_1", mask_1); + + + SetMDUsingMask alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace", InputWorkspace) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("MaskWorkspace", MaskWorkspace) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("ValueWorkspace", ValueWorkspace) ); + if (!Value.empty()) TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Value", Value) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", OutputWorkspace) ); + TS_ASSERT_THROWS_NOTHING( alg.execute(); ); + + if (succeeds) + { + TS_ASSERT( alg.isExecuted() ); + // Retrieve the workspace from data service. + IMDHistoWorkspace_sptr ws; + TS_ASSERT_THROWS_NOTHING( ws = boost::dynamic_pointer_cast<IMDHistoWorkspace>(AnalysisDataService::Instance().retrieve(OutputWorkspace)) ); + TS_ASSERT(ws); + if (!ws) return; + TS_ASSERT_DELTA( ws->signalAt(0), expectedSignal, 1e-6); + TS_ASSERT_DELTA( ws->errorSquaredAt(0), expectedError, 1e-6); + } + else + { + TS_ASSERT( !alg.isExecuted() ); + } + } + + + void test_bad_inputs() + { + do_test("histo_A", "histo_diff", "histo_B", "", "out", 0,0, false); + do_test("histo_A", "mask_1", "histo_diff", "", "out", 0,0, false); + do_test("histo_A", "histo_diff", "histo_diff", "", "out", 0,0, false); + } + + void test_not_inplace() + { + do_test("histo_A", "mask_0", "histo_B", "", "out", 2.0, 2.0); + do_test("histo_A", "mask_1", "histo_B", "", "out", 3.0, 3.0); + } + + void test_not_inplace_double() + { + do_test("histo_A", "mask_0", "", "34.5", "out", 2.0, 2.0); + do_test("histo_A", "mask_1", "", "34.5", "out", 34.5, 0.); + } + + void test_inplace() + { + do_test("histo_A", "mask_0", "histo_B", "", "histo_A", 2.0, 2.0); + do_test("histo_A", "mask_1", "histo_B", "", "histo_A", 3.0, 3.0); + } + + void test_inplace_double() + { + do_test("histo_A", "mask_0", "", "34.5", "histo_A", 2.0, 2.0); + do_test("histo_A", "mask_1", "", "34.5", "histo_A", 34.5, 0.); + } + +}; + + +#endif /* MANTID_MDALGORITHMS_SETMDUSINGMASKTEST_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/test/XorMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/XorMDTest.h new file mode 100644 index 0000000000000000000000000000000000000000..a0dd0c6ccb12e161b179af5c4799044c813c91bb --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/test/XorMDTest.h @@ -0,0 +1,49 @@ +#ifndef MANTID_MDALGORITHMS_XORMDTEST_H_ +#define MANTID_MDALGORITHMS_XORMDTEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidKernel/Timer.h" +#include "MantidKernel/System.h" +#include <iostream> +#include <iomanip> + +#include "MantidMDAlgorithms/XorMD.h" +#include "MantidTestHelpers/BinaryOperationMDTestHelper.h" +#include "MantidMDEvents/MDHistoWorkspace.h" + +using namespace Mantid; +using namespace Mantid::MDAlgorithms; +using namespace Mantid::API; +using Mantid::MDEvents::MDHistoWorkspace_sptr; + +class XorMDTest : public CxxTest::TestSuite +{ +public: + + void test_Init() + { + XorMD alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_histo_histo() + { + MDHistoWorkspace_sptr out; + out = BinaryOperationMDTestHelper::doTest("XorMD", "histo_A", "histo_zero", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 1.0, 1e-5); + out = BinaryOperationMDTestHelper::doTest("XorMD", "histo_A", "histo_B", "out"); + TS_ASSERT_DELTA( out->getSignalAt(0), 0.0, 1e-5); + } + + void test_scalar_or_event_fails() + { + BinaryOperationMDTestHelper::doTest("XorMD", "histo_A", "scalar", "out", false /*fails*/); + BinaryOperationMDTestHelper::doTest("XorMD", "event_A", "event_B", "out", false /*fails*/); + } + + +}; + + +#endif /* MANTID_MDALGORITHMS_XORMDTEST_H_ */ diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspace.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspace.h index 451e70ea3aa1ab3e434cea0b93d38e0e15c3f983..90a5d187ede9ea56399ec11ccd32517eac200d1e 100644 --- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspace.h +++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspace.h @@ -10,6 +10,7 @@ #include "MantidKernel/Exception.h" #include "MantidKernel/System.h" #include "MantidDataObjects/WorkspaceSingleValue.h" +#include "MantidAPI/IMDHistoWorkspace.h" using Mantid::DataObjects::WorkspaceSingleValue; @@ -32,7 +33,7 @@ namespace MDEvents * @author Janik Zikovsky * @date 2011-03-24 11:21:06.280523 */ - class DLLExport MDHistoWorkspace : public API::IMDWorkspace + class DLLExport MDHistoWorkspace : public API::IMDHistoWorkspace { public: MDHistoWorkspace(Mantid::Geometry::MDHistoDimension_sptr dimX, @@ -81,15 +82,26 @@ namespace MDEvents void divide(const MDHistoWorkspace & b); void divide(const signal_t signal, const signal_t error); + void log(double filler = 0.0); + void log10(double filler = 0.0); + void exp(); + void power(double exponent); + + // -------------------------------------------------------------------------------------------- MDHistoWorkspace & operator&=(const MDHistoWorkspace & b); MDHistoWorkspace & operator|=(const MDHistoWorkspace & b); MDHistoWorkspace & operator^=(const MDHistoWorkspace & b); - void operatorNot(); - void log(); - void log10(); - void exp(); - void power(double exponent); + + void lessThan(const MDHistoWorkspace & b); + void lessThan(const signal_t signal); + void greaterThan(const MDHistoWorkspace & b); + void greaterThan(const signal_t signal); + void equalTo(const MDHistoWorkspace & b, const signal_t tolerance=1e-5); + void equalTo(const signal_t signal, const signal_t tolerance=1e-5); + + void setUsingMask(const MDHistoWorkspace & mask, const MDHistoWorkspace & values); + void setUsingMask(const MDHistoWorkspace & mask, const signal_t signal, const signal_t error); @@ -109,7 +121,7 @@ namespace MDEvents } /** @return the inverse of volume of EACH cell in the workspace. For normalizing. */ - coord_t getInverseVolumeVolume() const + coord_t getInverseVolume() const { return m_inverseVolume; } @@ -138,13 +150,13 @@ namespace MDEvents } /// Sets the error (squared) at the specified index. - void setErrorAt(size_t index, signal_t value) + void setErrorSquaredAt(size_t index, signal_t value) { m_errorsSquared[index] = value; } - /// Get the error of the signal at the specified index. + /// Get the error (squared) of the signal at the specified index. signal_t getErrorAt(size_t index) const { return m_errorsSquared[index]; @@ -247,6 +259,64 @@ namespace MDEvents return getErrorAt(index1,index2,index3,index4) * m_inverseVolume; } + //--------------------------------------------------------------------------------------------- + /** @return a reference to the error (squared) at the linear index + * @param index :: linear index (see getLinearIndex). */ + signal_t & errorSquaredAt(size_t index) + { + if (index < m_length) + return m_errorsSquared[index]; + else + throw std::invalid_argument("MDHistoWorkspace::array index out of range"); + } + + /** @return a reference to the signal at the linear index + * @param index :: linear index (see getLinearIndex). */ + signal_t & signalAt(size_t index) + { + if (index < m_length) + return m_signals[index]; + else + throw std::invalid_argument("MDHistoWorkspace::array index out of range"); + } + + //--------------------------------------------------------------------------------------------- + size_t getLinearIndex(size_t index1, size_t index2) const + { + if (this->getNumDims() != 2) + throw std::runtime_error("Workspace does not have 2 dimensions!"); + return index1 + indexMultiplier[0]*index2; + } + + size_t getLinearIndex(size_t index1, size_t index2, size_t index3) const + { + if (this->getNumDims() != 3) + throw std::runtime_error("Workspace does not have 3 dimensions!"); + return index1 + indexMultiplier[0]*index2 + indexMultiplier[1]*index3; + } + + size_t getLinearIndex(size_t index1, size_t index2, size_t index3, size_t index4) const + { + if (this->getNumDims() != 4) + throw std::runtime_error("Workspace does not have 4 dimensions!"); + return index1 + indexMultiplier[0]*index2 + indexMultiplier[1]*index3 + indexMultiplier[2]*index4; + } + + + + /** Array subscript operator + * @param index :: linear index into array + * @return the signal (not normalized) at that index. + */ + signal_t& operator [](const size_t & index) + { + if (index < m_length) + return m_signals[index]; + else + throw std::invalid_argument("MDHistoWorkspace::array index out of range"); + } + + /// Return a vector containing a copy of the signal data in the workspace. TODO: Make this more efficient if needed. virtual std::vector<signal_t> getSignalDataVector() const; diff --git a/Code/Mantid/Framework/MDEvents/src/BinToMDHistoWorkspace.cpp b/Code/Mantid/Framework/MDEvents/src/BinToMDHistoWorkspace.cpp index 92c6d442c50f0e4edcf53734bc5433f150a16d91..0a40d9626b76bdc85d54ae0825d288c9064964d2 100644 --- a/Code/Mantid/Framework/MDEvents/src/BinToMDHistoWorkspace.cpp +++ b/Code/Mantid/Framework/MDEvents/src/BinToMDHistoWorkspace.cpp @@ -458,7 +458,7 @@ namespace MDEvents // Save the data into the dense histogram outWS->setSignalAt(linear_index, bin.m_signal); - outWS->setErrorAt(linear_index, bin.m_errorSquared); + outWS->setErrorSquaredAt(linear_index, bin.m_errorSquared); } // Report progress but not too often. diff --git a/Code/Mantid/Framework/MDEvents/src/FindPeaksMD.cpp b/Code/Mantid/Framework/MDEvents/src/FindPeaksMD.cpp index ea2f577c38be6986ea9fcd65fcc5a86a1d0b77d6..ac7876d319f94572f90c1f969d1037df4362d2f4 100644 --- a/Code/Mantid/Framework/MDEvents/src/FindPeaksMD.cpp +++ b/Code/Mantid/Framework/MDEvents/src/FindPeaksMD.cpp @@ -161,8 +161,15 @@ namespace MDEvents // Calculate a threshold below which a box is too diffuse to be considered a peak. signal_t thresholdDensity = 0.0; thresholdDensity = ws->getBox()->getSignalNormalized() * DensityThresholdFactor * densityScalingFactor; + if ((thresholdDensity != thresholdDensity) || (thresholdDensity == std::numeric_limits<double>::infinity()) + || (thresholdDensity == -std::numeric_limits<double>::infinity())) + { + g_log.warning() << "Infinite or NaN overall density found. Your input data may be invaliud. Using a 0 threshold instead." << std::endl; + thresholdDensity = 0; + } g_log.notice() << "Threshold signal density: " << thresholdDensity << std::endl; + // We will fill this vector with pointers to all the boxes (up to a given depth) typename std::vector<boxPtr> boxes; @@ -249,10 +256,10 @@ namespace MDEvents } peakBoxes.push_back(box); - g_log.information() << "Found box at "; + g_log.debug() << "Found box at "; for (size_t d=0; d<nd; d++) - g_log.information() << (d>0?",":"") << boxCenter[d]; - g_log.information() << "; Density = " << density << std::endl; + g_log.debug() << (d>0?",":"") << boxCenter[d]; + g_log.debug() << "; Density = " << density << std::endl; // Report progres for each box found. prog->report("Finding Peaks"); } diff --git a/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspace.cpp b/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspace.cpp index 1316aae60c6867e71b6dd5be44cdcffdd4014e37..2449fea25007f22ba28a067eb083aa3d5d3b98a3 100644 --- a/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspace.cpp +++ b/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspace.cpp @@ -245,7 +245,7 @@ namespace MDEvents coord_t * MDHistoWorkspace::getVertexesArray(size_t linearIndex, size_t & numVertices) const { // How many vertices does one box have? 2^nd, or bitwise shift left 1 by nd bits - numVertices = 1 << numDimensions; + numVertices = (size_t)(1) << numDimensions; // Cast avoids warning about result of 32-bit shift implicitly converted to 64 bits on MSVC // Index into each dimension. Built from the linearIndex. size_t dimIndexes[10]; @@ -349,6 +349,10 @@ namespace MDEvents return out; } + //============================================================================================== + //============================== ARITHMETIC OPERATIONS ========================================= + //============================================================================================== + //---------------------------------------------------------------------------------------------- /** Check if the two workspace's sizes match (for comparison or element-by-element operation * @@ -588,6 +592,95 @@ namespace MDEvents } } + //---------------------------------------------------------------------------------------------- + /** Perform the natural logarithm on each signal in the workspace. + * + * Error propagation of \f$ f = ln(a) \f$ is given by: + * \f$ df^2 = a^2 / da^2 \f$ + */ + void MDHistoWorkspace::log(double filler) + { + for (size_t i=0; i<m_length; ++i) + { + signal_t a = m_signals[i]; + signal_t da2 = m_errorsSquared[i]; + if (a <= 0) + { + m_signals[i] = filler; + m_errorsSquared[i] = 0; + } + else + { + m_signals[i] = std::log(a); + m_errorsSquared[i] = da2 / (a*a); + } + } + } + + //---------------------------------------------------------------------------------------------- + /** Perform the base-10 logarithm on each signal in the workspace. + * + * Error propagation of \f$ f = ln(a) \f$ is given by: + * \f$ df^2 = (ln(10)^-2) * a^2 / da^2 \f$ + */ + void MDHistoWorkspace::log10(double filler) + { + for (size_t i=0; i<m_length; ++i) + { + signal_t a = m_signals[i]; + signal_t da2 = m_errorsSquared[i]; + if (a <= 0) + { + m_signals[i] = filler; + m_errorsSquared[i] = 0; + } + else + { + m_signals[i] = std::log10(a); + m_errorsSquared[i] = 0.1886117 * da2 / (a*a); // 0.1886117 = ln(10)^-2 + } + } + } + + //---------------------------------------------------------------------------------------------- + /** Perform the exp() function on each signal in the workspace. + * + * Error propagation of \f$ f = exp(a) \f$ is given by: + * \f$ df^2 = f^2 * da^2 \f$ + */ + void MDHistoWorkspace::exp() + { + for (size_t i=0; i<m_length; ++i) + { + signal_t f = std::exp(m_signals[i]); + signal_t da2 = m_errorsSquared[i]; + m_signals[i] = f; + m_errorsSquared[i] = f*f * da2; + } + } + + //---------------------------------------------------------------------------------------------- + /** Perform the power function (signal^exponent) on each signal S in the workspace. + * + * Error propagation of \f$ f = a^b \f$ is given by: + * \f$ df^2 = f^2 * b^2 * (da^2 / a^2) \f$ + */ + void MDHistoWorkspace::power(double exponent) + { + double exponent_squared = exponent * exponent; + for (size_t i=0; i<m_length; ++i) + { + signal_t a = m_signals[i]; + signal_t f = std::pow(a, exponent); + signal_t da2 = m_errorsSquared[i]; + m_signals[i] = f; + m_errorsSquared[i] = f*f * exponent_squared * da2 / (a*a); + } + } + + //============================================================================================== + //============================== BOOLEAN OPERATIONS ============================================ + //============================================================================================== //---------------------------------------------------------------------------------------------- /** A boolean &= (and) operation, element-by-element, for two MDHistoWorkspace's. @@ -601,7 +694,7 @@ namespace MDEvents checkWorkspaceSize(b, "&= (and)"); for (size_t i=0; i<m_length; ++i) { - m_signals[i] = m_signals[i] && b.m_signals[i]; + m_signals[i] = ((m_signals[i] != 0) && (b.m_signals[i] != 0)) ? 1.0 : 0.0; m_errorsSquared[i] = 0; } return *this; @@ -619,7 +712,7 @@ namespace MDEvents checkWorkspaceSize(b, "|= (or)"); for (size_t i=0; i<m_length; ++i) { - m_signals[i] = m_signals[i] || b.m_signals[i]; + m_signals[i] = ((m_signals[i] != 0) || (b.m_signals[i] != 0)) ? 1.0 : 0.0; m_errorsSquared[i] = 0; } return *this; @@ -637,7 +730,7 @@ namespace MDEvents checkWorkspaceSize(b, "^= (xor)"); for (size_t i=0; i<m_length; ++i) { - m_signals[i] = bool(m_signals[i]) ^ bool(b.m_signals[i]); + m_signals[i] = ((m_signals[i] != 0) ^ (b.m_signals[i] != 0)) ? 1.0 : 0.0; m_errorsSquared[i] = 0; } return *this; @@ -653,78 +746,178 @@ namespace MDEvents { for (size_t i=0; i<m_length; ++i) { - m_signals[i] = !bool(m_signals[i]); + m_signals[i] = (m_signals[i] == 0.0); m_errorsSquared[i] = 0; } } + //---------------------------------------------------------------------------------------------- - /** Perform the natural logarithm on each signal in the workspace. + /** Turn this workspace into a boolean workspace, where + * signal[i] -> becomes true (1.0) if it is < b[i]. + * signal[i] -> becomes false (0.0) otherwise + * Errors are set to 0. * - * Error propagation of \f$ f = ln(a) \f$ is given by: - * \f$ df^2 = a^2 / da^2 \f$ + * @param b :: workspace on the RHS of the comparison. */ - void MDHistoWorkspace::log() + void MDHistoWorkspace::lessThan(const MDHistoWorkspace & b) { + checkWorkspaceSize(b, "lessThan"); for (size_t i=0; i<m_length; ++i) { - signal_t a = m_signals[i]; - signal_t da2 = m_errorsSquared[i]; - m_signals[i] = std::log(a); - m_errorsSquared[i] = da2 / (a*a); + m_signals[i] = (m_signals[i] < b.m_signals[i]) ? 1.0 : 0.0; + m_errorsSquared[i] = 0; } } //---------------------------------------------------------------------------------------------- - /** Perform the base-10 logarithm on each signal in the workspace. + /** Turn this workspace into a boolean workspace, where + * signal[i] -> becomes true (1.0) if it is < signal. + * signal[i] -> becomes false (0.0) otherwise + * Errors are set to 0. * - * Error propagation of \f$ f = ln(a) \f$ is given by: - * \f$ df^2 = a^2 / da^2 \f$ + * @param signal :: signal value on the RHS of the comparison. */ - void MDHistoWorkspace::log10() + void MDHistoWorkspace::lessThan(const signal_t signal) { for (size_t i=0; i<m_length; ++i) { - signal_t a = m_signals[i]; - signal_t da2 = m_errorsSquared[i]; - m_signals[i] = std::log10(a); - m_errorsSquared[i] = da2 / (a*a); + m_signals[i] = (m_signals[i] < signal) ? 1.0 : 0.0; + m_errorsSquared[i] = 0; } } //---------------------------------------------------------------------------------------------- - /** Perform the exp() function on each signal in the workspace. + /** Turn this workspace into a boolean workspace, where + * signal[i] -> becomes true (1.0) if it is > b[i]. + * signal[i] -> becomes false (0.0) otherwise + * Errors are set to 0. * - * Error propagation of \f$ f = exp(a) \f$ is given by: - * \f$ df^2 = f^2 * da^2 \f$ + * @param b :: workspace on the RHS of the comparison. */ - void MDHistoWorkspace::exp() + void MDHistoWorkspace::greaterThan(const MDHistoWorkspace & b) { + checkWorkspaceSize(b, "greaterThan"); for (size_t i=0; i<m_length; ++i) { - signal_t f = std::exp(m_signals[i]); - signal_t da2 = m_errorsSquared[i]; - m_signals[i] = f; - m_errorsSquared[i] = f*f * da2; + m_signals[i] = (m_signals[i] > b.m_signals[i]) ? 1.0 : 0.0; + m_errorsSquared[i] = 0; } } //---------------------------------------------------------------------------------------------- - /** Perform the power function (signal^exponent) on each signal S in the workspace. + /** Turn this workspace into a boolean workspace, where + * signal[i] -> becomes true (1.0) if it is > signal. + * signal[i] -> becomes false (0.0) otherwise + * Errors are set to 0. * - * Error propagation of \f$ f = a^b \f$ is given by: - * \f$ df^2 = f^2 * b^2 * (da^2 / a^2) \f$ + * @param signal :: signal value on the RHS of the comparison. */ - void MDHistoWorkspace::power(double exponent) + void MDHistoWorkspace::greaterThan(const signal_t signal) { - double exponent_squared = exponent * exponent; for (size_t i=0; i<m_length; ++i) { - signal_t a = m_signals[i]; - signal_t f = std::pow(a, exponent); - signal_t da2 = m_errorsSquared[i]; - m_signals[i] = f; - m_errorsSquared[i] = f*f * exponent_squared * da2 / (a*a); + m_signals[i] = (m_signals[i] > signal) ? 1.0 : 0.0; + m_errorsSquared[i] = 0; + } + } + + //---------------------------------------------------------------------------------------------- + /** Turn this workspace into a boolean workspace, where + * signal[i] -> becomes true (1.0) if it is == b[i]. + * signal[i] -> becomes false (0.0) otherwise + * Errors are set to 0. + * + * @param b :: workspace on the RHS of the comparison. + * @param tolerance :: accept this deviation from a perfect equality + */ + void MDHistoWorkspace::equalTo(const MDHistoWorkspace & b, const signal_t tolerance) + { + checkWorkspaceSize(b, "equalTo"); + for (size_t i=0; i<m_length; ++i) + { + signal_t diff = fabs(m_signals[i] - b.m_signals[i]); + m_signals[i] = (diff < tolerance) ? 1.0 : 0.0; + m_errorsSquared[i] = 0; + } + } + + //---------------------------------------------------------------------------------------------- + /** Turn this workspace into a boolean workspace, where + * signal[i] -> becomes true (1.0) if it is == signal. + * signal[i] -> becomes false (0.0) otherwise + * Errors are set to 0. + * + * @param signal :: signal value on the RHS of the comparison. + * @param tolerance :: accept this deviation from a perfect equality + */ + void MDHistoWorkspace::equalTo(const signal_t signal, const signal_t tolerance) + { + for (size_t i=0; i<m_length; ++i) + { + signal_t diff = fabs(m_signals[i] - signal); + m_signals[i] = (diff < tolerance) ? 1.0 : 0.0; + m_errorsSquared[i] = 0; + } + } + + + //---------------------------------------------------------------------------------------------- + /** Copy the values from another workspace onto this workspace, but only + * where a mask is true (non-zero) + * + * For example, in matlab or numpy python, you might write something like: + * "mask = (array < 5.0); array[mask] = other[mask];" + * + * The equivalent here is: + * mask = array; + * mask.lessThan(5.0); + * array.setUsingMask(mask, other); + * + * @param mask :: MDHistoWorkspace where (signal == 0.0) means false, and (signal != 0.0) means true. + * @param values :: MDHistoWorkspace of values to copy. + */ + void MDHistoWorkspace::setUsingMask(const MDHistoWorkspace & mask, const MDHistoWorkspace & values) + { + checkWorkspaceSize(mask, "setUsingMask"); + checkWorkspaceSize(values, "setUsingMask"); + for (size_t i=0; i<m_length; ++i) + { + if (mask.m_signals[i] != 0.0) + { + m_signals[i] = values.m_signals[i]; + m_errorsSquared[i] = values.m_errorsSquared[i]; + } + } + } + + //---------------------------------------------------------------------------------------------- + /** Copy the values from another workspace onto this workspace, but only + * where a mask is true (non-zero) + * + * For example, in matlab or numpy python, you might write something like: + * "mask = (array < 5.0); array[mask] = other[mask];" + * + * The equivalent here is: + * mask = array; + * mask.lessThan(5.0); + * array.setUsingMask(mask, other); + * + * @param mask :: MDHistoWorkspace where (signal == 0.0) means false, and (signal != 0.0) means true. + * @param signal :: signal to set everywhere mask is true + * @param error :: error (not squared) to set everywhere mask is true + */ + void MDHistoWorkspace::setUsingMask(const MDHistoWorkspace & mask, const signal_t signal, const signal_t error) + { + signal_t errorSquared = error * error; + checkWorkspaceSize(mask, "setUsingMask"); + for (size_t i=0; i<m_length; ++i) + { + if (mask.m_signals[i] != 0.0) + { + m_signals[i] = signal; + m_errorsSquared[i] = errorSquared; + } } } diff --git a/Code/Mantid/Framework/MDEvents/src/SaveMD.cpp b/Code/Mantid/Framework/MDEvents/src/SaveMD.cpp index a3d496779eee6849c0b04567ada3f35522b3086f..22ba40290116ffc2d4c0f21a9ce1322891625c04 100644 --- a/Code/Mantid/Framework/MDEvents/src/SaveMD.cpp +++ b/Code/Mantid/Framework/MDEvents/src/SaveMD.cpp @@ -357,14 +357,14 @@ namespace MDEvents exents_dims[0] = (int(maxBoxes)); exents_dims[1] = (nd*2); std::vector<int> exents_chunk(2,0); - exents_chunk[0] = int(100000); + exents_chunk[0] = int(16384); exents_chunk[1] = (nd*2); std::vector<int> box_2_dims(2,0); box_2_dims[0] = int(maxBoxes); box_2_dims[1] = (2); std::vector<int> box_2_chunk(2,0); - box_2_chunk[0] = int(100000); + box_2_chunk[0] = int(16384); box_2_chunk[1] = (2); if (!update) diff --git a/Code/Mantid/Framework/MDEvents/test/MDHistoWorkspaceTest.h b/Code/Mantid/Framework/MDEvents/test/MDHistoWorkspaceTest.h index 94eefc77fd6b50fb3207abefd2da9b7f5b5def50..39f5d9a8d2ea23066ef91d89765778cc4d6f3ce0 100644 --- a/Code/Mantid/Framework/MDEvents/test/MDHistoWorkspaceTest.h +++ b/Code/Mantid/Framework/MDEvents/test/MDHistoWorkspaceTest.h @@ -83,7 +83,7 @@ public: TS_ASSERT_DELTA( ws.getSignalAt(5), 2.3456, 1e-5); TS_ASSERT_DELTA( ws.getSignalNormalizedAt(5), 2.3456 / 256.0, 1e-5); // Cell volume is 256 - ws.setErrorAt(5,1.234); + ws.setErrorSquaredAt(5,1.234); TS_ASSERT_DELTA( ws.getErrorAt(5), 1.234, 1e-5); TS_ASSERT_DELTA( ws.getErrorNormalizedAt(5), 1.234 / 256.0, 1e-5); // Cell volume is 256 @@ -95,7 +95,7 @@ public: for (size_t i=0; i < ws.getNPoints(); ++i) { ws.setSignalAt(i, (signal_t) i); - ws.setErrorAt(i, (signal_t) i); + ws.setErrorSquaredAt(i, (signal_t) i); } // Test the 4 overloads of each method. Phew! @@ -139,7 +139,7 @@ public: ws.setSignalAt(5,2.3456); TS_ASSERT_DELTA( ws.getSignalAt(5), 2.3456, 1e-5); - ws.setErrorAt(5,1.234); + ws.setErrorSquaredAt(5,1.234); TS_ASSERT_DELTA( ws.getErrorAt(5), 1.234, 1e-5); std::vector<signal_t> data = ws.getSignalDataVector(); @@ -167,7 +167,7 @@ public: ws.setSignalAt(5,2.3456); TS_ASSERT_DELTA( ws.getSignalAt(5), 2.3456, 1e-5); - ws.setErrorAt(5,1.234); + ws.setErrorSquaredAt(5,1.234); TS_ASSERT_DELTA( ws.getErrorAt(5), 1.234, 1e-5); std::vector<signal_t> data = ws.getSignalDataVector(); @@ -186,6 +186,15 @@ public: checkWorkspace(b, 1.23, 3.234); } + //-------------------------------------------------------------------------------------- + void test_array_operator() + { + MDHistoWorkspace_sptr a = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.23, 2, 5, 10.0, 3.234); + TS_ASSERT_DELTA( (*a)[0], 1.23, 1e-5 ); + TS_ASSERT_THROWS_ANYTHING( (*a)[25] ); + TS_ASSERT_THROWS_ANYTHING( (*a)[-1] ); + } + //--------------------------------------------------------------------------------------------------- void test_getVertexesArray_1D() { @@ -491,7 +500,7 @@ public: { MDHistoWorkspace_sptr a = MDEventsTestHelper::makeFakeMDHistoWorkspace(10.0, 2, 5, 10.0, 3.0); a->log10(); - checkWorkspace(a, 1.0, 3./100.); + checkWorkspace(a, 1.0, 0.1886117 * 3./100.); } //-------------------------------------------------------------------------------------- @@ -553,6 +562,104 @@ public: checkWorkspace(b, 1.0, 0.0); } + //-------------------------------------------------------------------------------------- + void test_boolean_lessThan() + { + MDHistoWorkspace_sptr a, b, c; + a = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.23, 2, 5, 10.0, 3.0); + b = MDEventsTestHelper::makeFakeMDHistoWorkspace(2.34, 2, 5, 10.0, 2.0); + a->lessThan(*b); + checkWorkspace(a, 1.0, 0.0); + a = MDEventsTestHelper::makeFakeMDHistoWorkspace(4.56, 2, 5, 10.0, 3.0); + b = MDEventsTestHelper::makeFakeMDHistoWorkspace(2.34, 2, 5, 10.0, 2.0); + a->lessThan(*b); + checkWorkspace(a, 0.0, 0.0); + a = MDEventsTestHelper::makeFakeMDHistoWorkspace(4.56, 2, 5, 10.0, 3.0); + a->lessThan(4.57); + checkWorkspace(a, 1.0, 0.0); + a = MDEventsTestHelper::makeFakeMDHistoWorkspace(4.56, 2, 5, 10.0, 3.0); + a->lessThan(4.55); + checkWorkspace(a, 0.0, 0.0); + } + + //-------------------------------------------------------------------------------------- + void test_boolean_greaterThan() + { + MDHistoWorkspace_sptr a, b, c; + a = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.23, 2, 5, 10.0, 3.0); + b = MDEventsTestHelper::makeFakeMDHistoWorkspace(2.34, 2, 5, 10.0, 2.0); + a->greaterThan(*b); + checkWorkspace(a, 0.0, 0.0); + a = MDEventsTestHelper::makeFakeMDHistoWorkspace(4.56, 2, 5, 10.0, 3.0); + b = MDEventsTestHelper::makeFakeMDHistoWorkspace(2.34, 2, 5, 10.0, 2.0); + a->greaterThan(*b); + checkWorkspace(a, 1.0, 0.0); + a = MDEventsTestHelper::makeFakeMDHistoWorkspace(4.56, 2, 5, 10.0, 3.0); + a->greaterThan(4.57); + checkWorkspace(a, 0.0, 0.0); + a = MDEventsTestHelper::makeFakeMDHistoWorkspace(4.56, 2, 5, 10.0, 3.0); + a->greaterThan(4.55); + checkWorkspace(a, 1.0, 0.0); + } + + //-------------------------------------------------------------------------------------- + void test_boolean_equalTo() + { + MDHistoWorkspace_sptr a, b, c; + a = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.23, 2, 5, 10.0, 3.0); + b = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.23000001, 2, 5, 10.0, 2.0); + a->equalTo(*b); + checkWorkspace(a, 1.0, 0.0); + + a = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.12, 2, 5, 10.0, 3.0); + a->equalTo(*b); + checkWorkspace(a, 0.0, 0.0); + + a = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.23, 2, 5, 10.0, 3.0); + a->equalTo(1.2300001); + checkWorkspace(a, 1.0, 0.0); + + a = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.23, 2, 5, 10.0, 3.0); + a->equalTo(2.34, 1e-4); + checkWorkspace(a, 0.0, 0.0); + + a = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.23, 2, 5, 10.0, 3.0); + a->equalTo(2.34, 3 /* large tolerance */); + checkWorkspace(a, 1.0, 0.0); + } + + + //-------------------------------------------------------------------------------------- + void test_setUsingMask() + { + MDHistoWorkspace_sptr a, mask, c; + a = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.23, 2, 5, 10.0, 3.0); + mask = MDEventsTestHelper::makeFakeMDHistoWorkspace(0.00, 2, 5, 10.0, 0.0); //mask + c = MDEventsTestHelper::makeFakeMDHistoWorkspace(4.56, 2, 5, 10.0, 2.0); + a->setUsingMask(*mask, *c); + checkWorkspace(a, 1.23, 3.0); + + mask->setTo(1.0, 0.0); + a->setUsingMask(*mask, *c); + checkWorkspace(a, 4.56, 2.0); + + a->setUsingMask(*mask, 7.89, 11); + checkWorkspace(a, 7.89, 11*11 ); + + mask->setTo(0.0, 0.0); + a->setUsingMask(*mask, 6.66, 7.77); + checkWorkspace(a, 7.89, 11*11 ); + + // Now a partial mask + mask->setSignalAt(0, 1.0); + mask->setSignalAt(2, 1.0); + a->setTo(1.23, 4.56); + a->setUsingMask(*mask, 6.78, 7.89); + TS_ASSERT_DELTA( a->getSignalAt(0), 6.78, 1e-5); + TS_ASSERT_DELTA( a->getSignalAt(1), 1.23, 1e-5); + TS_ASSERT_DELTA( a->getSignalAt(2), 6.78, 1e-5); + } + }; diff --git a/Code/Mantid/Framework/MPIAlgorithms/test/GatherWorkspacesTest.h b/Code/Mantid/Framework/MPIAlgorithms/test/GatherWorkspacesTest.h index 4b923b99be4e54255106ae598491a24fc0cdee05..8e3b6931d3a97a9e5d7853ead4d57ad6b331d2c8 100644 --- a/Code/Mantid/Framework/MPIAlgorithms/test/GatherWorkspacesTest.h +++ b/Code/Mantid/Framework/MPIAlgorithms/test/GatherWorkspacesTest.h @@ -62,7 +62,7 @@ public: //TODO: Check spectrum numbers and detector IDs are copied correctly (perhaps?) } - TS_ASSERT_EQUALS( inWS->getInstrument(), outWS->getInstrument() ); + TS_ASSERT_EQUALS( inWS->getInstrument()->baseInstrument(), outWS->getInstrument()->baseInstrument() ); } // TODO: Work out a way of testing under MPI because absent that the test is not very interesting diff --git a/Code/Mantid/Framework/PythonAPI/CMakeLists.txt b/Code/Mantid/Framework/PythonAPI/CMakeLists.txt index 37870be5c0301c1403a4f828556f4faab8e0b689..ae3bba64ce0353f0dbe7b3e3bd4a7fd19aab2f1b 100644 --- a/Code/Mantid/Framework/PythonAPI/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonAPI/CMakeLists.txt @@ -39,14 +39,17 @@ set ( TEST_FILES ) # Python unit tests -set ( TEST_PY_FILES test/ImportTest.py - test/PythonAlgorithmTest.py - test/NumpyTest.py - test/WorkspaceHistoryTest.py - test/WorkspaceTests.py - test/SettingsTest.py - test/SANSWorkflowTest.py - test/SANSMaskCommandsTest.py +set ( TEST_PY_FILES + test/ImportTest.py + test/PythonAlgorithmTest.py + test/MDHistoWorkspaceTest.py + test/NumpyTest.py + test/MatrixWorkspaceTest.py + test/SettingsTest.py + test/SANSWorkflowTest.py + test/SANSMaskCommandsTest.py + test/WorkspaceHistoryTest.py + test/WorkspaceGroupTest.py ) if(UNITY_BUILD) diff --git a/Code/Mantid/Framework/PythonAPI/MantidFramework.py b/Code/Mantid/Framework/PythonAPI/MantidFramework.py index 99405cf38c28a38d60d4ed95d4217ef2461a5e1d..ca2b51972ad8f87cf387decd4f83b7c6572b074b 100644 --- a/Code/Mantid/Framework/PythonAPI/MantidFramework.py +++ b/Code/Mantid/Framework/PythonAPI/MantidFramework.py @@ -170,7 +170,8 @@ __operator_names=set(['CALL_FUNCTION','UNARY_POSITIVE','UNARY_NEGATIVE','UNARY_N 'INPLACE_DIVIDE', 'INPLACE_TRUE_DIVIDE','INPLACE_FLOOR_DIVIDE', 'INPLACE_MODULO', 'INPLACE_ADD', 'INPLACE_SUBTRACT', 'INPLACE_LSHIFT','INPLACE_RSHIFT','INPLACE_AND', 'INPLACE_XOR', - 'INPLACE_OR']) + 'INPLACE_OR', + 'COMPARE_OP']) #------------------------------------------------------------------------------- @@ -596,6 +597,93 @@ class WorkspaceProxy(ProxyObject): return self.__do_operation('Divide', rhs,inplace=True, reverse=False, lhs_vars=lhs) + def __lt__(self, rhs): + """ + Do the (self < rhs) comparison and return a new proxy managing that object + """ + lhs = lhs_info() + return self.__do_operation('LessThan', rhs, inplace=False, reverse=False, + lhs_vars=lhs) + + def __gt__(self, rhs): + """ + Do the (self > rhs) comparison and return a new proxy managing that object + """ + lhs = lhs_info() + return self.__do_operation('GreaterThan', rhs, inplace=False, reverse=False, + lhs_vars=lhs) + + def __or__(self, rhs): + """ + Do the (self || rhs) comparison and return a new proxy managing that object + """ + lhs = lhs_info() + return self.__do_operation('Or', rhs, inplace=False, reverse=False, + lhs_vars=lhs) + + def __and__(self, rhs): + """ + Do the (self && rhs) comparison and return a new proxy managing that object + """ + lhs = lhs_info() + return self.__do_operation('And', rhs, inplace=False, reverse=False, + lhs_vars=lhs) + + def __xor__(self, rhs): + """ + Do the (self ^ rhs) comparison and return a new proxy managing that object + """ + lhs = lhs_info() + return self.__do_operation('Xor', rhs, inplace=False, reverse=False, + lhs_vars=lhs) + + + + + def __do_unary_operation(self, op, lhs_vars): + """ + Perform the unary operation + + @param op :: name of the algorithm to run + @param lhs_vars :: is expected to be a tuple containing the number of lhs variables and + their names as the first and second element respectively + """ + global _binary_op_tmps + + if lhs_vars[0] > 0: + # Assume the first and clear the tempoaries as this + # must be the final assignment + output_name = lhs_vars[1][0] + clear_tmps = True + else: + # Give it a temporary name and keep track of it + clear_tmps = False + output_name = _binary_op_prefix + str(len(_binary_op_tmps)) + _binary_op_tmps.append(output_name) + + # Do the operation + alg = mtd.createAlgorithm(op) + alg.setPropertyValue("InputWorkspace", self.getName()) + alg.setPropertyValue("OutputWorkspace", output_name) + alg.execute() + resultws = alg.workspace() + + if clear_tmps: + for name in _binary_op_tmps: + if mtd.workspaceExists(name) and output_name != name: + mtd.deleteWorkspace(name) + _binary_op_tmps = [] + + return resultws + + def __invert__(self): + """ + Return the inversion (NOT operator) on self + """ + lhs = lhs_info() + return self.__do_unary_operation('NotMD', lhs_vars=lhs) + + def equals(self, rhs, tol): """ Checks whether the given workspace matches this one within the allowed @@ -1176,6 +1264,11 @@ class MantidPyFramework(FrameworkManager): except RuntimeError: pass + try: + return self._getRawIMDHistoWorkspacePointer(name) + except RuntimeError: + pass + try: return self._getRawIMDWorkspacePointer(name) except RuntimeError: diff --git a/Code/Mantid/Framework/PythonAPI/PythonAlgorithms/SNSSingleCrystalReduction.py b/Code/Mantid/Framework/PythonAPI/PythonAlgorithms/SNSSingleCrystalReduction.py index 29e6a70eba8d65332e0fa1eb5fb50f7c21989291..c850c8926b5b98de13155c9c29d5467ac26fa738 100755 --- a/Code/Mantid/Framework/PythonAPI/PythonAlgorithms/SNSSingleCrystalReduction.py +++ b/Code/Mantid/Framework/PythonAPI/PythonAlgorithms/SNSSingleCrystalReduction.py @@ -161,6 +161,7 @@ class SNSSingleCrystalReduction(PythonAlgorithm): PredictPeaks(InputWorkspace=wksp,WavelengthMin=self._minWL,WavelengthMax=self._maxWL,MinDSpacing=self._minD, ReflectionCondition="Rhombohedrally centred, obverse",OutputWorkspace='Peaks') peaksWS = mtd['Peaks'] + CentroidPeaks(InputWorkspace=wksp,InPeaksWorkspace=peaksWS,OutPeaksWorkspace=peaksWS) PeakIntegration(InputWorkspace=wksp,InPeaksWorkspace=peaksWS,OutPeaksWorkspace=peaksWS) hklfile = self._outFile SaveHKL(LinearScatteringCoef=self._amu,LinearAbsorptionCoef=self._smu,Radius=self._radius,ScalePeaks=self._scale, diff --git a/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/FrameworkManagerProxy.h b/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/FrameworkManagerProxy.h index decdfa8938aa9081d97b7bd187f489ac33a9e583..1491b616e76ee304d2216df82843e95ea09ee363 100644 --- a/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/FrameworkManagerProxy.h +++ b/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/FrameworkManagerProxy.h @@ -21,6 +21,7 @@ //#include <MantidDataObjects/PeaksWorkspace.h> #include <Poco/NObserver.h> +#include "MantidAPI/IMDHistoWorkspace.h" //------------------------------- @@ -139,8 +140,10 @@ public: // boost::shared_ptr<DataObjects::PeaksWorkspace> retrievePeaksWorkspace(const std::string& wsName); // /// Returns a pointer to the IEventWorkpace requested // boost::shared_ptr<DataObjects::EventWorkspace> retrieveEventWorkspace(const std::string& wsName); -// /// Returns a pointer to the IMDWorkspace requested + /// Returns a pointer to the IMDWorkspace requested boost::shared_ptr<API::IMDWorkspace> retrieveIMDWorkspace(const std::string& wsName); + /// Returns a pointer to the IMDWorkspace requested + boost::shared_ptr<API::IMDHistoWorkspace> retrieveIMDHistoWorkspace(const std::string& wsName); /// Returns a pointer to the IMDEventWorkspace requested boost::shared_ptr<API::IMDEventWorkspace> retrieveIMDEventWorkspace(const std::string& wsName); /// Returns a pointer to the TableWorkspace requested diff --git a/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/WorkspaceProxies.h b/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/WorkspaceProxies.h index 7164aa2dbc6cd91a31bd0961622eda28f1d222ae..9573b634dd310f6fd11db5dfc6bd12b166e889ee 100644 --- a/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/WorkspaceProxies.h +++ b/Code/Mantid/Framework/PythonAPI/inc/MantidPythonAPI/WorkspaceProxies.h @@ -80,11 +80,24 @@ namespace Mantid ResultType performBinaryOp(const LHSType lhs, const RHSType rhs, const std::string & op, const std::string & name, bool inplace, bool reverse); + + /// Binary op for two MDworkspaces + template<typename LHSType, typename RHSType, typename ResultType> + ResultType performBinaryOpMD(const LHSType lhs, const RHSType rhs, + const std::string & op, const std::string & name, + bool inplace, bool reverse); + /// Binary op for a workspace and a double template<typename LHSType, typename ResultType> ResultType performBinaryOpWithDouble(const LHSType inputWS, const double value, const std::string & op, const std::string & name, bool inplace, bool reverse); + + /// Binary op for MDworkspaces + double + template<typename LHSType, typename ResultType> + ResultType performBinaryOpMDWithDouble(const LHSType lhs, const double value, + const std::string & op, const std::string & name, + bool inplace, bool reverse); //@} /** diff --git a/Code/Mantid/Framework/PythonAPI/src/FrameworkManagerProxy.cpp b/Code/Mantid/Framework/PythonAPI/src/FrameworkManagerProxy.cpp index 1547c65befc361f242b4b30d53586698a975a60f..5d59d6815b17661ad9cf6f1c004437bd057ac0d3 100644 --- a/Code/Mantid/Framework/PythonAPI/src/FrameworkManagerProxy.cpp +++ b/Code/Mantid/Framework/PythonAPI/src/FrameworkManagerProxy.cpp @@ -16,6 +16,7 @@ #include <sstream> #include <stdexcept> #include <vector> +#include "MantidAPI/IMDHistoWorkspace.h" using Mantid::API::AlgorithmManager; @@ -353,6 +354,27 @@ boost::shared_ptr<API::IMDWorkspace> FrameworkManagerProxy::retrieveIMDWorkspace } } + +/** Return pointer to IMDHistoWorkspace + * @param wsName :: The name of the workspace to retrieve. + * @return Shared pointer to workspace. + * @throw runtime_error if not of the right type + */ +boost::shared_ptr<API::IMDHistoWorkspace> FrameworkManagerProxy::retrieveIMDHistoWorkspace(const std::string& wsName) +{ + API::IMDHistoWorkspace_sptr ws = boost::dynamic_pointer_cast<API::IMDHistoWorkspace>(retrieveWorkspace(wsName)); + if (ws != NULL) + { + return ws; + } + else + { + throw std::runtime_error("\"" + wsName + "\" is not an MDHistoWorkspace. "); + } +} + + + /** Return pointer to IMDEventWorkspace * @param wsName :: The name of the workspace to retrieve. * @return Shared pointer to workspace. diff --git a/Code/Mantid/Framework/PythonAPI/src/WorkspaceProxies.cpp b/Code/Mantid/Framework/PythonAPI/src/WorkspaceProxies.cpp index 95f021c2c56e1da8d5868573ce5067e22b5937cf..5282e056651789f5390a02c4cf1e1a297e744c1b 100644 --- a/Code/Mantid/Framework/PythonAPI/src/WorkspaceProxies.cpp +++ b/Code/Mantid/Framework/PythonAPI/src/WorkspaceProxies.cpp @@ -8,6 +8,11 @@ #include "MantidAPI/AlgorithmManager.h" #include "MantidAPI/AnalysisDataService.h" #include "MantidAPI/WorkspaceGroup.h" +#include "MantidAPI/IMDWorkspace.h" +#include "MantidAPI/MatrixWorkspace.h" +#include "MantidAPI/IMDHistoWorkspace.h" + +using namespace Mantid::API; namespace Mantid { @@ -71,7 +76,9 @@ namespace Mantid // //********************************************************************************** - /** Binary operation for two workspaces + /** Binary operation for two workspaces. Generic for IMDWorkspaces or MatrixWorkspaces... + * Called by python overloads for _binary_op (see api_exports.cpp) + * * @param lhs :: the left hand side workspace of the operation * @param rhs :: the right hand side workspace of the operation * @param op :: The operation @@ -85,17 +92,33 @@ namespace Mantid const std::string& op, const std::string & name, bool inplace,bool reverse) { + std::string algoName = op; + + // ----- Determine which version of the algo should be called ----- + MatrixWorkspace_const_sptr lhs_mat = boost::dynamic_pointer_cast<const MatrixWorkspace>(lhs); + MatrixWorkspace_const_sptr rhs_mat = boost::dynamic_pointer_cast<const MatrixWorkspace>(rhs); + WorkspaceGroup_const_sptr lhs_grp = boost::dynamic_pointer_cast<const WorkspaceGroup>(lhs); + WorkspaceGroup_const_sptr rhs_grp = boost::dynamic_pointer_cast<const WorkspaceGroup>(rhs); + + if ( (lhs_mat || lhs_grp) && (rhs_mat || rhs_grp) ) + // Both sides are matrixworkspace - use the original algos (e..g "Plus.") + algoName = op; + else + // One of the workspaces must be MDHistoWorkspace or MDEventWorkspace + // Use the MD version, e.g. "PlusMD" + algoName = op + "MD"; + ResultType result; std::string error(""); try { if( reverse ) { - result = API::OperatorOverloads::executeBinaryOperation<RHSType, LHSType, ResultType>(op, rhs, lhs, inplace, false, name, true); + result = API::OperatorOverloads::executeBinaryOperation<RHSType, LHSType, ResultType>(algoName, rhs, lhs, inplace, false, name, true); } else { - result = API::OperatorOverloads::executeBinaryOperation<LHSType, RHSType, ResultType>(op, lhs, rhs, inplace, false, name, true); + result = API::OperatorOverloads::executeBinaryOperation<LHSType, RHSType, ResultType>(algoName, lhs, rhs, inplace, false, name, true); } } catch(std::runtime_error & exc) @@ -114,8 +137,12 @@ namespace Mantid return result; } + /** - * Perform the given binary operation on a workspace and a double + * Perform the given binary operation on a workspace and a double. + * Generic to MDWorkspaces. + * Called by python overloads for _binary_op (see api_exports.cpp) + * * @param lhs :: The input workspace * @param rhs :: The input value * @param op :: The operation @@ -128,6 +155,8 @@ namespace Mantid const std::string& op, const std::string & name, bool inplace, bool reverse) { + std::string algoName = op; + // Create the single valued workspace first so that it is run as a top-level algorithm // such that it's history can be recreated API::Algorithm_sptr alg = API::AlgorithmManager::Instance().createUnmanaged("CreateSingleValuedWorkspace"); @@ -147,22 +176,38 @@ namespace Mantid { throw std::runtime_error("performBinaryOp: Error in execution of CreateSingleValuedWorkspace"); } - ResultType result = performBinaryOp<LHSType, MatrixWorkspace_sptr, ResultType>(inputWS, singleValue, op, name, inplace, reverse); + // Call the function above with the signle-value workspace + ResultType result = performBinaryOp<LHSType, MatrixWorkspace_sptr, ResultType>(inputWS, singleValue, algoName, name, inplace, reverse); // Delete the temporary data_store.remove(tmp_name); return result; } + + // Concrete instantations - template MatrixWorkspace_sptr performBinaryOp(const MatrixWorkspace_sptr, const MatrixWorkspace_sptr, const std::string& , const std::string & name, - bool, bool); + template IMDWorkspace_sptr performBinaryOp(const IMDWorkspace_sptr, const IMDWorkspace_sptr, const std::string& , const std::string & name, + bool, bool); + template WorkspaceGroup_sptr performBinaryOp(const IMDWorkspace_sptr, const WorkspaceGroup_sptr, const std::string& , const std::string & name, + bool, bool); + template WorkspaceGroup_sptr performBinaryOp(const WorkspaceGroup_sptr, const IMDWorkspace_sptr, const std::string& , const std::string & name, + bool, bool); template WorkspaceGroup_sptr performBinaryOp(const WorkspaceGroup_sptr, const WorkspaceGroup_sptr, const std::string& , const std::string & name, - bool, bool); + bool, bool); + + template IMDHistoWorkspace_sptr performBinaryOp(const IMDHistoWorkspace_sptr, const IMDHistoWorkspace_sptr, const std::string& , const std::string & name, + bool, bool); + template IMDHistoWorkspace_sptr performBinaryOp(const IMDHistoWorkspace_sptr, const MatrixWorkspace_sptr, const std::string& , const std::string & name, + bool, bool); + + // Double variants - template MatrixWorkspace_sptr performBinaryOpWithDouble(const MatrixWorkspace_sptr, const double, const std::string& op, - const std::string &, bool, bool); + template IMDWorkspace_sptr performBinaryOpWithDouble(const IMDWorkspace_sptr, const double, const std::string& op, + const std::string &, bool, bool); + template IMDHistoWorkspace_sptr performBinaryOpWithDouble(const IMDHistoWorkspace_sptr, const double, const std::string& op, + const std::string &, bool, bool); template WorkspaceGroup_sptr performBinaryOpWithDouble(const WorkspaceGroup_sptr, const double, const std::string& op, - const std::string &, bool, bool); + const std::string &, bool, bool); } diff --git a/Code/Mantid/Framework/PythonAPI/src/api_exports.cpp b/Code/Mantid/Framework/PythonAPI/src/api_exports.cpp index 4f0d066bb9c2b95043d1a57c03351dee8bda4943..2d008429201aa878fe9b6bc51fde245860c54729 100644 --- a/Code/Mantid/Framework/PythonAPI/src/api_exports.cpp +++ b/Code/Mantid/Framework/PythonAPI/src/api_exports.cpp @@ -15,6 +15,7 @@ #include "MantidAPI/IEventList.h" #include "MantidAPI/ISpectrum.h" #include "MantidAPI/IMDEventWorkspace.h" +#include "MantidAPI/IMDHistoWorkspace.h" #include "MantidAPI/ITableWorkspace.h" #include "MantidAPI/Sample.h" #include "MantidAPI/WorkspaceGroup.h" @@ -26,6 +27,7 @@ #include "MantidPythonAPI/PyAlgorithmWrapper.h" //Poco #include <Poco/ActiveResult.h> +#include "MantidAPI/IMDWorkspace.h" namespace Mantid { @@ -80,6 +82,7 @@ using namespace boost::python; .def("releaseFreeMemory", &FrameworkManagerProxy::releaseFreeMemory) .def("_getRawIEventWorkspacePointer", &FrameworkManagerProxy::retrieveIEventWorkspace) .def("_getRawIMDWorkspacePointer", &FrameworkManagerProxy::retrieveIMDWorkspace) + .def("_getRawIMDHistoWorkspacePointer", &FrameworkManagerProxy::retrieveIMDHistoWorkspace) .def("_getRawIMDEventWorkspacePointer", &FrameworkManagerProxy::retrieveIMDEventWorkspace) .def("_getRawMatrixWorkspacePointer", &FrameworkManagerProxy::retrieveMatrixWorkspace) .def("_getRawTableWorkspacePointer", &FrameworkManagerProxy::retrieveTableWorkspace) @@ -216,6 +219,7 @@ using namespace boost::python; // Overloads for createSubAlgorithm function which has 1 optional argument BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Workspace_isDirtyOverloader, API::Workspace::isDirty, 0, 1) + //----------------------------------------------------------------------------------------------- void export_workspace() { /// Shared pointer registration @@ -237,6 +241,7 @@ using namespace boost::python; // Overloads for binIndexOf function which has 1 optional argument BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(MatrixWorkspace_binIndexOfOverloads, API::MatrixWorkspace::binIndexOf, 1, 2) + //----------------------------------------------------------------------------------------------- void export_matrixworkspace() { /// Shared pointer registration @@ -284,24 +289,15 @@ using namespace boost::python; ; //Operator overloads dispatch through the above structure. The typedefs save some typing - typedef MatrixWorkspace_sptr(*binary_fn1)(const API::MatrixWorkspace_sptr, const API::MatrixWorkspace_sptr,const std::string &,const std::string &,bool, bool); - typedef WorkspaceGroup_sptr(*binary_fn2)(const API::WorkspaceGroup_sptr, const API::WorkspaceGroup_sptr,const std::string &,const std::string &,bool, bool); - typedef MatrixWorkspace_sptr(*binary_fn3)(const API::MatrixWorkspace_sptr, double,const std::string&,const std::string &,bool,bool); - typedef WorkspaceGroup_sptr(*binary_fn4)(const API::WorkspaceGroup_sptr, double,const std::string&,const std::string &,bool,bool); - typedef bool(*binary_fn5)(const API::MatrixWorkspace_sptr, const API::MatrixWorkspace_sptr,double); // Binary operations helpers - def("_binary_op", (binary_fn1)&PythonAPI::performBinaryOp); - def("_binary_op", (binary_fn2)&PythonAPI::performBinaryOp); - def("_binary_op", (binary_fn3)&PythonAPI::performBinaryOpWithDouble); - def("_binary_op", (binary_fn4)&PythonAPI::performBinaryOpWithDouble); - def("_equals_op", (binary_fn5)&API::equals); } + //----------------------------------------------------------------------------------------------- void export_IMDWorkspace() { register_ptr_to_python<API::IMDWorkspace_sptr>(); @@ -312,8 +308,56 @@ using namespace boost::python; .def("getNumDims", &IMDWorkspace::getNumDims) .def("getDimension", &IMDWorkspace::getDimension ) ; + + //Operator overloads dispatch through the above structure. The typedefs save some typing + typedef IMDWorkspace_sptr(*binary_fn_md_md)(const API::IMDWorkspace_sptr, const API::IMDWorkspace_sptr, const std::string &,const std::string &,bool, bool); + typedef WorkspaceGroup_sptr(*binary_fn_md_gp)(const API::IMDWorkspace_sptr, const API::WorkspaceGroup_sptr, const std::string &,const std::string &,bool, bool); + typedef WorkspaceGroup_sptr(*binary_fn_gp_md)(const API::WorkspaceGroup_sptr, const API::IMDWorkspace_sptr, const std::string &,const std::string &,bool, bool); + typedef WorkspaceGroup_sptr(*binary_fn_gp_gp)(const API::WorkspaceGroup_sptr, const API::WorkspaceGroup_sptr, const std::string &,const std::string &,bool, bool); + + typedef IMDHistoWorkspace_sptr(*binary_fn_mh_mh)(const API::IMDHistoWorkspace_sptr, const API::IMDHistoWorkspace_sptr, const std::string &,const std::string &,bool, bool); + + typedef IMDWorkspace_sptr(*binary_fn_md_db)(const API::IMDWorkspace_sptr, double, const std::string&,const std::string &,bool,bool); + typedef IMDHistoWorkspace_sptr(*binary_fn_mh_db)(const API::IMDHistoWorkspace_sptr, double, const std::string&,const std::string &,bool,bool); + typedef WorkspaceGroup_sptr(*binary_fn_gp_db)(const API::WorkspaceGroup_sptr, double, const std::string&,const std::string &,bool,bool); + + // Binary operations helpers + def("_binary_op", (binary_fn_md_md)&PythonAPI::performBinaryOp); + def("_binary_op", (binary_fn_md_gp)&PythonAPI::performBinaryOp); + def("_binary_op", (binary_fn_gp_md)&PythonAPI::performBinaryOp); + def("_binary_op", (binary_fn_gp_gp)&PythonAPI::performBinaryOp); + def("_binary_op", (binary_fn_mh_mh)&PythonAPI::performBinaryOp); + + def("_binary_op", (binary_fn_md_db)&PythonAPI::performBinaryOpWithDouble); + def("_binary_op", (binary_fn_mh_db)&PythonAPI::performBinaryOpWithDouble); + def("_binary_op", (binary_fn_gp_db)&PythonAPI::performBinaryOpWithDouble); + + } + + //----------------------------------------------------------------------------------------------- + void export_IMDHistoWorkspace() + { + register_ptr_to_python<API::IMDHistoWorkspace_sptr>(); + + // EventWorkspace class + class_< IMDHistoWorkspace, bases<API::IMDWorkspace>, boost::noncopyable >("IMDHistoWorkspace", no_init) + .def("signalAt", &IMDHistoWorkspace::signalAt, return_value_policy<copy_non_const_reference>()) + .def("errorSquaredAt", &IMDHistoWorkspace::errorSquaredAt, return_value_policy<copy_non_const_reference>()) + .def("setSignalAt", &IMDHistoWorkspace::setSignalAt) + .def("setErrorSquaredAt", &IMDHistoWorkspace::setErrorSquaredAt) + .def("setTo", &IMDHistoWorkspace::setTo) + .def("getInverseVolume", &IMDHistoWorkspace::getInverseVolume, return_value_policy< return_by_value >()) + .def("getLinearIndex", (size_t(IMDHistoWorkspace::*)(size_t,size_t) const) &IMDHistoWorkspace::getLinearIndex, return_value_policy< return_by_value >()) + .def("getLinearIndex", (size_t(IMDHistoWorkspace::*)(size_t,size_t,size_t) const) &IMDHistoWorkspace::getLinearIndex, return_value_policy< return_by_value >()) + .def("getLinearIndex", (size_t(IMDHistoWorkspace::*)(size_t,size_t,size_t,size_t) const) &IMDHistoWorkspace::getLinearIndex, return_value_policy< return_by_value >()) + .def("getCenter", &IMDHistoWorkspace::getCenter, return_value_policy< return_by_value >()) +// .def("__getitem__", &IMDHistoWorkspace::operator[]) + ; + + } + //----------------------------------------------------------------------------------------------- void export_IMDDimension() { register_ptr_to_python<Geometry::IMDDimension_sptr>(); @@ -328,6 +372,7 @@ using namespace boost::python; ; } + //----------------------------------------------------------------------------------------------- void export_BoxController() { register_ptr_to_python<API::BoxController_sptr>(); @@ -346,6 +391,7 @@ using namespace boost::python; ; } + //----------------------------------------------------------------------------------------------- void export_IMDEventWorkspace() { register_ptr_to_python<API::IMDEventWorkspace_sptr>(); @@ -357,6 +403,9 @@ using namespace boost::python; .def("getBoxController", (BoxController_sptr(IMDEventWorkspace::*)() ) &IMDEventWorkspace::getBoxController) ; } + + + //----------------------------------------------------------------------------------------------- void export_eventworkspace() { register_ptr_to_python<IEventWorkspace_sptr>(); @@ -371,6 +420,7 @@ using namespace boost::python; ; } + //----------------------------------------------------------------------------------------------- void export_ISpectrum() { register_ptr_to_python<ISpectrum*>(); @@ -385,6 +435,7 @@ using namespace boost::python; ; } + //----------------------------------------------------------------------------------------------- void export_EventList() { register_ptr_to_python<IEventList *>(); @@ -412,6 +463,7 @@ using namespace boost::python; } + //----------------------------------------------------------------------------------------------- void export_tableworkspace() { // Declare the pointer @@ -435,6 +487,7 @@ using namespace boost::python; ; } + //----------------------------------------------------------------------------------------------- // WorkspaceGroup void export_workspacegroup() { @@ -451,6 +504,7 @@ using namespace boost::python; ; } + //----------------------------------------------------------------------------------------------- void export_axis() { // Pointer @@ -488,6 +542,7 @@ using namespace boost::python; def("createTextAxis", & Mantid::PythonAPI::createTextAxis, return_internal_reference<>()); } + //----------------------------------------------------------------------------------------------- void export_sample() { //Pointer @@ -558,6 +613,10 @@ using namespace boost::python; ; class_< WorkspaceProperty<IEventWorkspace>, bases<Kernel::Property,API::IWorkspaceProperty>, boost::noncopyable>("EventWorkspaceProperty", no_init) ; + class_< WorkspaceProperty<IMDWorkspace>, bases<Kernel::Property,API::IWorkspaceProperty>, boost::noncopyable>("MDWorkspaceProperty", no_init) + ; + class_< WorkspaceProperty<IMDHistoWorkspace>, bases<Kernel::Property,API::IWorkspaceProperty>, boost::noncopyable>("MDHistoWorkspaceProperty", no_init) + ; } @@ -634,6 +693,7 @@ using namespace boost::python; export_matrixworkspace(); export_eventworkspace(); export_IMDWorkspace(); + export_IMDHistoWorkspace(); export_IMDEventWorkspace(); export_BoxController(); export_tableworkspace(); diff --git a/Code/Mantid/Framework/PythonAPI/test/MDHistoWorkspaceTest.py b/Code/Mantid/Framework/PythonAPI/test/MDHistoWorkspaceTest.py new file mode 100644 index 0000000000000000000000000000000000000000..d4c8789d3696c180912d1f08e5f876727afa0ba7 --- /dev/null +++ b/Code/Mantid/Framework/PythonAPI/test/MDHistoWorkspaceTest.py @@ -0,0 +1,145 @@ +import unittest + +from MantidFramework import mtd +mtd.initialise() +from mantidsimple import * + +class MDHistoWorkspaceTest(unittest.TestCase): + """ + Test the interface to MDHistoWorkspaces + """ + + def setUp(self): + CreateMDWorkspace(Dimensions='3',Extents='0,10,0,10,0,10',Names='x,y,z',Units='m,m,m',SplitInto='5',MaxRecursionDepth='20',OutputWorkspace='mdw') + FakeMDEventData("mdw", UniformParams="1e4") + BinToMDHistoWorkspace("mdw", "A", 1, "x,0,10,10", "y,0,10,10", "z,0,10,10", IterateEvents="1", Parallel="0") + BinToMDHistoWorkspace("mdw", "B", 1, "x,0,10,10", "y,0,10,10", "z,0,10,10", IterateEvents="1", Parallel="0") + pass + + def test_interface(self): + A = mtd['A'] + self.assertEqual(A.getNumDims(), 3) + self.assertEqual(A.getNPoints(), 1000) + # Can set/read signal and error + A.setSignalAt(23, 123.0) + A.setErrorSquaredAt(23, 345.0) + self.assertEqual(A.signalAt(23), 123.0) + self.assertEqual(A.errorSquaredAt(23), 345.0) + + """ Note: Look at each test for PlusMD MinusMD, and MDHistoWorkspaceTest for detailed tests including checking results. + These tests only check that they do run. """ + def test_operators_md_md(self): + A = mtd['A'] + B = mtd['B'] + C = A + B + C = A * B + C = A / B + C = A - B + A += B + A *= B + A /= B + A -= B + + """ MDHistoWorkspace + a number """ + def test_operators_md_double(self): + A = mtd['A'] + B = 3.5 + C = A + B + C = A * B + C = A / B + C = A - B + A += B + A *= B + A /= B + A -= B + + def test_compound_arithmetic(self): + A = mtd['A'] + B = mtd['B'] + C = (A + B) / (A - B) + assert (C is not None) + + """ boolean_workspace = MDHistoWorkspace < MDHistoWorkspace """ + def test_comparisons_and_boolean_operations(self): + A = mtd['A'] + B = mtd['B'] + B += 1 + C = A < B + self.assertEqual( C.getName(), 'C') + self.assertEqual( C.signalAt(0), 1.0) + D = A > B + self.assertEqual( D.getName(), 'D') + self.assertEqual( D.signalAt(0), 0.0) + E = C | D + self.assertEqual( E.getName(), 'E') + self.assertEqual( E.signalAt(0), 1.0) + F = C & D + self.assertEqual( F.getName(), 'F') + self.assertEqual( F.signalAt(0), 0.0) + G = C ^ C + self.assertEqual( G.getName(), 'G') + self.assertEqual( G.signalAt(0), 0.0) + H = C ^ D + self.assertEqual( H.getName(), 'H') + self.assertEqual( H.signalAt(0), 1.0) + + def test_comparisons_histo_scalar(self): + A = mtd['A'] + C = A < 1000.0 + self.assertEqual( C.getName(), 'C') + self.assertEqual( C.signalAt(0), 1.0) + D = A > 1.0 + self.assertEqual( D.getName(), 'D') + self.assertEqual( D.signalAt(0), 1.0) + + def test_inplace_boolean_operations(self): + A = mtd['A'] + B = mtd['B'] + B += 1 + C = A < B # all 1 (true) + D = A > B # all 0 (false) + + C |= D + self.assertEqual( C.signalAt(0), 1.0) + C &= D + self.assertEqual( C.signalAt(0), 0.0) + C += 1 + self.assertEqual( C.signalAt(0), 1.0) + C ^= C + self.assertEqual( C.signalAt(0), 0.0) + + def test_not_operator(self): + A = mtd['A'] + A *= 0 + self.assertEqual( A.signalAt(0), 0.0) + # Do with a copy + B = ~A + self.assertEqual( B.signalAt(0), 1.0) + # Do in-place + A = ~A + self.assertEqual( A.signalAt(0), 1.0) + + def test_compound_comparison(self): + A = mtd['A'] + B = mtd['B'] + C = (A > B) & (A > 123) & (B < 2345) + assert (C is not None) + + + def test_compound_boolean_operations(self): + A = mtd['A'] + A *= 0 + B = A + 1 + C = ~(A | B) + self.assertEqual( C.signalAt(0), 0.0) + C = ~(A | B) | B + self.assertEqual( C.signalAt(0), 1.0) + C = ~(A | B) | ~A + self.assertEqual( C.signalAt(0), 1.0) + C = ~(A | B) | ~(A & B) + self.assertEqual( C.signalAt(0), 1.0) + +if __name__ == '__main__': + unittest.main() + + diff --git a/Code/Mantid/Framework/PythonAPI/test/WorkspaceTests.py b/Code/Mantid/Framework/PythonAPI/test/MatrixWorkspaceTest.py similarity index 67% rename from Code/Mantid/Framework/PythonAPI/test/WorkspaceTests.py rename to Code/Mantid/Framework/PythonAPI/test/MatrixWorkspaceTest.py index 8a059c87bf569e05b2d9c92b89262a4182c6706a..47f2c73ed0732deedfcc05f071a29b3c740dea92 100644 --- a/Code/Mantid/Framework/PythonAPI/test/WorkspaceTests.py +++ b/Code/Mantid/Framework/PythonAPI/test/MatrixWorkspaceTest.py @@ -36,6 +36,35 @@ class MatrixWorkspaceTest(unittest.TestCase): Scale(InputWorkspace="test", OutputWorkspace="test", Factor=2.0) self.assertTrue(mtd["test"].isDirty()) + def test_operators(self): + CreateWorkspace('A', DataX=[1,2,3], DataY=[2,3], DataE=[2,3]) + CreateWorkspace('B', DataX=[1,2,3], DataY=[2,3], DataE=[2,3]) + A = mtd['A'] + B = mtd['B'] + # Two workspaces + C = A + B + C = A - B + C = A * B + C = A / B + C -= B + C += B + C *= B + C /= B + # Workspace + double + B = 123.456 + C = A + B + C = A - B + C = A * B + C = A / B + C -= B + C += B + C *= B + C /= B + # Commutative: double + workspace + C = B * A + C = B + A + + if __name__ == '__main__': unittest.main() diff --git a/Code/Mantid/Framework/PythonAPI/test/WorkspaceGroupTest.py b/Code/Mantid/Framework/PythonAPI/test/WorkspaceGroupTest.py new file mode 100644 index 0000000000000000000000000000000000000000..e3f451e9ad7af84c7da90a74c89fde80ba628e9e --- /dev/null +++ b/Code/Mantid/Framework/PythonAPI/test/WorkspaceGroupTest.py @@ -0,0 +1,70 @@ +import unittest + +from MantidFramework import mtd +mtd.initialise() +from mantidsimple import * + +class WorkspaceGroupTest(unittest.TestCase): + """ + Test the interface to WorkspaceGroups + """ + + def setUp(self): + pass + + """ Test various combinations of arithmetic with workspace groups """ + def test_operators(self): + CreateWorkspace('A', DataX=[1,2,3], DataY=[2,3], DataE=[2,3]) + CreateWorkspace('B', DataX=[1,2,3], DataY=[2,3], DataE=[2,3]) + CreateWorkspace('C', DataX=[1,2,3], DataY=[2,3], DataE=[2,3]) + CreateWorkspace('D', DataX=[1,2,3], DataY=[2,3], DataE=[2,3]) + GroupWorkspaces(InputWorkspaces='A,B', OutputWorkspace='AB') + GroupWorkspaces(InputWorkspaces='C,D', OutputWorkspace='CD') + A = mtd['A'] + B = mtd['B'] + C = mtd['C'] + D = mtd['D'] + AB = mtd['AB'] + CD = mtd['CD'] + + # Matrix + group + Q = A + AB + Q = A - AB + Q = A * AB + Q = A / AB + Q -= AB + Q += AB + Q *= AB + Q /= AB + + # group + matrix + Q = AB + A + Q = AB - A + Q = AB * A + Q = AB / A + CD -= A + CD += A + CD *= A + CD /= A + + # group + double + n = 123.456 + Q = AB + n + Q = AB - n + Q = AB * n + Q = AB / n + CD -= n + CD += n + CD *= n + CD /= n + + # Commutative: double + group + Q = n * AB + Q = n + AB + + + +if __name__ == '__main__': + unittest.main() + + diff --git a/Code/Mantid/Framework/PythonInterface/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/CMakeLists.txt index 767dc887c1dbb0a172c9f90750e9bcd0b67a1b3d..f70052f53c4c0c1befba22cbda7cdceee65203ef 100644 --- a/Code/Mantid/Framework/PythonInterface/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/CMakeLists.txt @@ -13,7 +13,7 @@ find_package ( Boost REQUIRED python ) add_definitions ( -DBOOST_DEBUG_PYTHON -DBOOST_PYTHON_NO_LIB ) find_package ( Numpy REQUIRED ) -include_directories ( ${PYTHON_NUMPY_INCLUDE_DIR} ) +include_directories ( SYSTEM ${PYTHON_NUMPY_INCLUDE_DIR} ) set ( HEADER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/inc/MantidPythonInterface ) include_directories ( inc ) @@ -36,10 +36,10 @@ add_subdirectory ( mantid ) ########################################################################### # tests ########################################################################### -# cxx unit tests # Not currently stable on all environments - +# C++ unit tests set ( TEST_FILES - test/cpp/PythonObjectInstantiatorTest.h + test/cpp/PythonObjectInstantiatorTest.h + test/cpp/VectorDelegateTest.h # Windows doesn't like having two around ) if ( CXXTEST_FOUND ) diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/NumpyTypeHandler.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/NumpyTypeHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..2872a9721f1ea6421f65ef7b5870cb8b13a1962b --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/NumpyTypeHandler.h @@ -0,0 +1,59 @@ +#ifndef MANTID_PYTHONINTERFACE_NUMPYTYPEHANDLER_H_ +#define MANTID_PYTHONINTERFACE_NUMPYTYPEHANDLER_H_ +/** + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +#include "MantidPythonInterface/kernel/PropertyHandler.h" + +//----------------------------------------------------------------------------- +// Forward delcarations +//----------------------------------------------------------------------------- +struct PyArrayObject; + +namespace Mantid +{ + namespace PythonInterface + { + namespace PropertyMarshal + { + /** + * A property handler that deals with translation of numpy arrays + * etc to/from Mantid algorithm properties + */ + struct DLLExport NumpyTypeHandler : PropertyHandler + { + /// Call to set a named property where the value is some container type + virtual void set(Kernel::IPropertyManager* alg, const std::string &name, boost::python::object value); + /// Is the given object an instance the handler's type + virtual bool isInstance(const boost::python::object&) const; + private: + /// Handle double-type properties + void setDoubleArrayProperty(Kernel::IPropertyManager* alg, const std::string &name, PyArrayObject * nparray); + /// Handle int-type properties + void setIntNumpyProperty(Kernel::IPropertyManager* alg, const std::string &name, + const std::type_info & typeInfo, PyArrayObject * nparray); + }; + + } + } +} + +#endif /* MANTID_PYTHONINTERFACE_NUMPYTYPEHANDLER_H_ */ diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyHandler.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..a2f8e205f9041ce926220236c0995592f08c8f09 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyHandler.h @@ -0,0 +1,59 @@ +#ifndef MANTID_PYTHONINTERFACE_PROPERTYHANDLER_H_ +#define MANTID_PYTHONINTERFACE_PROPERTYHANDLER_H_ +/** + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +#include "MantidKernel/System.h" + +#include <boost/python/object.hpp> + +#include <string> + +namespace Mantid +{ + namespace Kernel + { + // Forward declarations + class IPropertyManager; + } + namespace PythonInterface + { + namespace PropertyMarshal + { + /** + * A non-template base class that can be stored in a map so that + * its virtual functions are overridden in template derived classes + * that can extract the correct type from the Python object + */ + struct DLLExport PropertyHandler + { + /// Virtual Destructor + virtual ~PropertyHandler() {}; + /// Set function to handle Python -> C++ calls + virtual void set(Kernel::IPropertyManager* alg, const std::string &name, boost::python::object value) = 0; + /// Is the given object an instance the handler's type + virtual bool isInstance(const boost::python::object&) const = 0; + }; + } + } +} + +#endif /* MANTID_PYTHONINTERFACE_PROPERTYHANDLER_H_ */ diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyMarshal.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyMarshal.h index 81996e7598dc45d81ec51726532ef5fc71d67c6b..d73bd7a76ddacf00c353ad65c5e65a0e60656da8 100644 --- a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyMarshal.h +++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyMarshal.h @@ -23,15 +23,10 @@ Code Documentation is available at: <http://doxygen.mantidproject.org> */ #include "MantidKernel/System.h" -#include "MantidKernel/Property.h" -#include "MantidKernel/IPropertyManager.h" -#include "MantidKernel/DataItem.h" #include <boost/python/object.hpp> -#include <boost/python/extract.hpp> #include <string> -#include <iostream> namespace Mantid { @@ -54,26 +49,10 @@ namespace Mantid * The helpers declared here deal with calling the correct function depending * on the type passed to it. - * We will also need more marshaling for these functions as we want be able to - * pass numpy arrays seamlessly to algorithms. + * We will also need marshaling for these functions as we want be able to + * pass numpy arrays to algorithms. */ - /** - * A non-templated base class that can be stored in a map so that - * its virtual functions are overridden in templated derived classes - * that can extract the correct type from the Python object - */ - struct DLLExport PropertyHandler - { - /// Virtual Destructor - virtual ~PropertyHandler() {}; - /// Set function to handle Python -> C++ calls - virtual void set(Kernel::IPropertyManager* alg, const std::string &name, boost::python::object value) = 0; - /// Is the given object an instance the handler's type - virtual bool isInstance(const boost::python::object&) const = 0; - }; - - //------------------------------------------------------------------------------------------------------------ /** * A namespace for marshaling calls involving transferring property values in/out of an IPropertyManager. * @@ -83,12 +62,17 @@ namespace Mantid */ namespace PropertyMarshal { + //----------------------------------------------------------------------- + // Forward declarations + //----------------------------------------------------------------------- + struct PropertyHandler; + /// Insert a new property handler DLLExport void registerHandler(PyTypeObject* typeObject, PropertyHandler* handler); /// This static function allows a call to a method on an IPropertyManager object DLLExport void setProperty(boost::python::object self, const std::string & name, boost::python::object value); - /// Converts the value of a property to the most appropriate type, i.e. the most dervied exported interface + /// Converts the value of a property to the most appropriate type, i.e. the most derived exported interface DLLExport boost::python::object value(boost::python::object self); }; diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyWithValue.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyWithValue.h index 3fc115768799ba3ae15458635f9d53b038d2ddee..af4a3f50fdf151b171a4fecb66b6ea4a0b6544ff 100644 --- a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyWithValue.h +++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyWithValue.h @@ -26,6 +26,7 @@ #include "MantidKernel/PropertyWithValue.h" #include "MantidPythonInterface/kernel/PropertyMarshal.h" +#include <boost/python/class.hpp> #include <boost/python/bases.hpp> #include <boost/python/return_value_policy.hpp> #include <boost/python/copy_const_reference.hpp> @@ -33,9 +34,9 @@ /** * Define a macro to export PropertyWithValue template types */ -#define EXPORT_PROP_W_VALUE(type) \ - class_<Mantid::Kernel::PropertyWithValue<type>, \ - boost::python::bases<Mantid::Kernel::Property>, boost::noncopyable>("PropertyWithValue_"#type, boost::python::no_init) \ +#define EXPORT_PROP_W_VALUE(type,suffix) \ + boost::python::class_<Mantid::Kernel::PropertyWithValue< type >, \ + boost::python::bases<Mantid::Kernel::Property>, boost::noncopyable>("PropertyWithValue_"#suffix, boost::python::no_init) \ .add_property("value", Mantid::PythonInterface::PropertyMarshal::value) \ .add_property("value_as_declared", make_function(&Mantid::Kernel::PropertyWithValue<type>::operator(), \ boost::python::return_value_policy<boost::python::copy_const_reference>())) \ diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/SequenceTypeHandler.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/SequenceTypeHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..da814b53c385155dbed6083c6cd8ef526b3b007a --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/SequenceTypeHandler.h @@ -0,0 +1,49 @@ +#ifndef MANTID_PYTHONINTERFACE_SEQUENCETYPEHANDLER_H_ +#define MANTID_PYTHONINTERFACE_SEQUENCETYPEHANDLER_H_ +/** + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +#include "MantidPythonInterface/kernel/PropertyHandler.h" + +namespace Mantid +{ + namespace PythonInterface + { + namespace PropertyMarshal + { + /** + * A property handler that deals with translation of multi-value + * Python types, i.e. python arrays etc to/from Mantid algorithm properties + * It does not handle Numpy arrays, @see NumpyTypeHandler + */ + struct DLLExport SequenceTypeHandler : PropertyHandler + { + /// Call to set a named property where the value is some container type + virtual void set(Kernel::IPropertyManager* alg, const std::string &name, boost::python::object value); + /// Is the given object an instance the handler's type + virtual bool isInstance(const boost::python::object&) const; + }; + + } + } +} + +#endif /* MANTID_PYTHONINTERFACE_SEQUENCETYPEHANDLER_H_ */ diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/SingleValueTypeHandler.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/SingleValueTypeHandler.h index 1b5c534ccd0984f2bb6ffffb797e444a1f50e093..c26ad02909b93c50304cfc342ca7a607b9a0f09e 100644 --- a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/SingleValueTypeHandler.h +++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/SingleValueTypeHandler.h @@ -19,7 +19,15 @@ File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> Code Documentation is available at: <http://doxygen.mantidproject.org> */ +#include "MantidPythonInterface/kernel/PropertyHandler.h" #include "MantidPythonInterface/kernel/PropertyMarshal.h" +#include "MantidKernel/IPropertyManager.h" + +#ifdef __GNUC__ + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif + +#include <boost/python/extract.hpp> namespace Mantid { @@ -31,7 +39,7 @@ namespace Mantid /** * A templated handler that calls the appropriate setProperty method for the type on the given PropertyManager * A new typedhandler should be inserted into the type look up map with the - * DECLARE_TYPEHANDLER macro whenever a new class is exported that will be used with PropertyWithValue + * DECLARE_SINGLEVALUETYPEHANDLER macro whenever a new class is exported that will be used with PropertyWithValue */ template<typename BaseType, typename DerivedType=BaseType> struct DLLExport SingleValueTypeHandler : public PropertyHandler diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/StlExportDefinitions.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/StlExportDefinitions.h new file mode 100644 index 0000000000000000000000000000000000000000..ddd4dbef72db3ed87bdafaf72f38425002ba7e60 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/StlExportDefinitions.h @@ -0,0 +1,120 @@ +#ifndef MANTID_PYTHONINTERFACE_STLEXPORTDEFINITIONS_H_ +#define MANTID_PYTHONINTERFACE_STLEXPORTDEFINITIONS_H_ +/** + This file contains the export definitions for various stl containers. + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +#include <boost/python/class.hpp> +#include <boost/python/init.hpp> +#ifdef _MSC_VER + #pragma warning(disable:4267) // Kill warning from line 176 of indexing suite +#endif + #include <boost/python/suite/indexing/vector_indexing_suite.hpp> + +#include <vector> +#include <set> + +namespace Mantid +{ + namespace PythonInterface + { + /** + * Convert an element type within a sequence to a string for printing + * @param value :: The elements value + * @return A string representation of the value for printing within a sequence + */ + template<typename ElementType> + std::string toString(const ElementType & value) + { + std::ostringstream os; + os << value; + return os.str(); + } + + /** + * Convert a string element within a sequence to a string for printing + * @param value :: The elements value + * @return A string representation of the value for printing within a sequence, i.e. + * wrapped in single quotes to emulate printing a python sequence of strings + */ + template<> + std::string toString(const std::string & value) + { + std::ostringstream os; + os << value; + return os.str(); + } + + + /// Convert a sequence of values to a string for printing + template<typename SequenceType,typename ElementType> + std::string toString(const SequenceType & values) + { + typename SequenceType::const_iterator iend = values.end(); + std::ostringstream os; + std::string retval; + for( typename SequenceType::const_iterator itr = values.begin(); itr != iend; ) + { + os << toString(*itr); + os << *itr; + if( ++itr != iend ) + { + retval += ","; + } + } + return retval; + } + + /** + * A struct to help export std::vector types + */ + template <typename ElementType> + struct std_vector_exporter + { + ///A typedef of a vector of template ElementTypes + typedef std::vector<ElementType> w_t; + + static std::string to_string(const w_t & values) + { + if( values.empty() ) return "[]"; + std::string retval("["); + retval += toString<w_t, ElementType>(values); + retval += "]"; + return retval; + } + + ///a python wrapper + static void wrap(std::string const& python_name) + { + boost::python::class_<w_t, std::auto_ptr<w_t> >(python_name.c_str()) + .def(boost::python::init<w_t const&>()) + .def(boost::python::vector_indexing_suite<w_t>()) + .def("__str__", &std_vector_exporter::to_string) + ; + } + + }; + + } +} + +#endif /* MANTID_PYTHONINTERFACE_STLEXPORTDEFINITIONS_H_ */ diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/VectorDelegate.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/VectorDelegate.h new file mode 100644 index 0000000000000000000000000000000000000000..1325e48611c9fc301b9e7b5ce439e5c5e6894cc7 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/VectorDelegate.h @@ -0,0 +1,65 @@ +#ifndef MANTID_PYTHONINTERFACE_VECTORDELEGATE_H_ +#define MANTID_PYTHONINTERFACE_VECTORDELEGATE_H_ +/** + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- +#include "MantidKernel/System.h" + +#include <boost/python/object.hpp> +// Before Python 2.5 all indices were treated as integers +// Ensure we can still use the Py_ssize_t type +#if PY_VERSION_HEX < 0x02050000 +typedef int Py_ssize_t; +#define PY_SSIZE_T_MAX INT_MAX +#define PY_SSIZE_T_MIN INT_MIN +#endif + +#include <string> +#include <vector> + +//----------------------------------------------------------------------------- +// Forward declaration +//----------------------------------------------------------------------------- +struct PyArrayObject; + +namespace Mantid +{ + namespace PythonInterface + { + namespace VectorDelegate + { + /// Check the object contains a type that is some container of values + DLLExport std::string isSequenceType(PyObject* value); + /// Convert a Python type into a C++ std vector using the template element type + template<typename ElementType> + DLLExport const std::vector<ElementType> toStdVector(PyObject *value); + /// Convert a numpy array to a std::vector + template<typename VectorElementType, typename NumpyType> + DLLExport const std::vector<VectorElementType> toStdVectorFromNumpy(PyArrayObject *value); + + } + } +} + +#endif /* MANTID_PYTHONINTERFACE_VECTORDELEGATE_H_ */ diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/MatrixWorkspace.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/MatrixWorkspace.cpp index 8a014ef0e4ca9fae7a061f9398cf46c7638c6d29..947b45424cb569bea0047f2a379e94bc634260c5 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/MatrixWorkspace.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/MatrixWorkspace.cpp @@ -26,7 +26,7 @@ void export_MatrixWorkspace() void export_MatrixWorkspaceProperty() { - EXPORT_PROP_W_VALUE(MatrixWorkspace_sptr); + EXPORT_PROP_W_VALUE(MatrixWorkspace_sptr, MatrixWorkspace); register_ptr_to_python<WorkspaceProperty<MatrixWorkspace>*>(); class_<WorkspaceProperty<MatrixWorkspace>, bases<PropertyWithValue<MatrixWorkspace_sptr>,IWorkspaceProperty>, boost::noncopyable>("WorkspaceProperty_MatrixWorkspace", no_init) diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Workspace.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Workspace.cpp index a05994cc3615ed5538811b88495f4bd270f3511f..086d68334e77cda6a0506ec8cac5efbf8c0c8bb9 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Workspace.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Workspace.cpp @@ -49,7 +49,7 @@ void export_WorkspaceProperty() ; // Export the WorkspaceProperty hierarchy so that the plain Property* return from getPointerToProperty is automatically upcast to a WorkspaceProperty* - EXPORT_PROP_W_VALUE(Workspace_sptr); + EXPORT_PROP_W_VALUE(Workspace_sptr, Workspace); register_ptr_to_python<WorkspaceProperty<Workspace>*>(); class_<WorkspaceProperty<Workspace>, bases<PropertyWithValue<Workspace_sptr>,IWorkspaceProperty>, boost::noncopyable>("WorkspaceProperty_Workspace", no_init) ; diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt index ed19be1b0f4aea4f17b987e22b2a70a7b7337a11..dac0b524ebc9c5df22312cc2250f47e1356a5051 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt @@ -8,20 +8,30 @@ set ( EXPORT_FILES src/DataItem.cpp src/IPropertyManager.cpp src/Property.cpp + src/PropertyWithValue.cpp + src/ArrayProperty.cpp src/Quat.cpp src/V3D.cpp + src/StlContainers.cpp ) set ( SRC_FILES + src/NumpyTypeHandler.cpp src/PropertyMarshal.cpp + src/SequenceTypeHandler.cpp + src/VectorDelegate.cpp src/WrapperHelpers.cpp ) set ( INC_FILES + ${HEADER_DIR}/kernel/NumpyTypeHandler.h ${HEADER_DIR}/kernel/PythonObjectInstantiator.h ${HEADER_DIR}/kernel/PropertyWithValue.h + ${HEADER_DIR}/kernel/PropertyHandler.h ${HEADER_DIR}/kernel/PropertyMarshal.h ${HEADER_DIR}/kernel/SingleValueTypeHandler.h + ${HEADER_DIR}/kernel/StlExportDefinitions.h + ${HEADER_DIR}/kernel/VectorDelegate.h ${HEADER_DIR}/kernel/WrapperHelpers.h ) diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/ArrayProperty.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/ArrayProperty.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2e694b2920c568912c68a68a67a9a4abf4f404c7 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/ArrayProperty.cpp @@ -0,0 +1,19 @@ +#include "MantidKernel/ArrayProperty.h" +#include <boost/python/class.hpp> + +using Mantid::Kernel::ArrayProperty; +using Mantid::Kernel::PropertyWithValue; +using namespace boost::python; + +#define EXPORT_ARRAY_PROP(type, suffix) \ + class_<ArrayProperty<type>, \ + bases<PropertyWithValue<std::vector<type> > >, boost::noncopyable>("ArrayProperty_"#suffix, no_init); + + +void export_ArrayProperty() +{ + EXPORT_ARRAY_PROP(double,dbl); + EXPORT_ARRAY_PROP(int,int); + EXPORT_ARRAY_PROP(size_t,size_t); +} + diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/IPropertyManager.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/IPropertyManager.cpp index eee9c87a455eb3988218acb884592fd304109e9f..73d721805b9e8b1182ae343b3632490945bd035f 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/IPropertyManager.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/IPropertyManager.cpp @@ -14,6 +14,7 @@ void export_IPropertyManager() class_<IPropertyManager, boost::noncopyable>("IPropertyManager", no_init) .def("get_property", &IPropertyManager::getPointerToProperty, return_value_policy<return_by_value>(), "Returns the property of the given name. Use .value to give the value") + .def("get_property_value", &IPropertyManager::getPropertyValue, "Returns a string representation of the named property's value") .def("set_property_value", &IPropertyManager::setPropertyValue, "Set the value of the named property via a string") .def("set_property", &PropertyMarshal::setProperty, "Set the value of the named property") ; diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/NumpyTypeHandler.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/NumpyTypeHandler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7e90b9dfcb8340a4eb254fdc8291e70fe73a6613 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/NumpyTypeHandler.cpp @@ -0,0 +1,167 @@ +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- +#include "MantidPythonInterface/kernel/NumpyTypeHandler.h" +#include "MantidPythonInterface/kernel/VectorDelegate.h" +#include "MantidKernel/IPropertyManager.h" + +// See http://docs.scipy.org/doc/numpy/reference/c-api.array.html#PY_ARRAY_UNIQUE_SYMBOL +#define PY_ARRAY_UNIQUE_SYMBOL KERNEL_ARRAY_API +#define NO_IMPORT_ARRAY +#include <numpy/ndarrayobject.h> + +namespace Mantid +{ + namespace PythonInterface + { + namespace PropertyMarshal + { + /** + * Handle Python -> C++ calls to a property manager and get the correct type from the + * python object + * @param alg :: A pointer to an IPropertyManager + * @param name :: The name of the property + * @param value :: A boost python object that points to a numpy array + */ + void NumpyTypeHandler::set(Kernel::IPropertyManager* alg, + const std::string &name, boost::python::object value) + { + if( !PyArray_Check(value.ptr()) ) + { + throw std::invalid_argument(std::string("NumpyTypeHandler::set - Cannot handle non-numpy array. Type passed: ") + value.ptr()->ob_type->tp_name); + } + Kernel::Property *prop = alg->getPointerToProperty(name); + const std::type_info & propTypeInfo = *(prop->type_info()); + PyArrayObject *nparray=(PyArrayObject*)value.ptr(); + if( typeid(std::vector<double>) == propTypeInfo ) + { + this->setDoubleArrayProperty(alg, name, nparray); + } + else if( PyArray_ISINTEGER(nparray) ) + { + this->setIntNumpyProperty(alg, name, propTypeInfo, nparray); + } + + else + { + throw std::invalid_argument("NumpyTypeHandler::set - Unable to handle non-double std::vector property types."); + } + } + + /** + * Is the python object an instance a sequence type + * @param value :: A python object + * @returns True if it is, false otherwise + */ + bool NumpyTypeHandler::isInstance(const boost::python::object & value) const + { + UNUSED_ARG(value); + return false; + } + + //----------------------------------------------------------------------- + // Private memebers + //----------------------------------------------------------------------- + /** + * Handle double-type properties, i.e PropertyWithValue<std::vector<double> > types + * @param alg :: A pointer to a property manager + * @param name :: The name of the property to set + * @param nparray :: A pointer to a numpy array + */ + void NumpyTypeHandler::setDoubleArrayProperty(Kernel::IPropertyManager* alg, const std::string &name, PyArrayObject * nparray) + { + // If we have a property of type vector_double then we should be able to set that with an array of integers as well as doubles + std::vector<double> propValues; + switch(PyArray_TYPE(nparray)) + { + case NPY_DOUBLE: + propValues = VectorDelegate::toStdVectorFromNumpy<double, npy_double>(nparray); + break; + case NPY_INT64: + propValues = VectorDelegate::toStdVectorFromNumpy<double, npy_int64>(nparray); + break; + case NPY_INT32: + propValues = VectorDelegate::toStdVectorFromNumpy<double, npy_int32>(nparray); + break; + default: + throw std::invalid_argument( + std::string("NumpyTypeHandler::set - Cannot convert from ") + nparray->descr->type + + " to a C++ double without loss of precision"); + } + + alg->setProperty(name, propValues); + } + /** + * Handle integer-type properties, i.e PropertyWithValue<std::vector<double> > types + * @param alg :: A pointer to a property manager + * @param name :: The name of the property to set + * @param typeInfo :: A reference to the typeinfo object for the property's value type + * @param nparray :: A pointer to a numpy array + */ + void NumpyTypeHandler::setIntNumpyProperty(Kernel::IPropertyManager* alg, const std::string &name, + const std::type_info & typeInfo, PyArrayObject * nparray) + { + // We know that the numpy array is some kind of integer signed/unsigned + int typeNum = PyArray_TYPE(nparray); + + /** + * We need to make sure that some type isn't accidentally cast down to a lower + * precision type when going into a property + */ + + if( typeInfo == typeid(std::vector<size_t>) ) + { + std::vector<size_t> propValues; + switch(typeNum) + { + case NPY_INT32: + propValues = VectorDelegate::toStdVectorFromNumpy<size_t, npy_int32>(nparray); + break; + case NPY_INT64: + propValues = VectorDelegate::toStdVectorFromNumpy<size_t, npy_int64>(nparray); + break; + case NPY_UINT: + propValues = VectorDelegate::toStdVectorFromNumpy<size_t, npy_uint>(nparray); + break; + default: + throw std::invalid_argument( + std::string("NumpyTypeHandler::set - Cannot convert from ") + nparray->descr->typeobj->tp_name + + " to a C++ size_t without loss of precision"); + } + alg->setProperty(name, propValues); + } + else if( typeInfo == typeid(std::vector<int32_t>) ) + { + std::vector<int32_t> propValues; + switch(typeNum) + { + case NPY_INT32: + propValues = VectorDelegate::toStdVectorFromNumpy<int32_t, npy_int32>(nparray); + break; + default: + throw std::invalid_argument( + std::string("NumpyTypeHandler::set - Cannot convert from ") + nparray->descr->typeobj->tp_name + + " to a C++ 32-bit int without loss of precision"); + } + alg->setProperty(name, propValues); + } + else if( typeInfo == typeid(std::vector<int64_t>) ) + { + std::vector<int64_t> propValues; + switch(typeNum) + { + case NPY_INT64: + propValues = VectorDelegate::toStdVectorFromNumpy<int64_t, npy_int64>(nparray); + break; + default: + throw std::invalid_argument( + std::string("NumpyTypeHandler::set - Cannot convert from ") + nparray->descr->typeobj->tp_name + + " to a C++ 64-bit int without loss of precision"); + } + alg->setProperty(name, propValues); + } + } + + } + } +} diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Property.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Property.cpp index 204b1cb53fae526fc7a303e7190c890087dcf7b6..8d6c8a841f8be4260f15a3bfb65fd95cbb64f7eb 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Property.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Property.cpp @@ -1,5 +1,4 @@ #include "MantidKernel/Property.h" -#include "MantidPythonInterface/kernel/PropertyWithValue.h" #include <boost/python/class.hpp> #include <boost/python/register_ptr_to_python.hpp> @@ -36,15 +35,3 @@ void export_Property() .add_property("is_default", &Mantid::Kernel::Property::isDefault, "Is the property set at the default value") ; } - -/** - * I see know way around explicitly declaring each we use - */ -void export_PropertyWithValue() -{ - // See MantidPythonInterface/kernel/PropertyWithValue.h for macro definition - EXPORT_PROP_W_VALUE(int); - EXPORT_PROP_W_VALUE(double); - EXPORT_PROP_W_VALUE(bool); - EXPORT_PROP_W_VALUE(std::string); -} diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/PropertyMarshal.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/PropertyMarshal.cpp index c8a2da1d518cd8924a6560d12911deab3acffbf8..02f4cc2240f6dffd9c5870a119b68367324ebd4c 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/PropertyMarshal.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/PropertyMarshal.cpp @@ -2,6 +2,7 @@ // Includes //----------------------------------------------------------------------------- #include "MantidPythonInterface/kernel/PropertyMarshal.h" +#include "MantidPythonInterface/kernel/PropertyHandler.h" #include "MantidAPI/MatrixWorkspace.h" #include <boost/python/extract.hpp> diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/PropertyWithValue.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/PropertyWithValue.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8cd33862141c1bec702cd96488ad84da68e24930 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/PropertyWithValue.cpp @@ -0,0 +1,21 @@ +#include "MantidPythonInterface/kernel/PropertyWithValue.h" + +void export_BasicPropertyWithValueTypes() +{ + // See MantidPythonInterface/kernel/PropertyWithValue.h for macro definition + EXPORT_PROP_W_VALUE(int, int); + EXPORT_PROP_W_VALUE(std::vector<int>, vector_int); + + EXPORT_PROP_W_VALUE(size_t, size_t); + EXPORT_PROP_W_VALUE(std::vector<size_t>, vector_size_t); + + EXPORT_PROP_W_VALUE(double, dbl); + EXPORT_PROP_W_VALUE(std::vector<double>,vector_dbl); + + EXPORT_PROP_W_VALUE(bool, bool); + + EXPORT_PROP_W_VALUE(std::string, string); + EXPORT_PROP_W_VALUE(std::vector<std::string>,vector_str); +} + + diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/SequenceTypeHandler.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/SequenceTypeHandler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..90f9609c8314e141e3f0a5cf17a3c2e1ca2bbae4 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/SequenceTypeHandler.cpp @@ -0,0 +1,78 @@ +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- +#include "MantidPythonInterface/kernel/SequenceTypeHandler.h" +#include "MantidPythonInterface/kernel/VectorDelegate.h" +#include "MantidKernel/IPropertyManager.h" + +namespace Mantid +{ + namespace PythonInterface + { + namespace PropertyMarshal + { + + + /** + * Set function to handle Python -> C++ calls to a property manager and get the correct type + * @param alg :: A pointer to an IPropertyManager + * @param name :: The name of the property + * @param value :: A boost python object that stores the container values + */ + void SequenceTypeHandler::set(Kernel::IPropertyManager* alg, + const std::string &name, boost::python::object value) + { + // We can't avoid a copy here as the final values will have reside in an array allocated + // by the C++ new operator + + // We need some way of instantiating the correct vector type. We'll take the type from the + // first element in the list + PyObject *firstElement = PySequence_Fast_GET_ITEM(value.ptr(), 0); + if( PyInt_Check(firstElement) || PyLong_Check(firstElement) ) + { + // The actual property could be a variety of flavours of integer type + // MG (2011/11/09): I'm not over the moon about this implementation but I don't + // have a better idea. + Kernel::Property *prop = alg->getPointerToProperty(name); + const std::type_info * propTypeInfo = prop->type_info(); + if( typeid(std::vector<int>) == *propTypeInfo ) + { + std::vector<int> propValues = VectorDelegate::toStdVector<int>(value.ptr()); + alg->setProperty(name, propValues); + } + else if( typeid(std::vector<size_t>) == *propTypeInfo ) + { + std::vector<size_t> propValues = VectorDelegate::toStdVector<size_t>(value.ptr()); + alg->setProperty(name, propValues); + } + else + { + throw std::invalid_argument("SequenceTypeHandler::set - Unknown integer property type."); + } + } + else if( PyFloat_Check(firstElement) ) + { + std::vector<double> propValues = VectorDelegate::toStdVector<double>(value.ptr()); + alg->setProperty(name, propValues); + } + else + { + throw std::invalid_argument("SequenceTypeHandler::set - Unknown sequence element type."); + } + + } + + /** + * Is the python object an instance a sequence type + * @param value :: A python object + * @returns True if it is, false otherwise + */ + bool SequenceTypeHandler::isInstance(const boost::python::object & value) const + { + UNUSED_ARG(value); + return false; + } + + } + } +} diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/StlContainers.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/StlContainers.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e489d9c7fb2935a5b58975ed920249610937f5f7 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/StlContainers.cpp @@ -0,0 +1,14 @@ +#include "MantidPythonInterface/kernel/StlExportDefinitions.h" + +void exportStlContainers() +{ + using Mantid::PythonInterface::std_vector_exporter; + + // Export some frequently used stl containers + std_vector_exporter<int>::wrap("std_vector_int"); + std_vector_exporter<long>::wrap("std_vector_long"); + std_vector_exporter<std::size_t>::wrap("std_vector_size_t"); + std_vector_exporter<double>::wrap("std_vector_dbl"); + std_vector_exporter<bool>::wrap("std_vector_bool"); + std_vector_exporter<std::string>::wrap("cpp_list_str"); +} diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/VectorDelegate.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/VectorDelegate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a605c949ba3dc9ac5aa99a747567111f8057608a --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/VectorDelegate.cpp @@ -0,0 +1,120 @@ +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- +#include "MantidPythonInterface/kernel/VectorDelegate.h" +#include <boost/python/extract.hpp> + +// See http://docs.scipy.org/doc/numpy/reference/c-api.array.html#PY_ARRAY_UNIQUE_SYMBOL +#define PY_ARRAY_UNIQUE_SYMBOL KERNEL_ARRAY_API +#define NO_IMPORT_ARRAY +#include <numpy/ndarrayobject.h> + +#include <iostream> + +namespace Mantid +{ + namespace PythonInterface + { + namespace VectorDelegate + { + /** + * Check that the list contains items of the required type for the C++ type + * @param value :: A pointer to a python list object + * @return ""if the list can be converted to a vector, otherwise it returns an error string + */ + std::string isSequenceType(PyObject *value) + { + std::string error(""); + if( !PySequence_Check(value) ) + { + error = std::string("Cannot convert ") + value->ob_type->tp_name + " object to a std::vector."; + } + return error; + } + + /** + * Convert a python object into a std::vector + * @param value :: A pointer to a python list + * @return A new vector created from the python values (i.e. a copy) + */ + template<typename ElementType> + const std::vector<ElementType> toStdVector(PyObject *value) + { + const std::string msg = isSequenceType(value); + if( !msg.empty() ) + { + throw std::invalid_argument(msg); + } + Py_ssize_t len = PySequence_Size(value); + std::vector<ElementType> result((size_t)len); + for( Py_ssize_t i = 0; i < len; ++i ) + { + PyObject *item = PySequence_Fast_GET_ITEM(value, i); + ElementType element = boost::python::extract<ElementType>(item)(); + result[i]= element; + } + return result; + } + + /** + * Convert a python array object into a std::vector + * @param arr :: A pointer to a numpy array + * @return A new vector created from the python values (i.e. a copy) + */ + template<typename VectorElementType, typename NumpyType> + const std::vector<VectorElementType> toStdVectorFromNumpy(PyArrayObject *arr) + { + // A numpy array is a homogeneous array, i.e each type is identical and the underlying array is contiguous + const int ndim = PyArray_NDIM(arr); + if( ndim > 1 ) throw std::invalid_argument("toStdVectorNumpy - Unable to handle arrays with greater than 1 dimension."); + + npy_intp length = PyArray_SIZE(arr); + std::vector<VectorElementType> result(length); + if(length == 0) + { + return result; + } + + /** Use the iterator API to iterate through the array + * and assign each value to the corresponding vector + */ + PyObject *iter = PyArray_IterNew((PyObject*)arr); + size_t index(0); + do + { + NumpyType *item = (NumpyType*)PyArray_ITER_DATA(iter); + result[index] = static_cast<VectorElementType>(*item); + ++index; + PyArray_ITER_NEXT(iter); + } + while(PyArray_ITER_NOTDONE(iter)); + return result; + } + + //-------------------------------------------------------------------------- + // Concrete Instantiations + //-------------------------------------------------------------------------- + template DLLExport const std::vector<int> toStdVector<int>(PyObject *value); + template DLLExport const std::vector<size_t> toStdVector<size_t>(PyObject *value); + template DLLExport const std::vector<double> toStdVector<double>(PyObject *value); + // To Double vector types + template DLLExport const std::vector<double> toStdVectorFromNumpy<double, npy_double>(PyArrayObject *value); + template DLLExport const std::vector<double> toStdVectorFromNumpy<double, npy_int64>(PyArrayObject *value); + template DLLExport const std::vector<double> toStdVectorFromNumpy<double, npy_int32>(PyArrayObject *value); + + // To size_t vector + template DLLExport const std::vector<size_t> toStdVectorFromNumpy<size_t, npy_int32>(PyArrayObject *value); + template DLLExport const std::vector<size_t> toStdVectorFromNumpy<size_t, npy_int64>(PyArrayObject *value); + template DLLExport const std::vector<size_t> toStdVectorFromNumpy<size_t, npy_uint>(PyArrayObject *value); + + // To int32_t vector + template DLLExport const std::vector<int32_t> toStdVectorFromNumpy<int32_t, npy_int32>(PyArrayObject *value); + + // To int64_t vector + template DLLExport const std::vector<int64_t> toStdVectorFromNumpy<int64_t, npy_int64>(PyArrayObject *value); + + + } + } +} + diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/kernel.cpp.in b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/kernel.cpp.in index 7a26e1cd4ea34a75b9bddc900c951934677670c9..12f53b378abbbb2681b47030aa2c9f68a840a6dc 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/kernel.cpp.in +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/kernel.cpp.in @@ -1,11 +1,17 @@ #include <boost/python/module.hpp> #include <boost/python/docstring_options.hpp> -#include <boost/python/numeric.hpp> #include "MantidPythonInterface/kernel/SingleValueTypeHandler.h" +#include "MantidPythonInterface/kernel/SequenceTypeHandler.h" +#include "MantidPythonInterface/kernel/NumpyTypeHandler.h" + +// See http://docs.scipy.org/doc/numpy/reference/c-api.array.html#PY_ARRAY_UNIQUE_SYMBOL +#define PY_ARRAY_UNIQUE_SYMBOL KERNEL_ARRAY_API +#include <numpy/arrayobject.h> using namespace Mantid::PythonInterface; using PropertyMarshal::SingleValueTypeHandler; +using PropertyMarshal::SequenceTypeHandler; // Forward declare @EXPORT_DECLARE@ @@ -14,14 +20,18 @@ BOOST_PYTHON_MODULE(_kernel) { // Doc string options - User defined, python arguments, C++ call signatures boost::python::docstring_options docstrings(true, true, false); - // Use numpy arrays - boost::python::numeric::array::set_module_and_type("numpy", "ndarray"); + // Import numpy + _import_array(); // Map builtin type objects to appropriate handler classes for properties PropertyMarshal::registerHandler(&PyInt_Type, new SingleValueTypeHandler<int>()); PropertyMarshal::registerHandler(&PyBool_Type, new SingleValueTypeHandler<bool>()); PropertyMarshal::registerHandler(&PyFloat_Type, new SingleValueTypeHandler<double>()); PropertyMarshal::registerHandler(&PyString_Type, new SingleValueTypeHandler<std::string>()); + PropertyMarshal::registerHandler(&PyList_Type, new SequenceTypeHandler()); + PropertyMarshal::registerHandler(&PyTuple_Type, new SequenceTypeHandler()); + PropertyMarshal::registerHandler(&PyArray_Type, new PropertyMarshal::NumpyTypeHandler()); // Numpy array + @EXPORT_FUNCTIONS@ } diff --git a/Code/Mantid/Framework/PythonInterface/test/cpp/PythonObjectInstantiatorTest.h b/Code/Mantid/Framework/PythonInterface/test/cpp/PythonObjectInstantiatorTest.h index f4291f9ef7b5b91efe03fd4c839ebc86a6882c53..f06a77abf5cf55073a3e68dd9003f9d19097de2e 100644 --- a/Code/Mantid/Framework/PythonInterface/test/cpp/PythonObjectInstantiatorTest.h +++ b/Code/Mantid/Framework/PythonInterface/test/cpp/PythonObjectInstantiatorTest.h @@ -1,6 +1,7 @@ #ifndef PYTHONOBJECTINSTANTIATORTEST_H_ #define PYTHONOBJECTINSTANTIATORTEST_H_ +#include <cxxtest/GlobalFixture.h> #include <cxxtest/TestSuite.h> #include "MantidAPI/IAlgorithm.h" #include "MantidPythonInterface/kernel/PythonObjectInstantiator.h" @@ -9,6 +10,40 @@ #include <boost/python/object.hpp> +// ---------- Test world initialization --------------------------------- + +/** + * The cxxtest code ensures that the setup/tearDownWorld methods + * are called exactly once per test-process. We use this + * to initialize/shutdown the python interpreter + */ +class PythonProcessHandler : CxxTest::GlobalFixture +{ +public: + bool setUpWorld() + { + Py_Initialize(); + // A fatal error occurs if initialization fails so + // everything should be okay if we got here + return true; + } + + bool tearDownWorld() + { + // Py_Finalize(); // This kills RHEL5 for some reason + return true; + } +}; + +// From the cxxtest manual: +// +// We can rely on this file being included exactly once +// and declare this global variable in the header file. +// +static PythonProcessHandler pythonProcessHandler; + +//------------------------------------------------------------------------- + using Mantid::PythonInterface::PythonObjectInstantiator; using Mantid::API::IAlgorithm; using Mantid::API::IAlgorithm_sptr; @@ -25,7 +60,7 @@ public: // PythonObjectInstantiatorTest() : m_creator(NULL) { - Py_Initialize(); + //Py_Initialize(); } ~PythonObjectInstantiatorTest() diff --git a/Code/Mantid/Framework/PythonInterface/test/cpp/VectorDelegateTest.h b/Code/Mantid/Framework/PythonInterface/test/cpp/VectorDelegateTest.h new file mode 100644 index 0000000000000000000000000000000000000000..971cd5b48f17c834d45c3ef54c02e0c64991013c --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/cpp/VectorDelegateTest.h @@ -0,0 +1,69 @@ +#ifndef VECTORDELEGATETEST_H_ +#define VECTORDELEGATETEST_H_ + +#include "MantidPythonInterface/kernel/VectorDelegate.h" +#include <cxxtest/TestSuite.h> + +using namespace Mantid::PythonInterface; + +class VectorDelegateTest : public CxxTest::TestSuite +{ +public: + + void test_that_a_non_sequence_type_returns_an_appropriate_error_string_from_isConvertible() + { + PyObject *dict = PyDict_New(); + TS_ASSERT_EQUALS(VectorDelegate::isSequenceType(dict), "Cannot convert dict object to a std::vector."); + Py_DECREF(dict); + } + + void test_that_a_non_sequence_type_throws_an_error_when_trying_to_convert_to_a_vector() + { + PyObject *dict = PyDict_New(); + TS_ASSERT_THROWS(VectorDelegate::toStdVector<int>(dict), std::invalid_argument); + Py_DECREF(dict); + } + + void test_that_a_python_list_of_all_matching_types_is_converted_correctly() + { + const size_t length(3); + boost::python::object lst = createPyIntList((Py_ssize_t)length, false); + std::vector<int> cppvec = VectorDelegate::toStdVector<int>(lst.ptr()); + TS_ASSERT_EQUALS(cppvec.size(), length); + // Check values + for( size_t i = 0; i < length; ++i ) + { + TS_ASSERT_EQUALS(cppvec[i], i); + } + } + + void test_that_trying_to_convert_a_python_list_of_differing_types_throws_error_already_set() + { + const size_t length(4); + boost::python::object lst = createPyIntList((Py_ssize_t)length, true); + TS_ASSERT_THROWS(VectorDelegate::toStdVector<int>(lst.ptr()), boost::python::error_already_set); + } + +private: + + /// Create a Python list of the given length filled with integer values + /// v_i+1=v_i+1 starting at 0. If addItemOfDiffType is true add + /// a value of the second type + boost::python::object createPyIntList(Py_ssize_t length, bool addItemOfDiffType) + { + if(addItemOfDiffType) length += 1; + PyObject *lst = PyList_New((Py_ssize_t)length); + for(Py_ssize_t i = 0; i < length; ++i) + { + PyList_SetItem(lst, i, PyInt_FromLong((int)i)); // Cast avoids RHEL5 problem that doesn't have size_t + } + if(addItemOfDiffType) + { + PyList_SetItem(lst, length, PyFloat_FromDouble(100.0)); + } + return boost::python::object(boost::python::handle<>(lst)); + } +}; + + +#endif /* VECTORDELEGATETEST_H_ */ diff --git a/Code/Mantid/Framework/PythonInterface/test/python/PropertyWithValueTest.py b/Code/Mantid/Framework/PythonInterface/test/python/PropertyWithValueTest.py index 3266995475bdc2269d3e20351772a98935beb17f..b1fc10abfe3ffb01b73e4620949d48a8deb5a734 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/PropertyWithValueTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/PropertyWithValueTest.py @@ -2,20 +2,99 @@ import unittest from mantid.api import algorithm_mgr +import numpy as np + class PropertyWithValueTest(unittest.TestCase): + + # Integration algorithm handle + _integration = None + # MaskDetectors algorithm handle + _mask_dets = None + + def setUp(self): + if self._integration is None: + self.__class__._integration = algorithm_mgr.create_unmanaged("Integration") + self.__class__._integration.initialize() + if self._mask_dets is None: + self.__class__._mask_dets = algorithm_mgr.create_unmanaged("MaskDetectors") + self.__class__._mask_dets.initialize() - def test_set_property_basic_types(self): - prop_mgr = algorithm_mgr.create_unmanaged("Integration") - prop_mgr.initialize() - # Int type - prop_mgr.set_property("StartWorkspaceIndex", 5) - self.assertEquals(prop_mgr.get_property("StartWorkspaceIndex").value, 5) - # Bool type - prop_mgr.set_property("IncludePartialBins", True) - self.assertEquals(prop_mgr.get_property("IncludePartialBins").value, True) - # Float - prop_mgr.set_property("RangeLower", 100.5) - self.assertAlmostEqual(prop_mgr.get_property("RangeLower").value, 100.5) - prop_mgr.set_property("RangeLower", 50) # Set with an int should still work - self.assertAlmostEqual(prop_mgr.get_property("RangeLower").value, 50) - \ No newline at end of file + def test_set_property_int(self): + self._integration.set_property("StartWorkspaceIndex", 5) + self.assertEquals(self._integration.get_property("StartWorkspaceIndex").value, 5) + + def test_set_property_float(self): + self._integration.set_property("RangeLower", 100.5) + self.assertAlmostEqual(self._integration.get_property("RangeLower").value, 100.5) + self._integration.set_property("RangeLower", 50) # Set with an int should still work + self.assertAlmostEqual(self._integration.get_property("RangeLower").value, 50) + + def test_set_property_bool(self): + self._integration.set_property("IncludePartialBins", True) + self.assertEquals(self._integration.get_property("IncludePartialBins").value, True) + + def test_set_property_succeeds_with_python_int_lists(self): + value = [2,3,4,5,6] + self._mask_dets.set_property("WorkspaceIndexList", value) #size_t + idx_list = self._mask_dets.get_property("WorkspaceIndexList").value + self.assertEquals(len(idx_list), 5) + for i in range(5): + self.assertEquals(idx_list[i], i+2) + value.append(7) + + self._mask_dets.set_property("DetectorList", value) #integer + det_list = self._mask_dets.get_property("DetectorList").value + self.assertEquals(len(det_list), 6) + for i in range(6): + self.assertEquals(det_list[i], i+2) + + def test_set_property_succeeds_with_python_float_lists(self): + rebin = algorithm_mgr.create_unmanaged("Rebin") + rebin.initialize() + input = [0.5,1.0,5.5] + rebin.set_property('Params',input) + params = rebin.get_property('Params').value + self.assertEquals(len(params), 3) + for i in range(3): + self.assertEquals(params[i], input[i]) + + def test_set_property_raises_type_error_when_a_list_contains_multiple_types(self): + values = [2,3,4.0,5,6] + self.assertRaises(TypeError, self._mask_dets.set_property, "WorkspaceIndexList", values) #size_t + + def test_set_property_of_vector_double_succeeds_with_numpy_array_of_float_type(self): + self._do_vector_double_numpy_test() + + def test_set_property_of_vector_double_succeeds_with_numpy_array_of_int_type(self): + self._do_vector_double_numpy_test(True) + + def _do_vector_double_numpy_test(self, int_type=False): + create_ws = algorithm_mgr.create_unmanaged('CreateWorkspace') + create_ws.initialize() + if int_type: + datax = np.arange(10) + else: + datax = np.arange(10.0) + create_ws.set_property('DataX', datax) + x_values = create_ws.get_property('DataX').value + self.assertEquals(len(x_values), 10) + for i in range(10): + self.assertEquals(x_values[i], i) + + def _do_vector_int_numpy_test(self, property_name, dtype=None): + # Use the maskdetectors alg + indices = np.arange(6,dtype=dtype) + self._mask_dets.set_property(property_name, indices) + prop_values = self._mask_dets.get_property(property_name).value + self.assertEquals(len(prop_values), 6) + for i in range(6): + self.assertEquals(prop_values[i], i) + + def test_set_property_of_vector_int_succeeds_with_numpy_array_of_int_type(self): + # Minor hole with int64 as that technically can't be converted to an int32 without precision loss + # but I don't think it will be heavily used so we'll see + self._do_vector_int_numpy_test('DetectorList', np.int32) + + def test_set_property_of_vector_int_succeeds_with_numpy_array_of_int_type(self): + self._do_vector_int_numpy_test('WorkspaceIndexList') + diff --git a/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/BinaryOperationMDTestHelper.h b/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/BinaryOperationMDTestHelper.h index 651e5b61e2e299842165384f92e0decc150512a7..c01af41235bd8e247bf78af8a095e4a622dcc2fd 100644 --- a/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/BinaryOperationMDTestHelper.h +++ b/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/BinaryOperationMDTestHelper.h @@ -7,7 +7,17 @@ namespace BinaryOperationMDTestHelper { /// Run a binary algorithm. DLLExport Mantid::MDEvents::MDHistoWorkspace_sptr doTest(std::string algoName, std::string lhs, std::string rhs, std::string outName, - bool succeeds=true); + bool succeeds=true, + std::string otherProp="", std::string otherPropValue=""); + +} // (end namespace) + +namespace UnaryOperationMDTestHelper +{ + /// Run a unary algorithm. + DLLExport Mantid::MDEvents::MDHistoWorkspace_sptr doTest(std::string algoName, std::string inName, std::string outName, + bool succeeds=true, + std::string otherProp="", std::string otherPropValue=""); } // (end namespace) diff --git a/Code/Mantid/Framework/TestHelpers/src/BinaryOperationMDTestHelper.cpp b/Code/Mantid/Framework/TestHelpers/src/BinaryOperationMDTestHelper.cpp index 1be16187fc197354af39fb12b503d6660645d43e..803a1f9ed117ea77dc3e857675338d037a3cec3f 100644 --- a/Code/Mantid/Framework/TestHelpers/src/BinaryOperationMDTestHelper.cpp +++ b/Code/Mantid/Framework/TestHelpers/src/BinaryOperationMDTestHelper.cpp @@ -25,6 +25,7 @@ namespace BinaryOperationMDTestHelper { MDHistoWorkspace_sptr histo_A; MDHistoWorkspace_sptr histo_B; + MDHistoWorkspace_sptr histo_zero; IMDEventWorkspace_sptr event_A; IMDEventWorkspace_sptr event_B; WorkspaceSingleValue_sptr scalar; @@ -32,11 +33,13 @@ namespace BinaryOperationMDTestHelper histo_A = MDEventsTestHelper::makeFakeMDHistoWorkspace(2.0, 2, 5, 10.0, 1.0); histo_B = MDEventsTestHelper::makeFakeMDHistoWorkspace(3.0, 2, 5, 10.0, 1.0); + histo_zero = MDEventsTestHelper::makeFakeMDHistoWorkspace(0.0, 2, 5, 10.0, 0.0); event_A = MDEventsTestHelper::makeMDEW<2>(3, 0.0, 10.0, 1); event_B = MDEventsTestHelper::makeMDEW<2>(3, 0.0, 10.0, 1); scalar = WorkspaceCreationHelper::CreateWorkspaceSingleValue(3.0); AnalysisDataService::Instance().addOrReplace("histo_A", histo_A); AnalysisDataService::Instance().addOrReplace("histo_B", histo_B); + AnalysisDataService::Instance().addOrReplace("histo_zero", histo_zero); AnalysisDataService::Instance().addOrReplace("event_A", event_A); AnalysisDataService::Instance().addOrReplace("event_B", event_B); AnalysisDataService::Instance().addOrReplace("scalar", scalar); @@ -44,7 +47,7 @@ namespace BinaryOperationMDTestHelper /// Run a binary algorithm. MDHistoWorkspace_sptr doTest(std::string algoName, std::string lhs, std::string rhs, std::string outName, - bool succeeds) + bool succeeds, std::string otherProp, std::string otherPropValue) { setUpBinaryOperationMDTestHelper(); @@ -53,6 +56,8 @@ namespace BinaryOperationMDTestHelper alg->setPropertyValue("LHSWorkspace", lhs ); alg->setPropertyValue("RHSWorkspace", rhs ); alg->setPropertyValue("OutputWorkspace", outName ); + if (!otherProp.empty()) + alg->setPropertyValue(otherProp, otherPropValue); alg->execute(); if (succeeds) { @@ -72,3 +77,43 @@ namespace BinaryOperationMDTestHelper } } // (end namespace) + + + +namespace UnaryOperationMDTestHelper +{ + + MDHistoWorkspace_sptr doTest(std::string algoName, std::string inName, std::string outName, + bool succeeds, std::string otherProp, std::string otherPropValue) + { + MDHistoWorkspace_sptr histo = MDEventsTestHelper::makeFakeMDHistoWorkspace(2.0, 2, 5, 10.0, 2.0); + IMDEventWorkspace_sptr event = MDEventsTestHelper::makeMDEW<2>(3, 0.0, 10.0, 1); + WorkspaceSingleValue_sptr scalar = WorkspaceCreationHelper::CreateWorkspaceSingleValue(2.5); + AnalysisDataService::Instance().addOrReplace("histo", histo); + AnalysisDataService::Instance().addOrReplace("event", event); + AnalysisDataService::Instance().addOrReplace("scalar", scalar); + + IAlgorithm* alg = FrameworkManager::Instance().createAlgorithm(algoName); + alg->initialize(); + alg->setPropertyValue("InputWorkspace", inName ); + alg->setPropertyValue("OutputWorkspace", outName ); + if (!otherProp.empty()) + alg->setPropertyValue(otherProp, otherPropValue); + alg->execute(); + if (succeeds) + { + if (!alg->isExecuted()) + throw std::runtime_error("Algorithm " + algoName + " did not succeed."); + IMDWorkspace_sptr out = boost::dynamic_pointer_cast<IMDWorkspace>( AnalysisDataService::Instance().retrieve(outName)); + if (!out) + throw std::runtime_error("Algorithm " + algoName + " did not create the output workspace."); + return boost::dynamic_pointer_cast<MDHistoWorkspace>(out); + } + else + { + if (alg->isExecuted()) + throw std::runtime_error("Algorithm " + algoName + " did not fail as expected."); + return (MDHistoWorkspace_sptr()); + } + } +} // (end namespace) diff --git a/Code/Mantid/MantidPlot/mantidplot.py b/Code/Mantid/MantidPlot/mantidplot.py index c85f2345017e96f41d234599936782c016af76ba..68b156c7b0be8ee02ba9095ec2e06ca68a60a806 100644 --- a/Code/Mantid/MantidPlot/mantidplot.py +++ b/Code/Mantid/MantidPlot/mantidplot.py @@ -13,6 +13,10 @@ from MantidFramework import WorkspaceProxy, WorkspaceGroup, MatrixWorkspace, mtd #-------------------------- Wrapped MantidPlot functions ----------------- +# Overload for consistency with qtiplot table(..) & matrix(..) commands +def workspace(name): + return mtd[name] + def plotSpectrum(source, indices, error_bars = False): workspace_names = __getWorkspaceNames(source) index_list = __getWorkspaceIndices(indices) diff --git a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp index ebfdac59b745aff19677931c1c10cef1b9259196..31b95c4dc58798aac24de5b74c86d89933a91f8b 100644 --- a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp +++ b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp @@ -7602,7 +7602,7 @@ void ApplicationWindow::showCursor() /** Switch on the multi-peak selecting tool for fitting * with the Fit algorithm of multiple peaks on a single background */ -void ApplicationWindow::selectMultiPeak() +void ApplicationWindow::selectMultiPeak(bool showFitPropertyBrowser) { MultiLayer *plot = (MultiLayer *)activeWindow(MultiLayerWindow); if (!plot) @@ -7631,7 +7631,7 @@ void ApplicationWindow::selectMultiPeak() if (g->validCurvesDataSize()) { //Called when setting up usual peakPickerTool - PeakPickerTool* ppicker = new PeakPickerTool(g, mantidUI->fitFunctionBrowser()); + PeakPickerTool* ppicker = new PeakPickerTool(g, mantidUI->fitFunctionBrowser(), showFitPropertyBrowser); g->setActiveTool(ppicker); connect(plot,SIGNAL(windowStateChanged(Qt::WindowStates, Qt::WindowStates)),ppicker,SLOT(windowStateChanged(Qt::WindowStates, Qt::WindowStates))); } diff --git a/Code/Mantid/MantidPlot/src/ApplicationWindow.h b/Code/Mantid/MantidPlot/src/ApplicationWindow.h index 681ca6078b07dc8f83c74f607d0125cd7ce12a1a..da287a0ae743dd150a9c5386c3a9b48a89ad108f 100644 --- a/Code/Mantid/MantidPlot/src/ApplicationWindow.h +++ b/Code/Mantid/MantidPlot/src/ApplicationWindow.h @@ -616,7 +616,7 @@ public slots: void showScreenReader(); void pickPointerCursor(); void disableTools(); - void selectMultiPeak(); + void selectMultiPeak(bool showFitPropertyBrowser=true); void pickDataTool( QAction* action ); void updateLog(const QString& result); diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/GLObject.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/GLObject.cpp index ddc830c8907bd3329d98f38d02a346865897f0cf..87815c5cf413272d650f3aab450c0300440354cf 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/GLObject.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/GLObject.cpp @@ -58,7 +58,6 @@ void GLObject::construct()const this->define(); glEndList(); //if (dynamic_cast<ObjCompAssemblyActor*>(this)) - std::cerr<<"construct " << getName() << ' ' << mDisplayListId << '\n'; if(glGetError()==GL_OUT_OF_MEMORY) //Throw an exception throw Mantid::Kernel::Exception::OpenGLError("OpenGL: Out of video memory"); mChanged=false; //Object Marked as changed. diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentActor.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentActor.cpp index a8ddb385038833c7ec5b6d38f5e0e4c1bbd2289f..f489945b3e6806cedea9c3f8e61776dca10ef75a 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentActor.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentActor.cpp @@ -11,6 +11,8 @@ #include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/AnalysisDataService.h" +#include <boost/math/special_functions/fpclassify.hpp> + #include <QSettings> #include <QMessageBox> @@ -191,6 +193,11 @@ void InstrumentActor::setIntegrationRange(const double& xmin,const double& xmax) for (size_t i=0; i < m_specIntegrs.size(); i++) { double sum = m_specIntegrs[i]; + if( boost::math::isinf(sum) || boost::math::isnan(sum) ) + { + throw std::runtime_error("The workspace contains values that cannot be displayed (infinite or NaN).\n" + "Please run ReplaceSpecialValues algorithm for correction."); + } //integrated_values[i] = sum; if( sum < m_DataMinValue ) { diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.cpp index 0550d5d6323a879cf912c0ed768a88bdf7a2159f..24e803541f622020a70dcb289d7cd9eb72cad052 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.cpp @@ -51,6 +51,7 @@ using namespace MantidQt::API; InstrumentWindow::InstrumentWindow(const QString& wsName, const QString& label, ApplicationWindow *app , const QString& name , Qt::WFlags f ): MdiSubWindow(label, app, name, f), WorkspaceObserver(), m_workspaceName(wsName), + m_instrumentActor(NULL), mViewChanged(false), m_blocked(false) { m_surfaceType = FULL3D; @@ -161,16 +162,6 @@ InstrumentWindow::InstrumentWindow(const QString& wsName, const QString& label, connect(this,SIGNAL(needSetIntegrationRange(double,double)),this,SLOT(setIntegrationRange(double,double))); setAcceptDrops(true); - // Previously in (now removed) setWorkspaceName method - m_InstrumentDisplay->makeCurrent(); - m_instrumentActor = new InstrumentActor(m_workspaceName); - m_xIntegration->setTotalRange(m_instrumentActor->minBinValue(),m_instrumentActor->maxBinValue()); - m_xIntegration->setUnits(QString::fromStdString(m_instrumentActor->getWorkspace()->getAxis(0)->unit()->caption())); - setSurfaceType(m_surfaceType); // This call must come after the InstrumentActor is created - setupColorMap(); - mInstrumentTree->setInstrumentActor(m_instrumentActor); - setInfoText(m_InstrumentDisplay->getSurface()->getInfoText()); - setWindowTitle(QString("Instrument - ") + m_workspaceName); } @@ -179,9 +170,29 @@ InstrumentWindow::InstrumentWindow(const QString& wsName, const QString& label, */ InstrumentWindow::~InstrumentWindow() { - saveSettings(); + if (m_instrumentActor) + { + saveSettings(); + delete m_instrumentActor; + } delete m_InstrumentDisplay; - delete m_instrumentActor; +} + +/** + * Init the geometry and colour map outside constructor to prevent creating a broken MdiSubwindow. + * Must be called straight after constructor. + */ +void InstrumentWindow::init() +{ + // Previously in (now removed) setWorkspaceName method + m_InstrumentDisplay->makeCurrent(); + m_instrumentActor = new InstrumentActor(m_workspaceName); + m_xIntegration->setTotalRange(m_instrumentActor->minBinValue(),m_instrumentActor->maxBinValue()); + m_xIntegration->setUnits(QString::fromStdString(m_instrumentActor->getWorkspace()->getAxis(0)->unit()->caption())); + setSurfaceType(m_surfaceType); // This call must come after the InstrumentActor is created + setupColorMap(); + mInstrumentTree->setInstrumentActor(m_instrumentActor); + setInfoText(m_InstrumentDisplay->getSurface()->getInfoText()); } /** diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.h b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.h index ae78e992784c9b67d3673afb7666df7cda97a7b7..89a0fcb8466f8d159e153ebd7ba00f71b5e4d3c7 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.h +++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.h @@ -76,6 +76,7 @@ public: explicit InstrumentWindow(const QString& wsName, const QString& label = QString(), ApplicationWindow *app = 0, const QString& name = QString(), Qt::WFlags f = 0); ~InstrumentWindow(); + void init(); QString getWorkspaceName() const { return m_workspaceName; } void updateWindow(); diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidApplication.cpp b/Code/Mantid/MantidPlot/src/Mantid/MantidApplication.cpp index 6c28f5c8d21cdf5550112059b321db2a514108da..9e238239c80bcf21ae7b71b20aa86eb8b52cdd7f 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/MantidApplication.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/MantidApplication.cpp @@ -24,7 +24,7 @@ bool MantidApplication::notify( QObject * receiver, QEvent * event ) //std::cout << "MantidApplication::notify( event.type() == " << event->type() << ")\n"; res = QApplication::notify(receiver,event); } - catch(std::exception& e) + catch(std::exception& e) { if (MantidQt::API::MantidDialog::handle(receiver,e)) @@ -51,7 +51,7 @@ bool MantidApplication::notify( QObject * receiver, QEvent * event ) }else g_log.fatal("Continue working."); } - catch(...) + catch(...) { g_log.fatal()<<"Unknown exception\n"; diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidUI.cpp b/Code/Mantid/MantidPlot/src/Mantid/MantidUI.cpp index 0a72a97c229edd7d7fa372e3217d867900ccf1f5..e5197280a53f08a200c10bfb9f8f64fa7337b08b 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/MantidUI.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/MantidUI.cpp @@ -187,6 +187,10 @@ void MantidUI::init() } +/// Slot: Receives a new X range from a FitPropertyBrowser and re-emits it. +void MantidUI::x_range_from_picker(double xmin, double xmax){ + emit x_range_update(xmin, xmax); +} /// Updates the algorithms tree as this may have changed void MantidUI::updateAlgorithms() { @@ -1682,19 +1686,37 @@ void MantidUI::manageMantidWorkspaces() */ InstrumentWindow* MantidUI::getInstrumentView(const QString & wsName, int tab) { - + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); if( !Mantid::API::AnalysisDataService::Instance().doesExist(wsName.toStdString()) ) return NULL; Mantid::API::MatrixWorkspace_sptr ws = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(getWorkspace(wsName)); if (!ws) return NULL; Mantid::Geometry::Instrument_const_sptr instr = ws->getInstrument(); if (!instr || instr->getName().empty()) { + QApplication::restoreOverrideCursor(); + QMessageBox::critical(appWindow(),"MantidPlot - Error","Instrument view cannot be opened"); return NULL; } //Need a new window const QString windowName(QString("InstrumentWindow:") + wsName); InstrumentWindow *insWin = new InstrumentWindow(wsName,QString("Instrument"),appWindow(),windowName); + try + { + insWin->init(); + } + catch(const std::exception& e) + { + QApplication::restoreOverrideCursor(); + QMessageBox::critical(appWindow(),"MantidPlot - Error",e.what()); + if (insWin) + { + appWindow()->closeWindow(insWin); + insWin->close(); + } + return NULL; + } + insWin->selectTab(tab); appWindow()->d_workspace->addSubWindow(insWin); @@ -1709,22 +1731,20 @@ InstrumentWindow* MantidUI::getInstrumentView(const QString & wsName, int tab) SLOT(createDetectorTable(const QString&,const std::vector<int>&,bool))); connect(insWin, SIGNAL(execMantidAlgorithm(const QString&,const QString&,Mantid::API::AlgorithmObserver*)), this, SLOT(executeAlgorithm(const QString&, const QString&,Mantid::API::AlgorithmObserver*))); + + QApplication::restoreOverrideCursor(); return insWin; } void MantidUI::showMantidInstrument(const QString& wsName) { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); InstrumentWindow *insWin = getInstrumentView(wsName); if (!insWin) { - QApplication::restoreOverrideCursor(); - QMessageBox::critical(appWindow(),"MantidPlot - Error","Instrument view cannot be opened"); return; } insWin->show(); - QApplication::restoreOverrideCursor(); } void MantidUI::showMantidInstrument() diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidUI.h b/Code/Mantid/MantidPlot/src/Mantid/MantidUI.h index 3c5aeb898e2df117e3eb65862be17b5ec0318e97..15301e2a59101d95ff40ea858163f921d5d59d4f 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/MantidUI.h +++ b/Code/Mantid/MantidPlot/src/Mantid/MantidUI.h @@ -319,8 +319,13 @@ signals: // Display a critical error dialog box void needToShowCritical(const QString&); + // Signals that the fit property browser has updated its X range + void x_range_update(double, double); + public slots: + // Receives a new X range from a PeakPickerTool and re-emits it. + void x_range_from_picker(double, double); void test(); // Display a message in QtiPlot's results window. Used by MantidLog class to display Mantid log information. diff --git a/Code/Mantid/MantidPlot/src/Mantid/PeakPickerTool.cpp b/Code/Mantid/MantidPlot/src/Mantid/PeakPickerTool.cpp index 6350a7118caddd4f912bff1ef4d76ee59986c2e4..ba7016af697de8c18d63e59d60db90f7c7109318 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/PeakPickerTool.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/PeakPickerTool.cpp @@ -19,7 +19,7 @@ #include <iostream> -PeakPickerTool::PeakPickerTool(Graph *graph, MantidQt::MantidWidgets::FitPropertyBrowser *fitPropertyBrowser) : //MantidUI *mantidUI) : +PeakPickerTool::PeakPickerTool(Graph *graph, MantidQt::MantidWidgets::FitPropertyBrowser *fitPropertyBrowser, bool showFitPropertyBrowser) : //MantidUI *mantidUI) : QwtPlotPicker(graph->plotWidget()->canvas()), PlotToolInterface(graph), m_fitPropertyBrowser(fitPropertyBrowser),m_wsName(),m_spec(),m_init(false), //m_current(0), @@ -72,8 +72,7 @@ m_width_set(true),m_width(0),m_addingPeak(false),m_resetting(false) connect(m_fitPropertyBrowser,SIGNAL(removeFitCurves()),this,SLOT(removeFitCurves())); //Show the fitPropertyBrowser if it isn't already. - m_fitPropertyBrowser->show(); - + if (showFitPropertyBrowser) m_fitPropertyBrowser->show(); connect(this,SIGNAL(isOn(bool)),m_fitPropertyBrowser,SLOT(setPeakToolOn(bool))); emit isOn(true); @@ -602,7 +601,6 @@ void PeakPickerTool::startXChanged(double sX) { xMin(sX); graph()->replot(); - emit xRangeChanged(m_xMin, m_xMax); } /** @@ -613,7 +611,6 @@ void PeakPickerTool::endXChanged(double eX) { xMax(eX); graph()->replot(); - emit xRangeChanged(m_xMin, m_xMax); } /** diff --git a/Code/Mantid/MantidPlot/src/Mantid/PeakPickerTool.h b/Code/Mantid/MantidPlot/src/Mantid/PeakPickerTool.h index cca2fdb064b182a41d7625182e969b6d26f68714..a85fca6fbbd9af592ca3e755606dae7e45478058 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/PeakPickerTool.h +++ b/Code/Mantid/MantidPlot/src/Mantid/PeakPickerTool.h @@ -77,7 +77,7 @@ class PeakPickerTool : public QwtPlotPicker, public PlotToolInterface, public Qw Q_OBJECT public: /// Constructor - PeakPickerTool(Graph *graph, MantidQt::MantidWidgets::FitPropertyBrowser *fitPropertyBrowser); //MantidUI *mantidUI); + PeakPickerTool(Graph *graph, MantidQt::MantidWidgets::FitPropertyBrowser *fitPropertyBrowser, bool showFitPropertyBrowser=true); //MantidUI *mantidUI); /// Destructor ~PeakPickerTool(); /// Runtime type identifier @@ -98,10 +98,6 @@ public slots: signals: void peakChanged(); - // Signal used to dispatch the current selected X range - // It would be much cleaner if the FitPropertyBrowser and the PeakPickerTool - // were disentangled. - void xRangeChanged(double, double); void isOn(bool); private slots: diff --git a/Code/Mantid/MantidPlot/src/qti.sip b/Code/Mantid/MantidPlot/src/qti.sip index 58b925eda5af2d17412a2c56de3e35c2f7ae574e..29b511c9d25499785cf0472756af587dc8523035 100644 --- a/Code/Mantid/MantidPlot/src/qti.sip +++ b/Code/Mantid/MantidPlot/src/qti.sip @@ -894,7 +894,7 @@ public: void setWindowName(MdiSubWindow *, const QString &); void setPreferences(Graph*); - void selectMultiPeak(); + void selectMultiPeak(bool = true); void saveProjectAs(const QString& fileName = QString(), bool = false); MdiSubWindow* clone(MdiSubWindow*); diff --git a/Code/Mantid/MantidQt/API/CMakeLists.txt b/Code/Mantid/MantidQt/API/CMakeLists.txt index bbf32ae63dc64d7da51e120b5cc3b4a6f1a8d0da..15406196af75a215faca430710749af332d07cc7 100644 --- a/Code/Mantid/MantidQt/API/CMakeLists.txt +++ b/Code/Mantid/MantidQt/API/CMakeLists.txt @@ -46,6 +46,10 @@ set ( MOC_FILES inc/MantidQtAPI/AlgorithmDialog.h set ( UI_FILES inc/MantidQtAPI/ManageUserDirectories.ui ) +set( TEST_FILES + test/MantidColorMapTest.h +) + include_directories ( inc ) include_directories ( ../MantidWidgets/inc ) include_directories ( ../MantidWidgets ) @@ -66,6 +70,24 @@ add_library ( MantidQtAPI ${ALL_SRC} ${INC_FILES} ${UI_HDRS} ) target_link_libraries ( MantidQtAPI ${CORE_MANTIDLIBS} ${QT_LIBRARIES} ${QWT_LIBRARIES} ) +########################################################################### +# Testing +########################################################################### + +if ( CXXTEST_FOUND ) + include_directories( inc ../../Framework/TestHelpers/inc ../../Framework/DataObjects/inc ) + if ( GMOCK_FOUND AND GTEST_FOUND ) + cxxtest_add_test ( MantidQtAPITest ${TEST_FILES} ${GMOCK_TEST_FILES} ) + target_link_libraries( MantidQtAPITest MantidQtAPI ${MANTIDLIBS} + ${GMOCK_LIBRARIES} ${GTEST_LIBRARIES} + TestHelpers DataObjects) + add_dependencies( FrameworkTests MantidQtAPITest ) + # Add to the 'UnitTests' group in VS + set_property( TARGET MantidQtAPITest PROPERTY FOLDER "UnitTests" ) + endif () +endif () + + ########################################################################### # Installation settings ########################################################################### diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/AlgorithmDialog.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/AlgorithmDialog.h index c2fc1310c4e00eae6a6eef195897a764879ae2cc..ce25d7ee6bdcf52f4ebcf8edc74bd96ae21ec33c 100644 --- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/AlgorithmDialog.h +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/AlgorithmDialog.h @@ -199,8 +199,8 @@ protected: /// Create a row layout of buttons with specified text QHBoxLayout *createDefaultButtonLayout(const QString & helpText = QString("?"), - const QString & loadText = QString("Run"), - const QString & cancelText = QString("Cancel")); + const QString & loadText = QString("Run"), + const QString & cancelText = QString("Cancel")); /// Create a help button for this algorithm QPushButton* createHelpButton(const QString & helpText = QString("?")) const; @@ -242,8 +242,20 @@ private: void setOptionalMessage(const QString & message); /// Set a value based on any old input that we have void setPreviousValue(QWidget *widget, const QString & property); - protected: + /** The function analyses the property type and creates specific widget for it; + It used in dynamic propeties, which change as property contents, validators or settings change + @pProp -- the pointer to the property + @row -- the vertical position of the property widget within the initated dialog box + Should be pure virtual but as current custom vidgets do not use it, made empty unless overloaded */ + virtual void createSpecificPropertyWidget(Mantid::Kernel::Property *, int ){}; + /** The function deletes widgets, associated with property; + It used in dynamic propeties, which change as property contents, validators or settings change + @pProp -- the pointer to the property + returns-- the vertical position of the composite widget within the widget window; + Should be pure virtual but as current custom vidgets do not use it, made empty unless overloaded */ + virtual int deletePropertyWidgets(Mantid::Kernel::Property *){return -1;} + /** @name Member variables. */ //@{ /// The algorithm associated with this dialog diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/GenericDialog.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/GenericDialog.h index 6b0c104737a89acee01250b0b5345580b3438266..198a3a7c18a6780f892c490a38f9ab7b3a7df155 100644 --- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/GenericDialog.h +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/GenericDialog.h @@ -71,7 +71,12 @@ private: /// This does the work and must be overridden in each deriving class virtual void initLayout(); - +protected: + /// the function analyses the property type and creates specific widget for it + void createSpecificPropertyWidget(Mantid::Kernel::Property *pProp, int row); + /** The function deletes widgets, associated with property; + returns-- the vertical position of the composite widget within the widget window; */ + virtual int deletePropertyWidgets(Mantid::Kernel::Property *pProp); private slots: /// Any property changed diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MantidColorMap.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MantidColorMap.h index 4aae0098880c9682f9d9e408a574b8e3b566b01e..89fbef2160d89ef6f8286cf4fe1533deb3b4b490 100644 --- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MantidColorMap.h +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MantidColorMap.h @@ -38,48 +38,36 @@ class EXPORT_OPT_MANTIDQT_API MantidColorMap : public QwtColorMap { public: - /// Default constructor MantidColorMap(); - - /// Constructor with a type parameter explicit MantidColorMap(const QString & filename, GraphOptions::ScaleType type); - - /// (virtual) Destructor virtual ~MantidColorMap(); - - /// Create a clone of the color map QwtColorMap* copy() const; - /// Change the scale type void changeScaleType(GraphOptions::ScaleType type); - /** - * Retrieve the scale type - * @returns the current scale type - */ - GraphOptions::ScaleType getScaleType() const - { - return m_scale_type; - } - - /// Load a color map file bool loadMap(const QString & filename); - /// Setup a default color map. This is used if a file is not available + void setNanColor(int r, int g, int b); + void setupDefaultMap(); - /// Compute an rgb value for the given data value and interval QRgb rgb(const QwtDoubleInterval & interval, double value) const; - /// Compute fraction for the given value and range using the current scale type double normalize(const QwtDoubleInterval &interval, double value) const; - /// Compute a color index for the given data value and interval unsigned char colorIndex (const QwtDoubleInterval &interval, double value) const; - /// Compute a lookup table QVector<QRgb> colorTable(const QwtDoubleInterval & interval) const; + /** + * Retrieve the scale type + * @returns the current scale type + */ + GraphOptions::ScaleType getScaleType() const + { + return m_scale_type; + } + /** * Get the number of colors in this map */ @@ -109,6 +97,12 @@ private: /// The number of colors in this map short m_num_colors; + /// Color to show for not-a-number + QRgb m_nan_color; + + /// Cached NAN value + double m_nan; + }; diff --git a/Code/Mantid/MantidQt/API/src/AlgorithmDialog.cpp b/Code/Mantid/MantidQt/API/src/AlgorithmDialog.cpp index f961c3a3942ebeae203928408da8b582820fc9d9..0302e92328b3640e01457dfa0b0e0dcc7fb3ef10 100644 --- a/Code/Mantid/MantidQt/API/src/AlgorithmDialog.cpp +++ b/Code/Mantid/MantidQt/API/src/AlgorithmDialog.cpp @@ -261,8 +261,14 @@ void AlgorithmDialog::hideOrDisableProperties() if (m_tied_properties.contains(pName)) { // Set the enabled and visible flags based on what the validators say. Default is always true. - bool enabled = isWidgetEnabled(pName); - bool visible = p->isVisible(); + bool enabled = isWidgetEnabled(pName); + bool visible = p->isVisible(); + + if (p->isConditionChanged()){ + p->getSettings()->applyChanges(p); + int row = this->deletePropertyWidgets(p); + this->createSpecificPropertyWidget(p,row); + } // Show/hide the validator label (that red star) QString error = ""; @@ -275,9 +281,11 @@ void AlgorithmDialog::hideOrDisableProperties() QList<QWidget*> widgets = m_tied_all_widgets[pName]; for (int i=0; i<widgets.size(); i++) { + QWidget * widget = widgets[i]; widget->setEnabled( enabled ); widget->setVisible( visible ); + } if (visible) @@ -493,7 +501,7 @@ void AlgorithmDialog::untie(const QString & property) * returns a pointer to the QLabel instance marking the validity */ QWidget* AlgorithmDialog::tie(QWidget* widget, const QString & property, QLayout *parent_layout, - bool readHistory, QWidget * otherWidget1, QWidget * otherWidget2, QWidget * otherWidget3) + bool readHistory, QWidget * otherWidget1, QWidget * otherWidget2, QWidget * otherWidget3) { if( m_tied_properties.contains(property) ) m_tied_properties.remove(property); @@ -790,7 +798,7 @@ void AlgorithmDialog::fillLineEdit(const QString & propName, QLineEdit* textFiel { Mantid::Kernel::Property *property = getAlgorithmProperty(propName); if( property && property->isValid().empty() && - ( m_python_arguments.contains(propName) || !property->isDefault() ) ) + ( m_python_arguments.contains(propName) || !property->isDefault() ) ) { textField->setText(QString::fromStdString(property->value())); } @@ -803,8 +811,8 @@ void AlgorithmDialog::fillLineEdit(const QString & propName, QLineEdit* textFiel /** Layout the buttons and others in the generic dialog */ QHBoxLayout * AlgorithmDialog::createDefaultButtonLayout(const QString & helpText, - const QString & loadText, - const QString & cancelText) + const QString & loadText, + const QString & cancelText) { QPushButton *okButton = new QPushButton(loadText); connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); @@ -891,7 +899,7 @@ void AlgorithmDialog::accept() else { QMessageBox::critical(this, "", - "One or more properties are invalid. The invalid properties are\n" + "One or more properties are invalid. The invalid properties are\n" "marked with a *, hold your mouse over the * for more information." ); } } @@ -1095,8 +1103,8 @@ QString AlgorithmDialog::getValue(QWidget *widget) else { QMessageBox::warning(this, windowTitle(), - QString("Cannot parse input from ") + widget->metaObject()->className() + - ". Update AlgorithmDialog::getValue() to cope with this widget."); + QString("Cannot parse input from ") + widget->metaObject()->className() + + ". Update AlgorithmDialog::getValue() to cope with this widget."); return ""; } } @@ -1172,8 +1180,8 @@ void AlgorithmDialog::setPreviousValue(QWidget *widget, const QString & propName //Need to check if this is the default value as we don't fill them in if they are if( m_python_arguments.contains(propName) || !property->isDefault() ) { - if( textfield ) textfield->setText(value); - else mtdwidget->setUserInput(value); + if( textfield ) textfield->setText(value); + else mtdwidget->setUserInput(value); } } return; @@ -1181,6 +1189,6 @@ void AlgorithmDialog::setPreviousValue(QWidget *widget, const QString & propName // Reaching here means we have a widget type we don't understand. Tell the developer QMessageBox::warning(this, windowTitle(), - QString("Cannot set value for ") + widget->metaObject()->className() + - ". Update AlgorithmDialog::setValue() to cope with this widget."); + QString("Cannot set value for ") + widget->metaObject()->className() + + ". Update AlgorithmDialog::setValue() to cope with this widget."); } diff --git a/Code/Mantid/MantidQt/API/src/GenericDialog.cpp b/Code/Mantid/MantidQt/API/src/GenericDialog.cpp index 2f743691c9d5ccda6086f1bd04958a53aa037d0e..eb41183a4cd62b3ef52d6c82a5898ce16dc08b1f 100644 --- a/Code/Mantid/MantidQt/API/src/GenericDialog.cpp +++ b/Code/Mantid/MantidQt/API/src/GenericDialog.cpp @@ -26,6 +26,7 @@ #include <QDir> #include "MantidAPI/MultipleFileProperty.h" #include <QGroupBox> +#include <climits> // Dialog stuff is defined here using namespace MantidQt::API; @@ -49,11 +50,32 @@ GenericDialog::~GenericDialog() { // Delete all the mappers QHash<QString, QSignalMapper *>::iterator it; - for (it = m_mappers.begin(); it != m_mappers.end(); it++) + for(it = m_mappers.begin(); it != m_mappers.end(); it++) delete it.value(); } +//--------------------------------------------------------------------------------------------------------------- +bool haveInputWS(const std::vector<Property*> & prop_list) +{ + // For the few algorithms (mainly loading) that do not have input workspaces, we do not + // want to render the 'replace input workspace button'. Do a quick scan to check. + // Also the ones that don't have a set of allowed values as input workspace + std::vector<Property*>::const_iterator pEnd = prop_list.end(); + for(std::vector<Property*>::const_iterator pIter = prop_list.begin(); + pIter != pEnd; ++pIter) + { + Property *prop = *pIter; + if( prop->direction() == Direction::Input && dynamic_cast<IWorkspaceProperty*>(prop) ) + { + return true; + } + } + return false; +} + + + //--------------------------------------------------------------------------------------------------------------- /** Layout a checkbox for a bool property @@ -116,26 +138,6 @@ void GenericDialog::layoutOptionsProperty(Property* prop, int row) -//--------------------------------------------------------------------------------------------------------------- -bool haveInputWS(const std::vector<Property*> & prop_list) -{ - // For the few algorithms (mainly loading) that do not have input workspaces, we do not - // want to render the 'replace input workspace button'. Do a quick scan to check. - // Also the ones that don't have a set of allowed values as input workspace - std::vector<Property*>::const_iterator pEnd = prop_list.end(); - for(std::vector<Property*>::const_iterator pIter = prop_list.begin(); - pIter != pEnd; ++pIter) - { - Property *prop = *pIter; - if( prop->direction() == Direction::Input && dynamic_cast<IWorkspaceProperty*>(prop) ) - { - return true; - } - } - return false; -} - - //--------------------------------------------------------------------------------------------------------------- /** Layout a textbox for a property with options * @param prop :: Property to create controls for */ @@ -218,8 +220,6 @@ void GenericDialog::layoutTextProperty(Property* prop, int row) - - //---------------------------------- // Protected member functions //---------------------------------- @@ -325,29 +325,14 @@ void GenericDialog::initLayout() // m_inputGrid->addWidget(grpBox, row, 0, 0, 4); } - - // Only accept input for output properties or workspace properties + // Only accept input for output properties or workspace properties bool isWorkspaceProp(dynamic_cast<IWorkspaceProperty*>(prop)); if( prop->direction() == Direction::Output && !isWorkspaceProp ) continue; - // Look for specific property types - Mantid::API::FileProperty* fileType = dynamic_cast<Mantid::API::FileProperty*>(prop); - Mantid::API::MultipleFileProperty* multipleFileType = dynamic_cast<Mantid::API::MultipleFileProperty*>(prop); - PropertyWithValue<bool>* boolProp = dynamic_cast<PropertyWithValue<bool>* >(prop); - - if (boolProp) - { // CheckBox shown for BOOL properties - layoutBoolProperty(boolProp, row); - } - else if ( !prop->allowedValues().empty() && !fileType && !multipleFileType ) - { //Check if there are only certain allowed values for the property - layoutOptionsProperty(prop, row); - } - else - { //For everything else render a text box - layoutTextProperty(prop, row); - } + // the function analyses the property type and creates specific widget for it + // in the vertical position, specified by row; + this->createSpecificPropertyWidget(prop, row); ++row; } //(end for each property) @@ -389,8 +374,59 @@ void GenericDialog::initLayout() dialog_layout->setSizeConstraint(QLayout::SetMinimumSize); } +void +GenericDialog::createSpecificPropertyWidget(Mantid::Kernel::Property *pProp, int row) +{ + // Look for specific property types + Mantid::API::FileProperty* fileType = dynamic_cast<Mantid::API::FileProperty*>(pProp); + Mantid::API::MultipleFileProperty* multipleFileType = dynamic_cast<Mantid::API::MultipleFileProperty*>(pProp); + PropertyWithValue<bool>* boolProp = dynamic_cast<PropertyWithValue<bool>* >(pProp); + if (boolProp) + { // CheckBox shown for BOOL properties + layoutBoolProperty(boolProp, row); + } + else if ( !pProp->allowedValues().empty() && !fileType && !multipleFileType ) + { //Check if there are only certain allowed values for the property + layoutOptionsProperty(pProp, row); + } + else + { //For everything else render a text box + layoutTextProperty(pProp, row); + } + +} +// +int +GenericDialog::deletePropertyWidgets(Mantid::Kernel::Property *pProp) +{ + QString propName=QString::fromStdString(pProp->name()); + //QHash<QString, QSignalMapper *>::iterator it; + //while((it = m_mappers.find(propName))!=m_mappers.end()){ + // delete it.value(); + // it=m_mappers.erase(it); + //} + int iRow,iCol,irowSpan,icolSpan; + + + int nRow=INT_MAX; + QList<QWidget*> widgets = m_tied_all_widgets[propName]; + for (int i=0; i<widgets.size(); i++){ + int wInd = m_currentGrid->indexOf(widgets[i]); + m_currentGrid->getItemPosition(wInd,&iRow,&iCol,&irowSpan,&icolSpan); + if(iRow<nRow)nRow=iRow; + + widgets[i]->setVisible(false); + widgets[i]->setEnabled(false); + widgets[i]->setAttribute(Qt::WA_DeleteOnClose); + widgets[i]->close(); + } + m_currentGrid->parentWidget()->repaint(true); + + + return nRow; +} //-------------------------------------------------------------------------------------- diff --git a/Code/Mantid/MantidQt/API/src/MantidColorMap.cpp b/Code/Mantid/MantidQt/API/src/MantidColorMap.cpp index b87d5e7009babe004aadc931ac29cf7f92c272ab..1e4a281cbda242cc206648755e2b4ad69a184c3a 100644 --- a/Code/Mantid/MantidQt/API/src/MantidColorMap.cpp +++ b/Code/Mantid/MantidQt/API/src/MantidColorMap.cpp @@ -11,6 +11,7 @@ #include <iostream> #include <QRgb> +#include <limits> //-------------------------------------- // Public member functions @@ -21,9 +22,12 @@ MantidColorMap::MantidColorMap() : QwtColorMap(QwtColorMap::Indexed), m_scale_type(GraphOptions::Log10), m_colors(0), m_num_colors(0) { + m_nan = std::numeric_limits<double>::quiet_NaN(); + this->setNanColor(255,255,255); setupDefaultMap(); } +//------------------------------------------------------------------------------------------------- /** * Constructor with filename and type * @param @@ -32,6 +36,8 @@ MantidColorMap::MantidColorMap() : QwtColorMap(QwtColorMap::Indexed), m_scale_ty MantidColorMap::MantidColorMap(const QString & filename, GraphOptions::ScaleType type) : QwtColorMap(QwtColorMap::Indexed), m_scale_type(type), m_colors(0), m_num_colors(0) { + m_nan = std::numeric_limits<double>::quiet_NaN(); + this->setNanColor(255,255,255); // Check and load default if this doesn't work if( !loadMap(filename) ) { @@ -39,6 +45,7 @@ MantidColorMap::MantidColorMap(const QString & filename, GraphOptions::ScaleType } } +//------------------------------------------------------------------------------------------------- /** * Destructor */ @@ -46,6 +53,7 @@ MantidColorMap::~MantidColorMap() { } +//------------------------------------------------------------------------------------------------- /** * Create a clone of the color map */ @@ -57,6 +65,7 @@ QwtColorMap* MantidColorMap::copy() const return map; } +//------------------------------------------------------------------------------------------------- /** * Change the scale type * @param type :: The new scale type @@ -66,6 +75,7 @@ void MantidColorMap::changeScaleType(GraphOptions::ScaleType type) m_scale_type = type; } +//------------------------------------------------------------------------------------------------- /** * Load a color map from a file * @param filename :: The full path to the color map file @@ -108,10 +118,27 @@ bool MantidColorMap::loadMap(const QString & filename) { m_num_colors = count; m_colors = new_colormap; + if (m_num_colors > 1) + m_colors[0] = m_nan_color; } return is_success; } +//------------------------------------------------------------------------------------------------- +/** Set a color for Not-a-number + * + * @param r :: red, from 0 to 255 + * @param g :: green, from 0 to 255 + * @param b :: blue, from 0 to 255 + */ +void MantidColorMap::setNanColor(int r, int g, int b) +{ + m_nan_color = qRgb(r,g,b); + if (m_num_colors > 1) + m_colors[0] = m_nan_color; +} + +//------------------------------------------------------------------------------------------------- /** * Define a default color map to be used if a file is unavailable. */ @@ -157,9 +184,11 @@ void MantidColorMap::setupDefaultMap() reader >> red >> green >> blue; m_colors.push_back(qRgb((unsigned char)(red), (unsigned char)green, (unsigned char)blue)); } + this->setNanColor(255,255,255); } +//------------------------------------------------------------------------------------------------- /** * Normalize the value to the range[0,1] * @param interval :: The data range @@ -168,21 +197,17 @@ void MantidColorMap::setupDefaultMap() */ double MantidColorMap::normalize(const QwtDoubleInterval &interval, double value) const { - if( interval.isNull() || m_num_colors == 0 ) - { - return -1.0; - } + // nan numbers have the property that nan != nan, treat nan as being invalid + if( interval.isNull() || m_num_colors == 0 || value != value ) + return m_nan; const double width = interval.width(); if( width <= 0.0 || value <= interval.minValue() ) - { return 0.0; - } - // nan numbers have the property that nan != nan, treat nan as being the maximum - if ( value >= interval.maxValue() || value != value ) - { + + if ( value >= interval.maxValue()) return 1.0; - } + double ratio(0.0); if( m_scale_type == GraphOptions::Linear) { @@ -202,6 +227,7 @@ double MantidColorMap::normalize(const QwtDoubleInterval &interval, double value } +//------------------------------------------------------------------------------------------------- /** * Compute an rgb value for the given data value and interval * @param interval :: The data range @@ -214,17 +240,12 @@ QRgb MantidColorMap::rgb(const QwtDoubleInterval & interval, double value) const { return m_colors[ci]; } - return - // Return black - QRgb(); - -// QRgb col = getColor(); -// float r(0.0f), g(0.0f), b(0.0f), a(0.0f); -// col.get(r,g,b,a); -// return qRgb(int(r*255),int(g*255),int(b*255)); + // Return black + return QRgb(); } +//------------------------------------------------------------------------------------------------- /** * Compute a color index * @param interval :: The data range @@ -235,7 +256,10 @@ QRgb MantidColorMap::rgb(const QwtDoubleInterval & interval, double value) const unsigned char MantidColorMap::colorIndex (const QwtDoubleInterval &interval, double value) const { double fraction = normalize(interval, value); - if( fraction < 0.0 )return static_cast<unsigned char>(0); + // NAN: return index 0 + if (fraction != fraction) return static_cast<unsigned char>(0); + // Below minimum: return index 1 + if( fraction < 0.0 ) return static_cast<unsigned char>(1); short index = short(std::floor(fraction * m_num_colors)); // If the ratio gives back 1 then we need to adjust the index down 1 @@ -243,13 +267,15 @@ unsigned char MantidColorMap::colorIndex (const QwtDoubleInterval &interval, dou { index = short(m_num_colors - 1); } - if( index < 0 ) + if( index < 1 ) { - index = 0; + index = 1; } return static_cast<unsigned char>(index); } + +//------------------------------------------------------------------------------------------------- /** * Compute a lookup table * @param interval :: The interval for the table to cover @@ -261,14 +287,16 @@ QVector<QRgb> MantidColorMap::colorTable(const QwtDoubleInterval & interval) con m_scale_type = GraphOptions::Linear; short table_size = (m_num_colors > 1) ? m_num_colors : 2; - QVector<QRgb> rgbtable(table_size); + QVector<QRgb> rgbtable(table_size+1); if( interval.isValid() ) { const double step = interval.width() / table_size; for( short i = 0; i < table_size; ++i ) { - rgbtable[i] = rgb(interval, interval.minValue() + step*i); + rgbtable[i+1] = rgb(interval, interval.minValue() + step*i); } + // Special NAN at index 0 + rgbtable[0] = rgb(interval, m_nan); } //Restore scaling type diff --git a/Code/Mantid/MantidQt/API/test/MantidColorMapTest.h b/Code/Mantid/MantidQt/API/test/MantidColorMapTest.h new file mode 100644 index 0000000000000000000000000000000000000000..0889b26ef442726db72b0cf925e7747f29159099 --- /dev/null +++ b/Code/Mantid/MantidQt/API/test/MantidColorMapTest.h @@ -0,0 +1,70 @@ +#ifndef MANTIDQT_API_MANTIDCOLORMAPTEST_H_ +#define MANTIDQT_API_MANTIDCOLORMAPTEST_H_ + +#include <cxxtest/TestSuite.h> +#include <iostream> +#include <iomanip> +#include "MantidQtAPI/MantidColorMap.h" +#include <limits> +#include <QRgb> + +class MantidColorMapTest : public CxxTest::TestSuite +{ +public: + + /// Check default color map + void test_constructor() + { + MantidColorMap map; + QRgb col; + col = map.rgb( QwtDoubleInterval( 0.0, 1.0 ), 0.0); + TSM_ASSERT_EQUALS("Default min color.", col, qRgb(0, 170, 252) ); + col = map.rgb( QwtDoubleInterval( 0.0, 1.0 ), 1.0); + TSM_ASSERT_EQUALS("Default max color.", col, qRgb(255,255,255) ); + TSM_ASSERT_EQUALS("Default map is linear", map.getScaleType(), GraphOptions::Log10 ); + } + + void test_normalize_linear() + { + MantidColorMap map; + QwtDoubleInterval range(10.0, 20.0); + map.changeScaleType( GraphOptions::Linear ); + TS_ASSERT_DELTA( map.normalize(range, 15.), 0.5, 1e-5); + } + + void test_normalize_log() + { + MantidColorMap map; + QwtDoubleInterval range(1.0, 10000.0); + map.changeScaleType( GraphOptions::Log10 ); + TS_ASSERT_DELTA( map.normalize(range, 1000.), 0.75, 1e-5); + } + + /// Setting a NAN color + void test_nan_color() + { + MantidColorMap map; + map.setNanColor(123, 23, 34); + QRgb col; + QwtDoubleInterval range(10.0, 20.0); + double nan = std::numeric_limits<double>::quiet_NaN(); + col = map.rgb( range, nan); + TSM_ASSERT_EQUALS("Passing NAN to rgb returns the set color.", col, qRgb(123, 23, 34) ); + } + + void test_colorIndex() + { + MantidColorMap map; + QwtDoubleInterval range(10.0, 20.0); + double nan = std::numeric_limits<double>::quiet_NaN(); + TSM_ASSERT_EQUALS("Color index is 0 for NAN", map.colorIndex(range, nan), 0); + TSM_ASSERT_EQUALS("Color index is 1 for small numbers", map.colorIndex(range, -123.0), 1); + TSM_ASSERT_EQUALS("Color index is 255 for large numbers", map.colorIndex(range, +123.0), 255); + } + + + +}; + + +#endif /* MANTIDQT_API_MANTIDCOLORMAPTEST_H_ */ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp index 11cd66d71a896c91c71044fa399ddfcea3652c32..a5401dfd6836aa97ee68868b0c095cb773d8e5f2 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp @@ -2878,18 +2878,18 @@ void MuonAnalysis::groupFittedWorkspaces(QString workspaceName) if ( Mantid::API::AnalysisDataService::Instance().doesExist(groupName.toStdString()) ) { QString groupStr(""); - //if ( Mantid::API::AnalysisDataService::Instance().doesExist(wsNormalised.toStdString()) ) - //{ - // groupStr = ("GroupWorkspaces(InputWorkspaces='") + wsNormalised + "," + groupName - // + "',OutputWorkspace='" + groupName + "')\n"; - // runPythonCode( groupStr ).trimmed(); - //} - //if ( Mantid::API::AnalysisDataService::Instance().doesExist(wsParameters.toStdString()) ) - //{ - // groupStr = ("GroupWorkspaces(InputWorkspaces='") + wsParameters + "," + groupName - // + "',OutputWorkspace='" + groupName + "')\n"; - // runPythonCode( groupStr ).trimmed(); - //} + if ( Mantid::API::AnalysisDataService::Instance().doesExist(wsNormalised.toStdString()) ) + { + groupStr = ("GroupWorkspaces(InputWorkspaces='") + wsNormalised + "," + groupName + + "',OutputWorkspace='" + groupName + "')\n"; + runPythonCode( groupStr ).trimmed(); + } + if ( Mantid::API::AnalysisDataService::Instance().doesExist(wsParameters.toStdString()) ) + { + groupStr = ("GroupWorkspaces(InputWorkspaces='") + wsParameters + "," + groupName + + "',OutputWorkspace='" + groupName + "')\n"; + runPythonCode( groupStr ).trimmed(); + } if ( Mantid::API::AnalysisDataService::Instance().doesExist(wsWorkspace.toStdString()) ) { groupStr = ("GroupWorkspaces(InputWorkspaces='") + wsWorkspace + "," + groupName diff --git a/Code/Mantid/MantidQt/DesignerPlugins/CMakeLists.txt b/Code/Mantid/MantidQt/DesignerPlugins/CMakeLists.txt index 6eab4f24900f47622951033870a27123e4e9f8ea..41de695240487229477e2df641c9ab6197ae1d68 100644 --- a/Code/Mantid/MantidQt/DesignerPlugins/CMakeLists.txt +++ b/Code/Mantid/MantidQt/DesignerPlugins/CMakeLists.txt @@ -38,31 +38,8 @@ endif(UNITY_BUILD) add_library ( DesignerPlugins ${SRC_FILES} ${INC_FILES} ${MOCCED_FILES} ) # Change the destination of the target as Qt expects this in a directory called "designer" -if ( MSVC ) - # For some reason when the generator is MSVC 10 it ignores the LIBRARY_OUTPUT_DIRECTORY - # property so we have to do something slightly different - set ( LIB_EXTS ".dll" ) - set ( SRC_DIR ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR} ) - set ( DEST_DIR ${SRC_DIR}/designer ) - add_custom_command( TARGET DesignerPlugins POST_BUILD - COMMAND ${CMAKE_COMMAND} ARGS -E make_directory - ${DEST_DIR} ) - foreach ( LIB_EXT ${LIB_EXTS} ) - add_custom_command ( TARGET DesignerPlugins POST_BUILD - COMMAND ${CMAKE_COMMAND} ARGS -E echo - "Moving \"${LIB_NAME}${LIB_EXT}\" to designer directory." - COMMAND ${CMAKE_COMMAND} ARGS -E rename - ${SRC_DIR}/${LIB_NAME}${LIB_EXT} - ${DEST_DIR}/${LIB_NAME}${LIB_EXT} ) - endforeach ( LIB_EXT ) - # Clean up - set ( LIB_EXTS ) - set ( SRC_DIR ) - set ( DEST_DIR ) -else () - set_target_properties ( DesignerPlugins PROPERTIES LIBRARY_OUTPUT_DIRECTORY - ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/designer ) -endif ( MSVC ) +SET_TARGET_OUTPUT_DIRECTORY( DesignerPlugins ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/designer ) + # Set the name of the generated library set_target_properties ( DesignerPlugins PROPERTIES OUTPUT_NAME ${LIB_NAME} ) diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FitPropertyBrowser.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FitPropertyBrowser.h index dfd23ff5e19e12613640a63075c7ceaefb8ae028..a478ed0bf5bd9dbe5b9e4643c3219abde0318ad3 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FitPropertyBrowser.h +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FitPropertyBrowser.h @@ -236,6 +236,7 @@ signals: void startXChanged(double); void endXChanged(double); + void xRangeChanged(double, double); void parameterChanged(const Mantid::API::IFitFunction*); void functionCleared(); void plotGuess(); @@ -484,4 +485,4 @@ private: } // MantidQt } // API -#endif /*FITPROPERTYBROWSER_H_*/ \ No newline at end of file +#endif /*FITPROPERTYBROWSER_H_*/ diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/ICatAdvancedSearch.ui b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/ICatAdvancedSearch.ui index 5668bfba421562530c1eda85361f4774ad4ae4b6..3044c827cdeb934d2db3bdfb35d3b83fb787e9e9 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/ICatAdvancedSearch.ui +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/ICatAdvancedSearch.ui @@ -1,483 +1,487 @@ -<ui version="4.0" > +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> <class>ICatAdvancedSearch</class> - <widget class="QWidget" name="ICatAdvancedSearch" > - <property name="geometry" > + <widget class="QWidget" name="ICatAdvancedSearch"> + <property name="geometry"> <rect> <x>0</x> <y>0</y> - <width>719</width> + <width>735</width> <height>521</height> </rect> </property> - <property name="windowTitle" > + <property name="windowTitle"> <string>Catalog Advanced Search</string> </property> - <layout class="QGridLayout" name="gridLayout_3" > - <item row="0" column="0" > - <widget class="QLabel" name="advsearchtitleLabel" > - <property name="maximumSize" > + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <widget class="QLabel" name="advsearchtitleLabel"> + <property name="maximumSize"> <size> <width>16777215</width> <height>16</height> </size> </property> - <property name="frameShape" > + <property name="frameShape"> <enum>QFrame::StyledPanel</enum> </property> - <property name="frameShadow" > + <property name="frameShadow"> <enum>QFrame::Sunken</enum> </property> - <property name="text" > - <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <property name="text"> + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Advanced Investigations Search</span></p></body></html></string> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Advanced Investigations Search</span></p></body></html></string> </property> - <property name="indent" > - <number>321</number> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="indent"> + <number>0</number> </property> </widget> </item> - <item row="1" column="0" > - <widget class="QFrame" name="advframeWidget" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Expanding" hsizetype="Expanding" > + <item row="1" column="0"> + <widget class="QFrame" name="advframeWidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="styleSheet" > - <string notr="true" >background-image: url(:/BackGroundImage/ICatSearchBackGround.png);</string> + <property name="styleSheet"> + <string notr="true">background-image: url(:/BackGroundImage/ICatSearchBackGround.png);</string> </property> - <property name="frameShape" > + <property name="frameShape"> <enum>QFrame::StyledPanel</enum> </property> - <property name="frameShadow" > + <property name="frameShadow"> <enum>QFrame::Sunken</enum> </property> - <layout class="QGridLayout" name="gridLayout_2" > - <item row="0" column="0" > - <layout class="QGridLayout" name="gridLayout" > - <item row="0" column="0" > - <widget class="QLabel" name="invstNameLabel" > - <property name="text" > + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="invstNameLabel"> + <property name="text"> <string>Investigation Name:</string> </property> </widget> </item> - <item row="0" column="1" > - <widget class="QLineEdit" name="InvestigationName" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <item row="0" column="1"> + <widget class="QLineEdit" name="InvestigationName"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> </widget> </item> - <item row="0" column="2" > - <widget class="QLabel" name="InvestigationName_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="0" column="2"> + <widget class="QLabel" name="InvestigationName_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="0" column="3" > - <widget class="QLabel" name="runNumberLabel" > - <property name="text" > + <item row="0" column="3"> + <widget class="QLabel" name="runNumberLabel"> + <property name="text"> <string>StartRun:</string> </property> </widget> </item> - <item row="0" column="4" > - <widget class="QLineEdit" name="StartRun" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <item row="0" column="4"> + <widget class="QLineEdit" name="StartRun"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> </widget> </item> - <item row="0" column="5" > - <widget class="QLabel" name="StartRun_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="0" column="5"> + <widget class="QLabel" name="StartRun_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="0" column="7" > - <widget class="QLabel" name="label" > - <property name="text" > + <item row="0" column="7"> + <widget class="QLabel" name="label"> + <property name="text"> <string>EndRun:</string> </property> </widget> </item> - <item row="0" column="8" > - <widget class="QLineEdit" name="EndRun" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <item row="0" column="8"> + <widget class="QLineEdit" name="EndRun"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> </widget> </item> - <item row="0" column="10" > - <widget class="QLabel" name="EndRun_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="0" column="10"> + <widget class="QLabel" name="EndRun_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="1" column="0" > - <widget class="QLabel" name="invstAbstractLabel" > - <property name="text" > + <item row="1" column="0"> + <widget class="QLabel" name="invstAbstractLabel"> + <property name="text"> <string>Investigation Abstract:</string> </property> </widget> </item> - <item row="1" column="1" > - <widget class="QLineEdit" name="InvestigationAbstract" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <item row="1" column="1"> + <widget class="QLineEdit" name="InvestigationAbstract"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> </widget> </item> - <item row="1" column="2" > - <widget class="QLabel" name="InvestigationAbstract_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="1" column="2"> + <widget class="QLabel" name="InvestigationAbstract_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="1" column="3" > - <widget class="QLabel" name="startdateLabel" > - <property name="text" > + <item row="1" column="3"> + <widget class="QLabel" name="startdateLabel"> + <property name="text"> <string>Start Date:</string> </property> </widget> </item> - <item row="1" column="4" > - <widget class="QLineEdit" name="StartDate" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <item row="1" column="4"> + <widget class="QLineEdit" name="StartDate"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="toolTip" > + <property name="toolTip"> <string>Date in DD/MM/YYY format</string> </property> - <property name="inputMask" > + <property name="inputMask"> <string>99/99/9999;_</string> </property> - <property name="text" > + <property name="text"> <string>//</string> </property> </widget> </item> - <item row="1" column="5" > - <widget class="QToolButton" name="startdatetoolButton" > - <property name="maximumSize" > + <item row="1" column="5"> + <widget class="QToolButton" name="startdatetoolButton"> + <property name="maximumSize"> <size> <width>25</width> <height>16777215</height> </size> </property> - <property name="text" > + <property name="text"> <string>...</string> </property> </widget> </item> - <item row="1" column="6" > - <widget class="QLabel" name="StartDate_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="1" column="6"> + <widget class="QLabel" name="StartDate_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="1" column="7" > - <widget class="QLabel" name="enddateLabel" > - <property name="text" > + <item row="1" column="7"> + <widget class="QLabel" name="enddateLabel"> + <property name="text"> <string>End Date:</string> </property> </widget> </item> - <item row="1" column="8" > - <widget class="QLineEdit" name="EndDate" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <item row="1" column="8"> + <widget class="QLineEdit" name="EndDate"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="minimumSize" > + <property name="minimumSize"> <size> <width>0</width> <height>0</height> </size> </property> - <property name="toolTip" > + <property name="toolTip"> <string>Date in DD/MM/YYY format</string> </property> - <property name="inputMask" > + <property name="inputMask"> <string>99/99/9999;_</string> </property> - <property name="text" > + <property name="text"> <string>//</string> </property> </widget> </item> - <item row="1" column="10" > - <widget class="QToolButton" name="enddatetoolButton" > - <property name="maximumSize" > + <item row="1" column="10"> + <widget class="QToolButton" name="enddatetoolButton"> + <property name="maximumSize"> <size> <width>25</width> <height>16777215</height> </size> </property> - <property name="text" > + <property name="text"> <string>...</string> </property> </widget> </item> - <item row="1" column="11" > - <widget class="QLabel" name="EndDate_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="1" column="11"> + <widget class="QLabel" name="EndDate_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="2" column="0" > - <widget class="QLabel" name="sampleLabel" > - <property name="text" > + <item row="2" column="0"> + <widget class="QLabel" name="sampleLabel"> + <property name="text"> <string>Sample:</string> </property> </widget> </item> - <item row="2" column="1" > - <widget class="QLineEdit" name="SampleName" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <item row="2" column="1"> + <widget class="QLineEdit" name="SampleName"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="text" > + <property name="text"> <string/> </property> </widget> </item> - <item row="2" column="2" > - <widget class="QLabel" name="SampleName_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="2" column="2"> + <widget class="QLabel" name="SampleName_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="2" column="3" > - <widget class="QLabel" name="instrumentLabel" > - <property name="text" > + <item row="2" column="3"> + <widget class="QLabel" name="instrumentLabel"> + <property name="text"> <string>Instrument:</string> </property> </widget> </item> - <item row="2" column="4" > - <widget class="QComboBox" name="Instrument" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <item row="2" column="4"> + <widget class="QComboBox" name="Instrument"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="toolTip" > + <property name="toolTip"> <string>Instrument Box</string> </property> - <property name="styleSheet" > - <string notr="true" >QComboBox#Instrument QListView{background-color: white;background-image: url(ICatComboBackground.png);background-attachment: scroll;}QComboBox#Instrument QListView QScrollBar:vertical{background-image: url(:/images/ICatComboVScrollbar.png); background-repeat: repeat-y; width: 17px; height:20px;} </string> + <property name="styleSheet"> + <string notr="true">QComboBox#Instrument QListView{background-color: white;background-image: url(ICatComboBackground.png);background-attachment: scroll;}QComboBox#Instrument QListView QScrollBar:vertical{background-image: url(:/images/ICatComboVScrollbar.png); background-repeat: repeat-y; width: 17px; height:20px;} </string> </property> - <property name="sizeAdjustPolicy" > + <property name="sizeAdjustPolicy"> <enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum> </property> </widget> </item> - <item row="2" column="5" > - <widget class="QLabel" name="Instrument_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="2" column="5"> + <widget class="QLabel" name="Instrument_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="2" column="7" > - <widget class="QLabel" name="invstTypeLabel" > - <property name="text" > + <item row="2" column="7"> + <widget class="QLabel" name="invstTypeLabel"> + <property name="text"> <string>Investigation Type:</string> </property> </widget> </item> - <item row="2" column="8" > - <widget class="QComboBox" name="InvestigationType" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <item row="2" column="8"> + <widget class="QComboBox" name="InvestigationType"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="styleSheet" > - <string notr="true" >QComboBox#InvestigationType QListView{background-color: white;background-image: url(ICatComboBackground.png);background-attachment: scroll;}QComboBox#InvestigationType QListView QScrollBar:vertical{background-image: url(:/images/ICatComboVScrollbar.png); background-repeat: repeat-y; width: 17px; height:20px;} </string> + <property name="styleSheet"> + <string notr="true">QComboBox#InvestigationType QListView{background-color: white;background-image: url(ICatComboBackground.png);background-attachment: scroll;}QComboBox#InvestigationType QListView QScrollBar:vertical{background-image: url(:/images/ICatComboVScrollbar.png); background-repeat: repeat-y; width: 17px; height:20px;} </string> </property> - <property name="sizeAdjustPolicy" > + <property name="sizeAdjustPolicy"> <enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum> </property> </widget> </item> - <item row="2" column="10" > - <widget class="QLabel" name="InvestigationType_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="2" column="10"> + <widget class="QLabel" name="InvestigationType_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="3" column="0" > - <widget class="QLabel" name="invstsurnameLabel" > - <property name="text" > + <item row="3" column="0"> + <widget class="QLabel" name="invstsurnameLabel"> + <property name="text"> <string>Investigators surname:</string> </property> </widget> </item> - <item row="3" column="1" > - <widget class="QLineEdit" name="InvestigatorSurName" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <item row="3" column="1"> + <widget class="QLineEdit" name="InvestigatorSurName"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> </widget> </item> - <item row="3" column="2" > - <widget class="QLabel" name="InvestigatorSurName_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="3" column="2"> + <widget class="QLabel" name="InvestigatorSurName_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="3" column="3" > - <widget class="QLabel" name="datafilenameLabel" > - <property name="text" > + <item row="3" column="3"> + <widget class="QLabel" name="datafilenameLabel"> + <property name="text"> <string>Datafile name:</string> </property> </widget> </item> - <item row="3" column="4" > - <widget class="QLineEdit" name="DataFileName" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <item row="3" column="4"> + <widget class="QLineEdit" name="DataFileName"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> </widget> </item> - <item row="3" column="5" > - <widget class="QLabel" name="DataFileName_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="3" column="5"> + <widget class="QLabel" name="DataFileName_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="3" column="7" > - <widget class="QLabel" name="keywordsLabel" > - <property name="text" > + <item row="3" column="7"> + <widget class="QLabel" name="keywordsLabel"> + <property name="text"> <string> KeyWord(s):</string> </property> </widget> </item> - <item row="3" column="8" > - <widget class="QLineEdit" name="Keywords" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <item row="3" column="8"> + <widget class="QLineEdit" name="Keywords"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> </widget> </item> - <item row="3" column="10" > - <widget class="QLabel" name="Keywords_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="3" column="10"> + <widget class="QLabel" name="Keywords_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="4" column="8" > - <widget class="QCheckBox" name="casesensitiveBox" > - <property name="text" > + <item row="4" column="8"> + <widget class="QCheckBox" name="casesensitiveBox"> + <property name="text"> <string>Case Sensitive</string> </property> </widget> </item> - <item row="4" column="9" > - <widget class="QLabel" name="CaseSensitive_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="4" column="9"> + <widget class="QLabel" name="CaseSensitive_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> </layout> </item> - <item row="1" column="0" > - <layout class="QHBoxLayout" name="horizontalLayout_2" > + <item row="1" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> <item> - <spacer name="horizontalSpacer_2" > - <property name="orientation" > + <spacer name="horizontalSpacer_2"> + <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="sizeHint" stdset="0" > + <property name="sizeHint" stdset="0"> <size> <width>738</width> <height>20</height> @@ -486,11 +490,11 @@ p, li { white-space: pre-wrap; } </spacer> </item> <item> - <widget class="QPushButton" name="searchButton" > - <property name="toolTip" > + <widget class="QPushButton" name="searchButton"> + <property name="toolTip"> <string>Search Investigations</string> </property> - <property name="text" > + <property name="text"> <string>Search</string> </property> </widget> @@ -500,50 +504,50 @@ p, li { white-space: pre-wrap; } </layout> </widget> </item> - <item row="2" column="0" > - <widget class="QLabel" name="advsearchLabel" > - <property name="frameShape" > + <item row="2" column="0"> + <widget class="QLabel" name="advsearchLabel"> + <property name="frameShape"> <enum>QFrame::StyledPanel</enum> </property> - <property name="frameShadow" > + <property name="frameShadow"> <enum>QFrame::Sunken</enum> </property> - <property name="text" > + <property name="text"> <string/> </property> </widget> </item> - <item row="3" column="0" > - <widget class="QTableWidget" name="advSearchtableWidget" > - <property name="styleSheet" > - <string notr="true" >background-color: rgb(216, 225, 255);</string> + <item row="3" column="0"> + <widget class="QTableWidget" name="advSearchtableWidget"> + <property name="styleSheet"> + <string notr="true">background-color: rgb(216, 225, 255);</string> </property> - <property name="horizontalScrollBarPolicy" > + <property name="horizontalScrollBarPolicy"> <enum>Qt::ScrollBarAsNeeded</enum> </property> - <property name="selectionMode" > + <property name="selectionMode"> <enum>QAbstractItemView::SingleSelection</enum> </property> - <property name="selectionBehavior" > + <property name="selectionBehavior"> <enum>QAbstractItemView::SelectRows</enum> </property> </widget> </item> - <item row="4" column="0" > - <layout class="QHBoxLayout" name="horizontalLayout" > + <item row="4" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout"> <item> - <widget class="QPushButton" name="helpButton" > - <property name="text" > + <widget class="QPushButton" name="helpButton"> + <property name="text"> <string>Help</string> </property> </widget> </item> <item> - <spacer name="horizontalSpacer" > - <property name="orientation" > + <spacer name="horizontalSpacer"> + <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="sizeHint" stdset="0" > + <property name="sizeHint" stdset="0"> <size> <width>548</width> <height>17</height> @@ -552,8 +556,8 @@ p, li { white-space: pre-wrap; } </spacer> </item> <item> - <widget class="QPushButton" name="closeButton" > - <property name="text" > + <widget class="QPushButton" name="closeButton"> + <property name="text"> <string>Close</string> </property> </widget> diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/ICatSearch.ui b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/ICatSearch.ui index 566261c88a82ecf4e5f6affcaca9eb3ca396a489..e032fffc8d235a7dbf24edea98f2f2c0ebdc3fa4 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/ICatSearch.ui +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/ICatSearch.ui @@ -1,7 +1,8 @@ -<ui version="4.0" > +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> <class>ICatSearch</class> - <widget class="QWidget" name="ICatSearch" > - <property name="geometry" > + <widget class="QWidget" name="ICatSearch"> + <property name="geometry"> <rect> <x>0</x> <y>0</y> @@ -9,264 +10,267 @@ <height>465</height> </rect> </property> - <property name="windowTitle" > + <property name="windowTitle"> <string>Catalog Search</string> </property> - <layout class="QVBoxLayout" name="verticalLayout" > + <layout class="QVBoxLayout" name="verticalLayout"> <item> - <widget class="QLabel" name="label" > - <property name="frameShape" > + <widget class="QLabel" name="label"> + <property name="frameShape"> <enum>QFrame::StyledPanel</enum> </property> - <property name="frameShadow" > + <property name="frameShadow"> <enum>QFrame::Sunken</enum> </property> - <property name="text" > - <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + <property name="text"> + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><span style=" font-weight:600;">ISIS Investigations Search</span></p></body></html></string> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><span style=" font-weight:600;">Investigations Search</span></p></body></html></string> </property> - <property name="indent" > - <number>292</number> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="indent"> + <number>0</number> </property> </widget> </item> <item> - <widget class="QFrame" name="searchframeWidget" > - <property name="styleSheet" > - <string notr="true" >background-image: url(:/BackGroundImage/ICatSearchBackGround.png);</string> + <widget class="QFrame" name="searchframeWidget"> + <property name="styleSheet"> + <string notr="true">background-image: url(:/BackGroundImage/ICatSearchBackGround.png);</string> </property> - <property name="frameShape" > + <property name="frameShape"> <enum>QFrame::StyledPanel</enum> </property> - <property name="frameShadow" > + <property name="frameShadow"> <enum>QFrame::Sunken</enum> </property> - <layout class="QGridLayout" name="gridLayout_2" > - <item row="0" column="0" > - <layout class="QGridLayout" name="gridLayout" > - <item row="0" column="0" > - <widget class="QLabel" name="runNumberLabel" > - <property name="text" > + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="runNumberLabel"> + <property name="text"> <string>Run#:</string> </property> </widget> </item> - <item row="0" column="2" > - <widget class="QLabel" name="StartRun_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="0" column="2"> + <widget class="QLabel" name="StartRun_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="0" column="4" > - <widget class="QLabel" name="EndRun_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="0" column="4"> + <widget class="QLabel" name="EndRun_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="0" column="5" > - <widget class="QLabel" name="startdateLabel" > - <property name="text" > + <item row="0" column="5"> + <widget class="QLabel" name="startdateLabel"> + <property name="text"> <string>Start Date:</string> </property> </widget> </item> - <item row="0" column="7" > - <widget class="QToolButton" name="startdatetoolButton" > - <property name="text" > + <item row="0" column="7"> + <widget class="QToolButton" name="startdatetoolButton"> + <property name="text"> <string>...</string> </property> </widget> </item> - <item row="0" column="8" > - <widget class="QLabel" name="StartDate_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="0" column="8"> + <widget class="QLabel" name="StartDate_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="0" column="9" > - <widget class="QLabel" name="keywordsLabel" > - <property name="text" > + <item row="0" column="9"> + <widget class="QLabel" name="keywordsLabel"> + <property name="text"> <string>KeyWord(s):</string> </property> </widget> </item> - <item row="0" column="12" > - <widget class="QLabel" name="Keywords_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="0" column="12"> + <widget class="QLabel" name="Keywords_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="0" column="1" > - <widget class="QLineEdit" name="StartRun" > - <property name="toolTip" > + <item row="0" column="1"> + <widget class="QLineEdit" name="StartRun"> + <property name="toolTip"> <string>Start Run Number</string> </property> - <property name="statusTip" > + <property name="statusTip"> <string/> </property> - <property name="styleSheet" > - <string notr="true" >background-color: rgb(255, 255, 255);</string> + <property name="styleSheet"> + <string notr="true">background-color: rgb(255, 255, 255);</string> </property> - <property name="inputMask" > + <property name="inputMask"> <string/> </property> - <property name="cursorPosition" > + <property name="cursorPosition"> <number>0</number> </property> </widget> </item> - <item row="0" column="3" > - <widget class="QLineEdit" name="EndRun" > - <property name="toolTip" > + <item row="0" column="3"> + <widget class="QLineEdit" name="EndRun"> + <property name="toolTip"> <string>End Run Number</string> </property> - <property name="styleSheet" > - <string notr="true" >background-color: rgb(255, 255, 255);</string> + <property name="styleSheet"> + <string notr="true">background-color: rgb(255, 255, 255);</string> </property> - <property name="inputMask" > + <property name="inputMask"> <string/> </property> </widget> </item> - <item row="0" column="6" > - <widget class="QLineEdit" name="StartDate" > - <property name="toolTip" > + <item row="0" column="6"> + <widget class="QLineEdit" name="StartDate"> + <property name="toolTip"> <string>Start Date in DD/MM/YYYY format</string> </property> - <property name="styleSheet" > - <string notr="true" >background-color: rgb(255, 255, 255);</string> + <property name="styleSheet"> + <string notr="true">background-color: rgb(255, 255, 255);</string> </property> - <property name="inputMask" > + <property name="inputMask"> <string>00/00/0000;_</string> </property> - <property name="text" > + <property name="text"> <string>//</string> </property> </widget> </item> - <item row="0" column="10" colspan="2" > - <widget class="QLineEdit" name="Keywords" > - <property name="styleSheet" > - <string notr="true" >background-color: rgb(255, 255, 255);</string> + <item row="0" column="10" colspan="2"> + <widget class="QLineEdit" name="Keywords"> + <property name="styleSheet"> + <string notr="true">background-color: rgb(255, 255, 255);</string> </property> </widget> </item> - <item row="1" column="0" > - <widget class="QLabel" name="instrumentLabel" > - <property name="text" > + <item row="1" column="0"> + <widget class="QLabel" name="instrumentLabel"> + <property name="text"> <string>Instrument:</string> </property> </widget> </item> - <item row="1" column="1" > - <widget class="QComboBox" name="Instrument" > - <property name="toolTip" > + <item row="1" column="1"> + <widget class="QComboBox" name="Instrument"> + <property name="toolTip"> <string/> </property> - <property name="styleSheet" > - <string notr="true" >QComboBox#Instrument QListView{background-color: white;background-image: url(ICatComboBackground.png);background-attachment: scroll;}QComboBox#Instrument QListView QScrollBar:vertical{background-image: url(:/images/ICatComboVScrollbar.png); background-repeat: repeat-y; width: 17px; height:20px;} </string> + <property name="styleSheet"> + <string notr="true">QComboBox#Instrument QListView{background-color: white;background-image: url(ICatComboBackground.png);background-attachment: scroll;}QComboBox#Instrument QListView QScrollBar:vertical{background-image: url(:/images/ICatComboVScrollbar.png); background-repeat: repeat-y; width: 17px; height:20px;} </string> </property> </widget> </item> - <item row="1" column="2" > - <widget class="QLabel" name="Instrument_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="1" column="2"> + <widget class="QLabel" name="Instrument_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="1" column="5" > - <widget class="QLabel" name="enddateLabel" > - <property name="text" > + <item row="1" column="5"> + <widget class="QLabel" name="enddateLabel"> + <property name="text"> <string>End Date:</string> </property> </widget> </item> - <item row="1" column="6" > - <widget class="QLineEdit" name="EndDate" > - <property name="toolTip" > + <item row="1" column="6"> + <widget class="QLineEdit" name="EndDate"> + <property name="toolTip"> <string>End Date in DD/MM/YYYY format</string> </property> - <property name="styleSheet" > - <string notr="true" >background-color: rgb(255, 255, 255);</string> + <property name="styleSheet"> + <string notr="true">background-color: rgb(255, 255, 255);</string> </property> - <property name="inputMask" > + <property name="inputMask"> <string>00/00/0000;_</string> </property> - <property name="text" > + <property name="text"> <string>//</string> </property> </widget> </item> - <item row="1" column="7" > - <widget class="QToolButton" name="enddatetoolButton" > - <property name="text" > + <item row="1" column="7"> + <widget class="QToolButton" name="enddatetoolButton"> + <property name="text"> <string>...</string> </property> </widget> </item> - <item row="1" column="8" > - <widget class="QLabel" name="EndDate_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="1" column="8"> + <widget class="QLabel" name="EndDate_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> - <item row="1" column="10" > - <widget class="QCheckBox" name="CaseSensitive" > - <property name="toolTip" > + <item row="1" column="10"> + <widget class="QCheckBox" name="CaseSensitive"> + <property name="toolTip"> <string/> </property> - <property name="text" > + <property name="text"> <string>Case Sensitive</string> </property> </widget> </item> - <item row="1" column="11" colspan="2" > - <widget class="QLabel" name="CaseSensitive_2" > - <property name="styleSheet" > - <string notr="true" >color: rgb(255, 0, 0);</string> + <item row="1" column="11" colspan="2"> + <widget class="QLabel" name="CaseSensitive_2"> + <property name="styleSheet"> + <string notr="true">color: rgb(255, 0, 0);</string> </property> - <property name="text" > + <property name="text"> <string>*</string> </property> </widget> </item> </layout> </item> - <item row="1" column="0" > - <layout class="QHBoxLayout" name="horizontalLayout_2" > + <item row="1" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> <item> - <spacer name="horizontalSpacer" > - <property name="orientation" > + <spacer name="horizontalSpacer"> + <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="sizeHint" stdset="0" > + <property name="sizeHint" stdset="0"> <size> <width>582</width> <height>20</height> @@ -275,11 +279,11 @@ p, li { white-space: pre-wrap; } </spacer> </item> <item> - <widget class="QPushButton" name="searchButton" > - <property name="toolTip" > + <widget class="QPushButton" name="searchButton"> + <property name="toolTip"> <string>Search Investigations</string> </property> - <property name="text" > + <property name="text"> <string>Search</string> </property> </widget> @@ -290,61 +294,61 @@ p, li { white-space: pre-wrap; } </widget> </item> <item> - <widget class="QLabel" name="searchlabel" > - <property name="frameShape" > + <widget class="QLabel" name="searchlabel"> + <property name="frameShape"> <enum>QFrame::StyledPanel</enum> </property> - <property name="frameShadow" > + <property name="frameShadow"> <enum>QFrame::Sunken</enum> </property> - <property name="text" > + <property name="text"> <string/> </property> </widget> </item> <item> - <widget class="QTableWidget" name="searchtableWidget" > - <property name="toolTip" > + <widget class="QTableWidget" name="searchtableWidget"> + <property name="toolTip"> <string/> </property> - <property name="styleSheet" > - <string notr="true" >background-color: rgb(216, 225, 255);</string> + <property name="styleSheet"> + <string notr="true">background-color: rgb(216, 225, 255);</string> </property> - <property name="horizontalScrollBarPolicy" > + <property name="horizontalScrollBarPolicy"> <enum>Qt::ScrollBarAsNeeded</enum> </property> - <property name="autoScroll" > + <property name="autoScroll"> <bool>true</bool> </property> - <property name="alternatingRowColors" > + <property name="alternatingRowColors"> <bool>true</bool> </property> - <property name="selectionMode" > + <property name="selectionMode"> <enum>QAbstractItemView::SingleSelection</enum> </property> - <property name="selectionBehavior" > + <property name="selectionBehavior"> <enum>QAbstractItemView::SelectRows</enum> </property> - <property name="showGrid" > + <property name="showGrid"> <bool>true</bool> </property> </widget> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout" > + <layout class="QHBoxLayout" name="horizontalLayout"> <item> - <widget class="QPushButton" name="helpButton" > - <property name="text" > + <widget class="QPushButton" name="helpButton"> + <property name="text"> <string>Help</string> </property> </widget> </item> <item> - <spacer name="horizontalSpacer_4" > - <property name="orientation" > + <spacer name="horizontalSpacer_4"> + <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="sizeHint" stdset="0" > + <property name="sizeHint" stdset="0"> <size> <width>527</width> <height>20</height> @@ -353,8 +357,8 @@ p, li { white-space: pre-wrap; } </spacer> </item> <item> - <widget class="QPushButton" name="closeButton" > - <property name="text" > + <widget class="QPushButton" name="closeButton"> + <property name="text"> <string>Close</string> </property> </widget> @@ -368,8 +372,6 @@ p, li { white-space: pre-wrap; } <tabstop>closeButton</tabstop> <tabstop>searchtableWidget</tabstop> </tabstops> - <resources> - <include location="ICatSearchBackGround.qrc" /> - </resources> + <resources/> <connections/> </ui> diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp index 77b26b8589e433f74e50bd676eed6b5aaf6a2012..f151e9fb6b91004d7d536576ccc592551299b6bd 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp @@ -177,6 +177,8 @@ m_mantidui(mantidui) connect(m_filenameManager,SIGNAL(propertyChanged(QtProperty*)),this,SLOT(stringChanged(QtProperty*))); connect(m_formulaManager,SIGNAL(propertyChanged(QtProperty*)),this,SLOT(stringChanged(QtProperty*))); + connect(this,SIGNAL(xRangeChanged(double, double)), m_mantidui, SLOT(x_range_from_picker(double, double))); + /* Create function group */ QtProperty* functionsGroup = m_groupManager->addProperty("Functions"); QtProperty* settingsGroup(NULL); @@ -1078,6 +1080,7 @@ void FitPropertyBrowser::doubleChanged(QtProperty* prop) getHandler()->setAttribute(QString("Start (%1s)" ).arg(QChar(0x03BC)), value); // (mu) } emit startXChanged(startX()); + emit xRangeChanged(startX(), endX()); return; } else if (prop == m_endX ) @@ -1093,6 +1096,7 @@ void FitPropertyBrowser::doubleChanged(QtProperty* prop) getHandler()->setAttribute(QString("End (%1s)" ).arg(QChar(0x03BC)), value); } emit endXChanged(endX()); + emit xRangeChanged(startX(), endX()); return; } else if(getHandler()->setParameter(prop)) @@ -1376,6 +1380,20 @@ void FitPropertyBrowser::fit() { funStr = *(m_compositeFunction->getFunction(0)); } + + if ( Mantid::API::AnalysisDataService::Instance().doesExist(wsName+"_NormalisedCovarianceMatrix")) + { + Mantid::API::FrameworkManager::Instance().deleteWorkspace(wsName+"_NormalisedCovarianceMatrix"); + } + if ( Mantid::API::AnalysisDataService::Instance().doesExist(wsName+"_Parameters")) + { + Mantid::API::FrameworkManager::Instance().deleteWorkspace(wsName+"_Parameters"); + } + if ( Mantid::API::AnalysisDataService::Instance().doesExist(wsName+"_Workspace")) + { + Mantid::API::FrameworkManager::Instance().deleteWorkspace(wsName+"_Workspace"); + } + // If it is in the custom fitting (muon analysis) i.e not a docked widget in mantidPlot if (m_customFittings) { @@ -2755,7 +2773,6 @@ void FitPropertyBrowser::processMultiBGResults() { table->addColumn("double",par.toStdString()); } - // Create WorkspaceGroup with the fit results std::vector<std::string> worspaceNames(compositeFunction()->nFunctions()); for(size_t i = 0; i < compositeFunction()->nFunctions(); ++i) diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/ColorBarWidget.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/ColorBarWidget.h index e7cc3be50a1f892a12c862a39d9061631f8714b9..003c532a49a987d9500bbc7316ca7486b86171a2 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/ColorBarWidget.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/ColorBarWidget.h @@ -80,6 +80,7 @@ private: void setSpinBoxesSteps(); void mouseDoubleClickEvent(QMouseEvent * event); void updateMinMaxGUI(); + void resizeEvent(QResizeEvent * event); /// Auto-gen UI classes Ui::ColorBarWidgetClass ui; @@ -104,6 +105,9 @@ private: /// Min value being displayed double m_max; + + /// Show the value tooltip (off by default) + bool m_showTooltip; }; #endif // COLORBARWIDGET_H diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h index ecd4012acf43361aad5c7318e44c194ff678a5c6..77497299776220a4bc8bdb993fa0f7f07d6600ce 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h @@ -18,6 +18,7 @@ #include <qwt_scale_widget.h> #include <vector> #include "MantidQtAPI/MantidColorMap.h" +#include "MantidAPI/IMDIterator.h" class EXPORT_OPT_MANTIDQT_SLICEVIEWER SliceViewer : public QWidget @@ -55,6 +56,7 @@ private: void updateDisplay(bool resetAxes = false); void updateDimensionSliceWidgets(); void resetAxis(int axis, Mantid::Geometry::IMDDimension_const_sptr dim); + QwtDoubleInterval getRange(Mantid::API::IMDIterator * it); void findRangeFull(); void findRangeSlice(); @@ -116,6 +118,8 @@ private: QMenu * m_menuColorOptions; QMenu * m_menuView; + /// Cached double for infinity + double m_inf; }; #endif // SLICEVIEWER_H diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.ui b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.ui index f93953c8eb3e7619d177d36abc81d3d61966e0ae..ab96ba3579c825f86ae83e57a9238a0b208aed1a 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.ui +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.ui @@ -56,6 +56,22 @@ <property name="margin"> <number>2</number> </property> + </layout> + </widget> + <widget class="QFrame" name="frmBottom"> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <layout class="QVBoxLayout" name="layoutBottom"> + <property name="spacing"> + <number>2</number> + </property> + <property name="margin"> + <number>0</number> + </property> <item> <widget class="QFrame" name="frmToolbar"> <property name="autoFillBackground"> @@ -73,6 +89,21 @@ <enum>QFrame::Raised</enum> </property> <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>5</number> + </property> + <property name="leftMargin"> + <number>8</number> + </property> + <property name="topMargin"> + <number>4</number> + </property> + <property name="rightMargin"> + <number>8</number> + </property> + <property name="bottomMargin"> + <number>4</number> + </property> <item> <widget class="QToolButton" name="btnZoom"> <property name="enabled"> @@ -243,16 +274,18 @@ </layout> </widget> </item> + <item> + <widget class="QFrame" name="frmPlot"> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + </widget> + </item> </layout> </widget> - <widget class="QFrame" name="frmPlot"> - <property name="frameShape"> - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Raised</enum> - </property> - </widget> </widget> </item> </layout> diff --git a/Code/Mantid/MantidQt/SliceViewer/src/ColorBarWidget.cpp b/Code/Mantid/MantidQt/SliceViewer/src/ColorBarWidget.cpp index 07233126441d63b8cc52d80f81a227ff10c062c7..e2f78aed79204193308e561e66545bfd9c6e9099 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/ColorBarWidget.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/ColorBarWidget.cpp @@ -8,6 +8,7 @@ #include <qwt_scale_widget.h> #include <QKeyEvent> #include <qwt_plot.h> +#include <qwt_scale_engine.h> //------------------------------------------------------------------------------------------------- /** Constructor */ @@ -21,23 +22,20 @@ ColorBarWidget::ColorBarWidget(QWidget *parent) m_max = 1000; m_rangeMin = 0; m_rangeMax = 1000; + m_showTooltip = false; m_log = false; m_colorMap.changeScaleType( GraphOptions::Linear ); // Create and add the color bar m_colorBar = new QwtScaleWidgetExtended(); m_colorBar->setToolTip(""); + m_colorBar->setColorBarEnabled(true); + m_colorBar->setColorBarWidth(20); + m_colorBar->setAlignment(QwtScaleDraw::RightScale); + m_colorBar->setLabelAlignment( Qt::AlignRight | Qt::AlignVCenter); + //m_colorBar->setCursor(Qt::OpenHandCursor); ui.verticalLayout->insertWidget(2,m_colorBar, 1,0 ); -// QwtPlot * plot = new QwtPlot(this); -// plot->enableAxis( QwtPlot::xBottom, false); -// plot->enableAxis( QwtPlot::yLeft, false); -// plot->enableAxis( QwtPlot::yRight, true); -// plot->axisScaleDraw(QwtPlot::yRight)-> -// plot->setAxisScale(QwtPlot::yRight, 0, 1e12); -// ui.verticalLayout->insertWidget(2,plot, 1,0 ); - - // Hook up signals QObject::connect(ui.checkLog, SIGNAL(stateChanged(int)), this, SLOT(changedLogState(int))); QObject::connect(ui.valMin, SIGNAL(editingFinished()), this, SLOT(changedMinimum())); @@ -82,6 +80,15 @@ void ColorBarWidget::mouseDoubleClickEvent(QMouseEvent * event) emit colorBarDoubleClicked(); } +//------------------------------------------------------------------------------------------------- +/// Event called after resizing +void ColorBarWidget::resizeEvent(QResizeEvent * event) +{ + updateColorMap(); + QWidget::resizeEvent(event); +} + + //------------------------------------------------------------------------------------------------- /** Adjust the steps of the spin boxes for log/linear mode */ void ColorBarWidget::setSpinBoxesSteps() @@ -183,6 +190,7 @@ void ColorBarWidget::setLog(bool log) ui.valMin->setLogSteps( m_log ); ui.valMax->setLogSteps( m_log ); setSpinBoxesSteps(); + updateColorMap(); } //------------------------------------------------------------------------------------------------- @@ -195,6 +203,7 @@ void ColorBarWidget::changedMinimum() m_max = m_min+0.001; ui.valMax->setValue( m_max ); } + updateColorMap(); emit changedColorRange(m_min,m_max,m_log); } @@ -208,6 +217,7 @@ void ColorBarWidget::changedMaximum() m_min = m_max-0.001; ui.valMin->setValue( m_min ); } + updateColorMap(); emit changedColorRange(m_min,m_max,m_log); } @@ -215,13 +225,16 @@ void ColorBarWidget::changedMaximum() /** SLOT called when the mouse moves over the color bar*/ void ColorBarWidget::colorBarMouseMoved(QPoint globalPos, double fraction) { - double val = 0; - if (m_log) - val = pow(10., fraction * (log10(m_max)-log10(m_min)) + log10(m_min)); - else - val = fraction * (m_max-m_min) + m_min; - QString tooltip = QString::number(val,'g', 4); - QToolTip::showText(globalPos, tooltip, m_colorBar); + if (m_showTooltip) + { + double val = 0; + if (m_log) + val = pow(10., fraction * (log10(m_max)-log10(m_min)) + log10(m_min)); + else + val = fraction * (m_max-m_min) + m_min; + QString tooltip = QString::number(val,'g', 4); + QToolTip::showText(globalPos, tooltip, m_colorBar); + } } @@ -236,12 +249,27 @@ void ColorBarWidget::updateColorMap() m_colorBar->setColorBarWidth(15); m_colorBar->setEnabled(true); - QwtScaleDiv scaleDiv; - scaleDiv.setInterval(range); - if (m_log) - m_colorBar->setScaleDiv(new QwtScaleTransformation(QwtScaleTransformation::Log10), scaleDiv); + // Try to limit the number of steps based on the height of the color bar + int maxMajorSteps = m_colorBar->height()/15; // 15 pixels per div looked about right + //std::cout << "maxMajorSteps" << maxMajorSteps << std::endl; + if (maxMajorSteps > 10) maxMajorSteps = 10; + + // Show the scale on the right + double minValue = m_min; + double maxValue = m_max; + GraphOptions::ScaleType type = m_colorMap.getScaleType(); + if( type == GraphOptions::Linear ) + { + QwtLinearScaleEngine linScaler; + m_colorBar->setScaleDiv(linScaler.transformation(), linScaler.divideScale(minValue, maxValue, maxMajorSteps, 5)); + m_colorBar->setColorMap(QwtDoubleInterval(minValue, maxValue),m_colorMap); + } else - m_colorBar->setScaleDiv(new QwtScaleTransformation(QwtScaleTransformation::Linear), scaleDiv); + { + QwtLog10ScaleEngine logScaler; + m_colorBar->setScaleDiv(logScaler.transformation(), logScaler.divideScale(minValue, maxValue, maxMajorSteps, 5)); + m_colorBar->setColorMap(QwtDoubleInterval(minValue, maxValue), m_colorMap); + } } diff --git a/Code/Mantid/MantidQt/SliceViewer/src/QwtRasterDataMD.cpp b/Code/Mantid/MantidQt/SliceViewer/src/QwtRasterDataMD.cpp index 2464b3e6dbd4a71ca0aa6059743e15fb00491c18..7dca8102639416bcb95483d421981c5050b7993c 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/QwtRasterDataMD.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/QwtRasterDataMD.cpp @@ -77,14 +77,13 @@ double QwtRasterDataMD::value(double x, double y) const } // Get the signal at that point signal_t value = m_ws->getSignalAtCoord(lookPoint); - if (value < m_minVal) m_minVal = value; - if (value > m_maxVal) m_maxVal = value; delete [] lookPoint; + // Special case for 0 = show as NAN if (value == 0.) return nan; - else - return value; + + return value; } diff --git a/Code/Mantid/MantidQt/SliceViewer/src/SliceViewer.cpp b/Code/Mantid/MantidQt/SliceViewer/src/SliceViewer.cpp index f0d3990b01a65dcb31e2fa4474b3ba574484f41f..a009c235ed30b4eac98866c4a40d8966650275e1 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/SliceViewer.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/SliceViewer.cpp @@ -27,6 +27,7 @@ #include <sstream> #include <vector> #include <qfiledialog.h> +#include <limits> using namespace Mantid; using namespace Mantid::Kernel; @@ -43,6 +44,8 @@ SliceViewer::SliceViewer(QWidget *parent) { ui.setupUi(this); + m_inf = std::numeric_limits<double>::infinity(); + // Create the plot m_spectLayout = new QHBoxLayout(ui.frmPlot); m_plot = new QwtPlot(); @@ -462,7 +465,7 @@ void SliceViewer::resetAxis(int axis, Mantid::Geometry::IMDDimension_const_sptr * @param it :: IMDIterator of what to find * @return the min/max range, or 0-1.0 if not found */ -QwtDoubleInterval getRange(IMDIterator * it) +QwtDoubleInterval SliceViewer::getRange(IMDIterator * it) { if (!it) return QwtDoubleInterval(0., 1.0); @@ -474,15 +477,29 @@ QwtDoubleInterval getRange(IMDIterator * it) do { double signal = it->getNormalizedSignal(); - if (signal > 0 && signal < minSignal) minSignal = signal; - if (signal > maxSignal) maxSignal = signal; + // Skip any 'infs' as it screws up the color scale + if (signal != m_inf) + { + if (signal > 0 && signal < minSignal) minSignal = signal; + if (signal > maxSignal) maxSignal = signal; + } } while (it->next()); + if (minSignal == DBL_MAX) + { + minSignal = 0.0; + maxSignal = 1.0; + } if (minSignal < maxSignal) return QwtDoubleInterval(minSignal, maxSignal); else - // Possibly only one value in range - return QwtDoubleInterval(minSignal*0.5, minSignal*1.5); + { + if (minSignal != 0) + // Possibly only one value in range + return QwtDoubleInterval(minSignal*0.5, minSignal*1.5); + else + return QwtDoubleInterval(0., 1.0); + } } //------------------------------------------------------------------------------------ diff --git a/Code/Mantid/MantidQt/SliceViewer/src/main_ColorBarWidgetDemo.cpp b/Code/Mantid/MantidQt/SliceViewer/src/main_ColorBarWidgetDemo.cpp index 06dddc17120d26a57c401c1956917a3842d1fbb3..f90ae6838bf6de6b3c494a46366a34d111202ed9 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/main_ColorBarWidgetDemo.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/main_ColorBarWidgetDemo.cpp @@ -23,7 +23,7 @@ int main( int argc, char ** argv ) { double min=0; - double max=100; + double max=1e9; QApplication app(argc, argv); app.setOrganizationName("MantidProject"); diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/CMakeLists.txt index 2a35bfdd6977b9687d8b7b825988d7946330bd23..be004d1456660d8389fdadc7736c72dcf77d308e 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/CMakeLists.txt @@ -15,7 +15,7 @@ target_link_libraries( MantidParaViewMDEWRebinningCutterSMPlugin ${MANTID_SUBPROJECT_LIBS} ) # Put library into subfolder. -output_binary_to(MantidParaViewMDEWRebinningCutterSMPlugin ${PVPLUGINS_DIR}) +SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewMDEWRebinningCutterSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}) install( TARGETS MantidParaViewMDEWRebinningCutterSMPlugin ${TARGET_TYPE} DESTINATION ${PVPLUGINS_DIR} ) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/CMakeLists.txt index a2a2448d0cf283eb63167507286354aacfdab038..be6ec22c99708c972056646350e72eb8b13cac78 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/CMakeLists.txt @@ -14,7 +14,7 @@ target_link_libraries( MantidParaViewRebinningTransformSMPlugin ${MANTID_SUBPROJECT_LIBS} ) # Put library into subfolder. -output_binary_to(MantidParaViewRebinningTransformSMPlugin ${PVPLUGINS_DIR}) +SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewRebinningTransformSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}) install( TARGETS MantidParaViewRebinningTransformSMPlugin ${TARGET_TYPE} DESTINATION ${PVPLUGINS_DIR} ) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/CMakeLists.txt index 14e7218c8cd6fbe18930b5eb479b4ad1de529c61..376097ffde4cc55ab8eb6deb33ce83ee446edc8f 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/CMakeLists.txt @@ -1,11 +1,12 @@ PROJECT(ScaleWorkspace) ADD_PARAVIEW_PLUGIN(MantidParaViewScaleWorkspaceSMPlugin "1.0" - SERVER_MANAGER_XML ScaleWorkspace.xml - SERVER_MANAGER_SOURCES vtkScaleWorkspace.cxx - GUI_RESOURCE_FILES ScaleWorkspaceGUI.xml) - # Add to the 'VatesParaViewPlugins' group in VS - set_property( TARGET MantidParaViewScaleWorkspaceSMPlugin PROPERTY FOLDER "MantidVatesParaViewPlugins") - # Put library into subfolder. - output_binary_to(MantidParaViewScaleWorkspaceSMPlugin ${PVPLUGINS_DIR}) - install( TARGETS MantidParaViewScaleWorkspaceSMPlugin ${TARGET_TYPE} DESTINATION ${PVPLUGINS_DIR}) \ No newline at end of file +SERVER_MANAGER_XML ScaleWorkspace.xml +SERVER_MANAGER_SOURCES vtkScaleWorkspace.cxx +GUI_RESOURCE_FILES ScaleWorkspaceGUI.xml) +# Add to the 'VatesParaViewPlugins' group in VS +set_property( TARGET MantidParaViewScaleWorkspaceSMPlugin PROPERTY FOLDER "MantidVatesParaViewPlugins") +# Put library into subfolder. +SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewScaleWorkspaceSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}) + +install( TARGETS MantidParaViewScaleWorkspaceSMPlugin ${TARGET_TYPE} DESTINATION ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}) \ No newline at end of file diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/CMakeLists.txt index c39fe34bc52d091b50133a4f118d1935f61f5785..b1832f444289673745d8a43f45634ea6518b3c1a 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/CMakeLists.txt @@ -13,7 +13,7 @@ target_link_libraries( MantidParaViewSplatterPlotSMPlugin ${MANTID_SUBPROJECT_LIBS} ) # Put library into subfolder. -output_binary_to(MantidParaViewSplatterPlotSMPlugin ${PVPLUGINS_DIR}) +SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewSplatterPlotSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}) install( TARGETS MantidParaViewSplatterPlotSMPlugin ${TARGET_TYPE} DESTINATION ${PVPLUGINS_DIR} ) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/EventNexusReader/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/EventNexusReader/CMakeLists.txt index 511f1a866a1749113884f632197999eff66e16f3..f4e0e4e15552039b1553e5b068eca02d49cbd13d 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/EventNexusReader/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/EventNexusReader/CMakeLists.txt @@ -13,7 +13,7 @@ target_link_libraries( MantidParaViewEventNexusReaderSMPlugin ${MANTID_SUBPROJECT_LIBS} ) # Put library into subfolder. -output_binary_to(MantidParaViewEventNexusReaderSMPlugin ${PVPLUGINS_DIR}) +SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewEventNexusReaderSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}) install( TARGETS MantidParaViewEventNexusReaderSMPlugin ${TARGET_TYPE} DESTINATION ${PVPLUGINS_DIR} ) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/CMakeLists.txt index 22e0999d634a3b074faf769f9faced1bc0bef17f..17656472ff807b225d0064865bd0ba07597b878a 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/CMakeLists.txt @@ -13,7 +13,7 @@ target_link_libraries( MantidParaViewMDEWNexusReaderSMPlugin ${MANTID_SUBPROJECT_LIBS} ) # Put library into subfolder. -output_binary_to(MantidParaViewMDEWNexusReaderSMPlugin ${PVPLUGINS_DIR}) +SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewMDEWNexusReaderSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}) install( TARGETS MantidParaViewMDEWNexusReaderSMPlugin ${TARGET_TYPE} DESTINATION ${PVPLUGINS_DIR} ) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/PeaksReader/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/PeaksReader/CMakeLists.txt index 4d67c04fa1afce52395dd78094c9d7c5ef9201c8..06da2832d51b0e083b8b8679c8dd16c0892df51b 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/PeaksReader/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/PeaksReader/CMakeLists.txt @@ -13,7 +13,7 @@ target_link_libraries( MantidParaViewPeaksReaderSMPlugin ${MANTID_SUBPROJECT_LIBS} ) # Put library into subfolder. -output_binary_to(MantidParaViewPeaksReaderSMPlugin ${PVPLUGINS_DIR}) +SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewPeaksReaderSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}) install( TARGETS MantidParaViewPeaksReaderSMPlugin ${TARGET_TYPE} DESTINATION ${PVPLUGINS_DIR} ) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWEventReader/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWEventReader/CMakeLists.txt index d1b6e0d77298eb8f5a5b1e3c75b725ecb1b3cdeb..52a4955713f69a852269cda98d47eaf28537109e 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWEventReader/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWEventReader/CMakeLists.txt @@ -13,7 +13,7 @@ target_link_libraries( MantidParaViewSQWEventReaderSMPlugin ${MANTID_SUBPROJECT_LIBS} ) # Put library into subfolder. -output_binary_to(MantidParaViewSQWEventReaderSMPlugin ${PVPLUGINS_DIR}) +SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewSQWEventReaderSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}) install( TARGETS MantidParaViewSQWEventReaderSMPlugin ${TARGET_TYPE} DESTINATION ${PVPLUGINS_DIR} ) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/CMakeLists.txt index cb75fe701c6c2aef3b51768f6a8c47cc9219adeb..554e60d2447282d93044d552bd3bbf55a2e139ae 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/CMakeLists.txt @@ -13,7 +13,7 @@ target_link_libraries( MantidParaViewSQWReaderSMPlugin ${MANTID_SUBPROJECT_LIBS} ) # Put library into subfolder. -output_binary_to( MantidParaViewSQWReaderSMPlugin ${PVPLUGINS_DIR}) +SET_TARGET_OUTPUT_DIRECTORY( MantidParaViewSQWReaderSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}) install( TARGETS MantidParaViewSQWReaderSMPlugin ${TARGET_TYPE} DESTINATION ${PVPLUGINS_DIR} ) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/CMakeLists.txt index f0c2dda6d660230e84d6e554de8379737e77cd7b..42e0582fa9c830dfe535b1120807217ff893779d 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/CMakeLists.txt @@ -11,6 +11,6 @@ target_link_libraries( MantidParaViewMDEWSourceSMPlugin ${MANTID_SUBPROJECT_LIBS} ) # Put library into subfolder. -output_binary_to(MantidParaViewMDEWSourceSMPlugin ${PVPLUGINS_DIR}) +SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewMDEWSourceSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}) install( TARGETS MantidParaViewMDEWSourceSMPlugin ${TARGET_TYPE} DESTINATION ${PVPLUGINS_DIR} ) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/CMakeLists.txt index d40144c22036bb9bebd3e809c3c1be411e52934a..874c04c3dde0bb4ae2ff81dad326f04538c087b1 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/CMakeLists.txt @@ -11,6 +11,6 @@ target_link_libraries( MantidParaViewPeaksSourceSMPlugin ${MANTID_SUBPROJECT_LIBS} ) # Put library into subfolder. -output_binary_to(MantidParaViewPeaksSourceSMPlugin ${PVPLUGINS_DIR}) +SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewPeaksSourceSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}) install( TARGETS MantidParaViewPeaksSourceSMPlugin ${TARGET_TYPE} DESTINATION ${PVPLUGINS_DIR} ) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/CMakeLists.txt index 830becfe7041eae38767955ea8fde76d7c8ea14d..9224f28ca8a9769e6f6afdfceaa9829c0152b45c 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/CMakeLists.txt @@ -35,7 +35,7 @@ ${MANTID_SUBPROJECT_LIBS} ) add_definitions( -DIN_MANTIDPARAVIEWQT_MANTIDPARAVIEWWIDGETS ) # Put library into subfolder. -#output_binary_to(MantidParaViewQtWidgets PVPlugins) +#SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewQtWidgets PVPlugins) install( TARGETS MantidParaViewQtWidgets ${TARGET_TYPE} DESTINATION ${LIB_DIR} ) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningCutterObjectPanel/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningCutterObjectPanel/CMakeLists.txt index dd1d54bed12b96f3d70c8a02b7d6778f8dd827e3..2ed508f487fdc5959f4d0029623d9f9b07de727f 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningCutterObjectPanel/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningCutterObjectPanel/CMakeLists.txt @@ -19,7 +19,7 @@ target_link_libraries( MantidParaViewRebinningCutterObjectPanel MantidParaViewQtWidgets ) # Put library into subfolder. -output_binary_to( MantidParaViewRebinningCutterObjectPanel ${PVPLUGINS_DIR}) +SET_TARGET_OUTPUT_DIRECTORY( MantidParaViewRebinningCutterObjectPanel ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}) install( TARGETS MantidParaViewRebinningCutterObjectPanel ${TARGET_TYPE} DESTINATION ${PVPLUGINS_DIR} ) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningTransformObjectPanel/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningTransformObjectPanel/CMakeLists.txt index 0e56e0aebdf6218cf473a365f9a2811c3f2306ad..58f4704e693a9f8526543d2bfb49902037fba968 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningTransformObjectPanel/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningTransformObjectPanel/CMakeLists.txt @@ -19,7 +19,7 @@ target_link_libraries( MantidParaViewRebinningTransformObjectPanel MantidParaViewQtWidgets ) # Put library into subfolder. -output_binary_to( MantidParaViewRebinningTransformObjectPanel ${PVPLUGINS_DIR}) +SET_TARGET_OUTPUT_DIRECTORY( MantidParaViewRebinningTransformObjectPanel ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}) install( TARGETS MantidParaViewRebinningTransformObjectPanel ${TARGET_TYPE} DESTINATION ${PVPLUGINS_DIR} ) diff --git a/Code/Mantid/Vates/VatesAPI/src/DimensionPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/DimensionPresenter.cpp index ebd4d8aad0a944608ec2bd802f625238cb3cdd50..0cf4b52738ba6d38e1fb4fdc96f9ec346e6b63e1 100644 --- a/Code/Mantid/Vates/VatesAPI/src/DimensionPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/DimensionPresenter.cpp @@ -133,7 +133,7 @@ namespace Mantid { return Mantid::Geometry::createDimension(m_model->toXMLString(), nbins, min, max); } - catch(std::invalid_argument& err) + catch(std::invalid_argument&) { m_view->configureStrongly(); m_view->displayError("Check the ranges just entered. Must have min < max."); diff --git a/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/inc/MantidVatesSimpleGuiQtWidgets/AxisInteractor.h b/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/inc/MantidVatesSimpleGuiQtWidgets/AxisInteractor.h index a286607448d715b5c2b63e1128cb504a34de9336..24cab884eaa847653e9f38db354bad38c06e9c97 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/inc/MantidVatesSimpleGuiQtWidgets/AxisInteractor.h +++ b/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/inc/MantidVatesSimpleGuiQtWidgets/AxisInteractor.h @@ -5,9 +5,9 @@ #include <QWidget> +class QBoxLayout; class QGraphicsScene; class QGraphicsView; -class QGridLayout; class QMenu; class QMouseEvent; class QString; @@ -168,15 +168,6 @@ protected slots: */ void showContextMenu(const QPoint &pos); -protected: - /** - * Intercept mouse clicks to avoid inadvertent creation of indicators. This - * forces the mode of right clicking near the axis to get an indicator. - * @param obj the QObject that spawned the event - * @param event the associated QEvent - */ - bool eventFilter(QObject *obj, QEvent *event); - private: /// Create the context menu of the indicators void createContextMenu(); @@ -186,7 +177,7 @@ private: QMenu *indicatorContextMenu; ///< The indicator context menu QwtScaleEngine *engine; ///< The scale type for the axis widget QGraphicsView *graphicsView; ///< The holder for the slice indicators - QGridLayout *gridLayout; ///< Layout manager for widgets + QBoxLayout *boxLayout; ///< Layout manager for widgets bool isSceneGeomInit; ///< Flag to ensure the scene is initialized once Qt::Orientation orientation; ///< The overall orientation of the widget ScalePicker *scalePicker; ///< The picker that retrieves the axis location diff --git a/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/src/AxisInteractor.cpp b/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/src/AxisInteractor.cpp index 602d1dea8c5ca6b4b49cf6c72c197a0ca00c16c4..7c1d124d6445e3a08d850bc01ff40f87d4ee31b6 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/src/AxisInteractor.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/src/AxisInteractor.cpp @@ -12,11 +12,12 @@ #include <QGraphicsScene> #include <QGraphicsSceneMouseEvent> #include <QGraphicsView> -#include <QGridLayout> +#include <QHBoxLayout> #include <QList> #include <QMenu> #include <QMouseEvent> #include <QString> +#include <QVBoxLayout> #include <cmath> #include <iostream> @@ -41,18 +42,17 @@ AxisInteractor::AxisInteractor(QWidget *parent) : QWidget(parent) this->graphicsView->setFrameShape(QFrame::NoFrame); this->graphicsView->setFrameShadow(QFrame::Plain); this->graphicsView->setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing); + this->graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + this->graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - this->gridLayout = new QGridLayout(this); this->scaleWidget = new QwtScaleWidget(this); + this->scaleWidget->setSpacing(0); + this->scaleWidget->setMargin(0); this->scene = new QGraphicsScene(this); this->scene->setItemIndexMethod(QGraphicsScene::NoIndex); this->isSceneGeomInit = false; - - //this->widgetLayout(); - this->graphicsView->setScene(this->scene); - //this->graphicsView->installEventFilter(this); this->engine = new QwtLinearScaleEngine; this->transform = new QwtScaleTransformation(QwtScaleTransformation::Linear); @@ -70,71 +70,65 @@ AxisInteractor::AxisInteractor(QWidget *parent) : QWidget(parent) void AxisInteractor::widgetLayout() { - if (!this->gridLayout->isEmpty()) - { - for (int i = 0; i < this->gridLayout->count(); ++i) - { - this->gridLayout->removeItem(this->gridLayout->itemAt(i)); - } - } - // All set for vertical orientation - int scaleWidth = 50; - int scaleHeight = 150; - int gvWidth = 50; - int gvHeight = 150; - QSizePolicy policy(QSizePolicy::Fixed, QSizePolicy::Minimum); + QSize scaleSize(80, 400); + QSize gvSize(20, 400); + QSizePolicy policy(QSizePolicy::Fixed, QSizePolicy::Fixed); if (this->orientation == Qt::Vertical) { + this->boxLayout = new QHBoxLayout(this); + this->scaleWidget->setFixedSize(scaleSize); + this->graphicsView->setFixedSize(gvSize); switch (this->scalePos) { case LeftScale: { this->scaleWidget->setAlignment(QwtScaleDraw::RightScale); - this->gridLayout->addWidget(this->graphicsView, 0, 0, 1, 1); - this->gridLayout->addWidget(this->scaleWidget, 0, 1, 1, 1); + this->boxLayout->addWidget(this->graphicsView, 0); + this->boxLayout->addWidget(this->scaleWidget, 1); break; } case RightScale: default: { this->scaleWidget->setAlignment(QwtScaleDraw::LeftScale); - this->gridLayout->addWidget(this->scaleWidget, 0, 0, 1, 1); - this->gridLayout->addWidget(this->graphicsView, 0, 1, 1, 1); + this->boxLayout->addWidget(this->scaleWidget, 0); + this->boxLayout->addWidget(this->graphicsView, 1); break; } } } else // Qt::Horizontal { - qSwap(scaleWidth, scaleHeight); - qSwap(gvWidth, gvHeight); - policy.transpose(); + this->boxLayout = new QVBoxLayout(this); + scaleSize.transpose(); + gvSize.transpose(); + this->scaleWidget->setFixedSize(scaleSize); + this->graphicsView->setFixedSize(gvSize); switch (this->scalePos) { case BottomScale: { this->scaleWidget->setAlignment(QwtScaleDraw::TopScale); - this->gridLayout->addWidget(this->scaleWidget, 0, 0, 1, 1); - this->gridLayout->addWidget(this->graphicsView, 1, 0, 1, 1); + this->boxLayout->addWidget(this->scaleWidget, 0); + this->boxLayout->addWidget(this->graphicsView, 1); break; } case TopScale: default: { this->scaleWidget->setAlignment(QwtScaleDraw::BottomScale); - this->gridLayout->addWidget(this->graphicsView, 0, 0, 1, 1); - this->gridLayout->addWidget(this->scaleWidget, 1, 0, 1, 1); + this->boxLayout->addWidget(this->graphicsView, 0); + this->boxLayout->addWidget(this->scaleWidget, 1); break; } } } + this->boxLayout->setContentsMargins(0, 0, 0, 0); + this->boxLayout->setSpacing(0); this->scaleWidget->setSizePolicy(policy); - this->scaleWidget->setMinimumSize(QSize(scaleWidth, scaleHeight)); this->graphicsView->setSizePolicy(policy); - this->graphicsView->setMinimumSize(QSize(gvWidth, gvHeight)); - this->setSizePolicy(policy); } void AxisInteractor::setInformation(QString title, double min, double max) @@ -232,36 +226,6 @@ void AxisInteractor::updateIndicator(double value) } } -bool AxisInteractor::eventFilter(QObject *obj, QEvent *event) -{ - if (obj == this->graphicsView) - { - if (event->type() == QEvent::MouseButtonPress || - event->type() == QEvent::MouseButtonDblClick) - { - QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); - if (mouseEvent->button() == Qt::RightButton) - { - // Want to eat these so users don't add the indicators - // via the QGraphicsView (Yum!) - return true; - } - else - { - return false; - } - } - else - { - return false; - } - } - else - { - return AxisInteractor::eventFilter(obj, event); - } -} - AxisInteractor::ScalePos AxisInteractor::scalePosition() const { return this->scalePos; diff --git a/Code/Mantid/Vates/VatesSimpleGui/StandAloneExec/src/VsgMainWindow.cpp b/Code/Mantid/Vates/VatesSimpleGui/StandAloneExec/src/VsgMainWindow.cpp index 25aa6d517e02d93174e89ee51d7c9f3d9228f7f2..11a715ddb0d19355dc74a7f4dd4eb6afc9486e93 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/StandAloneExec/src/VsgMainWindow.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/StandAloneExec/src/VsgMainWindow.cpp @@ -15,6 +15,7 @@ VsgMainWindow::VsgMainWindow(QWidget *parent) : QMainWindow(parent) this->createActions(); this->createMenus(); + this->mdViewer->addMenus(); } VsgMainWindow::~VsgMainWindow() diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt index a2f4bc20481a0872488b942821a87c73ce21136a..cc13accd4d3b9891d1eab8a35e3a3639f2cea3cf 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt @@ -2,7 +2,7 @@ project( MantidVatesSimpleGuiViewWidgets ) # These are the C++ files to be compiled. set( INCLUDE_FILES - inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h + inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionDialog.h inc/MantidVatesSimpleGuiViewWidgets/ColorUpdater.h inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h inc/MantidVatesSimpleGuiViewWidgets/MultisliceView.h @@ -15,7 +15,7 @@ set( INCLUDE_FILES ) set( SOURCE_FILES - src/ColorSelectionWidget.cpp + src/ColorSelectionDialog.cpp src/ColorUpdater.cpp src/MdViewerWidget.cpp src/MultisliceView.cpp @@ -29,7 +29,7 @@ set( SOURCE_FILES # These are the headers to be preprocessed using # Qt's moc preprocessor. qt4_wrap_cpp( MOC_SOURCES - inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h + inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionDialog.h inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h inc/MantidVatesSimpleGuiViewWidgets/MultisliceView.h inc/MantidVatesSimpleGuiViewWidgets/StandardView.h @@ -42,7 +42,7 @@ qt4_wrap_cpp( MOC_SOURCES # These are the ui files to be processed using # Qt's ui file processor. qt4_wrap_ui( UI_BUILT_SOURCES - inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.ui + inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionDialog.ui inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.ui inc/MantidVatesSimpleGuiViewWidgets/MultisliceView.ui inc/MantidVatesSimpleGuiViewWidgets/StandardView.ui diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionDialog.h similarity index 92% rename from Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h rename to Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionDialog.h index 09ed007ce6e56e64b3fd2626c17ddab984500b63..69aa2dd7431bca179541558f8b97b363c4161cfc 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionDialog.h @@ -1,10 +1,10 @@ -#ifndef COLORSELECTIONWIDGET_H_ -#define COLORSELECTIONWIDGET_H_ +#ifndef COLORSELECTIONDIALOG_H_ +#define COLORSELECTIONDIALOG_H_ -#include "ui_ColorSelectionWidget.h" +#include "ui_ColorSelectionDialog.h" #include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h" -#include <QWidget> +#include <QDialog> class pqColorMapModel; class pqColorPresetManager; @@ -43,7 +43,7 @@ namespace SimpleGui File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> Code Documentation is available at: <http://doxygen.mantidproject.org> */ -class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS ColorSelectionWidget : public QWidget +class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS ColorSelectionDialog : public QDialog { Q_OBJECT @@ -52,9 +52,9 @@ public: * Default constructor. * @param parent the parent widget of the mode control widget */ - ColorSelectionWidget(QWidget *parent = 0); + ColorSelectionDialog(QWidget *parent = 0); /// Default destructor. - virtual ~ColorSelectionWidget() {} + virtual ~ColorSelectionDialog() {} public slots: /** @@ -127,7 +127,7 @@ private: void setEditorStatus(bool status); pqColorPresetManager *presets; ///< Dialog for choosing color presets - Ui::ColorSelectionWidgetClass ui; ///< The mode control widget's UI form + Ui::ColorSelectionDialogClass ui; ///< The mode control widget's UI form }; } diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.ui b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionDialog.ui similarity index 65% rename from Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.ui rename to Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionDialog.ui index 3d28a0ee2d160f6573fcacf7060f49612e10cef4..e03e98755a3cf9893c49da4fa7c09f81170968fa 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.ui +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionDialog.ui @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> - <class>ColorSelectionWidgetClass</class> - <widget class="QWidget" name="ColorSelectionWidgetClass"> + <class>ColorSelectionDialogClass</class> + <widget class="QDialog" name="ColorSelectionDialogClass"> <property name="geometry"> <rect> <x>0</x> <y>0</y> - <width>230</width> - <height>196</height> + <width>466</width> + <height>178</height> </rect> </property> <property name="sizePolicy"> @@ -17,30 +17,9 @@ </sizepolicy> </property> <property name="windowTitle"> - <string>Form</string> + <string>Color Options</string> </property> <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLabel" name="titleLabel"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="styleSheet"> - <string notr="true">QLabel[text="Color Options"] { - font: bold; -}</string> - </property> - <property name="text"> - <string>Color Options</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> <item> <widget class="QCheckBox" name="autoColorScaleCheckBox"> <property name="text"> @@ -100,6 +79,9 @@ <property name="text"> <string>Choose Preset</string> </property> + <property name="autoDefault"> + <bool>false</bool> + </property> </widget> </item> <item> @@ -117,14 +99,60 @@ </item> </layout> </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="closeButton"> + <property name="text"> + <string>Close</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </item> </layout> </widget> <tabstops> <tabstop>autoColorScaleCheckBox</tabstop> + <tabstop>useLogScaleCheckBox</tabstop> <tabstop>minValLineEdit</tabstop> <tabstop>maxValLineEdit</tabstop> <tabstop>presetButton</tabstop> + <tabstop>closeButton</tabstop> </tabstops> <resources/> - <connections/> + <connections> + <connection> + <sender>closeButton</sender> + <signal>clicked()</signal> + <receiver>ColorSelectionDialogClass</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>455</x> + <y>167</y> + </hint> + <hint type="destinationlabel"> + <x>175</x> + <y>189</y> + </hint> + </hints> + </connection> + </connections> </ui> diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h index 0f5f0f7c84efc671d00a0ad6cbff90a6624d3c61..470d074c8bbf6cf287d1c6040f389cacec2f7192 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h @@ -26,6 +26,7 @@ namespace Vates namespace SimpleGui { +class ColorSelectionDialog; class ViewBase; /** @@ -71,6 +72,8 @@ public: /// Default destructor. virtual ~MdViewerWidget(); + /// Add extra menus for standalone mode. + void addMenus(); /** * Connect ParaView's data loader the given action. * @param action the action to connect data loading to @@ -86,6 +89,8 @@ public: protected slots: /// Check for certain updates when an accept is fired. void checkForUpdates(); + /// Pop-up the color options dialog. + void onColorOptions(); /** * Load and render data from the given source. * @param source a ParaView compatible source @@ -100,6 +105,7 @@ protected slots: private: Q_DISABLE_COPY(MdViewerWidget) + ColorSelectionDialog *colorDialog; ///< Holder for the color options dialog ViewBase *currentView; ///< Holder for the current view pqLoadDataReaction *dataLoader; ///< Holder for the load data reaction ViewBase *hiddenView; ///< Holder for the view that is being switched from @@ -112,6 +118,8 @@ private: void checkEnvSetup(); /// Function to create the pqPVApplicationCore object in plugin mode void createAppCoreForPlugin(); + /// Add view specific stuff to a menu. + void createMenus(); /// Disable communication with the proxy tab widget. void removeProxyTabWidgetConnections(); /// Perform first render and final setup for mode buttons. diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.ui b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.ui index 0030495fff9e914eabdb11bf5203979fa12b95d7..d7790a606155dce9ccd8ac981588c335b0fdb61a 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.ui +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.ui @@ -14,6 +14,21 @@ <string>Form</string> </property> <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>1</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>1</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> <item> <layout class="QHBoxLayout" name="horizontalLayout"> <item> @@ -35,9 +50,6 @@ <item> <widget class="Mantid::Vates::SimpleGui::ModeControlWidget" name="modeControlWidget" native="true"/> </item> - <item> - <widget class="Mantid::Vates::SimpleGui::ColorSelectionWidget" name="colorSelectionWidget" native="true"/> - </item> <item> <spacer name="horizontalSpacer_2"> <property name="orientation"> @@ -132,12 +144,6 @@ <header>MantidVatesSimpleGuiQtWidgets/ModeControlWidget.h</header> <container>1</container> </customwidget> - <customwidget> - <class>Mantid::Vates::SimpleGui::ColorSelectionWidget</class> - <extends>QWidget</extends> - <header>MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h</header> - <container>1</container> - </customwidget> <customwidget> <class>Mantid::Vates::SimpleGui::TimeControlWidget</class> <extends>QWidget</extends> diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MultisliceView.ui b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MultisliceView.ui index f9da4663117a9b3b8575e7ac42d15c9b9f9de3c1..939117e73d4c57b1efb0b9922684671a961f1be4 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MultisliceView.ui +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MultisliceView.ui @@ -6,12 +6,12 @@ <rect> <x>0</x> <y>0</y> - <width>930</width> - <height>724</height> + <width>934</width> + <height>652</height> </rect> </property> <property name="sizePolicy"> - <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> @@ -19,11 +19,33 @@ <property name="windowTitle"> <string>MultiSliceView</string> </property> - <layout class="QGridLayout" name="gridLayout"> + <layout class="QGridLayout" name="gridLayout" rowstretch="0,1,1,1" columnstretch="0,1,1,1,0"> + <property name="sizeConstraint"> + <enum>QLayout::SetNoConstraint</enum> + </property> + <property name="margin"> + <number>1</number> + </property> + <property name="spacing"> + <number>1</number> + </property> <item row="0" column="1"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>291</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="2"> <widget class="Mantid::Vates::SimpleGui::AxisInteractor" name="yAxisWidget" native="true"> <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> @@ -31,28 +53,38 @@ <property name="minimumSize"> <size> <width>0</width> - <height>100</height> + <height>0</height> </size> </property> </widget> </item> + <item row="0" column="3"> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>291</width> + <height>20</height> + </size> + </property> + </spacer> + </item> <item row="1" column="0"> - <widget class="Mantid::Vates::SimpleGui::AxisInteractor" name="xAxisWidget" native="true"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> </property> - <property name="minimumSize"> + <property name="sizeHint" stdset="0"> <size> - <width>100</width> - <height>0</height> + <width>20</width> + <height>205</height> </size> </property> - </widget> + </spacer> </item> - <item row="1" column="1"> + <item row="1" column="1" rowspan="3" colspan="3"> <widget class="QFrame" name="renderFrame"> <property name="enabled"> <bool>true</bool> @@ -77,22 +109,77 @@ </property> </widget> </item> - <item row="1" column="2"> + <item row="1" column="4"> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>205</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="0"> + <widget class="Mantid::Vates::SimpleGui::AxisInteractor" name="xAxisWidget" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </widget> + </item> + <item row="2" column="4"> <widget class="Mantid::Vates::SimpleGui::AxisInteractor" name="zAxisWidget" native="true"> <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> - <width>100</width> + <width>0</width> <height>0</height> </size> </property> </widget> </item> + <item row="3" column="0"> + <spacer name="verticalSpacer_4"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>205</height> + </size> + </property> + </spacer> + </item> + <item row="3" column="4"> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>205</height> + </size> + </property> + </spacer> + </item> </layout> </widget> <layoutdefault spacing="6" margin="11"/> diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionDialog.cpp similarity index 91% rename from Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp rename to Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionDialog.cpp index c84267ff58e14e5695c1d8bc7d8832827e4d11ad..2fbb15db620adf84d72f09eb81a03e9578913a4a 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionDialog.cpp @@ -1,4 +1,4 @@ -#include "MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h" +#include "MantidVatesSimpleGuiViewWidgets/ColorSelectionDialog.h" #include <pqChartValue.h> #include <pqColorMapModel.h> @@ -16,7 +16,7 @@ namespace Vates namespace SimpleGui { -ColorSelectionWidget::ColorSelectionWidget(QWidget *parent) : QWidget(parent) +ColorSelectionDialog::ColorSelectionDialog(QWidget *parent) : QDialog(parent) { this->ui.setupUi(this); this->ui.autoColorScaleCheckBox->setChecked(true); @@ -42,7 +42,7 @@ ColorSelectionWidget::ColorSelectionWidget(QWidget *parent) : QWidget(parent) this, SLOT(useLogScaling(int))); } -void ColorSelectionWidget::setEditorStatus(bool status) +void ColorSelectionDialog::setEditorStatus(bool status) { this->ui.maxValLabel->setEnabled(status); this->ui.maxValLineEdit->setEnabled(status); @@ -50,7 +50,7 @@ void ColorSelectionWidget::setEditorStatus(bool status) this->ui.minValLineEdit->setEnabled(status); } -void ColorSelectionWidget::loadBuiltinColorPresets() +void ColorSelectionDialog::loadBuiltinColorPresets() { pqColorMapModel colorMap; pqColorPresetModel *model = this->presets->getModel(); @@ -105,7 +105,7 @@ void ColorSelectionWidget::loadBuiltinColorPresets() model->addBuiltinColorMap(colorMap, "CIELab Blue to Red"); } -void ColorSelectionWidget::autoOrManualScaling(int state) +void ColorSelectionDialog::autoOrManualScaling(int state) { switch (state) { @@ -119,7 +119,7 @@ void ColorSelectionWidget::autoOrManualScaling(int state) } } -void ColorSelectionWidget::loadPreset() +void ColorSelectionDialog::loadPreset() { this->presets->setUsingCloseButton(false); if (this->presets->exec() == QDialog::Accepted) @@ -135,14 +135,14 @@ void ColorSelectionWidget::loadPreset() } } -void ColorSelectionWidget::getColorScaleRange() +void ColorSelectionDialog::getColorScaleRange() { double min = this->ui.minValLineEdit->text().toDouble(); double max = this->ui.maxValLineEdit->text().toDouble(); emit this->colorScaleChanged(min, max); } -void ColorSelectionWidget::setColorScaleRange(double min, double max) +void ColorSelectionDialog::setColorScaleRange(double min, double max) { if (this->ui.autoColorScaleCheckBox->isChecked()) { @@ -157,7 +157,7 @@ void ColorSelectionWidget::setColorScaleRange(double min, double max) } } -void ColorSelectionWidget::useLogScaling(int state) +void ColorSelectionDialog::useLogScaling(int state) { // Qt::Checked is 2, need it to be 1 for boolean true conversion if (Qt::Checked == state) diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp index a1c377db5576559d08b1f34a6ba5897c809c1d5a..d3f002f809598d9c83e6f0ce953dbdcb3bf0b9c7 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp @@ -1,6 +1,7 @@ #include "MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h" #include "MantidVatesSimpleGuiQtWidgets/ModeControlWidget.h" +#include "MantidVatesSimpleGuiViewWidgets/ColorSelectionDialog.h" #include "MantidVatesSimpleGuiViewWidgets/MultisliceView.h" #include "MantidVatesSimpleGuiViewWidgets/SplatterPlotView.h" #include "MantidVatesSimpleGuiViewWidgets/StandardView.h" @@ -55,8 +56,10 @@ #include <pqViewFrameActionsBehavior.h> #include <pqVerifyRequiredPluginBehavior.h> +#include <QAction> #include <QHBoxLayout> #include <QMainWindow> +#include <QMenuBar> #include <QModelIndex> #include <QWidget> @@ -76,6 +79,7 @@ MdViewerWidget::MdViewerWidget() : VatesViewerInterface() { this->isPluginInitialized = false; this->pluginMode = true; + this->colorDialog = NULL; } MdViewerWidget::MdViewerWidget(QWidget *parent) : VatesViewerInterface(parent) @@ -84,6 +88,7 @@ MdViewerWidget::MdViewerWidget(QWidget *parent) : VatesViewerInterface(parent) // We're in the standalone application mode this->isPluginInitialized = false; this->pluginMode = false; + this->colorDialog = NULL; this->setupUiAndConnections(); // FIXME: This doesn't allow a clean split of the classes. I will need // to investigate creating the individual behaviors to see if that @@ -154,6 +159,7 @@ void MdViewerWidget::setupPluginMode() if (!this->isPluginInitialized) { this->setupParaViewBehaviors(); + this->createMenus(); } this->setupMainView(); } @@ -281,23 +287,6 @@ void MdViewerWidget::setParaViewComponentsForView() QObject::connect(this->currentView, SIGNAL(setViewsStatus(bool)), this->ui.modeControlWidget, SLOT(enableViewButtons(bool))); - // Set color selection widget <-> view signals/slots - QObject::connect(this->ui.colorSelectionWidget, - SIGNAL(colorMapChanged(const pqColorMapModel *)), - this->currentView, - SLOT(onColorMapChange(const pqColorMapModel *))); - QObject::connect(this->ui.colorSelectionWidget, - SIGNAL(colorScaleChanged(double, double)), - this->currentView, - SLOT(onColorScaleChange(double, double))); - QObject::connect(this->currentView, SIGNAL(dataRange(double, double)), - this->ui.colorSelectionWidget, - SLOT(setColorScaleRange(double, double))); - QObject::connect(this->ui.colorSelectionWidget, SIGNAL(autoScale()), - this->currentView, SLOT(onAutoScale())); - QObject::connect(this->ui.colorSelectionWidget, SIGNAL(logScale(int)), - this->currentView, SLOT(onLogScale(int))); - // Set animation (time) control widget <-> view signals/slots. QObject::connect(this->currentView, SIGNAL(setAnimationControlState(bool)), @@ -353,8 +342,11 @@ void MdViewerWidget::checkForUpdates() vtkSMDoubleVectorProperty *range = \ vtkSMDoubleVectorProperty::SafeDownCast(\ proxy->GetProperty("ThresholdBetween")); - this->ui.colorSelectionWidget->setColorScaleRange(range->GetElement(0), - range->GetElement(1)); + if (NULL != this->colorDialog) + { + this->colorDialog->setColorScaleRange(range->GetElement(0), + range->GetElement(1)); + } } } @@ -408,6 +400,81 @@ bool MdViewerWidget::eventFilter(QObject *obj, QEvent *ev) return VatesViewerInterface::eventFilter(obj, ev); } +/** + * This function creates the main view widget specific menu items. + */ +void MdViewerWidget::createMenus() +{ + QMenuBar *menubar; + if (this->pluginMode) + { + menubar = new QMenuBar(this); + QSizePolicy policy(QSizePolicy::Preferred, QSizePolicy::Fixed); + menubar->setSizePolicy(policy); + } + else + { + menubar = qobject_cast<QMainWindow *>(this->parentWidget())->menuBar(); + } + + QMenu *viewMenu = menubar->addMenu(QApplication::tr("&View")); + + QAction *colorAction = new QAction(QApplication::tr("&Color Options"), this); + colorAction->setShortcut(QKeySequence::fromString("Ctrl+Shift+C")); + colorAction->setStatusTip(QApplication::tr("Open the color options dialog.")); + QObject::connect(colorAction, SIGNAL(triggered()), + this, SLOT(onColorOptions())); + viewMenu->addAction(colorAction); + + if (this->pluginMode) + { + this->ui.verticalLayout->insertWidget(0, menubar); + } +} + +/** + * This function adds the menus defined here to a QMainWindow menu bar. + * This must be done after the setup of the standalone application so that + * the MdViewerWidget menus aren't added before the standalone ones. + */ +void MdViewerWidget::addMenus() +{ + this->createMenus(); +} + +/** + * This function handles creating the color options dialog box and setting + * the signal and slot comminucation between it and the current view. + */ +void MdViewerWidget::onColorOptions() +{ + if (NULL == this->colorDialog) + { + this->colorDialog = new ColorSelectionDialog(this); + + // Set color selection widget <-> view signals/slots + QObject::connect(this->colorDialog, + SIGNAL(colorMapChanged(const pqColorMapModel *)), + this->currentView, + SLOT(onColorMapChange(const pqColorMapModel *))); + QObject::connect(this->colorDialog, + SIGNAL(colorScaleChanged(double, double)), + this->currentView, + SLOT(onColorScaleChange(double, double))); + QObject::connect(this->currentView, SIGNAL(dataRange(double, double)), + this->colorDialog, + SLOT(setColorScaleRange(double, double))); + QObject::connect(this->colorDialog, SIGNAL(autoScale()), + this->currentView, SLOT(onAutoScale())); + QObject::connect(this->colorDialog, SIGNAL(logScale(int)), + this->currentView, SLOT(onLogScale(int))); + this->currentView->onAutoScale(); + } + this->colorDialog->show(); + this->colorDialog->raise(); + this->colorDialog->activateWindow(); +} + } } } diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp index 68cd0d7f52ccd66c8a8e23e425d5108a3a5c0bc5..a1b17c8e9f0204ced6ccfd4e81926864bfc4be0f 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp @@ -14,6 +14,7 @@ #include <pqServerManagerModel.h> #include <vtkSMDoubleVectorProperty.h> #include <vtkSMPropertyHelper.h> +#include <vtkSMProxy.h> #include <vtkSMSourceProxy.h> #include <QHBoxLayout> @@ -205,8 +206,8 @@ unsigned int ViewBase::getNumSources() sources = smModel->findItems<pqPipelineSource *>(server); for (source = sources.begin(); source != sources.end(); ++source) { - const QString sourceName = (*source)->getSMGroup(); - if (sourceName == QString("sources")) + const QString srcProxyName = (*source)->getProxy()->GetXMLGroup(); + if (srcProxyName == QString("sources")) { count++; } diff --git a/Code/Mantid/instrument/Facilities.xml b/Code/Mantid/instrument/Facilities.xml index 41f1051630abbd870078e5d8053c54752eb3c74e..be4fe7e28874978b2fa959c46b37205ca230f550 100644 --- a/Code/Mantid/instrument/Facilities.xml +++ b/Code/Mantid/instrument/Facilities.xml @@ -211,7 +211,7 @@ <catalog name="ICat3Catalog"> </catalog> - <soapEndPoint url="https://icat.sns.gov:8181/ICATService/ICAT"> + <soapEndPoint url="https://icat.sns.gov:443/ICATService/ICAT"> </soapEndPoint> <instrument name="DAS"> diff --git a/Code/Mantid/scripts/Inelastic/DirectEnergyConversion.py b/Code/Mantid/scripts/Inelastic/DirectEnergyConversion.py index 78b20c9e9174ec8d1806df03504ac352e5781faa..815f0ffd1ec591d659a2252e4f0570d22eebdd2f 100755 --- a/Code/Mantid/scripts/Inelastic/DirectEnergyConversion.py +++ b/Code/Mantid/scripts/Inelastic/DirectEnergyConversion.py @@ -755,4 +755,4 @@ class DirectEnergyConversion(object): if self._log_to_mantid: mtd.sendLogMessage(msg) -#----------------------------------------------------------------- +#----------------------------------------------------------------- \ No newline at end of file diff --git a/Code/Mantid/scripts/Interface/reduction_application.py b/Code/Mantid/scripts/Interface/reduction_application.py index d9014be9b28060429d92cb43ffe90f6d63d1c18b..8820a2709d5eb957005057ac4b1b45f77908457a 100644 --- a/Code/Mantid/scripts/Interface/reduction_application.py +++ b/Code/Mantid/scripts/Interface/reduction_application.py @@ -116,7 +116,7 @@ class ReductionGUI(QtGui.QMainWindow, ui.ui_reduction_main.Ui_SANSReduction): def _progress_updated(self, value): self.progress_bar.setValue(value) - def setup_layout(self): + def setup_layout(self, load_last=False): """ Sets up the instrument-specific part of the UI layout """ @@ -140,6 +140,9 @@ class ReductionGUI(QtGui.QMainWindow, ui.ui_reduction_main.Ui_SANSReduction): self.tabWidget.addTab(tab[1], tab[0]) self._set_window_title() self.progress_bar.hide() + + if load_last: + self._interface.load_last_reduction() else: self.close() @@ -341,6 +344,7 @@ class ReductionGUI(QtGui.QMainWindow, ui.ui_reduction_main.Ui_SANSReduction): self.reduce_button.setEnabled(False) self.export_button.setEnabled(False) self.save_button.setEnabled(False) + self.interface_chk.setEnabled(False) if IS_IN_MANTIDPLOT: qti.app.mantidUI.setIsRunning(True) self._interface.reduce() @@ -349,6 +353,7 @@ class ReductionGUI(QtGui.QMainWindow, ui.ui_reduction_main.Ui_SANSReduction): self.reduce_button.setEnabled(True) self.export_button.setEnabled(True) self.save_button.setEnabled(True) + self.interface_chk.setEnabled(True) def open_file(self, file_path=None): """ @@ -368,9 +373,13 @@ class ReductionGUI(QtGui.QMainWindow, ui.ui_reduction_main.Ui_SANSReduction): self.reduce_button.setEnabled(False) self.export_button.setEnabled(False) + self.save_button.setEnabled(False) + self.interface_chk.setEnabled(False) self._interface.load_file(file_path) self.reduce_button.setEnabled(True) self.export_button.setEnabled(True) + self.save_button.setEnabled(True) + self.interface_chk.setEnabled(True) self._filename = file_path self._update_file_menu() @@ -482,7 +491,7 @@ def start(argv=[]): app.setApplicationName("Mantid Reduction") reducer = ReductionGUI() - reducer.setup_layout() + reducer.setup_layout(load_last=True) reducer.show() app.exec_() diff --git a/Code/Mantid/scripts/Interface/reduction_gui/instruments/interface.py b/Code/Mantid/scripts/Interface/reduction_gui/instruments/interface.py index 1d8f94a975847a14ef88876ff5db27258a4ae246..920f004e26edca846f0b0950fba2ea15d2a464dc 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/instruments/interface.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/instruments/interface.py @@ -15,6 +15,7 @@ class InstrumentInterface(object): ## List of widgets with associated observers widgets = [] ERROR_REPORT_NAME = "sans_error_report.xml" + LAST_REDUCTION_NAME = ".mantid_last_reduction.xml" ERROR_REPORT_DIR = "" def __init__(self, name, settings): @@ -62,7 +63,14 @@ class InstrumentInterface(object): if len(self.widgets)>0: QtGui.QMessageBox.warning(self.widgets[0], title, message) - + def load_last_reduction(self): + try: + red_path = os.path.join(self.ERROR_REPORT_DIR, self.LAST_REDUCTION_NAME) + if os.path.isfile(red_path): + self.load_file(red_path) + except: + print "Could not load last reduction\n %s" % str(traceback.format_exc()) + def load_file(self, file_name): """ Load an XML file containing reduction parameters and @@ -117,8 +125,17 @@ class InstrumentInterface(object): """ self.scripter.update() + # Save the last reduction for later try: + red_path = os.path.join(self.ERROR_REPORT_DIR, self.LAST_REDUCTION_NAME) + self.save_file(red_path) + except: + print "Could not save last reduction\n %s" % str(traceback.format_exc()) + + try: + self.set_running(True) self.scripter.apply() + self.set_running(False) except RuntimeError, e: if self._settings.debug: msg = "Reduction could not be executed:\n\n%s" % unicode(traceback.format_exc()) @@ -137,7 +154,7 @@ class InstrumentInterface(object): self._error_report(traceback.format_exc()) # Update widgets self.scripter.push_state() - + def _error_report(self, trace=''): """ Try to dump the state of the UI to a file, with a traceback @@ -166,6 +183,13 @@ class InstrumentInterface(object): tab_list.append([item.name, item]) return tab_list + def set_running(self, is_running=True): + """ + Tell the widgets whether they are running or not + """ + for widget in self.widgets: + widget.is_running(is_running) + def reset(self): """ Reset the interface diff --git a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/data_cat.py b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/data_cat.py index 48511808c8baf5ca2b12098807890db40a1eab4d..a11e6dbc40054384cb5cf994bf68ebbca99db3f2 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/data_cat.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/data_cat.py @@ -8,6 +8,7 @@ import sqlite3 import re import time import sys +import traceback # Check whether Mantid is available try: @@ -18,13 +19,55 @@ try: except: HAS_MANTID = False +class DataType(object): + TABLE_NAME = "datatype" + + # Data type names + DATA_TYPES = {"FLOOD_FIELD":"Flood Field", + "DARK_CURRENT":"Dark Current", + "TRANS_SAMPLE":"Transmission Sample", + "TRANS_BCK":"Transmission Background", + "TRANS_DIRECT":"Transmission Empty"} + + @classmethod + def create_table(cls, cursor, data_set_table): + cursor.execute("""create table if not exists %s ( + id integer primary key, + type_id integer, + dataset_id integer, + foreign key(dataset_id) references %s(id))""" % (cls.TABLE_NAME, data_set_table)) + + @classmethod + def add(cls, dataset_id, type_id, cursor): + """ + Add a data type entry to the datatype table + """ + if not type_id in cls.DATA_TYPES.keys(): + raise RuntimeError, "DataType got an unknown type ID: %s" % type_id + + t = (type_id, dataset_id,) + cursor.execute("insert into %s(type_id, dataset_id) values (?,?)" % cls.TABLE_NAME, t) + + @classmethod + def get_likely_type(cls, dataset_id, cursor): + t = (dataset_id,) + cursor.execute("select type_id from %s where dataset_id=?" % cls.TABLE_NAME, t) + rows = cursor.fetchall() + if len(rows)>1: + return cls.DATA_TYPES[rows[len(rows)-1][0]] + return None + class DataSet(object): - def __init__(self, run_number, title, run_start, duration, ssd): + TABLE_NAME = "dataset" + data_type_cls = DataType + + def __init__(self, run_number, title, run_start, duration, sdd, id=None): self.run_number = run_number self.title = title self.run_start = run_start self.duration = duration - self.ssd = ssd + self.sdd = sdd + self.id = id @classmethod def header(cls): @@ -55,20 +98,30 @@ class DataSet(object): """ Pretty print the current data set attributes """ - return "%-6s %-60s %-16s %-7g %-10.0f" % (self.run_number, self.title, self.run_start, self.duration, self.ssd) + return "%-6s %-60s %-16s %-7g %-10.0f" % (self.run_number, self.title, self.run_start, self.duration, self.sdd) def as_list(self): """ Return a list of data set attributes """ - return (self.run_number, self.title, self.run_start, self.duration, self.ssd) + return (self.run_number, self.title, self.run_start, self.duration, self.sdd) def as_string_list(self): """ Return a list of data set attributes as strings """ - return (str(self.run_number), self.title, self.run_start, "%-g"%self.duration, "%-10.0f"%self.ssd) + return (str(self.run_number), self.title, self.run_start, "%-g"%self.duration, "%-10.0f"%self.sdd) + @classmethod + def get_data_set_id(cls, run, cursor): + t = (run,) + cursor.execute('select * from %s where run=?'% cls.TABLE_NAME, t) + rows = cursor.fetchall() + if len(rows) == 0: + return -1 + else: + return rows[0][0] + @classmethod def find(cls, file_path, cursor, process_files=True): """ @@ -79,7 +132,7 @@ class DataSet(object): return None t = (run,) - cursor.execute('select * from dataset where run=?', t) + cursor.execute('select * from %s where run=?'% cls.TABLE_NAME, t) rows = cursor.fetchall() if len(rows) == 0: @@ -93,7 +146,23 @@ class DataSet(object): return None else: row = rows[0] - return DataSet(row[0], row[1], row[2], row[3], row[4]) + return DataSet(row[1], row[2], row[3], row[4], row[5], id=row[0]) + + @classmethod + def create_table(cls, cursor): + cursor.execute("""create table if not exists %s ( + id integer primary key, + run text unique, + title text, + start text, + duration real, sdd real)""" % cls.TABLE_NAME) + + cls.data_type_cls.create_table(cursor, cls.TABLE_NAME) + + def insert_in_db(self, cursor): + t = (self.run_number, self.title, self.run_start, self.duration, self.sdd,) + cursor.execute('insert into %s(run, title, start, duration,sdd) values (?,?,?,?,?)'%self.TABLE_NAME, t) + return cursor.lastrowid class DataCatalog(object): """ @@ -102,7 +171,7 @@ class DataCatalog(object): extension = "nxs" data_set_cls = DataSet - def __init__(self, replace_db=False): + def __init__(self, replace_db=True): ## List of data sets self.catalog = [] @@ -123,20 +192,15 @@ class DataCatalog(object): """ Create the database if we need to """ - self.db_exists = False if os.path.isfile(db_path): if replace_db: os.remove(db_path) - else: - self.db_exists = True self.db = sqlite3.connect(db_path) cursor = self.db.cursor() - - if not self.db_exists: - cursor.execute("""create table dataset (run text, title text, start text, duration real, ssd real)""") - self.db.commit() - cursor.close() + self.data_set_cls.create_table(cursor) + self.db.commit() + cursor.close() def __str__(self): """ @@ -173,6 +237,20 @@ class DataCatalog(object): output.append(r.as_string_list()) return output + def add_type(self, run, type): + if self.db is None: + if HAS_MANTID: + mtd.sendLogMessage("DataCatalog: Could not access local data catalog") + return + + c = self.db.cursor() + id = self.data_set_cls.get_data_set_id(run, c) + if id>0: + self.data_set_cls.data_type_cls.add(id, type, c) + + self.db.commit() + c.close() + def list_data_sets(self, data_dir=None, call_back=None, process_files=True): """ Process a data directory @@ -196,15 +274,16 @@ class DataCatalog(object): d = self.data_set_cls.find(path, c, process_files=process_files) if d is not None: if call_back is not None: - call_back(d.as_string_list()) + attr_list = d.as_string_list() + type_id = self.data_set_cls.data_type_cls.get_likely_type(d.id, c) + attr_list += (type_id,) + call_back(attr_list) self.catalog.append(d) self.db.commit() c.close() except: if HAS_MANTID: - mtd.sendLogMessage("DataCatalog: Error working with the local data catalog\n%s" % sys.exc_value) + mtd.sendLogMessage("DataCatalog: Error working with the local data catalog\n%s" % str(traceback.format_exc())) else: - raise - - self.db_exists = True \ No newline at end of file + raise \ No newline at end of file diff --git a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/eqsans_catalog.py b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/eqsans_catalog.py index 20792ed70b09889d7047a608e6dea286fc8944b1..f86b4db6d837195e07a1d6d67ec32381426e5194 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/eqsans_catalog.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/eqsans_catalog.py @@ -2,7 +2,8 @@ Data catalog for EQSANS """ from reduction_gui.reduction.sans.data_cat import DataCatalog as BaseCatalog -from reduction_gui.reduction.sans.data_cat import DataSet as BaseDataSet +from reduction_gui.reduction.sans.data_cat import DataSet +from data_cat import DataType import re import time @@ -15,29 +16,41 @@ try: except: HAS_MANTID = False -class EQSANSDataSet(BaseDataSet): - def __init__(self, run_number, title, run_start, duration, ssd): - super(EQSANSDataSet, self).__init__(run_number, title, run_start, duration, ssd) +class EQSANSDataType(DataType): + TABLE_NAME="eqsans_datatype" + +class EQSANSDataSet(DataSet): + TABLE_NAME="eqsans_dataset" + data_type_cls = EQSANSDataType + + def __init__(self, run_number, title, run_start, duration, sdd): + super(EQSANSDataSet, self).__init__(run_number, title, run_start, duration, sdd) @classmethod def load_meta_data(cls, file_path, outputWorkspace): - if HAS_MANTID: - try: - mantidsimple.LoadEventNexus(file_path, OutputWorkspace=outputWorkspace, MetaDataOnly=True) - return True - except: - return False + try: + mantidsimple.LoadEventNexus(file_path, OutputWorkspace=outputWorkspace, MetaDataOnly=True) + return True + except: + return False @classmethod def handle(cls, file_path): """ Return a DB handle for the given file, such as a run number """ + file_path = file_path.strip() r_re = re.search("EQSANS_([0-9]+)_event", file_path) - if r_re is None: - return None - - return r_re.group(1) + if r_re is not None: + return r_re.group(1) + else: + # Check whether we simply have a run number + try: + run = int(file_path) + return file_path + except: + return None + return None @classmethod def read_properties(cls, ws, run, cursor): @@ -68,10 +81,10 @@ class EQSANSDataSet(BaseDataSet): duration = 0 sdd = read_series("detectorZ") - - t = (runno, title, run_start, duration, sdd) - cursor.execute('insert into dataset values (?,?,?,?,?)', t) - return EQSANSDataSet(runno, title, run_start, duration, sdd) + + d = EQSANSDataSet(runno, title, run_start, duration, sdd) + d.insert_in_db(cursor) + return d class DataCatalog(BaseCatalog): diff --git a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/hfir_catalog.py b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/hfir_catalog.py index ee2b75ed36ec03eeaccbf231f42c1d7bb42ae367..525cec75ed2c4a9d230220a2ad29e02b3b8329ad 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/hfir_catalog.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/hfir_catalog.py @@ -2,7 +2,8 @@ Data catalog for HFIR SANS """ from data_cat import DataCatalog as BaseCatalog -from data_cat import DataSet as BaseDataSet +from data_cat import DataSet +from data_cat import DataType import os import time @@ -15,9 +16,15 @@ try: except: HAS_MANTID = False -class HFIRDataSet(BaseDataSet): - def __init__(self, run_number, title, run_start, duration, ssd): - super(HFIRDataSet, self).__init__(run_number, title, run_start, duration, ssd) +class HFIRDataType(DataType): + TABLE_NAME="hfir_datatype" + +class HFIRDataSet(DataSet): + TABLE_NAME="hfir_dataset" + data_type_cls = HFIRDataType + + def __init__(self, run_number, title, run_start, duration, sdd): + super(HFIRDataSet, self).__init__(run_number, title, run_start, duration, sdd) @classmethod def load_meta_data(cls, file_path, outputWorkspace): @@ -26,8 +33,6 @@ class HFIRDataSet(BaseDataSet): return True except: return False - import sys - print sys.exc_value @classmethod def handle(cls, file_path): @@ -65,9 +70,9 @@ class HFIRDataSet(BaseDataSet): sdd = float(read_prop("sample-detector-distance")) - t = (run, title, run_start, duration, sdd) - cursor.execute('insert into dataset values (?,?,?,?,?)', t) - return HFIRDataSet(run, title, run_start, duration, sdd) + d = HFIRDataSet(run, title, run_start, duration, sdd) + d.insert_in_db(cursor) + return d class DataCatalog(BaseCatalog): diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/base_widget.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/base_widget.py index b23aeecbd2f7dc0fe1bb4677f58906e8408f1325..6dc4d5147ef654b05689a62d18875ba688da99b0 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/base_widget.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/base_widget.py @@ -62,6 +62,14 @@ class BaseWidget(QtGui.QWidget): self._data_proxy = data_proxy self._in_mantidplot = IS_IN_MANTIDPLOT and self._data_proxy is not None + self._is_running = True + + def is_running(self, is_running): + """ + Change running state + """ + self._is_running = is_running + def initialize_content(self): """ Declare the validators and event connections for the diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/eqsans_data.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/eqsans_data.py index e786536c226a0500be0efbdf1929ed184edf7e12..a0833c26c89171f97c547e540c9b268a5b82ecfe 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/eqsans_data.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/eqsans_data.py @@ -6,8 +6,6 @@ from reduction_gui.settings.application_settings import GeneralSettings from reduction_gui.widgets.base_widget import BaseWidget import ui.sans.ui_eqsans_sample_data -from hfir_sample_data import DirectBeam - class DataSetsWidget(BaseWidget): """ Widget that presents the transmission options to the user @@ -260,6 +258,10 @@ class DataSetsWidget(BaseWidget): d.sample_file = unicode(self._content.bck_sample_edit.text()) d.direct_beam = unicode(self._content.bck_empty_edit.text()) + self._settings.emit_key_value("TRANS_SAMPLE", QtCore.QString(str(self._content.sample_edit.text()))) + self._settings.emit_key_value("TRANS_DIRECT", QtCore.QString(str(self._content.empty_edit.text()))) + self._settings.emit_key_value("TRANS_BCK", QtCore.QString(str(self._content.bck_sample_edit.text()))) + self._settings.emit_key_value("TRANS_DIRECT", QtCore.QString(str(self._content.bck_empty_edit.text()))) return m def _background_clicked(self, is_checked): diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/eqsans_instrument.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/eqsans_instrument.py index e35c9eaa5afeb116475291beeab223de254925dc..6d26fc8a1ad495b3dfffd864c0a3f0b963c84969 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/eqsans_instrument.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/eqsans_instrument.py @@ -458,6 +458,7 @@ class SANSInstrumentWidget(BaseWidget): m.use_data_directory = self._summary.use_data_dir_radio.isChecked() m.output_directory = str(self._summary.output_dir_edit.text()) + self._settings.emit_key_value("DARK_CURRENT", QtCore.QString(str(self._summary.dark_file_edit.text()))) return m def _show_help(self): diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_detector.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_detector.py index 8733e8b16815cb8b1f33cd6f0c98d638684c2c5e..45d0f12a97c3e06cb534a88773b71e5db3f39a02 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_detector.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_detector.py @@ -203,6 +203,8 @@ class DetectorWidget(BaseWidget): m.flood_use_finder = self._content.use_beam_finder_checkbox_2.isChecked() m.flood_beam_file = unicode(self._content.beam_data_file_edit_2.text()) m.flood_use_direct_beam = self._content.direct_beam_2.isChecked() + + self._settings.emit_key_value("FLOOD_FIELD", QtCore.QString(str(self._content.sensitivity_file_edit.text()))) return m def _use_sample_center_changed(self, is_checked): diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_instrument.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_instrument.py index 745201494b2d789ce241223380f37cb293884e50..284bb998373d85fc9d2473a85fbdb044bd52a304 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_instrument.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_instrument.py @@ -413,4 +413,5 @@ class SANSInstrumentWidget(BaseWidget): ids_str = masked_detectors.getPropertyValue("DetectorList") m.detector_ids = map(int, ids_str.split(',')) - return m + self._settings.emit_key_value("DARK_CURRENT", QtCore.QString(str(self._summary.dark_file_edit.text()))) + return m \ No newline at end of file diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_sample_data.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_sample_data.py index bac5de474a7f8559ad681d0389ec551703c22812..dd99d098c30d38cab3f4b5a215ac8c072ed70026 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_sample_data.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_sample_data.py @@ -72,6 +72,8 @@ class DirectBeam(BaseWidget): m.beam_radius = util._check_and_get_float_line_edit(self._content.beam_radius_edit) m.sample_file = unicode(self._content.sample_edit.text()) m.direct_beam = unicode(self._content.direct_edit.text()) + self._settings.emit_key_value("TRANS_SAMPLE", QtCore.QString(str(self._content.sample_edit.text()))) + self._settings.emit_key_value("TRANS_DIRECT", QtCore.QString(str(self._content.direct_edit.text()))) return m def _sample_browse(self): diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/sans_catalog.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/sans_catalog.py index e7fb9ce75b56a468769c8bebf77919653a4cba1f..dba9496fd80c073871e6161c36109fe65877bdc7 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/sans_catalog.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/sans_catalog.py @@ -11,6 +11,7 @@ try: mtd.initialise(False) from mantidsimple import * IS_IN_MANTIDPLOT = True + from reduction.find_data import find_data except: pass @@ -25,6 +26,7 @@ class SANSCatalogWidget(BaseWidget): """ ## Widget name name = "Data Catalog" + _current_run = None def __init__(self, parent=None, state=None, settings=None, catalog_cls=None): super(SANSCatalogWidget, self).__init__(parent, state, settings) @@ -45,6 +47,9 @@ class SANSCatalogWidget(BaseWidget): settings = GeneralSettings() self._settings = settings + # Connect do UI data update + self._settings.data_updated.connect(self._data_updated) + def initialize_content(self): self.connect(self._content.refresh_button, QtCore.SIGNAL("clicked()"), self._update_content) self.connect(self._content.browse_button, QtCore.SIGNAL("clicked()"), self._browse_directory) @@ -52,12 +57,43 @@ class SANSCatalogWidget(BaseWidget): self._content.directory_edit.setText(self._settings.data_path) self._update_content(False) + def is_running(self, is_running): + """ + Enable/disable controls depending on whether a reduction is running or not + @param is_running: True if a reduction is running + """ + super(SANSCatalogWidget, self).is_running(is_running) + self._content.refresh_button.setEnabled(not is_running) + self._content.browse_button.setEnabled(not is_running) + self._content.directory_edit.setEnabled(not is_running) + + def _data_updated(self, key, value): + """ + Respond to application-level key/value pair updates. + @param key: key string + @param value: value string + """ + try: + if key == "sample_run": + self._current_run = self._catalog_cls.data_set_cls.handle(str(value)) + elif key in self._catalog_cls.data_set_cls.data_type_cls.DATA_TYPES.keys(): + run = self._catalog_cls.data_set_cls.handle(str(value)) + if self._catalog_cls is not None and run is not None: + #TODO: At some point we want to tie the type to a given sample run too + self._catalog_cls().add_type(run, key) + except: + if IS_IN_MANTIDPLOT: + mtd.sendLogMessage("SANSCatalogWidget: Could not access local data catalog") + else: + print "SANSCatalogWidget: Could not access local data catalog" + + def _update_content(self, process_files=True): self._settings.data_path = str(self._content.directory_edit.text()) self._content.data_set_table.clear() self._content.data_set_table.setSortingEnabled(False) self._content.data_set_table.setRowCount(0) - headers = ["Run", "Title", "Start", "Time[s]", "SDD[mm]"] + headers = ["Run", "Title", "Start", "Time[s]", "SDD[mm]", "Comment"] self._content.data_set_table.setColumnCount(len(headers)) self._content.data_set_table.setHorizontalHeaderLabels(headers) @@ -66,10 +102,11 @@ class SANSCatalogWidget(BaseWidget): def _add_item(data): row = dc.size() self._content.data_set_table.insertRow(row) - for i in range(5): - item = QtGui.QTableWidgetItem(str(data[i])) - item.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) - self._content.data_set_table.setItem(row, i, item) + for i in range(len(data)): + if data[i] is not None: + item = QtGui.QTableWidgetItem(str(data[i])) + item.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) + self._content.data_set_table.setItem(row, i, item) dc.list_data_sets(self._settings.data_path, call_back=_add_item, process_files=process_files) @@ -85,15 +122,16 @@ class SANSCatalogWidget(BaseWidget): self._content.data_set_table.clear() self._content.data_set_table.setSortingEnabled(False) self._content.data_set_table.setRowCount(len(rows)) - headers = ["Run", "Title", "Start", "Time[s]", "SDD[mm]"] + headers = ["Run", "Title", "Start", "Time[s]", "SDD[mm]", "Comment"] self._content.data_set_table.setColumnCount(len(headers)) self._content.data_set_table.setHorizontalHeaderLabels(headers) for row, data in enumerate(rows): - for i in range(5): - item = QtGui.QTableWidgetItem(str(data[i])) - item.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) - self._content.data_set_table.setItem(row, i, item) + for i in range(len(data)): + if data[i] is not None: + item = QtGui.QTableWidgetItem(str(data[i])) + item.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) + self._content.data_set_table.setItem(row, i, item) self._content.data_set_table.setSortingEnabled(True) self._content.data_set_table.resizeColumnsToContents() diff --git a/Code/Mantid/scripts/LargeScaleStructures/ScalingFactorCalculation/DataTransformation.py b/Code/Mantid/scripts/LargeScaleStructures/ScalingFactorCalculation/DataTransformation.py index 13265a39935e5af07fad12b8651c1a4b22865d28..86d1c0199c7bd529563a593af469c83ecfb414a4 100644 --- a/Code/Mantid/scripts/LargeScaleStructures/ScalingFactorCalculation/DataTransformation.py +++ b/Code/Mantid/scripts/LargeScaleStructures/ScalingFactorCalculation/DataTransformation.py @@ -45,11 +45,13 @@ class Setup: y_axis_ratio = None y_axis_error_ratio = None x_axis_ratio = None - + #fitting parameters y=a+b*x a = None b = None - + error_a = None + error_b = None + def __init__(self): self.x_axis_ratio = None self.y_axis_ratio = None @@ -165,10 +167,13 @@ class Setup: res = mtd['Res_Parameters'] self.a = res.getDouble("Value",0) self.b = res.getDouble("Value",1) - + self.error_a = res.getDouble("Error",0) + self.error_b = res.getDouble("Error",1) + class CalculateAD(Setup): - id_numerator = None #ex: AiD0 + #name of numerators and denominators + id_numerator = None #ex: AiD0 id_denominator = None #ex: AiD1 _y_axis_numerator = None @@ -275,7 +280,6 @@ class CalculateAD(Setup): rebin(InputWorkspace='EventDataWks', OutputWorkspace='HistoDataWks', Params=self.rebin_parameters) - #mtd.deleteWorkspace('EventDataWks') mt2 = mtd['HistoDataWks'] _x_axis = mt2.readX(0)[:] self._x_axis = _x_axis @@ -286,27 +290,29 @@ class CalculateAD(Setup): from_pixel=self.x_pixel_min, to_pixel=self.x_pixel_max) - #mtd.deleteWorkspace('HistoDataWks') Transpose(InputWorkspace='IntegratedDataWks', OutputWorkspace='TransposeIntegratedDataWks') - #mtd.deleteWorkspace('IntegratedDataWks') ConvertToHistogram(InputWorkspace='TransposeIntegratedDataWks', OutputWorkspace='TransposeIntegratedDataWks_t') - #mtd.deleteWorkspace('TransposeIntegratedDataWks') FlatBackground(InputWorkspace='TransposeIntegratedDataWks_t', OutputWorkspace='TransposeHistoFlatDataWks', StartX=self.back_pixel_min, EndX=self.peak_pixel_min) - #mtd.deleteWorkspace('TransposeIntegratedDataWks_t') Transpose(InputWorkspace='TransposeHistoFlatDataWks', OutputWorkspace='DataWks') - #mtd.deleteWorkspace('TransposeHistoFlatDataWks') mt3 = mtd['DataWks'] self._calculateFinalAxis(Workspace=mt3, bNumerator=bNumerator) - #mtd.deleteWorkspace('DataWks') - - + + #cleanup workspaces +# mtd.deleteWorkspace('EventDataWks') +# mtd.deleteWorkspace('HistoDataWks') +# mtd.deleteWorkspace('IntegratedDataWks') +# mtd.deleteWorkspace('TransposeIntegratedDataWks') +# mtd.deleteWorkspace('TransposeIntegratedDataWks_t') +# mtd.deleteWorkspace('TransposeHistoFlatDataWks') +# mtd.deleteWorkspace('DataWks') + def _calculateFinalAxis(self, Workspace=None, bNumerator=None): """ this calculates the final y_axis and y_axis_error of numerator and denominator @@ -402,8 +408,8 @@ def plotObject(instance): return - print 'a: ' + str(instance.a) - print 'b: ' + str(instance.b) + print 'a: ' + str(instance.a[-1]) + print 'b: ' + str(instance.b[-1]) figure() errorbar(instance.x_axis_ratio, @@ -419,45 +425,93 @@ def plotObject(instance): title(instance.id_numerator + '/' + instance.id_denominator) show() +def record_settings(a,b,error_a,error_b,name,instance): + """ + This function will record the various fitting parameters and the + name of the ratio + """ + a.append(instance.a) + b.append(instance.b) + error_a.append(instance.error_a) + error_b.append(instance.error_b) + name.append(instance.id_numerator + '/' + instance.id_denominator) + +def outputFittingParameters(a,b,a_error,b_error,name,output_file_name): + """ + Create an ascii file of the various fittings parameters + y=a+bx + 1st column: name of numerator/denominator + 2nd column: a + 3rd column: b + 4th column: error_a + 5th column: error_b + """ + _content = ['#y=a+bx\n','#numerator/denominator a b error_a error_b\n','#\n'] + sz = len(a) + for i in range(sz): + _line = name[i] + ' ' + _line += str(a[i]) + ' ' + _line += str(b[i]) + ' ' + _line += str(error_a[i]) + ' ' + _line += str(error_b[i]) + '\n' + _content.append(_line) + + f = open(output_file_name, 'w') + f.writelines(_content) + f.close() if __name__ == '__main__': # t_start = time.time() + #initialize record fitting parameters arrays + a=[] + b=[] + error_a=[] + error_b=[] + name=[] + cal_D1 = CalculateAD(id_numerator='AiD1', id_denominator='AiD0') cal_D1.run() cal_D1.fit() + record_settings(a,b,error_a,error_b,name,cal_D1) plotObject(cal_D1) cal_D2 = CalculateAD(id_numerator='AiD2', id_denominator='AiD0') cal_D2.run() cal_D2.fit() + record_settings(a,b,error_a,error_b,name,cal_D2) plotObject(cal_D2) cal_D3 = CalculateAD(id_numerator='AiD3', id_denominator='AiD0') cal_D3.run() cal_D3.fit() + record_settings(a,b,error_a,error_b,name,cal_D3) plotObject(cal_D3) cal_D4 = CalculateAD(id_numerator='AiD4', id_denominator='AiD0') cal_D4.run() cal_D4.fit() + record_settings(a,b,error_a,error_b,name,cal_D4) plotObject(cal_D4) cal_D5 = CalculateAD(id_numerator='AiD5', id_denominator='AiD0') cal_D5.run() cal_D5.fit() + record_settings(a,b,error_a,error_b,name,cal_D5) plotObject(cal_D5) cal_D6 = CalculateAD(id_numerator='AiiAiD6', id_denominator='AiiAiD5') cal_D6.run() cal_D6.fit() + record_settings(a,b,error_a,error_b,name,cal_D6) plotObject(cal_D6) cal_D6 = CalculateAD(id_numerator='AiiAiD6', id_denominator='AiiAiD5') cal_D6.run() product_D6 = cal_D6 * cal_D5 product_D6.fit() + record_settings(a,b,error_a,error_b,name,product_D6) plotObject(product_D6) cal_D7 = CalculateAD(id_numerator='AiiAiD7', id_denominator='AiiAiD5') @@ -465,6 +519,7 @@ if __name__ == '__main__': cal_D7.run() product_D7 = cal_D7 * cal_D5 product_D7.fit() + record_settings(a,b,error_a,error_b,name,product_D7) plotObject(product_D7) cal_D8 = CalculateAD(id_numerator='AiiiAiiAiD8', id_denominator='AiiiAiiAiD7') @@ -473,6 +528,7 @@ if __name__ == '__main__': cal_D8.run() product_D8 = cal_D8 * product_D7 product_D8.fit() + record_settings(a,b,error_a,error_b,name,product_D8) plotObject(product_D8) cal_D9 = CalculateAD(id_numerator='AivAiiiAiiAiD9', id_denominator='AivAiiiAiiAiD8') @@ -481,8 +537,13 @@ if __name__ == '__main__': cal_D9.run() product_D9 = cal_D9 * product_D8 product_D9.fit() + record_settings(a,b,error_a,error_b,name,product_D9) plotObject(product_D9) + #output the fitting parameters in an ascii + output_file_name = '/home/j35/Desktop/SFcalculator.txt' + outputFittingParameters(a,b,error_a,error_b,name,output_file_name) + # t_end = time.time() # print 'Time to run the process: %0.1f s' % (t_end-t_start) diff --git a/Code/Mantid/scripts/ORNL_SANS.py b/Code/Mantid/scripts/ORNL_SANS.py index ee07261d15825cc81e56a6d0978366aee9aeb214..415acec0389c0194fde0c38c5feeec74513204f7 100644 --- a/Code/Mantid/scripts/ORNL_SANS.py +++ b/Code/Mantid/scripts/ORNL_SANS.py @@ -6,5 +6,5 @@ from Interface.reduction_application import ReductionGUI from PyQt4 import QtCore, uic reducer = ReductionGUI(instrument_list=["BIOSANS", "GPSANS", "EQSANS"]) -reducer.setup_layout() +reducer.setup_layout(load_last=True) reducer.show() \ No newline at end of file diff --git a/Code/Mantid/scripts/SANS/isis_reduction_steps.py b/Code/Mantid/scripts/SANS/isis_reduction_steps.py index 24adfd32d34a26f596c55079f0aaaa46c167776e..68c57adb1b6d036b14c5dbbb204b064bd23ffcf3 100644 --- a/Code/Mantid/scripts/SANS/isis_reduction_steps.py +++ b/Code/Mantid/scripts/SANS/isis_reduction_steps.py @@ -1617,7 +1617,8 @@ class UserFile(ReductionStep): if len(limits) != 2: _issueWarning("Badly formed L/Q/RCUT line") else: - reducer.to_Q.r_cut = float(limits[1]) + # When read from user file the unit is in mm but stored here it units of meters + reducer.to_Q.r_cut = float(limits[1]) / 1000.0 return if limits.upper().startswith('Q/WCUT'): limits = limits.upper().split('WCUT') diff --git a/Code/Mantid/scripts/reduction/instruments/sans/sans_reduction_steps.py b/Code/Mantid/scripts/reduction/instruments/sans/sans_reduction_steps.py index 93ee55a548b17c584d7335847352c44b4adeef15..f3b1b8416f4b6fd01d93e95d8f1cb0fd59843eeb 100644 --- a/Code/Mantid/scripts/reduction/instruments/sans/sans_reduction_steps.py +++ b/Code/Mantid/scripts/reduction/instruments/sans/sans_reduction_steps.py @@ -1036,7 +1036,7 @@ class ConvertToQ(ReductionStep): self.binning = None #if set to true the normalization is done out side of the convert to Q algorithm self.prenorm = False - #The minimum distance in metres from the beam center at which all wavelengths are used in the calculation in mm + #The minimum distance in metres from the beam center at which all wavelengths are used in the calculation self.r_cut = 0.0 #The shortest wavelength in angstrom at which counts should be summed from all detector pixels in Angstrom self.w_cut = 0.0 @@ -1098,10 +1098,10 @@ class ConvertToQ(ReductionStep): try: if self._Q_alg == 'Q1D': - Q1D(workspace, workspace, OutputBinning=self.binning, WavelengthAdj=wave_adj, PixelAdj=pixel_adj, AccountForGravity=self._use_gravity, RadiusCut=self.r_cut/1000., WaveCut=self.w_cut) + Q1D(workspace, workspace, OutputBinning=self.binning, WavelengthAdj=wave_adj, PixelAdj=pixel_adj, AccountForGravity=self._use_gravity, RadiusCut=self.r_cut*1000.0, WaveCut=self.w_cut) elif self._Q_alg == 'Qxy': - Qxy(workspace, workspace, reducer.QXY2, reducer.DQXY, WavelengthAdj=wave_adj, PixelAdj=pixel_adj, AccountForGravity=self._use_gravity, RadiusCut=self.r_cut/1000., WaveCut=self.w_cut) + Qxy(workspace, workspace, reducer.QXY2, reducer.DQXY, WavelengthAdj=wave_adj, PixelAdj=pixel_adj, AccountForGravity=self._use_gravity, RadiusCut=self.r_cut*1000.0, WaveCut=self.w_cut) ReplaceSpecialValues(workspace, workspace, NaNValue="0", InfinityValue="0") else: raise NotImplementedError('The type of Q reduction has not been set, e.g. 1D or 2D') diff --git a/Code/Tools/TestViewer/test_info.py b/Code/Tools/TestViewer/test_info.py index 4849d6ca393deb701ac04e7d0d2896f996853c01..8dbc09297047baa20c5a815e20a1d0a4a8ad506d 100644 --- a/Code/Tools/TestViewer/test_info.py +++ b/Code/Tools/TestViewer/test_info.py @@ -1059,7 +1059,7 @@ class MultipleProjects(object): dirList=os.listdir(path) for fname in dirList: # Look for executables ending in Test - if fname.endswith("Test") and os.path.isfile(fname): + if (fname.endswith("Test") or fname.endswith("Test.py")) and os.path.isfile( os.path.join(path, fname) ): testnames.add(fname) # Now add the known tests, in case they were deleted diff --git a/Test/AutoTestData/regionofinterest.xml b/Test/AutoTestData/regionofinterest.xml new file mode 100644 index 0000000000000000000000000000000000000000..e54275eb3ac33b2e0082190c81b590383968b33f --- /dev/null +++ b/Test/AutoTestData/regionofinterest.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<detector-masking default="notuse"> + <group type="use"> + <detids>1,2,17,32</detids> + <component>bank123</component> + <component>bank124</component> + </group> +</detector-masking> diff --git a/Test/AutoTestData/testmasking.xml b/Test/AutoTestData/testmasking.xml new file mode 100644 index 0000000000000000000000000000000000000000..530e5417186ee3807856c7c3cffc32852b7b3486 --- /dev/null +++ b/Test/AutoTestData/testmasking.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<detector-masking default="use"> + <group type="notuse"> + <detids>1,2,17,32</detids> + <component>bank123</component> + <component>bank124</component> + </group> +</detector-masking>