diff --git a/Code/Mantid/Build/CMake/CommonSetup.cmake b/Code/Mantid/Build/CMake/CommonSetup.cmake index 10625001e3b6c574ece4d422177e8ab415847cd6..d0876357e91013655141b556ee9626d421b026fb 100644 --- a/Code/Mantid/Build/CMake/CommonSetup.cmake +++ b/Code/Mantid/Build/CMake/CommonSetup.cmake @@ -41,7 +41,7 @@ set ( TESTING_TIMEOUT 300 CACHE INTEGER "Timeout in seconds for each test (default 300=5minutes)") ########################################################################### -# Look for dependencies - bail out if any not found +# Look for dependencies ########################################################################### set ( Boost_NO_BOOST_CMAKE TRUE ) @@ -60,6 +60,7 @@ include_directories ( SYSTEM ${NEXUS_INCLUDE_DIR} ) find_package ( MuParser REQUIRED ) find_package ( JsonCPP REQUIRED ) +include_directories ( SYSTEM ${JSONCPP_INCLUDE_DIR} ) find_package ( Doxygen ) # optional @@ -71,6 +72,14 @@ set ( CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH}/zlib123 ) find_package ( ZLIB REQUIRED ) set ( CMAKE_INCLUDE_PATH ${MAIN_CMAKE_INCLUDE_PATH} ) +if (${CMAKE_SYSTEM_NAME} MATCHES "Windows" OR (APPLE AND OSX_VERSION VERSION_LESS 10.9)) + set (HDF5_DIR "${CMAKE_MODULE_PATH}") + find_package ( HDF5 COMPONENTS HL REQUIRED + CONFIGS hdf5-config.cmake ) +else() + find_package ( HDF5 COMPONENTS HL REQUIRED ) +endif() + find_package ( PythonInterp ) if ( MSVC ) diff --git a/Code/Mantid/Build/CMake/DarwinSetup.cmake b/Code/Mantid/Build/CMake/DarwinSetup.cmake index 59a5d0a6be297522f7d09136794fca5063164dc0..9821a44e261db29f3f377f2ce4d3605e8630ae08 100644 --- a/Code/Mantid/Build/CMake/DarwinSetup.cmake +++ b/Code/Mantid/Build/CMake/DarwinSetup.cmake @@ -80,7 +80,7 @@ endif () # Force 64-bit compiler as that's all we support ########################################################################### -set ( CLANG_WARNINGS "-Wall -Wextra -Winit-self -Wpointer-arith -Wcast-qual -fno-common -Wno-deprecated-register") +set ( CLANG_WARNINGS "-Wall -Wextra -pedantic -Winit-self -Wpointer-arith -Wcast-qual -fno-common -Wno-deprecated-register") set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64 ${CLANG_WARNINGS}" ) set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64 -std=c++0x" ) diff --git a/Code/Mantid/Build/CMake/FindJsonCPP.cmake b/Code/Mantid/Build/CMake/FindJsonCPP.cmake index 947dda4c29f66a2347888a9e49437e84a267dece..a28f35fd333419710e6fd43c98b8c88ac28fbacb 100644 --- a/Code/Mantid/Build/CMake/FindJsonCPP.cmake +++ b/Code/Mantid/Build/CMake/FindJsonCPP.cmake @@ -10,7 +10,8 @@ # JSONCPP_LIBRARIES - All required libraries, including the configuration type # Headers -find_path ( JSONCPP_INCLUDE_DIR jsoncpp/json/json.h ) +find_path ( JSONCPP_INCLUDE_DIR json/reader.h + PATH_SUFFIXES jsoncpp ) # Libraries find_library ( JSONCPP_LIBRARY NAMES jsoncpp ) # optimized diff --git a/Code/Mantid/Build/CMake/FindOpenCascade.cmake b/Code/Mantid/Build/CMake/FindOpenCascade.cmake index ed88d20d029c4108eb220b3208fb46a643592f5e..4a32f023d327ce7a4958c2581a073373e1a79d40 100644 --- a/Code/Mantid/Build/CMake/FindOpenCascade.cmake +++ b/Code/Mantid/Build/CMake/FindOpenCascade.cmake @@ -18,50 +18,61 @@ if ( WIN32 ) add_definitions ( -DWNT ) endif ( WIN32 ) -set ( OC_REDHAT_RPM /opt/OpenCASCADE/lib64 ) +find_path ( OPENCASCADE_LIBRARY_DIR libTKernel.so PATHS + /opt/OpenCASCADE/lib64 + $ENV{CASROOT}/lib64 + /opt/OpenCASCADE/lib + $ENV{CASROOT}/lib + /opt/OpenCASCADE/lib32 + $ENV{CASROOT}/lib32 +) + find_library ( OPENCASCADE_LIB_TKERNEL NAMES TKernel - PATHS ${OC_REDHAT_RPM} + PATHS ${OPENCASCADE_LIBRARY_DIR} ) find_library ( OPENCASCADE_LIB_TKBO NAMES TKBO - PATHS ${OC_REDHAT_RPM} + PATHS ${OPENCASCADE_LIBRARY_DIR} ) find_library ( OPENCASCADE_LIB_TKPRIM NAMES TKPrim - PATHS ${OC_REDHAT_RPM} + PATHS ${OPENCASCADE_LIBRARY_DIR} ) find_library ( OPENCASCADE_LIB_TKMESH NAMES TKMesh - PATHS ${OC_REDHAT_RPM} + PATHS ${OPENCASCADE_LIBRARY_DIR} ) find_library ( OPENCASCADE_LIB_TKBREP NAMES TKBRep - PATHS ${OC_REDHAT_RPM} + PATHS ${OPENCASCADE_LIBRARY_DIR} ) find_library ( OPENCASCADE_LIB_TKTOPALGO NAMES TKTopAlgo - PATHS ${OC_REDHAT_RPM} + PATHS ${OPENCASCADE_LIBRARY_DIR} ) find_library ( OPENCASCADE_LIB_TKMATH NAMES TKMath - PATHS ${OC_REDHAT_RPM} + PATHS ${OPENCASCADE_LIBRARY_DIR} ) find_library ( OPENCASCADE_LIB_TKG2D NAMES TKG2d - PATHS ${OC_REDHAT_RPM} + PATHS ${OPENCASCADE_LIBRARY_DIR} ) find_library ( OPENCASCADE_LIB_TKG3D NAMES TKG3d + PATHS ${OPENCASCADE_LIBRARY_DIR} ) find_library ( OPENCASCADE_LIB_TKGEOMBASE NAMES TKGeomBase + PATHS ${OPENCASCADE_LIBRARY_DIR} ) find_library ( OPENCASCADE_LIB_TKGEOMALGO NAMES TKGeomAlgo + PATHS ${OPENCASCADE_LIBRARY_DIR} ) set ( OPENCASCADE_LIBRARIES @@ -83,7 +94,7 @@ set ( OPENCASCADE_LIBRARIES include ( FindPackageHandleStandardArgs ) find_package_handle_standard_args( OpenCascade DEFAULT_MSG OPENCASCADE_LIBRARIES OPENCASCADE_INCLUDE_DIR ) -mark_as_advanced ( OPENCASCADE_INCLUDE_DIR +mark_as_advanced ( OPENCASCADE_INCLUDE_DIR OPENCASCADE_LIBRARY_DIR OPENCASCADE_LIB_TKERNEL OPENCASCADE_LIB_TKBO OPENCASCADE_LIB_TKPRIM OPENCASCADE_LIB_TKMESH OPENCASCADE_LIB_TKBREP OPENCASCADE_LIB_TKTOPALGO diff --git a/Code/Mantid/Build/CMake/FindQwt.cmake b/Code/Mantid/Build/CMake/FindQwt.cmake index 389fc8a99c831c8830e6f903c65b2d3380562092..14cb76f7ba710c294a87c7b52cf61e717256b51b 100644 --- a/Code/Mantid/Build/CMake/FindQwt.cmake +++ b/Code/Mantid/Build/CMake/FindQwt.cmake @@ -9,7 +9,7 @@ find_path ( QWT_INCLUDE_DIR qwt.h PATHS /opt/include /usr/local/include /usr/include ${CMAKE_INCLUDE_PATH} PATH_SUFFIXES qwt5 qwt5-qt4 qwt-qt4 qwt ) -find_library ( QWT_LIBRARY NAMES qwt5-qt4 qwt-qt4 qwt ) +find_library ( QWT_LIBRARY NAMES qwt5-qt4 qwt-qt4 qwt5 qwt ) find_library ( QWT_LIBRARY_DEBUG qwtd ) # in REQUIRED mode: terminate if one of the above find commands failed diff --git a/Code/Mantid/Build/CMake/GNUSetup.cmake b/Code/Mantid/Build/CMake/GNUSetup.cmake index 37d6f9bc32dbe8edbdc4f053ec18209516b5163f..67b373b55a4bbe10b4e764cc16480e1ae960fa87 100644 --- a/Code/Mantid/Build/CMake/GNUSetup.cmake +++ b/Code/Mantid/Build/CMake/GNUSetup.cmake @@ -24,9 +24,10 @@ set( GNUFLAGS "-Wall -Wextra -Wconversion -Winit-self -Wpointer-arith -Wcast-qua set( GNUFLAGS "${GNUFLAGS} -Wno-deprecated -Wno-write-strings") # Check if we have a new enough version for this flag +# some -pedantic warnings remain with gcc 4.4.7 if ( CMAKE_COMPILER_IS_GNUCXX ) - if (GCC_COMPILER_VERSION VERSION_GREATER "4.3") - set(GNUFLAGS "${GNUFLAGS} -Wno-unused-result") + if (NOT (GCC_COMPILER_VERSION VERSION_LESS "4.5")) + set(GNUFLAGS "${GNUFLAGS} -Wno-unused-result -pedantic") endif () elseif ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) set(GNUFLAGS "${GNUFLAGS} -Wno-sign-conversion") diff --git a/Code/Mantid/Build/CMake/LinuxPackageScripts.cmake b/Code/Mantid/Build/CMake/LinuxPackageScripts.cmake index 760ecee5a349f34017f6cb804bf8eee8f58b671f..9a642a4d49bb2faf4bc79f8b623b99ef2d260d6e 100644 --- a/Code/Mantid/Build/CMake/LinuxPackageScripts.cmake +++ b/Code/Mantid/Build/CMake/LinuxPackageScripts.cmake @@ -26,21 +26,6 @@ set ( CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/${LIB_DIR};${CMAKE_INSTALL_PRE # Required for Fedora >= 18 and RHEL >= 7 set ( CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION /opt /usr/share/applications /usr/share/pixmaps ) -########################################################################### -# LD_PRELOAD TCMalloc -########################################################################### -# User systems will only have the libraries and not the symbolic link -# so we must set the preload to the versioned library. We will assume it is -# in the same location as the system that the package was built on -if ( TCMALLOC_LIBRARIES ) - execute_process ( COMMAND readlink --no-newline --canonicalize-existing ${TCMALLOC_LIBRARIES} - OUTPUT_VARIABLE TCMALLOC_PRELOAD - RESULT_VARIABLE READLINK_RESULT ) - if ( READLINK_RESULT EQUAL 1 ) - message ( FATAL_ERROR "Unable to find real file that tcmalloc symlink, ${TCMALLOC_LIBRARIES}, points to." ) - endif() -endif() - ########################################################################### # Environment scripts (profile.d) ########################################################################### @@ -151,6 +136,12 @@ configure_file ( ${CMAKE_MODULE_PATH}/Packaging/launch_mantidplot.sh.in # Needs to be executable execute_process ( COMMAND "chmod" "+x" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launch_mantidplot.sh" OUTPUT_QUIET ERROR_QUIET ) +configure_file ( ${CMAKE_MODULE_PATH}/Packaging/mantidpython.in + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mantidpython @ONLY ) +# Needs to be executable +execute_process ( COMMAND "chmod" "+x" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mantidpython" + OUTPUT_QUIET ERROR_QUIET ) + # Package version set ( MANTIDPLOT_EXEC MantidPlot_exe ) configure_file ( ${CMAKE_MODULE_PATH}/Packaging/launch_mantidplot.sh.in @@ -161,3 +152,11 @@ install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/launch_mantidplot.sh.install GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ ) +configure_file ( ${CMAKE_MODULE_PATH}/Packaging/mantidpython.in + ${CMAKE_CURRENT_BINARY_DIR}/mantidpython.install @ONLY ) +install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/mantidpython.install + DESTINATION ${BIN_DIR} RENAME mantidpython + PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ + GROUP_EXECUTE GROUP_READ + WORLD_EXECUTE WORLD_READ +) diff --git a/Code/Mantid/Build/CMake/Packaging/launch_mantidplot.sh.in b/Code/Mantid/Build/CMake/Packaging/launch_mantidplot.sh.in index 33556e1b1c79e6836742bad3bab57bd42a17a49a..f26493a133120275e42f77fd51c4c9601d39ca29 100644 --- a/Code/Mantid/Build/CMake/Packaging/launch_mantidplot.sh.in +++ b/Code/Mantid/Build/CMake/Packaging/launch_mantidplot.sh.in @@ -9,7 +9,7 @@ SCRIPTFILE=$(readlink -f "$0") INSTALLDIR=$(echo $SCRIPTFILE | sed -r -e 's|^(.*)/(.*)$|\1|g') #.* is greedy and eats up until the final slash # Define extra libraries and load paths -LOCAL_PRELOAD=@TCMALLOC_PRELOAD@ +LOCAL_PRELOAD=`readlink --no-newline --canonicalize-existing @TCMALLOC_LIBRARIES@` if [ -n "${LD_PRELOAD}" ]; then LOCAL_PRELOAD=${LOCAL_PRELOAD}:${LD_PRELOAD} fi @@ -21,4 +21,6 @@ else fi # Launch -LD_PRELOAD=${LOCAL_PRELOAD} TCMALLOC_RELEASE_RATE=${TCM_RELEASE} LD_LIBRARY_PATH=${LOCAL_LDPATH} QT_API=pyqt @WRAPPER_PREFIX@$INSTALLDIR/@MANTIDPLOT_EXEC@ $*@WRAPPER_POSTFIX@ +LD_PRELOAD=${LOCAL_PRELOAD} TCMALLOC_RELEASE_RATE=${TCM_RELEASE} \ + LD_LIBRARY_PATH=${LOCAL_LDPATH} QT_API=pyqt \ + @WRAPPER_PREFIX@$INSTALLDIR/@MANTIDPLOT_EXEC@ $*@WRAPPER_POSTFIX@ diff --git a/Code/Mantid/Build/CMake/Packaging/mantidpython.in b/Code/Mantid/Build/CMake/Packaging/mantidpython.in new file mode 100755 index 0000000000000000000000000000000000000000..55cbe36924e81bbfc5e36caebaf5033faa3939de --- /dev/null +++ b/Code/Mantid/Build/CMake/Packaging/mantidpython.in @@ -0,0 +1,34 @@ +#!/bin/sh +# +# Launch Mantidplot using any necessary LD_PRELOAD or software collection behaviour +# +# Script is configured by CMake + +# Find out where we are +SCRIPTFILE=$(readlink -f "$0") +INSTALLDIR=$(echo $SCRIPTFILE | sed -r -e 's|^(.*)/(.*)$|\1|g') #.* is greedy and eats up until the final slash +IPYTHON=$(command -v ipython) + +# Define extra libraries and load paths +LOCAL_PRELOAD=`readlink --no-newline --canonicalize-existing @TCMALLOC_LIBRARIES@` +if [ -n "${LD_PRELOAD}" ]; then + LOCAL_PRELOAD=${LOCAL_PRELOAD}:${LD_PRELOAD} +fi +LOCAL_LDPATH=@EXTRA_LDPATH@:${LD_LIBRARY_PATH} +if [ -z "${TCMALLOC_RELEASE_RATE}" ]; then + TCM_RELEASE=10000 +else + TCM_RELEASE=${TCMALLOC_RELEASE_RATE} +fi + +# Define extra libraries for python +LOCAL_PYTHONPATH=@WRAPPER_PREFIX@$INSTALLDIR +if [ -n "${PYTHONPATH}" ]; then + LOCAL_PYTHONPATH=${LOCAL_PYTHONPATH}:${PYTHONPATH} +fi + +# Launch +LD_PRELOAD=${LOCAL_PRELOAD} TCMALLOC_RELEASE_RATE=${TCM_RELEASE} \ + LD_LIBRARY_PATH=${LOCAL_LDPATH} QT_API=pyqt \ + PYTHONPATH=${LOCAL_PYTHONPATH} \ + ${IPYTHON} $*@WRAPPER_POSTFIX@ diff --git a/Code/Mantid/Build/Jenkins/buildscript b/Code/Mantid/Build/Jenkins/buildscript index 40f6003fab63ebfa08448f47edca10bb313ac689..bf9df07b22372756d094a2184f3d54b6f09eda26 100755 --- a/Code/Mantid/Build/Jenkins/buildscript +++ b/Code/Mantid/Build/Jenkins/buildscript @@ -85,6 +85,10 @@ else SCL_ON_RHEL6="eval" fi +if [[ ${NODE_LABELS} == *rhel7* ]]; then + ON_RHEL7=true +fi + ############################################################################### # Check job requirements from the name ############################################################################### @@ -212,6 +216,6 @@ fi # Run the system tests on RHEL6 when doing a pull request build. Run # from a package to have at least one Linux checks it install okay ############################################################################### -if [[ "${ON_RHEL6}" == true ]] && [[ ${JOB_NAME} == *pull_requests* ]]; then +if [[ "${ON_RHEL7}" == true ]] && [[ ${JOB_NAME} == *pull_requests* ]]; then $SCRIPT_DIR/systemtests fi diff --git a/Code/Mantid/Build/Jenkins/buildscript.bat b/Code/Mantid/Build/Jenkins/buildscript.bat index ce0d2ca69f03e0da6f8139da31afbf0e3aa86df6..cda8a6cb7d61c4189aaa12233f29907bd068db90 100755 --- a/Code/Mantid/Build/Jenkins/buildscript.bat +++ b/Code/Mantid/Build/Jenkins/buildscript.bat @@ -87,7 +87,7 @@ if not "%JOB_NAME%"=="%JOB_NAME:relwithdbg=%" ( ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: Update the PATH so that we can find everything ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -set PATH=%WORKSPACE%\Code\Third_Party\lib\win64;%WORKSPACE%\Code\Third_Party\lib\win64\Python27;%PARAVIEW_DIR%\bin\%BUILD_CONFIG%;%PATH% +set PATH=%WORKSPACE%\Code\Third_Party\lib\win64;%WORKSPACE%\Code\Third_Party\lib\win64\Python27;%WORKSPACE%\Code\Third_Party\lib\win64\mingw;%PARAVIEW_DIR%\bin\%BUILD_CONFIG%;%PATH% ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: CMake configuration diff --git a/Code/Mantid/Build/dev-packages/rpm/mantid-developer/mantid-developer.spec b/Code/Mantid/Build/dev-packages/rpm/mantid-developer/mantid-developer.spec index 95fc838ccd985329c9633b5e1c9fc6ed292b65a3..39a9d019dff3cb93bc6fd1aedb2a0cb8db3ecf91 100644 --- a/Code/Mantid/Build/dev-packages/rpm/mantid-developer/mantid-developer.spec +++ b/Code/Mantid/Build/dev-packages/rpm/mantid-developer/mantid-developer.spec @@ -1,5 +1,5 @@ Name: mantid-developer -Version: 1.9 +Version: 1.10 Release: 1%{?dist} Summary: Meta Package to install dependencies for Mantid Development @@ -30,7 +30,7 @@ Requires: poco-devel Requires: PyQt4-devel Requires: python-devel Requires: python-ipython >= 1.1 -Conflicts: python-ipython >= 2.0 +%{?el6:Conflicts: python-ipython >= 2.0} Requires: python-pip Requires: python-sphinx Requires: qscintilla-devel diff --git a/Code/Mantid/CMakeLists.txt b/Code/Mantid/CMakeLists.txt index a055859f89e134e210001db843e9a22b293919e6..37e8763843f062003919fdb4f80a036305db62e8 100644 --- a/Code/Mantid/CMakeLists.txt +++ b/Code/Mantid/CMakeLists.txt @@ -121,6 +121,7 @@ set( DOCS_BUILDDIR ${CMAKE_BINARY_DIR}/docs ) # Framework Build options set ( CXXTEST_SINGLE_LOGFILE CACHE BOOL "Switch to have the tests for each package run together") set ( CXXTEST_ADD_PERFORMANCE OFF CACHE BOOL "Switch to add Performance tests to the list of tests run by ctest?") +set ( ENABLE_OPENCASCADE ON CACHE BOOL "Enable OpenCascade-based 3D visualisation") add_subdirectory ( Framework ) diff --git a/Code/Mantid/Framework/API/CMakeLists.txt b/Code/Mantid/Framework/API/CMakeLists.txt index 543277381857054fd04622824217d944f6176be5..1a8ece42503b648102159f60ac84b77ebfd39880 100644 --- a/Code/Mantid/Framework/API/CMakeLists.txt +++ b/Code/Mantid/Framework/API/CMakeLists.txt @@ -106,6 +106,7 @@ set ( SRC_FILES src/PropertyManagerDataService.cpp src/PropertyNexus.cpp src/RefAxis.cpp + src/RemoteJobManagerFactory.cpp src/Run.cpp src/Sample.cpp src/SampleEnvironment.cpp @@ -221,6 +222,7 @@ set ( INC_FILES inc/MantidAPI/IPeakFunction.h inc/MantidAPI/IPeaksWorkspace.h inc/MantidAPI/IPowderDiffPeakFunction.h + inc/MantidAPI/IRemoteJobManager.h inc/MantidAPI/ISpectrum.h inc/MantidAPI/ISplittersWorkspace.h inc/MantidAPI/ITableWorkspace.h @@ -270,6 +272,7 @@ set ( INC_FILES inc/MantidAPI/PropertyManagerDataService.h inc/MantidAPI/PropertyNexus.h inc/MantidAPI/RefAxis.h + inc/MantidAPI/RemoteJobManagerFactory.h inc/MantidAPI/Run.h inc/MantidAPI/Sample.h inc/MantidAPI/SampleEnvironment.h @@ -366,6 +369,7 @@ set ( TEST_FILES ProjectionTest.h PropertyManagerDataServiceTest.h PropertyNexusTest.h + RemoteJobManagerFactoryTest.h RunTest.h SampleEnvironmentTest.h SampleShapeValidatorTest.h diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/DomainCreatorFactory.h b/Code/Mantid/Framework/API/inc/MantidAPI/DomainCreatorFactory.h index 09f4ab0100b4c64b744ee0d7eca25925be979dc6..0b232c59f0d87ea764047d9ec93bc4b8dafacfb6 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/DomainCreatorFactory.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/DomainCreatorFactory.h @@ -59,7 +59,7 @@ private: /// Private Constructor for singleton class DomainCreatorFactoryImpl(); /// No copying - DISABLE_COPY_AND_ASSIGN(DomainCreatorFactoryImpl); + DISABLE_COPY_AND_ASSIGN(DomainCreatorFactoryImpl) /// Private Destructor for singleton virtual ~DomainCreatorFactoryImpl(); diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/FileFinder.h b/Code/Mantid/Framework/API/inc/MantidAPI/FileFinder.h index 410ef30b7541bb158ab47d138df0b01223630628..a970c73008349afb1177d499efc917113c789155 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/FileFinder.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/FileFinder.h @@ -50,7 +50,7 @@ Code Documentation is available at: <http://doxygen.mantidproject.org> */ class MANTID_API_DLL FileFinderImpl { public: - std::string getFullPath(const std::string &filename) const; + std::string getFullPath(const std::string &filename, const bool ignoreDirs = false) const; std::string getPath(const std::vector<IArchiveSearch_sptr> &archs, const std::set<std::string> &filename, const std::vector<std::string> &extensions) const; diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/FunctionDomain1D.h b/Code/Mantid/Framework/API/inc/MantidAPI/FunctionDomain1D.h index c777f47dc80897476da07fd9d12165117956a89a..f3a34da22c9ed3bdeb42ae52bb2592e1fd1f0871 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/FunctionDomain1D.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/FunctionDomain1D.h @@ -52,6 +52,8 @@ public: double operator[](size_t i) const { return m_data[i]; } /// Get a pointer to i-th value const double *getPointerAt(size_t i) const { return m_data + i; } + /// Convert to a vector + std::vector<double> toVector() const; protected: /// Protected constructor, shouldn't be created directly. Use diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h b/Code/Mantid/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h index 533c9942cdd251169ddc1fa24ea1386ef566d14b..78fd23781cbfba3733de852912260fe029f9b530 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h @@ -50,6 +50,11 @@ public: IFunction_sptr clone() const; + virtual void setWorkspace(boost::shared_ptr<const Workspace> ws); + virtual void + setMatrixWorkspace(boost::shared_ptr<const MatrixWorkspace> workspace, + size_t wi, double startX, double endX); + /// Set i-th parameter of decorated function. virtual void setParameter(size_t i, const double &value, bool explicitlySet = true); diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/FunctionValues.h b/Code/Mantid/Framework/API/inc/MantidAPI/FunctionValues.h index 44e32826ad6fd6bf94e3b69629a17471861247bf..836f1aff61ac82dfb7d12206a193203d1ea1b6a0 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/FunctionValues.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/FunctionValues.h @@ -103,6 +103,9 @@ public: /// instance. void setFitDataFromCalculated(const FunctionValues &values); + /// Return the calculated values as a vector + std::vector<double> toVector() const {return m_calculated;} + protected: /// Copy calculated values to a buffer /// @param to :: Pointer to the buffer diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IFuncMinimizer.h b/Code/Mantid/Framework/API/inc/MantidAPI/IFuncMinimizer.h index ee45efe672c45976eaa764d737f3332899dae461..e3532a0f53c2ff1e6b002c112f4326dfb03186a8 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IFuncMinimizer.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IFuncMinimizer.h @@ -69,6 +69,10 @@ public: /// Get value of cost function virtual double costFunctionVal() = 0; + /// Finalize minimization, eg store additional outputs + virtual void finalize() {} + + protected: /// Error string. std::string m_errorString; diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IMDEventWorkspace.h b/Code/Mantid/Framework/API/inc/MantidAPI/IMDEventWorkspace.h index 723ce3d7a8f8da076bb032444b5b61e7d8df89eb..b02beb1fa264e356ce810fcf9a8a8dc69582a6fc 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IMDEventWorkspace.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IMDEventWorkspace.h @@ -51,11 +51,6 @@ public: virtual void getBoxes(std::vector<API::IMDNode *> &boxes, size_t maxDepth, bool leafOnly) = 0; - /// TODO: The meaning of this method have changed! Helper method that makes a - /// table workspace with some box data - // virtual Mantid::API::ITableWorkspace_sptr makeBoxTable(size_t start, size_t - // num) = 0; - /// @return true if the workspace is file-backed virtual bool isFileBacked() const = 0; diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IMDHistoWorkspace.h b/Code/Mantid/Framework/API/inc/MantidAPI/IMDHistoWorkspace.h index 942e14af6ee2816a927fee8c6b1fa77f55feefc3..cc7c014a382a07ff9bf27bc15cebb1f03703d5b2 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IMDHistoWorkspace.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IMDHistoWorkspace.h @@ -89,7 +89,7 @@ public: virtual double &operator[](const size_t &index) = 0; virtual void setCoordinateSystem( - const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem) = 0; + const Kernel::SpecialCoordinateSystem coordinateSystem) = 0; virtual boost::shared_ptr<IMDHistoWorkspace> clone() const = 0; diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IMDWorkspace.h b/Code/Mantid/Framework/API/inc/MantidAPI/IMDWorkspace.h index c3bebd3e4f1d700f685eace018759928faf90eb9..35203727852cbdc1dbf5deed99311f12fe2abd61 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IMDWorkspace.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IMDWorkspace.h @@ -67,8 +67,7 @@ enum MDNormalization { Code Documentation is available at: <http://doxygen.mantidproject.org> */ -class MANTID_API_DLL IMDWorkspace : public Workspace, - public Mantid::API::MDGeometry { +class MANTID_API_DLL IMDWorkspace : public Workspace, public API::MDGeometry { public: IMDWorkspace(); IMDWorkspace(const IMDWorkspace &other); @@ -119,11 +118,11 @@ public: /// Clear existing masks virtual void clearMDMasking() = 0; /// - virtual Mantid::Kernel::SpecialCoordinateSystem + virtual Kernel::SpecialCoordinateSystem getSpecialCoordinateSystem() const = 0; /// if a workspace was filebacked, this should clear file-based status, delete /// file-based information and close related files. - virtual void clearFileBacked(bool /* loadFileContentsToMemory*/){}; + virtual void clearFileBacked(bool /* loadFileContentsToMemory*/) {} /// this is the method to build table workspace from any workspace. It does /// not have much sence and may be placed here erroneously virtual ITableWorkspace_sptr makeBoxTable(size_t /*start*/, size_t /* num*/) { diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IPeaksWorkspace.h b/Code/Mantid/Framework/API/inc/MantidAPI/IPeaksWorkspace.h index 15bd48bf8b94bfb00d57f11f577d09a928e7a009..03e115047abbae8fb93df685ecc415521e1ed13b 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IPeaksWorkspace.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IPeaksWorkspace.h @@ -55,10 +55,6 @@ public: /// Destructor virtual ~IPeaksWorkspace(); - // boost::shared_ptr<IPeaksWorkspace> clone() = 0; - // void appendFile( std::string filename, Mantid::Geometry::Instrument_sptr - // inst) = 0; - //--------------------------------------------------------------------------------------------- /** @return the number of peaks */ @@ -99,14 +95,15 @@ public: //--------------------------------------------------------------------------------------------- /** Create an instance of a Peak - * @param QLabFrame :: Q of the center of the peak in the lab frame, in reciprocal space - * @param detectorDistance :: Optional distance between the sample and the detector. Calculated if not provided. + * @param QLabFrame :: Q of the center of the peak in the lab frame, in + * reciprocal space + * @param detectorDistance :: Optional distance between the sample and the + * detector. Calculated if not provided. * @return a pointer to a new Peak object. */ virtual IPeak *createPeak(Mantid::Kernel::V3D QLabFrame, boost::optional<double> detectorDistance) const = 0; - /** * Create an instance of a peak using a V3D * @param HKL V3D @@ -136,16 +133,16 @@ public: * @param coordinateSystem : Special Q3D coordinate system to use. */ virtual void setCoordinateSystem( - const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem) = 0; - + const Kernel::SpecialCoordinateSystem coordinateSystem) = 0; //--------------------------------------------------------------------------------------------- /** * Get the special coordinate system. * @returns special Q3D coordinate system to use being used by this * PeaksWorkspace object. Probably the one the workspace was generated with. */ - virtual Mantid::Kernel::SpecialCoordinateSystem + virtual Kernel::SpecialCoordinateSystem getSpecialCoordinateSystem() const = 0; + virtual std::vector<std::pair<std::string, std::string>> peakInfo(Kernel::V3D QFrame, bool labCoords) const = 0; virtual int peakInfoNumber(Kernel::V3D qLabFrame, bool labCoords) const = 0; diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h b/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h new file mode 100644 index 0000000000000000000000000000000000000000..eb6d2ef97bd9dc3a643f69368c4be2be348d5757 --- /dev/null +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h @@ -0,0 +1,280 @@ +#ifndef MANTID_KERNEL_IREMOTEJOBMANAGER_H +#define MANTID_KERNEL_IREMOTEJOBMANAGER_H + +#include "MantidAPI/DllConfig.h" +#include "MantidKernel/DateAndTime.h" + +namespace Mantid { +namespace API { +/** +Common interface to different remote job managers (job schedulers, web +services, etc. such as MOAB, Platform LSF, or SLURM). + +IremoteJobManager objects are (in principle) created via the +RemoteJobManagerFactory. There are several "remote algorithms" in +Mantid: Authenticate, SubmitRemoteJob, QueryRemoteJobStatus, +etc. These algorithms are meant to use this interface to the different +specific implementations. Or, from the opposite angle, the methods of +this interface provide the functionality required by the remote +algorithms in a generic way (with respect to different job schedulers +or underlying mechanisms to handle remote jobs). So-called remote job +manager classes can implement this interface to provide +specialisations for Platform LSF, SLURM, MOAB, the Mantid web service +API, etc. + +A typical sequence of calls when you use this interface would be: + +1) Authenticate/log-in (authenticate()) +2) Do transactions + +Where the sequence of calls within a transaction is: + +2.1) Start transaction (startRemoteTransaction()) +2.2) Do actions +2.3) Stop transaction (stopRemoteTransaction()) + +In 2.2, several types of actions are possible: +- Submit a job to run on the (remote) compute resource (submitRemoteJob()). +- Get status info for one or all jobs (queryRemoteJob() and +queryAllRemoteJobs()). +- Cancel a job (abortRemoteJob()). +- Get list of available files for a transaction on the compute resource +(queryRemoteFile()) +- Upload / download files ( uploadRemoteFile() and downloadRemoteFile()). + + +Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge +National Laboratory & European Spallation Source + +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://github.com/mantidproject/mantid>. +Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_API_DLL IRemoteJobManager { +public: + virtual ~IRemoteJobManager(){}; + + /** + * Status and general information about jobs running on (remote) + * compute resources. + */ + struct RemoteJobInfo { + /// Job ID, usually assigned by a job scheduler as an integer + /// number or similar. + std::string id; + /// name of the job, whether given by the user or automatically + /// assigned by the job scheduler + std::string name; + /// Name of the script or executable. Depending on the specific + /// implementation, job scheduler, etc. this can be an + /// 'application' name, a script name or different ways of + /// specifying what is run + std::string runnableName; + /// Last status retrieved (typically: Pending, Running, Exited, + /// etc.). The values are implementation/job scheduler dependent. + std::string status; + /// ID of the transaction where this job is included + std::string transactionID; + /// Date-time of submission. No particular format can be assumed + /// from the specific remote job managers, and some of them may + /// not provide this info + Mantid::Kernel::DateAndTime submitDate; + /// Date-time the job actually started running. No particular + /// format can be assumed + Mantid::Kernel::DateAndTime startDate; + /// Date-time the job finished. No particular format can be + /// assumed + Mantid::Kernel::DateAndTime completionTime; + }; + + /** + * Authenticate or log-in, previous to submitting jobs, up/downloading, etc. + * + * @param username User name or credentials + * + * @param password Password (or other type of authentication token) + * string. + * + * @throws std::invalid_argument If any of the inputs is not set + * properly. + * @throws std::runtime_error If authentication fails + */ + virtual void authenticate(const std::string &username, + const std::string &password) = 0; + + /** + * Submit a job (and implicitly request to start it) within a + * transaction. + * + * @param transactionID ID obtained from a startRemoteTransaction() + * + * @param runnable Name of the script or executable for the + * job. This can be a name or path to a file (implementation + * dependent). + * + * @param param Parameters for the job. This is implementation + * dependent and may be a list of command line options, the name of + * a script or configuration file, the contents of a script to run + * or configuration template, etc. For example, for the Mantid web + * service API, this is the content of a python script. + * + * @param taskName (optional) human readable name for this job. + * + * @param numNodes number of nodes to use (optional and dependent on + * implementation and compute resource) + * + * @param coresPerNode number of cores to use in each node (optional + * and dependent on implemenation and compute resource) + * + * @return jobID string for the job started (if successful). + * + * @throws std::invalid_argument If any of the inputs is not set + * properly. + * @throws std::runtime_error if job submission fails. + */ + virtual std::string + submitRemoteJob(const std::string &transactionID, const std::string &runnable, + const std::string ¶m, const std::string &taskName = "", + const int numNodes = 1, const int coresPerNode = 1) = 0; + + /** + * Get/download a file from the (remote) compute resource. + * + * @param transactionID ID obtained from a startRemoteTransaction() + * + * @param remoteFileName Name of file on the (remote) compute + * resource. This can be a full or relative path or a simple file + * name, depending on implementation. + * + * @param localFileName Where to place the downloaded file on the + * local machine. + * + * @throws std::invalid_argument If any of the inputs is not set + * properly. + * @throws std::runtime_error If the download operation fails + */ + virtual void downloadRemoteFile(const std::string &transactionID, + const std::string &remoteFileName, + const std::string &localFileName) = 0; + + /** + * Get information (status etc.) for all running jobs on the remote + * compute resource + * + * @return Status and general info for all the jobs found on the + * (remote) compute resource. Each of them should come identified by + * its ID. + * + * @throws std::runtime_error If the query fails + */ + virtual std::vector<RemoteJobInfo> queryAllRemoteJobs() const = 0; + + /** + * Get the list of files available for a transaction at the (remote) + * compute resource. + * + * @param transactionID ID obtained from startRemoteTransaction() + * + * @return The names of all the available files + * + * @throws std::invalid_argument If there's an issue with the + * transaction ID + * + * @throws std::runtime_error If the query fails + */ + virtual std::vector<std::string> + queryRemoteFile(const std::string &transactionID) const = 0; + + /** + * Get information (status etc.) for an (in principle) running job + * + * @param jobID ID of a job as obtained from submitRemoteJob() + * + * @return Status and general info for the job requested + * + * @throws std::invalid_argument If there's an issue with the + * job ID + * + * @throws std::runtime_error If the query fails + */ + virtual RemoteJobInfo queryRemoteJob(const std::string &jobID) const = 0; + + /** + * Start a transaction before up/downloading files and submitting + * jobs + * + * @return ID of the transaction as produced by the job scheduler + * and/or remote job manager. + * + * @throws std::runtime_error If the transaction creation fails + */ + virtual std::string startRemoteTransaction() = 0; + + /** + * Finish a transaction. This implicitly can cancel all the + * operations (jobs) associated with this transaction. + * + * @param transactionID An Id of a transaction, as returned by + * startRemoteTransaction() + * + * @throws std::invalid_argument If there's an issue with the + * transaction ID + * + * @throws std::runtime_error If the stop operation fails + */ + virtual void stopRemoteTransaction(const std::string &transactionID) = 0; + + /** + * Cancel a job (expected to be currently running on the remote resource) + * + * @param jobID ID for a job in a transaction, as returned by + * submitRemoteJob() + * + * @throws std::invalid_argument If there's an issue with the + * job ID + * @throws std::runtime_error If the abort/cancel operation fails + */ + virtual void abortRemoteJob(const std::string &jobID) = 0; + + /** + * Upload file for a transaction on the rmeote compute resource + * + * @param transactionID ID, as you get them from + * startRemoteTransaction() + * + * @param remoteFileName Name of file on the (remote) compute + * resource. This can be a full or relative path or a simple file + * name, depending on implementation. + * + * @param localFileName Path to the file to upload + * + * @throws std::invalid_argument If there's an issue with the + * arguments passed + * @throws std::runtime_error If the upload fails + */ + virtual void uploadRemoteFile(const std::string &transactionID, + const std::string &remoteFileName, + const std::string &localFileName) = 0; +}; + +// shared pointer type for the IRemoteJobManager +typedef boost::shared_ptr<IRemoteJobManager> IRemoteJobManager_sptr; + +} // namespace API +} // namespace Mantid + +#endif // MANTID_API_IREMOTEJOBMANAGER_H diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h b/Code/Mantid/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..34fa04176d18cd43e191eb4bf346bdbfdb02b66e --- /dev/null +++ b/Code/Mantid/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h @@ -0,0 +1,124 @@ +#ifndef MANTID_API_REMOTEJOBMANAGERFACTORY_H_ +#define MANTID_API_REMOTEJOBMANAGERFACTORY_H_ + +#include "MantidAPI/DllConfig.h" +#include "MantidAPI/IRemoteJobManager.h" +#include "MantidKernel/DynamicFactory.h" +#include "MantidKernel/SingletonHolder.h" + +namespace Mantid { +namespace API { +/** +The RemoteJobManagerFactory handles the creation of remote job +managers specialised for different types of compute resources (for +different underlying job schedulers, web services, front-ends, +etc.). Through the create method of this class a shared pointer to a +remote job manager object can be obtained for a particular compute +resource. + +The remote job managers built by this factory know how to start and +stop jobs, upload/download files, etc. for the compute resource +specified when creating the job manager (as long as the compute +resource is found for the current facility in the facilities +definition file). + +Remote job manager classes must be registered/subscribe using the +macro DECLARE_REMOTEJOBMANAGER (the same way you use DECLARE_ALGORITHM +for algorithms and remote algorithms). + +As the algorithm, workspace and other factories in Mantid, this +factory is implemented as a singleton class. Typical usages: + +Mantid::API::IRemoteJob|Manager_sptr jobManager = + Mantid::API::RemoteJobManagerFactory::Instance().create("Fermi"); + +Mantid::API::IRemoteJob|Manager_sptr jobManager = + Mantid::API::RemoteJobManagerFactory::Instance().create("SCARF@STFC"); + + +Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge +National Laboratory & European Spallation Source + +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://github.com/mantidproject/mantid>. +Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_API_DLL RemoteJobManagerFactoryImpl + : public Kernel::DynamicFactory<IRemoteJobManager> { +public: + /// Create a remote job manager that will know how to use the + /// underlying mechanism that suits the compute resource passed + IRemoteJobManager_sptr create(const std::string &computeResourceName) const; + + /// alternative (lower level) create where the specific type of + /// manager and base URL are directly given + IRemoteJobManager_sptr create(const std::string baseURL, + const std::string jobManagerType) const; + +private: + /// So that the singleton can be created (cons/destructor are private) + friend struct Mantid::Kernel::CreateUsingNew<RemoteJobManagerFactoryImpl>; + + /// Private Constructor for singleton class + RemoteJobManagerFactoryImpl(); + /// Disallow copy construction + RemoteJobManagerFactoryImpl(const RemoteJobManagerFactoryImpl &); + /// Disallow assignment + RemoteJobManagerFactoryImpl &operator=(const RemoteJobManagerFactoryImpl &); + + /// Private Destructor + virtual ~RemoteJobManagerFactoryImpl(); + + // Unhide the inherited create method but make it private + using Kernel::DynamicFactory<IRemoteJobManager>::create; +}; + +/// Forward declaration of a specialisation of SingletonHolder for +/// RemoteJobManagerFactoryImpl (needed for dllexport) and a typedef for it. +#ifdef _WIN32 +// this breaks new namespace declaraion rules; need to find a better fix +template class MANTID_API_DLL + Mantid::Kernel::SingletonHolder<RemoteJobManagerFactoryImpl>; +#endif /* _WIN32 */ + +// The factory is just a specialisation of SingletonHolder +typedef MANTID_API_DLL Mantid::Kernel::SingletonHolder< + RemoteJobManagerFactoryImpl> RemoteJobManagerFactory; + +} // namespace API +} // namespace Mantid + +/* Macro to register (remote job manager) classes into the factory. As + * with the equivalent macros of the workspace factory or the + * algorithm factory, this creates a global object in an anonymous + * namespace. The object itself does nothing, but the comma operator + * is used in the call to its constructor to effect a call to the + * factory's subscribe method. + * + * You need to use this in every remote job manager. For example: + * DECLARE_REMOTEJOBMANAGER(MantidWebServiceAPI) + * DECLARE_REMOTEJOBMANAGER(SCARFLSFJobManager) + */ +#define DECLARE_REMOTEJOBMANAGER(classname) \ + namespace { \ + Mantid::Kernel::RegistrationHelper register_ws_##classname( \ + ((Mantid::API::RemoteJobManagerFactory::Instance().subscribe<classname>( \ + #classname)), \ + 0)); \ + } + +#endif // MANTID_API_REMOTEJOBMANAGERFACTORY_H_ diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/ScopedWorkspace.h b/Code/Mantid/Framework/API/inc/MantidAPI/ScopedWorkspace.h index e379a04431fbf73a8c45f5b989f0596fce19338e..50595222e3f2406b1ca07f36a50f9d181d0a5da5 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/ScopedWorkspace.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/ScopedWorkspace.h @@ -74,7 +74,7 @@ public: void set(Workspace_sptr newWS); private: - DISABLE_COPY_AND_ASSIGN(ScopedWorkspace); + DISABLE_COPY_AND_ASSIGN(ScopedWorkspace) /// ADS name of the workspace const std::string m_name; diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/ScriptRepository.h b/Code/Mantid/Framework/API/inc/MantidAPI/ScriptRepository.h index b528bdb6e70991309ac60945f5ba0f501c8e0fc9..97b91a4e7dc1fc4609df364d27ca050548fe7542 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/ScriptRepository.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/ScriptRepository.h @@ -48,7 +48,7 @@ enum SCRIPTSTATUS { LOCAL_ONLY = (1u << 1), REMOTE_CHANGED = (1u << 2), LOCAL_CHANGED = (1u << 3), - BOTH_CHANGED = (REMOTE_CHANGED | LOCAL_CHANGED), + BOTH_CHANGED = (REMOTE_CHANGED | LOCAL_CHANGED) }; /** @@ -610,7 +610,7 @@ public: /// shared pointer to the function base class typedef boost::shared_ptr<ScriptRepository> ScriptRepository_sptr; -}; -}; +} +} #endif // MANTID_API_SCRIPTREPOSITORY_H_ diff --git a/Code/Mantid/Framework/API/src/FileBackedExperimentInfo.cpp b/Code/Mantid/Framework/API/src/FileBackedExperimentInfo.cpp index 79bff7b89c7793898584705474f84e73fab73152..64c7084fdff37c1b41c4e4124fcab7beb547f22c 100644 --- a/Code/Mantid/Framework/API/src/FileBackedExperimentInfo.cpp +++ b/Code/Mantid/Framework/API/src/FileBackedExperimentInfo.cpp @@ -28,11 +28,12 @@ FileBackedExperimentInfo::FileBackedExperimentInfo(const std::string &filename, : ExperimentInfo(), m_loaded(false), m_filename(filename), m_nxpath(nxpath) {} /** - * @return A clone of the object + * This clones the FileBackedExperimentInfo and will not cause a load + * of the information. + * @return A clone of the object. */ ExperimentInfo *FileBackedExperimentInfo::cloneExperimentInfo() const { - populateIfNotLoaded(); - return ExperimentInfo::cloneExperimentInfo(); + return new FileBackedExperimentInfo(*this); } /// @returns A human-readable description of the object diff --git a/Code/Mantid/Framework/API/src/FileFinder.cpp b/Code/Mantid/Framework/API/src/FileFinder.cpp index 3c07e3517894609dfb97786743bc89bba2fe6bbf..e350531d110798e72a26c0a92eb281d2cb0d55ff 100644 --- a/Code/Mantid/Framework/API/src/FileFinder.cpp +++ b/Code/Mantid/Framework/API/src/FileFinder.cpp @@ -101,11 +101,12 @@ bool FileFinderImpl::getCaseSensitive() const { /** * Return the full path to the file given its name * @param filename :: A file name (without path) including extension + * @param ignoreDirs :: If true, directories that match are skipped unless the path given is already absolute * @return The full path if the file exists and can be found in one of the * search locations * or an empty string otherwise. */ -std::string FileFinderImpl::getFullPath(const std::string &filename) const { +std::string FileFinderImpl::getFullPath(const std::string &filename, const bool ignoreDirs) const { std::string fName = Kernel::Strings::strip(filename); g_log.debug() << "getFullPath(" << fName << ")\n"; // If this is already a full path, nothing to do @@ -116,7 +117,7 @@ std::string FileFinderImpl::getFullPath(const std::string &filename) const { // circumstances with extensions that have wild cards try { Poco::File fullPath(Poco::Path().resolve(fName)); - if (fullPath.exists()) + if (fullPath.exists() && (!ignoreDirs || !fullPath.isDirectory())) return fullPath.path(); } catch (std::exception &) { } @@ -137,15 +138,20 @@ std::string FileFinderImpl::getFullPath(const std::string &filename) const { std::set<std::string> files; Kernel::Glob::glob(pathPattern, files, m_globOption); if (!files.empty()) { + Poco::File matchPath(*files.begin()); + if(ignoreDirs && matchPath.isDirectory()) { + continue; + } return *files.begin(); + } #ifdef _WIN32 } else { Poco::Path path(*it, fName); Poco::File file(path); - if (file.exists()) { + if (file.exists() && !(ignoreDirs && file.isDirectory())) { return path.toString(); - } + } } #endif } diff --git a/Code/Mantid/Framework/API/src/FunctionDomain1D.cpp b/Code/Mantid/Framework/API/src/FunctionDomain1D.cpp index 14c7f2e2bc121a1c38624b97ffe303895b36a6ad..0de9abdc6c76f30ec2a3a07848f995f6d6155135 100644 --- a/Code/Mantid/Framework/API/src/FunctionDomain1D.cpp +++ b/Code/Mantid/Framework/API/src/FunctionDomain1D.cpp @@ -7,6 +7,16 @@ namespace Mantid { namespace API { +/// Convert to a vector +std::vector<double> FunctionDomain1D::toVector() const +{ + std::vector<double> res; + if ( m_n > 0 ){ + res.assign(m_data, m_data+m_n); + } + return res; +} + /** * Create a domain from a vector. * @param xvalues :: Vector with function arguments to be copied from. diff --git a/Code/Mantid/Framework/API/src/FunctionParameterDecorator.cpp b/Code/Mantid/Framework/API/src/FunctionParameterDecorator.cpp index 9c1a1e80045a4060b1fd20a47755ffbaede1ecc4..0f953040eaeea0b03eaf55f861f188feed10f08a 100644 --- a/Code/Mantid/Framework/API/src/FunctionParameterDecorator.cpp +++ b/Code/Mantid/Framework/API/src/FunctionParameterDecorator.cpp @@ -37,6 +37,21 @@ IFunction_sptr FunctionParameterDecorator::clone() const { return cloned; } +void FunctionParameterDecorator::setWorkspace( + boost::shared_ptr<const Workspace> ws) { + throwIfNoFunctionSet(); + + m_wrappedFunction->setWorkspace(ws); +} + +void FunctionParameterDecorator::setMatrixWorkspace( + boost::shared_ptr<const MatrixWorkspace> workspace, size_t wi, + double startX, double endX) { + throwIfNoFunctionSet(); + + m_wrappedFunction->setMatrixWorkspace(workspace, wi, startX, endX); +} + void FunctionParameterDecorator::setParameter(size_t i, const double &value, bool explicitlySet) { throwIfNoFunctionSet(); @@ -91,8 +106,8 @@ double FunctionParameterDecorator::getParameter(const std::string &name) const { } size_t FunctionParameterDecorator::nParams() const { - if(!m_wrappedFunction) { - return 0; + if (!m_wrappedFunction) { + return 0; } return m_wrappedFunction->nParams(); @@ -161,8 +176,8 @@ size_t FunctionParameterDecorator::getParameterIndex( } size_t FunctionParameterDecorator::nAttributes() const { - if(!m_wrappedFunction) { - return 0; + if (!m_wrappedFunction) { + return 0; } return m_wrappedFunction->nAttributes(); diff --git a/Code/Mantid/Framework/API/src/LinearScale.cpp b/Code/Mantid/Framework/API/src/LinearScale.cpp index 14d1ff6820dbb9f2d3fe18379098e1dcc641a98c..4d11c0fb96276eec88ab36a6ab73b0f90e16cb8f 100644 --- a/Code/Mantid/Framework/API/src/LinearScale.cpp +++ b/Code/Mantid/Framework/API/src/LinearScale.cpp @@ -9,7 +9,7 @@ namespace Mantid { namespace API { -DECLARE_TRANSFORMSCALE(LinearScale); +DECLARE_TRANSFORMSCALE(LinearScale) /* Transform the grid to adopt a linear scale * @param gd a grid object diff --git a/Code/Mantid/Framework/API/src/LogManager.cpp b/Code/Mantid/Framework/API/src/LogManager.cpp index 572043d930322980e1c9a40b1032243fabd119f5..ae405738634e112d9377f3e6505f08a16fa41ca6 100644 --- a/Code/Mantid/Framework/API/src/LogManager.cpp +++ b/Code/Mantid/Framework/API/src/LogManager.cpp @@ -434,13 +434,13 @@ void LogManager::clearLogs() { m_manager.clear(); } template MANTID_API_DLL TYPE \ LogManager::getPropertyValueAsType(const std::string &) const; -INSTANTIATE(double); -INSTANTIATE(int); -INSTANTIATE(long); -INSTANTIATE(uint32_t); -INSTANTIATE(uint64_t); -INSTANTIATE(std::string); -INSTANTIATE(bool); +INSTANTIATE(double) +INSTANTIATE(int) +INSTANTIATE(long) +INSTANTIATE(uint32_t) +INSTANTIATE(uint64_t) +INSTANTIATE(std::string) +INSTANTIATE(bool) template MANTID_API_DLL uint16_t LogManager::getPropertyValueAsType(const std::string &) const; diff --git a/Code/Mantid/Framework/API/src/LogarithmScale.cpp b/Code/Mantid/Framework/API/src/LogarithmScale.cpp index 1ecb35a5d5333f91a48fb66518b20fb3f0d07b44..1e4abfdd83cf4cd95d0c3f74af6ea6d478c86380 100644 --- a/Code/Mantid/Framework/API/src/LogarithmScale.cpp +++ b/Code/Mantid/Framework/API/src/LogarithmScale.cpp @@ -16,7 +16,7 @@ namespace { Kernel::Logger g_log("LogarithmScale"); } -DECLARE_TRANSFORMSCALE(LogarithmScale); +DECLARE_TRANSFORMSCALE(LogarithmScale) void LogarithmScale::setBase(double &base) { if (base <= 0) { diff --git a/Code/Mantid/Framework/API/src/RemoteJobManagerFactory.cpp b/Code/Mantid/Framework/API/src/RemoteJobManagerFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..744123627a144265173445af3f7b11cd96c3c40a --- /dev/null +++ b/Code/Mantid/Framework/API/src/RemoteJobManagerFactory.cpp @@ -0,0 +1,88 @@ +#include "MantidAPI/RemoteJobManagerFactory.h" +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/FacilityInfo.h" +#include "MantidKernel/Logger.h" + +namespace Mantid { +namespace API { +namespace { +/// static logger object +Kernel::Logger g_log("RemoteJobManagerFactory"); +} + +/// Private constructor, singleton class +RemoteJobManagerFactoryImpl::RemoteJobManagerFactoryImpl() + : Mantid::Kernel::DynamicFactory<IRemoteJobManager>() { + g_log.debug() << "RemoteJobManager factory created." << std::endl; +} + +/** + * Private destructor, prevent client code from using this. + */ +RemoteJobManagerFactoryImpl::~RemoteJobManagerFactoryImpl() {} + +/** + * Create a remote algorithm with the underlying mechanism that suits + * the compute resource passed. + * + * @param computeResourceName Name of a (remote) compute resource + * + * @throw std::invalid_argument If no resource is found by the name + * given (compute resources are looked up in the facilities definition + * (XML) file for the current facility. + */ +IRemoteJobManager_sptr RemoteJobManagerFactoryImpl::create( + const std::string &computeResourceName) const { + IRemoteJobManager_sptr jm; + + if (computeResourceName.empty()) + return jm; + + Mantid::Kernel::ComputeResourceInfo cr = + Mantid::Kernel::ConfigService::Instance().getFacility().computeResource( + computeResourceName); + + // this is the default. It could be "MantidWebServiceAPI", "LSF", + // "SCARFLSF", "MOAB", etc. + std::string type = "MantidWebServiceAPIJobManager"; + std::string fdfType = cr.remoteJobManagerType(); + if (!fdfType.empty()) + type = fdfType; + return create(cr.baseURL(), type); +} + +/** + * Lower level create method that makes a remote algorithm given a + * base URL and the type of remote job manager. + * + * @param baseURL URL where the resource is accessible + * + * @param jobManagerType Type/class that can handle this remote + * compute resource (string names as used in the facilities definition + * file, for example: MantidWebServiceAPIJobManager). + * + * @throw std::invalid_argument If there is an issue with the URL or + * the type (for example the type is not recognized). + */ +Mantid::API::IRemoteJobManager_sptr +RemoteJobManagerFactoryImpl::create(const std::string baseURL, + const std::string jobManagerType) const { + Mantid::API::IRemoteJobManager_sptr jm; + + // use the inherited/generic create method + try { + jm = this->create(jobManagerType); + } catch (Kernel::Exception::NotFoundError &e) { + throw Kernel::Exception::NotFoundError( + "RemoteJobManagerFactory: failed to create a remote job manager of " + "type (class) '" + + jobManagerType + "' with base URL " + baseURL + + ". Error description: " + e.what(), + jobManagerType); + } + + return jm; +} + +} // namespace API +} // Namespace Mantid diff --git a/Code/Mantid/Framework/API/test/CostFunctionFactoryTest.h b/Code/Mantid/Framework/API/test/CostFunctionFactoryTest.h index c0c567cc8b22d2b6db9917c31b325cad6796ece1..d54b9807c852db41267b21196b5fddf1adaee830 100644 --- a/Code/Mantid/Framework/API/test/CostFunctionFactoryTest.h +++ b/Code/Mantid/Framework/API/test/CostFunctionFactoryTest.h @@ -38,7 +38,7 @@ public: }; -DECLARE_COSTFUNCTION(CostFunctionFactoryTest_A, nedtur); +DECLARE_COSTFUNCTION(CostFunctionFactoryTest_A, nedtur) class CostFunctionFactoryTest : public CxxTest::TestSuite diff --git a/Code/Mantid/Framework/API/test/FileBackedExperimentInfoTest.h b/Code/Mantid/Framework/API/test/FileBackedExperimentInfoTest.h index b7ec12deea2623c62f7a1f549a5331f76a69ad92..f3fa9eb6c621e80188e7144bc58e139e45c4ca73 100644 --- a/Code/Mantid/Framework/API/test/FileBackedExperimentInfoTest.h +++ b/Code/Mantid/Framework/API/test/FileBackedExperimentInfoTest.h @@ -45,12 +45,12 @@ public: TS_ASSERT_EQUALS(fileBacked->toString(), m_inMemoryExptInfo->toString()); } - void test_cloneExperimentInfo_populates_object() { + void test_cloneExperimentInfo_returns_new_file_backed_object_and_does_not_touch_file() { auto fileBacked = createTestObject(); auto *clonedFileBacked = fileBacked->cloneExperimentInfo(); - TS_ASSERT_EQUALS(clonedFileBacked->toString(), - m_inMemoryExptInfo->toString()); + TS_ASSERT(dynamic_cast<FileBackedExperimentInfo*>(clonedFileBacked)); + delete clonedFileBacked; } diff --git a/Code/Mantid/Framework/API/test/FileFinderTest.h b/Code/Mantid/Framework/API/test/FileFinderTest.h index 728a394221e0cf46f454f88625f67f53a133562b..927b0d4c8efa89d68c1f850ad922d84ea952fca1 100644 --- a/Code/Mantid/Framework/API/test/FileFinderTest.h +++ b/Code/Mantid/Framework/API/test/FileFinderTest.h @@ -105,12 +105,48 @@ public: m_facFile.remove(); } - void testGetFullPath() + void testGetFullPathWithFilename() { std::string path = FileFinder::Instance().getFullPath("CSP78173.raw"); TS_ASSERT(!path.empty()); } + void testGetFullPathWithDirectoryFindsDirectoryPath() + { + // Use the Schema directory under instrument + std::string path = FileFinder::Instance().getFullPath("Schema"); + TS_ASSERT(!path.empty()); + + // Code has separate path for path relative to working directory so check that too + std::string tempTestName("__FileFinderTestTempTestDir__"); + Poco::File tempTestDir(Poco::Path().resolve(tempTestName)); + tempTestDir.createDirectory(); + + path = FileFinder::Instance().getFullPath(tempTestName); + TS_ASSERT(!path.empty()); + + tempTestDir.remove(); + + } + + void testGetFullPathSkipsDirectoriesOnRequest() + { + // Use the Schema directory under instrument + const bool ignoreDirs(true); + std::string path = FileFinder::Instance().getFullPath("Schema", ignoreDirs); + TSM_ASSERT("Expected an empty path when looking for a directory, instead I found " + path, path.empty()); + + // Code has separate path for path relative to working directory so check that too + std::string tempTestName("__FileFinderTestTempTestDir__"); + Poco::File tempTestDir(Poco::Path().resolve(tempTestName)); + tempTestDir.createDirectory(); + + path = FileFinder::Instance().getFullPath(tempTestName, ignoreDirs); + TSM_ASSERT("Expected an empty path when looking for a directory relative to current, instead I found " + path, path.empty()); + + tempTestDir.remove(); + } + void testMakeFileNameForISIS() { // Set the facility diff --git a/Code/Mantid/Framework/API/test/FuncMinimizerFactoryTest.h b/Code/Mantid/Framework/API/test/FuncMinimizerFactoryTest.h index 640b7345c483c0aa039beea8f5973f4884c813ca..2cef42deca31ca5c2d84cfb1fe03ef4e210bf9bb 100644 --- a/Code/Mantid/Framework/API/test/FuncMinimizerFactoryTest.h +++ b/Code/Mantid/Framework/API/test/FuncMinimizerFactoryTest.h @@ -33,7 +33,7 @@ public: } }; -DECLARE_FUNCMINIMIZER(FuncMinimizerFactoryTest_A, nedtur); +DECLARE_FUNCMINIMIZER(FuncMinimizerFactoryTest_A, nedtur) class FuncMinimizerFactoryTest : public CxxTest::TestSuite diff --git a/Code/Mantid/Framework/API/test/FunctionFactoryTest.h b/Code/Mantid/Framework/API/test/FunctionFactoryTest.h index 0654f99aca5c3d4e669d0d013428cfc220b60fc0..131988e174f30366b6ae99bcbacf66fe60087bf6 100644 --- a/Code/Mantid/Framework/API/test/FunctionFactoryTest.h +++ b/Code/Mantid/Framework/API/test/FunctionFactoryTest.h @@ -134,10 +134,10 @@ public: }; -DECLARE_FUNCTION(FunctionFactoryTest_FunctA); -DECLARE_FUNCTION(FunctionFactoryTest_FunctB); -DECLARE_FUNCTION(FunctionFactoryTest_CompFunctA); -DECLARE_FUNCTION(FunctionFactoryTest_CompFunctB); +DECLARE_FUNCTION(FunctionFactoryTest_FunctA) +DECLARE_FUNCTION(FunctionFactoryTest_FunctB) +DECLARE_FUNCTION(FunctionFactoryTest_CompFunctA) +DECLARE_FUNCTION(FunctionFactoryTest_CompFunctB) class FunctionFactoryTest : public CxxTest::TestSuite { diff --git a/Code/Mantid/Framework/API/test/FunctionParameterDecoratorTest.h b/Code/Mantid/Framework/API/test/FunctionParameterDecoratorTest.h index 4cea527b1a51457ec25804df2501749dc6335f6a..a73c6afee7b5028f02768b94ed58d798d8f535e8 100644 --- a/Code/Mantid/Framework/API/test/FunctionParameterDecoratorTest.h +++ b/Code/Mantid/Framework/API/test/FunctionParameterDecoratorTest.h @@ -6,7 +6,9 @@ #include "MantidAPI/FunctionParameterDecorator.h" #include "MantidAPI/ParamFunction.h" #include "MantidAPI/FunctionFactory.h" +#include "MantidAPI/WorkspaceGroup.h" #include "MantidKernel/Exception.h" + #include <boost/make_shared.hpp> #include <gtest/gtest.h> @@ -44,11 +46,11 @@ public: } }; -DECLARE_FUNCTION(TestableFunctionParameterDecorator); +DECLARE_FUNCTION(TestableFunctionParameterDecorator) class FunctionWithParameters : public ParamFunction { public: - FunctionWithParameters() : ParamFunction() {} + FunctionWithParameters() : ParamFunction(), m_workspace() {} std::string name() const { return "FunctionWithParameters"; } @@ -63,8 +65,15 @@ public: UNUSED_ARG(values); // Does nothing, not required for this test. } + + void setWorkspace(boost::shared_ptr<const Workspace> ws) { m_workspace = ws; } + + Workspace_const_sptr getWorkspace() const { return m_workspace; } + +private: + Workspace_const_sptr m_workspace; }; -DECLARE_FUNCTION(FunctionWithParameters); +DECLARE_FUNCTION(FunctionWithParameters) class FunctionWithAttributes : public ParamFunction { public: @@ -88,7 +97,7 @@ public: } }; -DECLARE_FUNCTION(FunctionWithAttributes); +DECLARE_FUNCTION(FunctionWithAttributes) class FunctionParameterDecoratorTest : public CxxTest::TestSuite { public: @@ -349,6 +358,25 @@ public: TS_ASSERT_EQUALS(cloned->getParameter("Sigma"), 0.3); } + void testSetWorkspace() { + // using WorkspaceGroup because it is in API + Workspace_const_sptr ws = boost::make_shared<const WorkspaceGroup>(); + + TestableFunctionParameterDecorator invalidFn; + TS_ASSERT_THROWS(invalidFn.setWorkspace(ws), std::runtime_error); + + FunctionParameterDecorator_sptr fn = + getFunctionParameterDecoratorGaussian(); + + TS_ASSERT_THROWS_NOTHING(fn->setWorkspace(ws)); + + boost::shared_ptr<FunctionWithParameters> decorated = + boost::dynamic_pointer_cast<FunctionWithParameters>( + fn->getDecoratedFunction()); + + TS_ASSERT_EQUALS(decorated->getWorkspace(), ws); + } + private: FunctionParameterDecorator_sptr getFunctionParameterDecoratorGaussian() { FunctionParameterDecorator_sptr fn = diff --git a/Code/Mantid/Framework/API/test/FunctionPropertyTest.h b/Code/Mantid/Framework/API/test/FunctionPropertyTest.h index ee488c5a7cdb49d2201bf1d1ffc28f30ae066339..4618e0e2c89c2edb7dea898f3b31d2f4ec5b6404 100644 --- a/Code/Mantid/Framework/API/test/FunctionPropertyTest.h +++ b/Code/Mantid/Framework/API/test/FunctionPropertyTest.h @@ -23,7 +23,7 @@ public: virtual void function(const FunctionDomain&,FunctionValues&)const {} }; -DECLARE_FUNCTION(FunctionPropertyTest_Function); +DECLARE_FUNCTION(FunctionPropertyTest_Function) class FunctionPropertyTest : public CxxTest::TestSuite { diff --git a/Code/Mantid/Framework/API/test/ImmutableCompositeFunctionTest.h b/Code/Mantid/Framework/API/test/ImmutableCompositeFunctionTest.h index cf4287e72d71d6ace7541240d6b9a4bd23e5cae6..b3299c9b3567cddb277fca5f8f428c6a1f5fcceb 100644 --- a/Code/Mantid/Framework/API/test/ImmutableCompositeFunctionTest.h +++ b/Code/Mantid/Framework/API/test/ImmutableCompositeFunctionTest.h @@ -67,7 +67,7 @@ public: std::string name()const {return "ImmutableCompositeFunctionTest_Function";} }; -DECLARE_FUNCTION(ImmutableCompositeFunctionTest_Function); +DECLARE_FUNCTION(ImmutableCompositeFunctionTest_Function) //--------------------------------------------------------------------------------- class ImmutableCompositeFunctionTest_FunctionWithTies: public ImmutableCompositeFunction @@ -95,7 +95,7 @@ public: std::string name()const {return "ImmutableCompositeFunctionTest_FunctionWithTies";} }; -DECLARE_FUNCTION(ImmutableCompositeFunctionTest_FunctionWithTies); +DECLARE_FUNCTION(ImmutableCompositeFunctionTest_FunctionWithTies) //--------------------------------------------------------------------------------- class ImmutableCompositeFunctionTest_FunctionThrow: public ImmutableCompositeFunction diff --git a/Code/Mantid/Framework/API/test/MatrixWorkspaceTest.h b/Code/Mantid/Framework/API/test/MatrixWorkspaceTest.h index 38aedd753411f8461f5de26f1ee3dc0159945c98..d3dbf13890143f1021df863049cd37bb33da38e0 100644 --- a/Code/Mantid/Framework/API/test/MatrixWorkspaceTest.h +++ b/Code/Mantid/Framework/API/test/MatrixWorkspaceTest.h @@ -26,7 +26,7 @@ using namespace testing; // Declare into the factory. -DECLARE_WORKSPACE(WorkspaceTester); +DECLARE_WORKSPACE(WorkspaceTester) /** Create a workspace with numSpectra, with * each spectrum having one detector, at id = workspace index. diff --git a/Code/Mantid/Framework/API/test/MultiDomainFunctionTest.h b/Code/Mantid/Framework/API/test/MultiDomainFunctionTest.h index adf7b610d24711a7b9f21881677d43d44b156570..4e7b1870ec6e8936f7e4e5b365a5332626e8a8f1 100644 --- a/Code/Mantid/Framework/API/test/MultiDomainFunctionTest.h +++ b/Code/Mantid/Framework/API/test/MultiDomainFunctionTest.h @@ -49,7 +49,7 @@ protected: } }; -DECLARE_FUNCTION(MultiDomainFunctionTest_Function); +DECLARE_FUNCTION(MultiDomainFunctionTest_Function) namespace { diff --git a/Code/Mantid/Framework/API/test/RemoteJobManagerFactoryTest.h b/Code/Mantid/Framework/API/test/RemoteJobManagerFactoryTest.h new file mode 100644 index 0000000000000000000000000000000000000000..9fa693d8893d48bac960394befb79f17d06bf71b --- /dev/null +++ b/Code/Mantid/Framework/API/test/RemoteJobManagerFactoryTest.h @@ -0,0 +1,149 @@ +#ifndef REMOTEJOBMANAGERFACTORYTEST_H_ +#define REMOTEJOBMANAGERFACTORYTEST_H_ + +#include "MantidAPI/RemoteJobManagerFactory.h" +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/FacilityInfo.h" + +using namespace Mantid::API; + +// Just a minimal implementation of IRemoteJobManager, sufficient for the +// factory +class TestJM : public IRemoteJobManager { +public: + virtual void authenticate(const std::string &username, + const std::string &password) { + UNUSED_ARG(username); + UNUSED_ARG(password); + } + + virtual std::string + submitRemoteJob(const std::string &transactionID, const std::string &runnable, + const std::string ¶m, const std::string &taskName = "", + const int numNodes = 1, const int coresPerNode = 1) { + UNUSED_ARG(transactionID); + UNUSED_ARG(runnable); + UNUSED_ARG(param); + UNUSED_ARG(taskName); + UNUSED_ARG(numNodes); + UNUSED_ARG(coresPerNode); + return ""; + } + + virtual void downloadRemoteFile(const std::string &transactionID, + const std::string &remoteFileName, + const std::string &localFileName) { + UNUSED_ARG(transactionID); + UNUSED_ARG(remoteFileName); + UNUSED_ARG(localFileName); + } + + virtual std::vector<RemoteJobInfo> queryAllRemoteJobs() const { + return std::vector<RemoteJobInfo>(); + } + + virtual std::vector<std::string> + queryRemoteFile(const std::string &transactionID) const { + UNUSED_ARG(transactionID); + return std::vector<std::string>(); + } + + virtual RemoteJobInfo queryRemoteJob(const std::string &jobID) const { + UNUSED_ARG(jobID); + return RemoteJobInfo(); + } + + virtual std::string startRemoteTransaction() { return ""; } + + virtual void stopRemoteTransaction(const std::string &transactionID) { + UNUSED_ARG(transactionID); + } + + virtual void abortRemoteJob(const std::string &jobID) { UNUSED_ARG(jobID); } + + virtual void uploadRemoteFile(const std::string &transactionID, + const std::string &remoteFileName, + const std::string &localFileName) { + UNUSED_ARG(transactionID); + UNUSED_ARG(remoteFileName); + UNUSED_ARG(localFileName); + } +}; + +class RemoteJobManagerFactoryTest : public CxxTest::TestSuite { +public: + void test_unsubscribed() { + + IRemoteJobManager_sptr jobManager; + TS_ASSERT_THROWS( + jobManager = RemoteJobManagerFactory::Instance().create("Inexistent"), + std::runtime_error); + + TS_ASSERT_THROWS(jobManager = + RemoteJobManagerFactory::Instance().create("TestJM"), + std::runtime_error); + } + + // minimal positive test + void test_createTestJM() { + RemoteJobManagerFactory::Instance().subscribe<TestJM>("TestJM"); + // throws not found cause it is not in facilities.xml, but otherwise fine + TS_ASSERT_THROWS( + jm = Mantid::API::RemoteJobManagerFactory::Instance().create("TestJM"), + Mantid::Kernel::Exception::NotFoundError); + } + + // this must fail, resource not found in the current facility + void test_createAlienResource() { + // save facility, do this before any changes + const Mantid::Kernel::FacilityInfo &prevFac = + Mantid::Kernel::ConfigService::Instance().getFacility(); + + Mantid::Kernel::ConfigService::Instance().setFacility("ISIS"); + TS_ASSERT_THROWS( + jm = Mantid::API::RemoteJobManagerFactory::Instance().create("Fermi"), + Mantid::Kernel::Exception::NotFoundError); + + Mantid::Kernel::ConfigService::Instance().setFacility("SNS"); + TS_ASSERT_THROWS( + Mantid::API::IRemoteJobManager_sptr jobManager = + Mantid::API::RemoteJobManagerFactory::Instance().create( + "SCARF@STFC"), + Mantid::Kernel::Exception::NotFoundError); + + // restore facility, always do this at the end + Mantid::Kernel::ConfigService::Instance().setFacility(prevFac.name()); + } + + // a simple positive test + void test_createRemoteManagers() { + // save facility, do this before any changes + const Mantid::Kernel::FacilityInfo &prevFac = + Mantid::Kernel::ConfigService::Instance().getFacility(); + + Mantid::Kernel::ConfigService::Instance().setFacility("SNS"); + // TODO: at the moment these two create throw a NotFoundError + // because the RemoteJobManager classes are missing and have not + // done a DECLARE_REMOTEJOBMANAGER. Change this test when that is + // done (ticket #11126 etc.) + TS_ASSERT_THROWS( + Mantid::API::IRemoteJobManager_sptr jobManager = + Mantid::API::RemoteJobManagerFactory::Instance().create("Fermi"), + Mantid::Kernel::Exception::NotFoundError); + + Mantid::Kernel::ConfigService::Instance().setFacility("ISIS"); + TS_ASSERT_THROWS( + Mantid::API::IRemoteJobManager_sptr jobManager = + Mantid::API::RemoteJobManagerFactory::Instance().create( + "SCARF@STFC"), + Mantid::Kernel::Exception::NotFoundError); + + // restore facility, always do this at the end + Mantid::Kernel::ConfigService::Instance().setFacility(prevFac.name()); + } + +private: + Mantid::API::IRemoteJobManager_sptr jm; +}; + +#endif /* REMOTEJOBMANAGERFACTORYTEST_H_ */ diff --git a/Code/Mantid/Framework/API/test/VectorParameterParserTest.h b/Code/Mantid/Framework/API/test/VectorParameterParserTest.h index ece3e673a302aa86190a7f7bb1e686791397c597..305353f12e6433e7d1a774a3e02708e10ab9c3ae 100644 --- a/Code/Mantid/Framework/API/test/VectorParameterParserTest.h +++ b/Code/Mantid/Framework/API/test/VectorParameterParserTest.h @@ -94,7 +94,7 @@ public: TSM_ASSERT_THROWS("No successor, so should throw!", parser.createParameter(pRootElem), std::runtime_error); } - DECLARE_VECTOR_PARAMETER(SucessorVectorParameter, double); + DECLARE_VECTOR_PARAMETER(SucessorVectorParameter, double) void testChainOfResponsibility() { diff --git a/Code/Mantid/Framework/Algorithms/src/AppendSpectra.cpp b/Code/Mantid/Framework/Algorithms/src/AppendSpectra.cpp index 6567ccf080c3a8d5506d6f5ef140c1930385a1d2..7c37d7c6e2cb40b7cba7b9cf5a7e3cdd90bcd845 100644 --- a/Code/Mantid/Framework/Algorithms/src/AppendSpectra.cpp +++ b/Code/Mantid/Framework/Algorithms/src/AppendSpectra.cpp @@ -23,10 +23,10 @@ AppendSpectra::AppendSpectra() : WorkspaceJoiners() {} AppendSpectra::~AppendSpectra() {} /// Algorithm's name for identification. @see Algorithm::name -const std::string AppendSpectra::name() const { return "AppendSpectra"; }; +const std::string AppendSpectra::name() const { return "AppendSpectra"; } /// Algorithm's version for identification. @see Algorithm::version -int AppendSpectra::version() const { return 1; }; +int AppendSpectra::version() const { return 1; } /** Initialize the algorithm's properties. */ diff --git a/Code/Mantid/Framework/Algorithms/src/AverageLogData.cpp b/Code/Mantid/Framework/Algorithms/src/AverageLogData.cpp index 40fa96ee2e9fe32c5a6ce8907e461b0eac7ffe5d..7430a5f108bc389ce1fdb161546632a23342ae76 100644 --- a/Code/Mantid/Framework/Algorithms/src/AverageLogData.cpp +++ b/Code/Mantid/Framework/Algorithms/src/AverageLogData.cpp @@ -20,10 +20,10 @@ AverageLogData::~AverageLogData() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string AverageLogData::name() const { return "AverageLogData"; }; +const std::string AverageLogData::name() const { return "AverageLogData"; } /// Algorithm's version for identification. @see Algorithm::version -int AverageLogData::version() const { return 1; }; +int AverageLogData::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string AverageLogData::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/CalculateDIFC.cpp b/Code/Mantid/Framework/Algorithms/src/CalculateDIFC.cpp index a77fb56a196855d006605f368ce155e3e076e277..8b7b1fcbf156220bf9cd4154b2f5d59d376b7358 100644 --- a/Code/Mantid/Framework/Algorithms/src/CalculateDIFC.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CalculateDIFC.cpp @@ -35,7 +35,7 @@ const std::string CalculateDIFC::name() const { return "CalculateDIFC"; } /// Algorithm's version for identification. @see Algorithm::version int CalculateDIFC::version() const { return 1; -}; +} /// Algorithm's category for identification. @see Algorithm::category const std::string CalculateDIFC::category() const { @@ -45,7 +45,7 @@ const std::string CalculateDIFC::category() const { /// Algorithm's summary for use in the GUI and help. @see Algorithm::summary const std::string CalculateDIFC::summary() const { return "Calculate the DIFC for every pixel"; -}; +} //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. diff --git a/Code/Mantid/Framework/Algorithms/src/CalculateResolution.cpp b/Code/Mantid/Framework/Algorithms/src/CalculateResolution.cpp index 51eac3c536bc4914f89856e77a8a1c0c8c8dbc08..a0a8980966416a5a744c5026214cf3c2935a9db1 100644 --- a/Code/Mantid/Framework/Algorithms/src/CalculateResolution.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CalculateResolution.cpp @@ -34,10 +34,10 @@ CalculateResolution::~CalculateResolution() {} /// Algorithm's name for identification. @see Algorithm::name const std::string CalculateResolution::name() const { return "CalculateResolution"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int CalculateResolution::version() const { return 1; }; +int CalculateResolution::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string CalculateResolution::category() const { @@ -48,7 +48,7 @@ const std::string CalculateResolution::category() const { const std::string CalculateResolution::summary() const { return "Calculates the reflectometry resolution (dQ/Q) for a given " "workspace."; -}; +} //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. diff --git a/Code/Mantid/Framework/Algorithms/src/CalculateSlits.cpp b/Code/Mantid/Framework/Algorithms/src/CalculateSlits.cpp index 7808595add88994465b14b5c569b5b525a5703fb..b3e4872292cddebc315d3387aebc3d1d6398c8ec 100644 --- a/Code/Mantid/Framework/Algorithms/src/CalculateSlits.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CalculateSlits.cpp @@ -28,10 +28,10 @@ CalculateSlits::~CalculateSlits() {} /// Algorithm's name for identification. @see Algorithm::name const std::string CalculateSlits::name() const { return "CalculateSlits"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int CalculateSlits::version() const { return 1; }; +int CalculateSlits::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string CalculateSlits::category() const { @@ -41,7 +41,7 @@ const std::string CalculateSlits::category() const { /// Algorithm's summary for use in the GUI and help. @see Algorithm::summary const std::string CalculateSlits::summary() const { return "Calculates appropriate slit widths for reflectometry instruments."; -}; +} //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. diff --git a/Code/Mantid/Framework/Algorithms/src/ChangeLogTime.cpp b/Code/Mantid/Framework/Algorithms/src/ChangeLogTime.cpp index 8663e0a329e62384d965adaabd104a56db599aae..a42d58d76769cb5da8fd40d4cbaad43b3d1549cd 100644 --- a/Code/Mantid/Framework/Algorithms/src/ChangeLogTime.cpp +++ b/Code/Mantid/Framework/Algorithms/src/ChangeLogTime.cpp @@ -7,7 +7,7 @@ namespace Mantid { namespace Algorithms { // Register the algorithm into the AlgorithmFactory -DECLARE_ALGORITHM(ChangeLogTime); +DECLARE_ALGORITHM(ChangeLogTime) using std::string; using std::stringstream; diff --git a/Code/Mantid/Framework/Algorithms/src/ClearInstrumentParameters.cpp b/Code/Mantid/Framework/Algorithms/src/ClearInstrumentParameters.cpp index 74fc77c9e1d3aface1ff2fbedf61fa3e38e8e003..04c3f06953c48b941a9bc5f62214ff9483e010b1 100644 --- a/Code/Mantid/Framework/Algorithms/src/ClearInstrumentParameters.cpp +++ b/Code/Mantid/Framework/Algorithms/src/ClearInstrumentParameters.cpp @@ -29,7 +29,7 @@ ClearInstrumentParameters::~ClearInstrumentParameters() {} /// Algorithm's name for identification. @see Algorithm::name const std::string ClearInstrumentParameters::name() const { return "ClearInstrumentParameters"; -}; +} /// Summary of the algorithm's purpose. @see Algorithm::summary const std::string ClearInstrumentParameters::summary() const { @@ -37,7 +37,7 @@ const std::string ClearInstrumentParameters::summary() const { } /// Algorithm's version for identification. @see Algorithm::version -int ClearInstrumentParameters::version() const { return 1; }; +int ClearInstrumentParameters::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string ClearInstrumentParameters::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/ClearMaskFlag.cpp b/Code/Mantid/Framework/Algorithms/src/ClearMaskFlag.cpp index 71b53a9b1d99c61234c6a27cbfe26addbb64e31f..ba16cd12b7f8044256c751457a1aa14eeb3b6a06 100644 --- a/Code/Mantid/Framework/Algorithms/src/ClearMaskFlag.cpp +++ b/Code/Mantid/Framework/Algorithms/src/ClearMaskFlag.cpp @@ -21,10 +21,10 @@ ClearMaskFlag::~ClearMaskFlag() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string ClearMaskFlag::name() const { return "ClearMaskFlag"; }; +const std::string ClearMaskFlag::name() const { return "ClearMaskFlag"; } /// Algorithm's version for identification. @see Algorithm::version -int ClearMaskFlag::version() const { return 1; }; +int ClearMaskFlag::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string ClearMaskFlag::category() const { return "Utility"; } diff --git a/Code/Mantid/Framework/Algorithms/src/ConvertAxesToRealSpace.cpp b/Code/Mantid/Framework/Algorithms/src/ConvertAxesToRealSpace.cpp index 6ef693883bb56513353d84f4ed220d3722750a13..0305cd928470fd7a5dcf0d54204b66d680741784 100644 --- a/Code/Mantid/Framework/Algorithms/src/ConvertAxesToRealSpace.cpp +++ b/Code/Mantid/Framework/Algorithms/src/ConvertAxesToRealSpace.cpp @@ -35,7 +35,7 @@ const std::string ConvertAxesToRealSpace::name() const { } /// Algorithm's version for identification. @see Algorithm::version -int ConvertAxesToRealSpace::version() const { return 1; }; +int ConvertAxesToRealSpace::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string ConvertAxesToRealSpace::category() const { @@ -46,7 +46,7 @@ const std::string ConvertAxesToRealSpace::category() const { const std::string ConvertAxesToRealSpace::summary() const { return "Converts the spectrum and TOF axes to real space values, integrating " "the data in the process"; -}; +} //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. diff --git a/Code/Mantid/Framework/Algorithms/src/ConvertEmptyToTof.cpp b/Code/Mantid/Framework/Algorithms/src/ConvertEmptyToTof.cpp index 28bbd9076ecbcf22d92efdc8e57f623dd3f505f1..144171a08a4da4024893ff6003757e3e2ecbf8ee 100644 --- a/Code/Mantid/Framework/Algorithms/src/ConvertEmptyToTof.cpp +++ b/Code/Mantid/Framework/Algorithms/src/ConvertEmptyToTof.cpp @@ -39,10 +39,10 @@ ConvertEmptyToTof::~ConvertEmptyToTof() {} /// Algorithm's name for identification. @see Algorithm::name const std::string ConvertEmptyToTof::name() const { return "ConvertEmptyToTof"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int ConvertEmptyToTof::version() const { return 1; }; +int ConvertEmptyToTof::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string ConvertEmptyToTof::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/ConvertToHistogram.cpp b/Code/Mantid/Framework/Algorithms/src/ConvertToHistogram.cpp index 3b87dc49dbe5d080dbe0b425abbc117cdb715232..37acbb1439ea3462532815b25831d0052ef30db2 100644 --- a/Code/Mantid/Framework/Algorithms/src/ConvertToHistogram.cpp +++ b/Code/Mantid/Framework/Algorithms/src/ConvertToHistogram.cpp @@ -7,7 +7,7 @@ namespace Mantid { namespace Algorithms { -DECLARE_ALGORITHM(ConvertToHistogram); +DECLARE_ALGORITHM(ConvertToHistogram) using API::MatrixWorkspace_sptr; using Mantid::MantidVec; diff --git a/Code/Mantid/Framework/Algorithms/src/ConvertToPointData.cpp b/Code/Mantid/Framework/Algorithms/src/ConvertToPointData.cpp index ccc2e8ac79b5c8ff788a56868d9e4b32bb49008d..739ca37a9109c93cadafb7bdf95aa4d6e12d1800 100644 --- a/Code/Mantid/Framework/Algorithms/src/ConvertToPointData.cpp +++ b/Code/Mantid/Framework/Algorithms/src/ConvertToPointData.cpp @@ -7,7 +7,7 @@ namespace Mantid { namespace Algorithms { -DECLARE_ALGORITHM(ConvertToPointData); +DECLARE_ALGORITHM(ConvertToPointData) using API::MatrixWorkspace_sptr; using Mantid::MantidVec; diff --git a/Code/Mantid/Framework/Algorithms/src/CopyLogs.cpp b/Code/Mantid/Framework/Algorithms/src/CopyLogs.cpp index f7aadd28a094c9c05d02f86fd93e9a54df1b33a0..c250b7077847c64fa0d37e3716190dcec0afffdf 100644 --- a/Code/Mantid/Framework/Algorithms/src/CopyLogs.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CopyLogs.cpp @@ -23,10 +23,10 @@ CopyLogs::~CopyLogs() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string CopyLogs::name() const { return "CopyLogs"; }; +const std::string CopyLogs::name() const { return "CopyLogs"; } /// Algorithm's version for identification. @see Algorithm::version -int CopyLogs::version() const { return 1; }; +int CopyLogs::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string CopyLogs::category() const { return "Utility\\Workspaces"; } diff --git a/Code/Mantid/Framework/Algorithms/src/CreateFlatEventWorkspace.cpp b/Code/Mantid/Framework/Algorithms/src/CreateFlatEventWorkspace.cpp index f2dc26c177f68fc2ff56e71c025bdf75b46d2e31..525c556bfca688aa7dd33a8c7ee7ecf386cbb0e0 100644 --- a/Code/Mantid/Framework/Algorithms/src/CreateFlatEventWorkspace.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CreateFlatEventWorkspace.cpp @@ -25,10 +25,10 @@ CreateFlatEventWorkspace::~CreateFlatEventWorkspace() {} /// Algorithm's name for identification. @see Algorithm::name const std::string CreateFlatEventWorkspace::name() const { return "CreateFlatEventWorkspace"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int CreateFlatEventWorkspace::version() const { return 1; }; +int CreateFlatEventWorkspace::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string CreateFlatEventWorkspace::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/CreateSampleWorkspace.cpp b/Code/Mantid/Framework/Algorithms/src/CreateSampleWorkspace.cpp index 0b665c471eb4a41cf1bce71853622bb3fa61d1f1..0c08dda844cbe54c945b2b9df5569fb1ff425797 100644 --- a/Code/Mantid/Framework/Algorithms/src/CreateSampleWorkspace.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CreateSampleWorkspace.cpp @@ -47,10 +47,10 @@ CreateSampleWorkspace::~CreateSampleWorkspace() { delete m_randGen; } /// Algorithm's name for identification. @see Algorithm::name const std::string CreateSampleWorkspace::name() const { return "CreateSampleWorkspace"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int CreateSampleWorkspace::version() const { return 1; }; +int CreateSampleWorkspace::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string CreateSampleWorkspace::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/CreateTransmissionWorkspace.cpp b/Code/Mantid/Framework/Algorithms/src/CreateTransmissionWorkspace.cpp index ac913604c97f872015616edfd73bf1bb67a5371b..2b7b6da122750c306b499535f4028362fcaf0a29 100644 --- a/Code/Mantid/Framework/Algorithms/src/CreateTransmissionWorkspace.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CreateTransmissionWorkspace.cpp @@ -32,10 +32,10 @@ CreateTransmissionWorkspace::~CreateTransmissionWorkspace() {} /// Algorithm's name for identification. @see Algorithm::name const std::string CreateTransmissionWorkspace::name() const { return "CreateTransmissionWorkspace"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int CreateTransmissionWorkspace::version() const { return 1; }; +int CreateTransmissionWorkspace::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string CreateTransmissionWorkspace::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/DeleteWorkspace.cpp b/Code/Mantid/Framework/Algorithms/src/DeleteWorkspace.cpp index 329b737da1923c24e6b4b8c493b03253961dcc37..7cb53d9b5af47c1ef13374b3de1e1101bd04fea7 100644 --- a/Code/Mantid/Framework/Algorithms/src/DeleteWorkspace.cpp +++ b/Code/Mantid/Framework/Algorithms/src/DeleteWorkspace.cpp @@ -8,7 +8,7 @@ namespace Mantid { namespace Algorithms { // Register the algorithm -DECLARE_ALGORITHM(DeleteWorkspace); +DECLARE_ALGORITHM(DeleteWorkspace) //-------------------------------------------------------------------------- // Private member functions diff --git a/Code/Mantid/Framework/Algorithms/src/DetectorDiagnostic.cpp b/Code/Mantid/Framework/Algorithms/src/DetectorDiagnostic.cpp index 2b6ab8e2618e18c0dcd1df852bc7105428b10d3c..35dafe442d1123b564500d52c744a7b9fa1489de 100644 --- a/Code/Mantid/Framework/Algorithms/src/DetectorDiagnostic.cpp +++ b/Code/Mantid/Framework/Algorithms/src/DetectorDiagnostic.cpp @@ -737,6 +737,6 @@ double DetectorDiagnostic::advanceProgress(double toAdd) { void DetectorDiagnostic::failProgress(RunTime aborted) { advanceProgress(-aborted); m_TotalTime -= aborted; -}; +} } } diff --git a/Code/Mantid/Framework/Algorithms/src/DetectorEfficiencyCorUser.cpp b/Code/Mantid/Framework/Algorithms/src/DetectorEfficiencyCorUser.cpp index 4c92103f327c915a79fa3e498c7280ce2783f63c..559a747688bc1e561cf4550995d40415d180174a 100644 --- a/Code/Mantid/Framework/Algorithms/src/DetectorEfficiencyCorUser.cpp +++ b/Code/Mantid/Framework/Algorithms/src/DetectorEfficiencyCorUser.cpp @@ -29,10 +29,10 @@ DetectorEfficiencyCorUser::~DetectorEfficiencyCorUser() {} /// Algorithm's name for identification. @see Algorithm::name const std::string DetectorEfficiencyCorUser::name() const { return "DetectorEfficiencyCorUser"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int DetectorEfficiencyCorUser::version() const { return 1; }; +int DetectorEfficiencyCorUser::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string DetectorEfficiencyCorUser::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/FilterByXValue.cpp b/Code/Mantid/Framework/Algorithms/src/FilterByXValue.cpp index a73f536d6edfcd52d45523298f83865f50d31172..29a8be14083c59ce77e8d373ef3335834a0a5ea7 100644 --- a/Code/Mantid/Framework/Algorithms/src/FilterByXValue.cpp +++ b/Code/Mantid/Framework/Algorithms/src/FilterByXValue.cpp @@ -17,9 +17,9 @@ FilterByXValue::FilterByXValue() {} FilterByXValue::~FilterByXValue() {} /// Algorithm's name for identification. @see Algorithm::name -const std::string FilterByXValue::name() const { return "FilterByXValue"; }; +const std::string FilterByXValue::name() const { return "FilterByXValue"; } /// Algorithm's version for identification. @see Algorithm::version -int FilterByXValue::version() const { return 1; }; +int FilterByXValue::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string FilterByXValue::category() const { return "Events\\EventFiltering"; diff --git a/Code/Mantid/Framework/Algorithms/src/GroupWorkspaces.cpp b/Code/Mantid/Framework/Algorithms/src/GroupWorkspaces.cpp index fd55a82efa033b870456698cb54bcdb7ea395ecb..110b07a9e15adb4491cc1a95cbe344cf3f23d8f8 100644 --- a/Code/Mantid/Framework/Algorithms/src/GroupWorkspaces.cpp +++ b/Code/Mantid/Framework/Algorithms/src/GroupWorkspaces.cpp @@ -7,7 +7,7 @@ namespace Mantid { namespace Algorithms { -DECLARE_ALGORITHM(GroupWorkspaces); +DECLARE_ALGORITHM(GroupWorkspaces) using namespace Kernel; using namespace API; diff --git a/Code/Mantid/Framework/Algorithms/src/IntegrateByComponent.cpp b/Code/Mantid/Framework/Algorithms/src/IntegrateByComponent.cpp index f5e1a98e61b37a35ff1fa027cfb445a165ff1ed3..3736939ef44d5308342132576d077262bd22c1a5 100644 --- a/Code/Mantid/Framework/Algorithms/src/IntegrateByComponent.cpp +++ b/Code/Mantid/Framework/Algorithms/src/IntegrateByComponent.cpp @@ -25,10 +25,10 @@ IntegrateByComponent::~IntegrateByComponent() {} /// Algorithm's name for identification. @see Algorithm::name const std::string IntegrateByComponent::name() const { return "IntegrateByComponent"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int IntegrateByComponent::version() const { return 1; }; +int IntegrateByComponent::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string IntegrateByComponent::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/LorentzCorrection.cpp b/Code/Mantid/Framework/Algorithms/src/LorentzCorrection.cpp index 0100a0000efc59c6f46b67a98744db4476520d9a..2d42cd4b7ccfccc6e28dfd1c2dbd4103ab9fb745 100644 --- a/Code/Mantid/Framework/Algorithms/src/LorentzCorrection.cpp +++ b/Code/Mantid/Framework/Algorithms/src/LorentzCorrection.cpp @@ -31,7 +31,7 @@ LorentzCorrection::~LorentzCorrection() {} //---------------------------------------------------------------------------------------------- /// Algorithm's version for identification. @see Algorithm::version -int LorentzCorrection::version() const { return 1; }; +int LorentzCorrection::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string LorentzCorrection::category() const { return "Crystal"; } @@ -39,7 +39,7 @@ const std::string LorentzCorrection::category() const { return "Crystal"; } /// Algorithm's summary for use in the GUI and help. @see Algorithm::summary const std::string LorentzCorrection::summary() const { return "Performs a white beam Lorentz Correction"; -}; +} const std::string LorentzCorrection::name() const { return "LorentzCorrection"; diff --git a/Code/Mantid/Framework/Algorithms/src/MedianDetectorTest.cpp b/Code/Mantid/Framework/Algorithms/src/MedianDetectorTest.cpp index db2e7c678a22d16a0b612aaebd87c890ab344e01..a6798977247cb4b40b811f4c0e7df63406af6847 100644 --- a/Code/Mantid/Framework/Algorithms/src/MedianDetectorTest.cpp +++ b/Code/Mantid/Framework/Algorithms/src/MedianDetectorTest.cpp @@ -19,7 +19,7 @@ using namespace Geometry; MedianDetectorTest::MedianDetectorTest() : DetectorDiagnostic(), m_inputWS(), m_loFrac(0.1), m_hiFrac(1.5), m_minSpec(0), m_maxSpec(EMPTY_INT()), m_rangeLower(0.0), - m_rangeUpper(0.0){}; + m_rangeUpper(0.0){} const std::string MedianDetectorTest::category() const { return "Diagnostics"; } diff --git a/Code/Mantid/Framework/Algorithms/src/ModeratorTzero.cpp b/Code/Mantid/Framework/Algorithms/src/ModeratorTzero.cpp index 36224d81a0e9b70fbd1effe9d12edc1b6a5b3b5d..c7a22c2a163256a76b46dd8a990492c1abc5a1f1 100644 --- a/Code/Mantid/Framework/Algorithms/src/ModeratorTzero.cpp +++ b/Code/Mantid/Framework/Algorithms/src/ModeratorTzero.cpp @@ -14,7 +14,7 @@ namespace Mantid { namespace Algorithms { // Register the algorithm into the AlgorithmFactory -DECLARE_ALGORITHM(ModeratorTzero); +DECLARE_ALGORITHM(ModeratorTzero) using namespace Mantid::Kernel; using namespace Mantid::API; diff --git a/Code/Mantid/Framework/Algorithms/src/MuonGroupDetectors.cpp b/Code/Mantid/Framework/Algorithms/src/MuonGroupDetectors.cpp index b1d711f7e208823eac0dd0552ba481c13838ff39..105188cee04e4f7794ab05415807019397dac28f 100644 --- a/Code/Mantid/Framework/Algorithms/src/MuonGroupDetectors.cpp +++ b/Code/Mantid/Framework/Algorithms/src/MuonGroupDetectors.cpp @@ -26,10 +26,10 @@ MuonGroupDetectors::~MuonGroupDetectors() {} /// Algorithm's name for identification. @see Algorithm::name const std::string MuonGroupDetectors::name() const { return "MuonGroupDetectors"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int MuonGroupDetectors::version() const { return 1; }; +int MuonGroupDetectors::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string MuonGroupDetectors::category() const { return "Muon"; } diff --git a/Code/Mantid/Framework/Algorithms/src/NormaliseByDetector.cpp b/Code/Mantid/Framework/Algorithms/src/NormaliseByDetector.cpp index 3c4cfc0867cd45227d302ff1bc2c726b0007d5e3..97e2ee6a72ee2c4ce3bddd1cb8b9f1af6f8a61b9 100644 --- a/Code/Mantid/Framework/Algorithms/src/NormaliseByDetector.cpp +++ b/Code/Mantid/Framework/Algorithms/src/NormaliseByDetector.cpp @@ -39,10 +39,10 @@ NormaliseByDetector::~NormaliseByDetector() {} /// Algorithm's name for identification. @see Algorithm::name const std::string NormaliseByDetector::name() const { return "NormaliseByDetector"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int NormaliseByDetector::version() const { return 1; }; +int NormaliseByDetector::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string NormaliseByDetector::category() const { @@ -199,7 +199,7 @@ NormaliseByDetector::processHistograms(MatrixWorkspace_sptr inWS) { } return denominatorWS; -}; +} //---------------------------------------------------------------------------------------------- /** Execute the algorithm. diff --git a/Code/Mantid/Framework/Algorithms/src/Pause.cpp b/Code/Mantid/Framework/Algorithms/src/Pause.cpp index 007f5e10f8dd170a935eca1e53988155e13c11f4..170559caff20115e7cbdc320bd1661fff5aa418d 100644 --- a/Code/Mantid/Framework/Algorithms/src/Pause.cpp +++ b/Code/Mantid/Framework/Algorithms/src/Pause.cpp @@ -24,10 +24,10 @@ Pause::~Pause() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string Pause::name() const { return "Pause"; }; +const std::string Pause::name() const { return "Pause"; } /// Algorithm's version for identification. @see Algorithm::version -int Pause::version() const { return 1; }; +int Pause::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string Pause::category() const { return "Utility\\Development"; } diff --git a/Code/Mantid/Framework/Algorithms/src/PerformIndexOperations.cpp b/Code/Mantid/Framework/Algorithms/src/PerformIndexOperations.cpp index 3a8fb0f7dd754c470699eed9ebe88c7854eb74ff..a3d760f3e67e301a0fef2bc41a1c0346fec13bc5 100644 --- a/Code/Mantid/Framework/Algorithms/src/PerformIndexOperations.cpp +++ b/Code/Mantid/Framework/Algorithms/src/PerformIndexOperations.cpp @@ -268,10 +268,10 @@ PerformIndexOperations::~PerformIndexOperations() {} /// Algorithm's name for identification. @see Algorithm::name const std::string PerformIndexOperations::name() const { return "PerformIndexOperations"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int PerformIndexOperations::version() const { return 1; }; +int PerformIndexOperations::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string PerformIndexOperations::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/PolarizationCorrection.cpp b/Code/Mantid/Framework/Algorithms/src/PolarizationCorrection.cpp index b2a1760dd6fc0996ab6d2d473123f7d9bb536224..4a9ef9b303a1f28ba5b1f2cac7ad778853fffc73 100644 --- a/Code/Mantid/Framework/Algorithms/src/PolarizationCorrection.cpp +++ b/Code/Mantid/Framework/Algorithms/src/PolarizationCorrection.cpp @@ -119,10 +119,10 @@ PolarizationCorrection::~PolarizationCorrection() {} /// Algorithm's name for identification. @see Algorithm::name const std::string PolarizationCorrection::name() const { return "PolarizationCorrection"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int PolarizationCorrection::version() const { return 1; }; +int PolarizationCorrection::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string PolarizationCorrection::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/RebinByPulseTimes.cpp b/Code/Mantid/Framework/Algorithms/src/RebinByPulseTimes.cpp index 2bbe560658f4b97186cfeb60b1a08292dd0940e9..fce9355eb4d9257196073111df03d062ad9d68d7 100644 --- a/Code/Mantid/Framework/Algorithms/src/RebinByPulseTimes.cpp +++ b/Code/Mantid/Framework/Algorithms/src/RebinByPulseTimes.cpp @@ -29,10 +29,10 @@ RebinByPulseTimes::~RebinByPulseTimes() {} /// Algorithm's name for identification. @see Algorithm::name const std::string RebinByPulseTimes::name() const { return "RebinByPulseTimes"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int RebinByPulseTimes::version() const { return 1; }; +int RebinByPulseTimes::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string RebinByPulseTimes::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/RebinByTimeAtSample.cpp b/Code/Mantid/Framework/Algorithms/src/RebinByTimeAtSample.cpp index c7d3f0491c987b7a93139e6347725ab34d14e17c..ff2234d2fec9fa9a206c1d2ecf0220f1f2512215 100644 --- a/Code/Mantid/Framework/Algorithms/src/RebinByTimeAtSample.cpp +++ b/Code/Mantid/Framework/Algorithms/src/RebinByTimeAtSample.cpp @@ -28,7 +28,7 @@ RebinByTimeAtSample::~RebinByTimeAtSample() {} //---------------------------------------------------------------------------------------------- /// Algorithm's version for identification. @see Algorithm::version -int RebinByTimeAtSample::version() const { return 1; }; +int RebinByTimeAtSample::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string RebinByTimeAtSample::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/ReflectometryReductionOne.cpp b/Code/Mantid/Framework/Algorithms/src/ReflectometryReductionOne.cpp index ab6ebf78f1ac94f41706b0da58a3857a243705bc..dfb1a2932196bc442fc5ce1046f0f5e833edd8ba 100644 --- a/Code/Mantid/Framework/Algorithms/src/ReflectometryReductionOne.cpp +++ b/Code/Mantid/Framework/Algorithms/src/ReflectometryReductionOne.cpp @@ -95,10 +95,10 @@ ReflectometryReductionOne::~ReflectometryReductionOne() {} /// Algorithm's name for identification. @see Algorithm::name const std::string ReflectometryReductionOne::name() const { return "ReflectometryReductionOne"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int ReflectometryReductionOne::version() const { return 1; }; +int ReflectometryReductionOne::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string ReflectometryReductionOne::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp b/Code/Mantid/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp index f29229096e23610e97eb7e73efc03b43904d4027..884848559d96a6bdeddd81e471ca0d54f71c3b69 100644 --- a/Code/Mantid/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp +++ b/Code/Mantid/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp @@ -31,10 +31,10 @@ ReflectometryReductionOneAuto::~ReflectometryReductionOneAuto() {} /// Algorithm's name for identification. @see Algorithm::name const std::string ReflectometryReductionOneAuto::name() const { return "ReflectometryReductionOneAuto"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int ReflectometryReductionOneAuto::version() const { return 1; }; +int ReflectometryReductionOneAuto::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string ReflectometryReductionOneAuto::category() const { @@ -45,7 +45,7 @@ const std::string ReflectometryReductionOneAuto::category() const { const std::string ReflectometryReductionOneAuto::summary() const { return "Reduces a single TOF/Lambda reflectometry run into a mod Q vs I/I0 " "workspace. Performs transmission corrections."; -}; +} //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. diff --git a/Code/Mantid/Framework/Algorithms/src/RemoveBackground.cpp b/Code/Mantid/Framework/Algorithms/src/RemoveBackground.cpp index 706570edca1093be8f5d0ff5f10a119e0434ca31..8601d1e2c38ec13f727d1200424e329797326ea0 100644 --- a/Code/Mantid/Framework/Algorithms/src/RemoveBackground.cpp +++ b/Code/Mantid/Framework/Algorithms/src/RemoveBackground.cpp @@ -150,7 +150,7 @@ void RemoveBackground::exec() { BackgroundHelper::BackgroundHelper() : m_WSUnit(), m_bgWs(), m_wkWS(), m_pgLog(NULL), m_inPlace(true), m_singleValueBackground(false), m_NBg(0), m_dtBg(1), // m_ErrSq(0), - m_Emode(0), m_L1(0), m_Efix(0), m_Sample(){}; + m_Emode(0), m_L1(0), m_Efix(0), m_Sample(){} /// Destructor BackgroundHelper::~BackgroundHelper() { this->deleteUnitsConverters(); } diff --git a/Code/Mantid/Framework/Algorithms/src/RemoveWorkspaceHistory.cpp b/Code/Mantid/Framework/Algorithms/src/RemoveWorkspaceHistory.cpp index 8d30c4fa14d1734998002801366360dbcddc76a4..4d6ecc74b7c086e20ae676fb58379e41b5325b97 100644 --- a/Code/Mantid/Framework/Algorithms/src/RemoveWorkspaceHistory.cpp +++ b/Code/Mantid/Framework/Algorithms/src/RemoveWorkspaceHistory.cpp @@ -24,10 +24,10 @@ RemoveWorkspaceHistory::~RemoveWorkspaceHistory() {} /// Algorithm's name for identification. @see Algorithm::name const std::string RemoveWorkspaceHistory::name() const { return "RemoveWorkspaceHistory"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int RemoveWorkspaceHistory::version() const { return 1; }; +int RemoveWorkspaceHistory::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string RemoveWorkspaceHistory::category() const { return "Utility"; } @@ -35,7 +35,7 @@ const std::string RemoveWorkspaceHistory::category() const { return "Utility"; } /// Algorithm's summary for identification. @see Algorithm::summary const std::string RemoveWorkspaceHistory::summary() const { return "Removes all algorithm history records from a given workspace."; -}; +} //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. diff --git a/Code/Mantid/Framework/Algorithms/src/ResizeRectangularDetector.cpp b/Code/Mantid/Framework/Algorithms/src/ResizeRectangularDetector.cpp index bb719da642518b5ff56a3da0302eac25d3f2aab6..d5c40de7a071562011e9a415651980c7a7db93b7 100644 --- a/Code/Mantid/Framework/Algorithms/src/ResizeRectangularDetector.cpp +++ b/Code/Mantid/Framework/Algorithms/src/ResizeRectangularDetector.cpp @@ -30,10 +30,10 @@ ResizeRectangularDetector::~ResizeRectangularDetector() {} /// Algorithm's name for identification. @see Algorithm::name const std::string ResizeRectangularDetector::name() const { return "ResizeRectangularDetector"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int ResizeRectangularDetector::version() const { return 1; }; +int ResizeRectangularDetector::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string ResizeRectangularDetector::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/RingProfile.cpp b/Code/Mantid/Framework/Algorithms/src/RingProfile.cpp index b558c1a8584d161ed8d94c5021e3521891d38a4d..21be96faae17a952d49631c3fe09579a7dfd9de7 100644 --- a/Code/Mantid/Framework/Algorithms/src/RingProfile.cpp +++ b/Code/Mantid/Framework/Algorithms/src/RingProfile.cpp @@ -582,7 +582,7 @@ void RingProfile::getBinForPixel(const API::MatrixWorkspace_sptr ws, // call fromAngleToBin (radians) bins_pos[i] = fromAngleToBin(angle, false); } -}; +} /* Return the bin position for a given angle. * @@ -618,7 +618,7 @@ int RingProfile::fromAngleToBin(double angle, bool degree) { angle /= bin_size; return (int)angle; -}; +} } // namespace Algorithms } // namespace Mantid diff --git a/Code/Mantid/Framework/Algorithms/src/SassenaFFT.cpp b/Code/Mantid/Framework/Algorithms/src/SassenaFFT.cpp index c51071190ef9622f8ec8b788cef21823f9254449..bd0e048fd71389869f0d3dd824806f8bb0eb901a 100644 --- a/Code/Mantid/Framework/Algorithms/src/SassenaFFT.cpp +++ b/Code/Mantid/Framework/Algorithms/src/SassenaFFT.cpp @@ -13,7 +13,7 @@ namespace Mantid { namespace Algorithms { // Register the class into the algorithm factory -DECLARE_ALGORITHM(SassenaFFT); +DECLARE_ALGORITHM(SassenaFFT) /// Override Algorithm::checkGroups bool SassenaFFT::checkGroups() { return false; } diff --git a/Code/Mantid/Framework/Algorithms/src/SetInstrumentParameter.cpp b/Code/Mantid/Framework/Algorithms/src/SetInstrumentParameter.cpp index 487d95665918268f99bc46e476c81055492c54f1..e06d9b1f72eb441cf90572f88ff4e4551f7db4a2 100644 --- a/Code/Mantid/Framework/Algorithms/src/SetInstrumentParameter.cpp +++ b/Code/Mantid/Framework/Algorithms/src/SetInstrumentParameter.cpp @@ -30,10 +30,10 @@ SetInstrumentParameter::~SetInstrumentParameter() {} /// Algorithm's name for identification. @see Algorithm::name const std::string SetInstrumentParameter::name() const { return "SetInstrumentParameter"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int SetInstrumentParameter::version() const { return 1; }; +int SetInstrumentParameter::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string SetInstrumentParameter::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/SignalOverError.cpp b/Code/Mantid/Framework/Algorithms/src/SignalOverError.cpp index 2354d0369c331ebc12301081d613c8edebafe971..9d36340512c7e2d896b13d5280fa570ff412d6ed 100644 --- a/Code/Mantid/Framework/Algorithms/src/SignalOverError.cpp +++ b/Code/Mantid/Framework/Algorithms/src/SignalOverError.cpp @@ -25,10 +25,10 @@ SignalOverError::~SignalOverError() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string SignalOverError::name() const { return "SignalOverError"; }; +const std::string SignalOverError::name() const { return "SignalOverError"; } /// Algorithm's version for identification. @see Algorithm::version -int SignalOverError::version() const { return 1; }; +int SignalOverError::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string SignalOverError::category() const { return "Arithmetic"; } diff --git a/Code/Mantid/Framework/Algorithms/src/SpecularReflectionCalculateTheta.cpp b/Code/Mantid/Framework/Algorithms/src/SpecularReflectionCalculateTheta.cpp index 917f3aa741e17ea02c5cbf86e0361f10468ac507..ac7c575361fcc7908661d91c07170dd0c3ddfb63 100644 --- a/Code/Mantid/Framework/Algorithms/src/SpecularReflectionCalculateTheta.cpp +++ b/Code/Mantid/Framework/Algorithms/src/SpecularReflectionCalculateTheta.cpp @@ -35,10 +35,10 @@ SpecularReflectionCalculateTheta::~SpecularReflectionCalculateTheta() {} /// Algorithm's name for identification. @see Algorithm::name const std::string SpecularReflectionCalculateTheta::name() const { return "SpecularReflectionCalculateTheta"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int SpecularReflectionCalculateTheta::version() const { return 1; }; +int SpecularReflectionCalculateTheta::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string SpecularReflectionCalculateTheta::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/SpecularReflectionPositionCorrect.cpp b/Code/Mantid/Framework/Algorithms/src/SpecularReflectionPositionCorrect.cpp index b69a6128a5e1a1ed2db63c9a09233408bc16f782..3497a23d437b317b942c9f2da90897a1a40f95f5 100644 --- a/Code/Mantid/Framework/Algorithms/src/SpecularReflectionPositionCorrect.cpp +++ b/Code/Mantid/Framework/Algorithms/src/SpecularReflectionPositionCorrect.cpp @@ -70,10 +70,10 @@ SpecularReflectionPositionCorrect::~SpecularReflectionPositionCorrect() {} /// Algorithm's name for identification. @see Algorithm::name const std::string SpecularReflectionPositionCorrect::name() const { return "SpecularReflectionPositionCorrect"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int SpecularReflectionPositionCorrect::version() const { return 1; }; +int SpecularReflectionPositionCorrect::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string SpecularReflectionPositionCorrect::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/Stitch1DMany.cpp b/Code/Mantid/Framework/Algorithms/src/Stitch1DMany.cpp index 8b028f620da9c66aa46453d8493847d35becba75..8611b757ee9372acc8d756c7727534fc5312364a 100644 --- a/Code/Mantid/Framework/Algorithms/src/Stitch1DMany.cpp +++ b/Code/Mantid/Framework/Algorithms/src/Stitch1DMany.cpp @@ -207,23 +207,25 @@ void Stitch1DMany::exec() { // List of workspaces to be grouped std::vector<std::string> toGroup; + const std::string groupName = this->getProperty("OutputWorkspace"); + size_t numWSPerGroup = groupWorkspaces[0]->size(); for (size_t i = 0; i < numWSPerGroup; ++i) { // List of workspaces to stitch std::vector<std::string> toProcess; // The name of the resulting workspace - std::string outName; + std::string outName = groupName; for (size_t j = 0; j < groupWorkspaces.size(); ++j) { const std::string wsName = groupWorkspaces[j]->getItem(i)->name(); toProcess.push_back(wsName); - outName += wsName; + outName += "_" + wsName; } - IAlgorithm_sptr stitchAlg = - AlgorithmManager::Instance().create("Stitch1DMany"); + IAlgorithm_sptr stitchAlg = createChildAlgorithm("Stitch1DMany"); stitchAlg->initialize(); + stitchAlg->setAlwaysStoreInADS(true); stitchAlg->setProperty("InputWorkspaces", toProcess); stitchAlg->setProperty("OutputWorkspace", outName); stitchAlg->setProperty("StartOverlaps", m_startOverlaps); @@ -245,11 +247,9 @@ void Stitch1DMany::exec() { scaleFactors.end()); } - const std::string groupName = this->getProperty("OutputWorkspace"); - - IAlgorithm_sptr groupAlg = - AlgorithmManager::Instance().create("GroupWorkspaces"); + IAlgorithm_sptr groupAlg = createChildAlgorithm("GroupWorkspaces"); groupAlg->initialize(); + groupAlg->setAlwaysStoreInADS(true); groupAlg->setProperty("InputWorkspaces", toGroup); groupAlg->setProperty("OutputWorkspace", groupName); groupAlg->execute(); diff --git a/Code/Mantid/Framework/Algorithms/src/SumEventsByLogValue.cpp b/Code/Mantid/Framework/Algorithms/src/SumEventsByLogValue.cpp index 7829bd0452a0062659720df8f9e6a9b34a1b4c62..48f47cff4a6f2b0af50d291e0cf097fc4f95d5ae 100644 --- a/Code/Mantid/Framework/Algorithms/src/SumEventsByLogValue.cpp +++ b/Code/Mantid/Framework/Algorithms/src/SumEventsByLogValue.cpp @@ -10,7 +10,7 @@ namespace Mantid { namespace Algorithms { // Register the class into the algorithm factory -DECLARE_ALGORITHM(SumEventsByLogValue); +DECLARE_ALGORITHM(SumEventsByLogValue) using namespace Kernel; using namespace API; diff --git a/Code/Mantid/Framework/Algorithms/src/UpdateScriptRepository.cpp b/Code/Mantid/Framework/Algorithms/src/UpdateScriptRepository.cpp index b56a1c0be37fa8991388e2e5a10a3596f115e142..45e620542ce14a6f0d2a28b3e1af3f2bdea1df28 100644 --- a/Code/Mantid/Framework/Algorithms/src/UpdateScriptRepository.cpp +++ b/Code/Mantid/Framework/Algorithms/src/UpdateScriptRepository.cpp @@ -22,10 +22,10 @@ UpdateScriptRepository::~UpdateScriptRepository() {} /// Algorithm's name for identification. @see Algorithm::name const std::string UpdateScriptRepository::name() const { return "UpdateScriptRepository"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int UpdateScriptRepository::version() const { return 1; }; +int UpdateScriptRepository::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string UpdateScriptRepository::category() const { return "Utility"; } diff --git a/Code/Mantid/Framework/Algorithms/src/WeightedMeanOfWorkspace.cpp b/Code/Mantid/Framework/Algorithms/src/WeightedMeanOfWorkspace.cpp index baf8f5094140f906c9a723410d0d4feb6c73c7ad..4703eb91d2f8810ff1dca33cc95c7f8986bf8c3f 100644 --- a/Code/Mantid/Framework/Algorithms/src/WeightedMeanOfWorkspace.cpp +++ b/Code/Mantid/Framework/Algorithms/src/WeightedMeanOfWorkspace.cpp @@ -28,10 +28,10 @@ WeightedMeanOfWorkspace::~WeightedMeanOfWorkspace() {} /// Algorithm's name for identification. @see Algorithm::name const std::string WeightedMeanOfWorkspace::name() const { return "WeightedMeanOfWorkspace"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int WeightedMeanOfWorkspace::version() const { return 1; }; +int WeightedMeanOfWorkspace::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string WeightedMeanOfWorkspace::category() const { diff --git a/Code/Mantid/Framework/Algorithms/src/WeightingStrategy.cpp b/Code/Mantid/Framework/Algorithms/src/WeightingStrategy.cpp index f09fd1e6658301afb71350742d40198d5d2cd409..17af7d37dedeb47c3456953a01de9ac1f730c51c 100644 --- a/Code/Mantid/Framework/Algorithms/src/WeightingStrategy.cpp +++ b/Code/Mantid/Framework/Algorithms/src/WeightingStrategy.cpp @@ -15,10 +15,10 @@ namespace Algorithms { Constructor @param cutOff : radius cutoff */ -WeightingStrategy::WeightingStrategy(const double cutOff) : m_cutOff(cutOff){}; +WeightingStrategy::WeightingStrategy(const double cutOff) : m_cutOff(cutOff){} /// Constructor -WeightingStrategy::WeightingStrategy() : m_cutOff(0){}; +WeightingStrategy::WeightingStrategy() : m_cutOff(0){} /// Destructor WeightingStrategy::~WeightingStrategy() {} diff --git a/Code/Mantid/Framework/Algorithms/src/WienerSmooth.cpp b/Code/Mantid/Framework/Algorithms/src/WienerSmooth.cpp index e4baaba6d2b072c91d6a7f4777a8fd2dfb70f7b1..f8762cd5a56678a9a521549a927a4684964050e1 100644 --- a/Code/Mantid/Framework/Algorithms/src/WienerSmooth.cpp +++ b/Code/Mantid/Framework/Algorithms/src/WienerSmooth.cpp @@ -38,7 +38,7 @@ WienerSmooth::~WienerSmooth() {} //---------------------------------------------------------------------------------------------- /// Algorithm's version for identification. @see Algorithm::version -int WienerSmooth::version() const { return 1; }; +int WienerSmooth::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string WienerSmooth::category() const { @@ -48,7 +48,7 @@ const std::string WienerSmooth::category() const { /// Algorithm's summary for use in the GUI and help. @see Algorithm::summary const std::string WienerSmooth::summary() const { return "Smooth spectra using Wiener filter."; -}; +} //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. diff --git a/Code/Mantid/Framework/Algorithms/test/PolarizationCorrectionTest.h b/Code/Mantid/Framework/Algorithms/test/PolarizationCorrectionTest.h index ea8ebf25defd3f47972f3316b709369c6b90be9c..e1c508f642497a2edf88ad230a6d6979d26cffec 100644 --- a/Code/Mantid/Framework/Algorithms/test/PolarizationCorrectionTest.h +++ b/Code/Mantid/Framework/Algorithms/test/PolarizationCorrectionTest.h @@ -178,6 +178,7 @@ public: checkAlg->setChild(true); checkAlg->setProperty("Workspace1", groupWS->getItem(i)); checkAlg->setProperty("Workspace2", outWS->getItem(i)); + checkAlg->setProperty("Tolerance", 3e-16); checkAlg->execute(); const std::string result = checkAlg->getProperty("Result"); TS_ASSERT_EQUALS("Success!", result); diff --git a/Code/Mantid/Framework/Crystal/src/AddPeakHKL.cpp b/Code/Mantid/Framework/Crystal/src/AddPeakHKL.cpp index 78c563d096e9f80d630d3277b441317c5236f09b..2e770043c2b4c4322cbbe4bf855d2b08f1ab60d6 100644 --- a/Code/Mantid/Framework/Crystal/src/AddPeakHKL.cpp +++ b/Code/Mantid/Framework/Crystal/src/AddPeakHKL.cpp @@ -39,13 +39,13 @@ namespace Crystal const std::string AddPeakHKL::name() const { return "AddPeakHKL"; } /// Algorithm's version for identification. @see Algorithm::version - int AddPeakHKL::version() const { return 1;}; + int AddPeakHKL::version() const { return 1;} /// Algorithm's category for identification. @see Algorithm::category const std::string AddPeakHKL::category() const { return "Crystal";} /// Algorithm's summary for use in the GUI and help. @see Algorithm::summary - const std::string AddPeakHKL::summary() const { return "Add a peak in the hkl frame";}; + const std::string AddPeakHKL::summary() const { return "Add a peak in the hkl frame";} //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. diff --git a/Code/Mantid/Framework/Crystal/src/CalculatePeaksHKL.cpp b/Code/Mantid/Framework/Crystal/src/CalculatePeaksHKL.cpp index 46cac8737cdf810c0726e162dccaeca34d9b3322..10dc1653c945a9b9165be5748d7aec67bd2cc759 100644 --- a/Code/Mantid/Framework/Crystal/src/CalculatePeaksHKL.cpp +++ b/Code/Mantid/Framework/Crystal/src/CalculatePeaksHKL.cpp @@ -30,10 +30,10 @@ CalculatePeaksHKL::~CalculatePeaksHKL() {} /// Algorithm's name for identification. @see Algorithm::name const std::string CalculatePeaksHKL::name() const { return "CalculatePeaksHKL"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int CalculatePeaksHKL::version() const { return 1; }; +int CalculatePeaksHKL::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string CalculatePeaksHKL::category() const { return "Crystal"; } diff --git a/Code/Mantid/Framework/Crystal/src/ClearUB.cpp b/Code/Mantid/Framework/Crystal/src/ClearUB.cpp index fdcefa2a8939f31d66ae57874d1f3c960086a577..54f27de7e263aa9c44a2aee4fd43a3c5fd5f17ee 100644 --- a/Code/Mantid/Framework/Crystal/src/ClearUB.cpp +++ b/Code/Mantid/Framework/Crystal/src/ClearUB.cpp @@ -22,10 +22,10 @@ ClearUB::~ClearUB() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string ClearUB::name() const { return "ClearUB"; }; +const std::string ClearUB::name() const { return "ClearUB"; } /// Algorithm's version for identification. @see Algorithm::version -int ClearUB::version() const { return 1; }; +int ClearUB::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string ClearUB::category() const { return "Crystal"; } diff --git a/Code/Mantid/Framework/Crystal/src/CombinePeaksWorkspaces.cpp b/Code/Mantid/Framework/Crystal/src/CombinePeaksWorkspaces.cpp index f59b28b0a0afec6d2bccc69d407f01d1c286392f..e4e518348f73a2af6d0618fe8d555587157fbcff 100644 --- a/Code/Mantid/Framework/Crystal/src/CombinePeaksWorkspaces.cpp +++ b/Code/Mantid/Framework/Crystal/src/CombinePeaksWorkspaces.cpp @@ -27,9 +27,9 @@ CombinePeaksWorkspaces::~CombinePeaksWorkspaces() {} /// Algorithm's name for identification. @see Algorithm::name const std::string CombinePeaksWorkspaces::name() const { return "CombinePeaksWorkspaces"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int CombinePeaksWorkspaces::version() const { return 1; }; +int CombinePeaksWorkspaces::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string CombinePeaksWorkspaces::category() const { return "Crystal"; } diff --git a/Code/Mantid/Framework/Crystal/src/DiffPeaksWorkspaces.cpp b/Code/Mantid/Framework/Crystal/src/DiffPeaksWorkspaces.cpp index 00a3cb839e66ac218354ba7d9b2d0ac266d6ed87..34337d74f916b5f752f209cd46e81ab1639e2530 100644 --- a/Code/Mantid/Framework/Crystal/src/DiffPeaksWorkspaces.cpp +++ b/Code/Mantid/Framework/Crystal/src/DiffPeaksWorkspaces.cpp @@ -25,9 +25,9 @@ DiffPeaksWorkspaces::~DiffPeaksWorkspaces() {} /// Algorithm's name for identification. @see Algorithm::name const std::string DiffPeaksWorkspaces::name() const { return "DiffPeaksWorkspaces"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int DiffPeaksWorkspaces::version() const { return 1; }; +int DiffPeaksWorkspaces::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string DiffPeaksWorkspaces::category() const { return "Crystal"; } diff --git a/Code/Mantid/Framework/Crystal/src/FilterPeaks.cpp b/Code/Mantid/Framework/Crystal/src/FilterPeaks.cpp index efecf7a037a398f7f6a04f7dc48d4b189bde7b5f..86ff9a78ccc89431627d17f7fec913511e499924 100644 --- a/Code/Mantid/Framework/Crystal/src/FilterPeaks.cpp +++ b/Code/Mantid/Framework/Crystal/src/FilterPeaks.cpp @@ -40,9 +40,9 @@ FilterPeaks::FilterPeaks() {} FilterPeaks::~FilterPeaks() {} /// Algorithm's name for identification. @see Algorithm::name -const std::string FilterPeaks::name() const { return "FilterPeaks"; }; +const std::string FilterPeaks::name() const { return "FilterPeaks"; } /// Algorithm's version for identification. @see Algorithm::version -int FilterPeaks::version() const { return 1; }; +int FilterPeaks::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string FilterPeaks::category() const { return "Crystal"; } diff --git a/Code/Mantid/Framework/Crystal/src/FindClusterFaces.cpp b/Code/Mantid/Framework/Crystal/src/FindClusterFaces.cpp index fe9266df134f40195b04b710e4769a0f23ba5705..2332de05184709d69f6492a0b20ea0a374c851ab 100644 --- a/Code/Mantid/Framework/Crystal/src/FindClusterFaces.cpp +++ b/Code/Mantid/Framework/Crystal/src/FindClusterFaces.cpp @@ -270,10 +270,10 @@ FindClusterFaces::~FindClusterFaces() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string FindClusterFaces::name() const { return "FindClusterFaces"; }; +const std::string FindClusterFaces::name() const { return "FindClusterFaces"; } /// Algorithm's version for identification. @see Algorithm::version -int FindClusterFaces::version() const { return 1; }; +int FindClusterFaces::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string FindClusterFaces::category() const { return "Crystal"; } diff --git a/Code/Mantid/Framework/Crystal/src/HasUB.cpp b/Code/Mantid/Framework/Crystal/src/HasUB.cpp index fcc9477ff9ff3357cc5ef6182249279a1491153f..2bf028caa4c0f39b6b4b302ccda2c69a2bf0fcb0 100644 --- a/Code/Mantid/Framework/Crystal/src/HasUB.cpp +++ b/Code/Mantid/Framework/Crystal/src/HasUB.cpp @@ -21,10 +21,10 @@ HasUB::~HasUB() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string HasUB::name() const { return "HasUB"; }; +const std::string HasUB::name() const { return "HasUB"; } /// Algorithm's version for identification. @see Algorithm::version -int HasUB::version() const { return 1; }; +int HasUB::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string HasUB::category() const { return "Crystal"; } diff --git a/Code/Mantid/Framework/Crystal/src/IntegratePeaksHybrid.cpp b/Code/Mantid/Framework/Crystal/src/IntegratePeaksHybrid.cpp index 83c00772d38cabaa8fb32c690d49513dbb3d5737..c7d2f6fd8ede9ea1f60c8ae3d529eca139d2900c 100644 --- a/Code/Mantid/Framework/Crystal/src/IntegratePeaksHybrid.cpp +++ b/Code/Mantid/Framework/Crystal/src/IntegratePeaksHybrid.cpp @@ -101,10 +101,10 @@ IntegratePeaksHybrid::~IntegratePeaksHybrid() {} /// Algorithm's name for identification. @see Algorithm::name const std::string IntegratePeaksHybrid::name() const { return "IntegratePeaksHybrid"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int IntegratePeaksHybrid::version() const { return 1; }; +int IntegratePeaksHybrid::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string IntegratePeaksHybrid::category() const { diff --git a/Code/Mantid/Framework/Crystal/src/IntegratePeaksUsingClusters.cpp b/Code/Mantid/Framework/Crystal/src/IntegratePeaksUsingClusters.cpp index 84843b0b2b34c15bec5ba2044904bf0b2a2152db..5b6aeeb76773b008fd7acaa5f907d5de6b150c52 100644 --- a/Code/Mantid/Framework/Crystal/src/IntegratePeaksUsingClusters.cpp +++ b/Code/Mantid/Framework/Crystal/src/IntegratePeaksUsingClusters.cpp @@ -48,10 +48,10 @@ IntegratePeaksUsingClusters::~IntegratePeaksUsingClusters() {} /// Algorithm's name for identification. @see Algorithm::name const std::string IntegratePeaksUsingClusters::name() const { return "IntegratePeaksUsingClusters"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int IntegratePeaksUsingClusters::version() const { return 1; }; +int IntegratePeaksUsingClusters::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string IntegratePeaksUsingClusters::category() const { diff --git a/Code/Mantid/Framework/Crystal/src/LoadIsawPeaks.cpp b/Code/Mantid/Framework/Crystal/src/LoadIsawPeaks.cpp index 1e4e7a331a111c8efd0688c074c6b2c543565d5d..9612ce7b2638fb1c36be68acb38c8000fc5d96f6 100644 --- a/Code/Mantid/Framework/Crystal/src/LoadIsawPeaks.cpp +++ b/Code/Mantid/Framework/Crystal/src/LoadIsawPeaks.cpp @@ -28,7 +28,7 @@ using Mantid::Kernel::Units::Wavelength; namespace Mantid { namespace Crystal { -DECLARE_FILELOADER_ALGORITHM(LoadIsawPeaks); +DECLARE_FILELOADER_ALGORITHM(LoadIsawPeaks) using namespace Mantid::Kernel; using namespace Mantid::API; diff --git a/Code/Mantid/Framework/Crystal/src/PeakIntensityVsRadius.cpp b/Code/Mantid/Framework/Crystal/src/PeakIntensityVsRadius.cpp index 53ccf36f9059ddcbbe5f714b6f87e9199cfc01ab..e1381d541dabb89a468fb74552c1018693e9adac 100644 --- a/Code/Mantid/Framework/Crystal/src/PeakIntensityVsRadius.cpp +++ b/Code/Mantid/Framework/Crystal/src/PeakIntensityVsRadius.cpp @@ -29,10 +29,10 @@ PeakIntensityVsRadius::~PeakIntensityVsRadius() {} /// Algorithm's name for identification. @see Algorithm::name const std::string PeakIntensityVsRadius::name() const { return "PeakIntensityVsRadius"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int PeakIntensityVsRadius::version() const { return 1; }; +int PeakIntensityVsRadius::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string PeakIntensityVsRadius::category() const { return "Crystal"; } diff --git a/Code/Mantid/Framework/Crystal/src/PeaksInRegion.cpp b/Code/Mantid/Framework/Crystal/src/PeaksInRegion.cpp index b8b112cb7a46bb892bb362620f8b32ec93f8fc5f..dc590f5b4c62941b8d5fe6b2ced7bd86515ad3dd 100644 --- a/Code/Mantid/Framework/Crystal/src/PeaksInRegion.cpp +++ b/Code/Mantid/Framework/Crystal/src/PeaksInRegion.cpp @@ -26,10 +26,10 @@ PeaksInRegion::~PeaksInRegion() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string PeaksInRegion::name() const { return "PeaksInRegion"; }; +const std::string PeaksInRegion::name() const { return "PeaksInRegion"; } /// Algorithm's version for identification. @see Algorithm::version -int PeaksInRegion::version() const { return 1; }; +int PeaksInRegion::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string PeaksInRegion::category() const { return "Crystal"; } diff --git a/Code/Mantid/Framework/Crystal/src/PeaksOnSurface.cpp b/Code/Mantid/Framework/Crystal/src/PeaksOnSurface.cpp index f0dded52a8424d6417810af3c1126d062c266761..3bd6da8e03fd5d7b4815a3fc17d4a80730719d0c 100644 --- a/Code/Mantid/Framework/Crystal/src/PeaksOnSurface.cpp +++ b/Code/Mantid/Framework/Crystal/src/PeaksOnSurface.cpp @@ -25,10 +25,10 @@ PeaksOnSurface::~PeaksOnSurface() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string PeaksOnSurface::name() const { return "PeaksOnSurface"; }; +const std::string PeaksOnSurface::name() const { return "PeaksOnSurface"; } /// Algorithm's version for identification. @see Algorithm::version -int PeaksOnSurface::version() const { return 1; }; +int PeaksOnSurface::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string PeaksOnSurface::category() const { return "Crystal"; } diff --git a/Code/Mantid/Framework/Crystal/src/SCDCalibratePanels.cpp b/Code/Mantid/Framework/Crystal/src/SCDCalibratePanels.cpp index 79f0d3da50ea775480d39fcb55ba4ba911e09927..106ed965dab2d10f23f8e4be54ceb8bc845d3837 100644 --- a/Code/Mantid/Framework/Crystal/src/SCDCalibratePanels.cpp +++ b/Code/Mantid/Framework/Crystal/src/SCDCalibratePanels.cpp @@ -1669,7 +1669,7 @@ void SCDCalibratePanels::FixUpBankParameterMap( void writeXmlParameter(ofstream &ostream, const string &name, const double value) { ostream << " <parameter name =\"" << name << "\"><value val=\"" << value - << "\" />" << endl; + << "\" /> </parameter>" << endl; } void diff --git a/Code/Mantid/Framework/Crystal/src/SetSpecialCoordinates.cpp b/Code/Mantid/Framework/Crystal/src/SetSpecialCoordinates.cpp index 784d7244d529599c40f3bebd8d40bc8b362762be..61ecc88afb96ba393511d9b0d1dc4b58c8643696 100644 --- a/Code/Mantid/Framework/Crystal/src/SetSpecialCoordinates.cpp +++ b/Code/Mantid/Framework/Crystal/src/SetSpecialCoordinates.cpp @@ -56,10 +56,10 @@ SetSpecialCoordinates::~SetSpecialCoordinates() {} /// Algorithm's name for identification. @see Algorithm::name const std::string SetSpecialCoordinates::name() const { return "SetSpecialCoordinates"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int SetSpecialCoordinates::version() const { return 1; }; +int SetSpecialCoordinates::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string SetSpecialCoordinates::category() const { return "Crystal"; } diff --git a/Code/Mantid/Framework/Crystal/src/SortPeaksWorkspace.cpp b/Code/Mantid/Framework/Crystal/src/SortPeaksWorkspace.cpp index d9422413e6c5f6fdb0100a31f3f849943ff3abf3..2045ca8d73f848bc1658162d4650c8b51cba1a4e 100644 --- a/Code/Mantid/Framework/Crystal/src/SortPeaksWorkspace.cpp +++ b/Code/Mantid/Framework/Crystal/src/SortPeaksWorkspace.cpp @@ -29,10 +29,10 @@ SortPeaksWorkspace::~SortPeaksWorkspace() {} /// Algorithm's name for identification. @see Algorithm::name const std::string SortPeaksWorkspace::name() const { return "SortPeaksWorkspace"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int SortPeaksWorkspace::version() const { return 1; }; +int SortPeaksWorkspace::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string SortPeaksWorkspace::category() const { return "Crystal"; } diff --git a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt index 6486b1f2e157235b1fcc2275df15d22d81eef0d9..987301cf78bcd134fa4d89bb421996bfaa8c2a63 100644 --- a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt +++ b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt @@ -32,6 +32,7 @@ set ( SRC_FILES src/DiffSphere.cpp src/DynamicKuboToyabe.cpp src/EndErfc.cpp + src/EstimatePeakErrors.cpp src/ExpDecay.cpp src/ExpDecayMuon.cpp src/ExpDecayOsc.cpp @@ -67,6 +68,8 @@ set ( SRC_FILES src/NormaliseByPeakArea.cpp src/PRConjugateGradientMinimizer.cpp src/ParDomain.cpp + src/PawleyFit.cpp + src/PawleyFunction.cpp src/PeakParameterFunction.cpp src/PlotPeakByLogValue.cpp src/Polynomial.cpp @@ -141,6 +144,7 @@ set ( INC_FILES inc/MantidCurveFitting/DllConfig.h inc/MantidCurveFitting/DynamicKuboToyabe.h inc/MantidCurveFitting/EndErfc.h + inc/MantidCurveFitting/EstimatePeakErrors.h inc/MantidCurveFitting/ExpDecay.h inc/MantidCurveFitting/ExpDecayMuon.h inc/MantidCurveFitting/ExpDecayOsc.h @@ -179,6 +183,8 @@ set ( INC_FILES inc/MantidCurveFitting/NormaliseByPeakArea.h inc/MantidCurveFitting/PRConjugateGradientMinimizer.h inc/MantidCurveFitting/ParDomain.h + inc/MantidCurveFitting/PawleyFit.h + inc/MantidCurveFitting/PawleyFunction.h inc/MantidCurveFitting/PeakParameterFunction.h inc/MantidCurveFitting/PlotPeakByLogValue.h inc/MantidCurveFitting/Polynomial.h @@ -245,6 +251,7 @@ set ( TEST_FILES DiffSphereTest.h DynamicKuboToyabeTest.h EndErfcTest.h + EstimatePeakErrorsTest.h ExpDecayMuonTest.h ExpDecayOscTest.h ExpDecayTest.h @@ -257,14 +264,14 @@ set ( TEST_FILES FullprofPolynomialTest.h FunctionDomain1DSpectrumCreatorTest.h FunctionFactoryConstraintTest.h - FunctionParameterDecoratorFitTest.h + FunctionParameterDecoratorFitTest.h GSLMatrixTest.h GausDecayTest.h GausOscTest.h GaussianComptonProfileTest.h GaussianTest.h GramCharlierComptonProfileTest.h - IPeakFunctionCentreParameterNameTest.h + IPeakFunctionCentreParameterNameTest.h IPeakFunctionIntensityTest.h IkedaCarpenterPVTest.h LeBailFitTest.h @@ -282,6 +289,8 @@ set ( TEST_FILES NeutronBk2BkExpConvPVoigtTest.h NormaliseByPeakAreaTest.h PRConjugateGradientTest.h + PawleyFitTest.h + PawleyFunctionTest.h PeakParameterFunctionTest.h PlotPeakByLogValueTest.h PolynomialTest.h diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/AugmentedLagrangianOptimizer.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/AugmentedLagrangianOptimizer.h index ae06a79fe7bf08012a271901077c1302d6634217..8bbc05dd38b50e3d10f48d44c99bba05d12038a2 100644 --- a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/AugmentedLagrangianOptimizer.h +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/AugmentedLagrangianOptimizer.h @@ -154,8 +154,8 @@ public: void minimize(std::vector<double> &xv) const; private: - DISABLE_DEFAULT_CONSTRUCT(AugmentedLagrangianOptimizer); - DISABLE_COPY_AND_ASSIGN(AugmentedLagrangianOptimizer); + DISABLE_DEFAULT_CONSTRUCT(AugmentedLagrangianOptimizer) + DISABLE_COPY_AND_ASSIGN(AugmentedLagrangianOptimizer) friend class UnconstrainedCostFunction; /// Using gradient optimizer to perform limited optimization of current set diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/EstimatePeakErrors.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/EstimatePeakErrors.h new file mode 100644 index 0000000000000000000000000000000000000000..fe76f6ba7686c0a4caef39545f8478888f456def --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/EstimatePeakErrors.h @@ -0,0 +1,50 @@ +#ifndef MANTID_CURVEFITTING_ESTIMATEPEAKERRORS_H_ +#define MANTID_CURVEFITTING_ESTIMATEPEAKERRORS_H_ + +#include "MantidAPI/Algorithm.h" + +namespace Mantid { +namespace CurveFitting { +//--------------------------------------------------------------------------- +/** + +Copyright © 2013 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge +National Laboratory & European Spallation Source + +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://github.com/mantidproject/mantid> +Code Documentation is available at: <http://doxygen.mantidproject.org> + */ +class DLLExport EstimatePeakErrors : public API::Algorithm { +public: + EstimatePeakErrors(); + + const std::string name() const; + virtual const std::string summary() const ; + + int version() const; + const std::string category() const; + +private: + void init(); + void exec(); +}; + +} // namespace CurveFitting +} // namespace Mantid + +#endif /* MANTID_CURVEFITTING_ESTIMATEPEAKERRORS_H_ */ diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/FABADAMinimizer.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/FABADAMinimizer.h index 96c17435ca3dcc78da315df6bd3ab5dfe0435703..751e195e233676fd8a9f8be9af86c8a123189af1 100644 --- a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/FABADAMinimizer.h +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/FABADAMinimizer.h @@ -40,8 +40,6 @@ public: /// Constructor FABADAMinimizer(); virtual ~FABADAMinimizer(); - /// Lo ha puesto Roman y no se para que!! creo que es el destructor - /// Name of the minimizer. std::string name() const { return "FABADA"; } /// Initialize minimizer, i.e. pass a function to minimize. @@ -51,6 +49,8 @@ public: virtual bool iterate(size_t iter); /// Return current value of the cost function virtual double costFunctionVal(); + /// Finalize minimization, eg store additional outputs + virtual void finalize(); private: /// Pointer to the cost function. Must be the least squares. @@ -85,8 +85,9 @@ private: std::vector<bool> m_bound; /// Convergence criteria for each parameter std::vector<double> m_criteria; + /// Maximum number of iterations + size_t m_max_iter; }; - } // namespace CurveFitting } // namespace Mantid diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/GSLMatrix.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/GSLMatrix.h index 4be954bd466e06e349884a681bcfec483d2fb3a8..98f69c7cc7ca1742cd80ed40a71c392b6f37659e 100644 --- a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/GSLMatrix.h +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/GSLMatrix.h @@ -4,6 +4,8 @@ #include "MantidCurveFitting/DllConfig.h" #include "MantidCurveFitting/GSLVector.h" +#include "MantidKernel/Matrix.h" + #include <gsl/gsl_matrix.h> #include <gsl/gsl_blas.h> #include <gsl/gsl_linalg.h> @@ -97,7 +99,6 @@ Code Documentation is available at: <http://doxygen.mantidproject.org> class MANTID_CURVEFITTING_DLL GSLMatrix { /// The pointer to the GSL matrix gsl_matrix *m_matrix; - public: /// Constructor GSLMatrix() : m_matrix(NULL) {} @@ -109,11 +110,47 @@ public: } /// Copy constructor + /// @param M :: The other matrix. GSLMatrix(const GSLMatrix &M) { m_matrix = gsl_matrix_alloc(M.size1(), M.size2()); gsl_matrix_memcpy(m_matrix, M.gsl()); } + /// Create a submatrix. A submatrix is a view into the parent matrix. + /// Lifetime of a submatrix cannot exceed the lifetime of the parent. + /// @param M :: The parent matrix. + /// @param row :: The first row in the submatrix. + /// @param col :: The first column in the submatrix. + /// @param nRows :: The number of rows in the submatrix. + /// @param nCols :: The number of columns in the submatrix. + GSLMatrix(const GSLMatrix &M, size_t row, size_t col, size_t nRows, size_t nCols) { + if ( row + nRows > M.size1() || col + nCols > M.size2() ) + { + throw std::runtime_error("Submatrix exceeds matrix size."); + } + auto view = gsl_matrix_const_submatrix(M.gsl(), row, col, nRows, nCols); + m_matrix = gsl_matrix_alloc(nRows, nCols); + gsl_matrix_memcpy(m_matrix, &view.matrix); + } + + /// Constructor + /// @param M :: A matrix to copy. + GSLMatrix(const Kernel::Matrix<double>& M) { + m_matrix = gsl_matrix_alloc(M.numRows(), M.numCols()); + for(size_t i = 0; i < size1(); ++i) + for(size_t j = 0; j < size2(); ++j){ + set(i,j, M[i][j]); + } + } + + /// Create this matrix from a product of two other matrices + /// @param mult2 :: Matrix multiplication helper object. + GSLMatrix(const GSLMatrixMult2 &mult2) : m_matrix(NULL) {*this = mult2;} + + /// Create this matrix from a product of three other matrices + /// @param mult3 :: Matrix multiplication helper object. + GSLMatrix(const GSLMatrixMult3 &mult3) : m_matrix(NULL) {*this = mult3;} + /// Destructor. ~GSLMatrix() { if (m_matrix) { diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/PawleyFit.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/PawleyFit.h new file mode 100644 index 0000000000000000000000000000000000000000..4c00d9b1c35c99de7bb46b96796ea4400fc13f58 --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/PawleyFit.h @@ -0,0 +1,83 @@ +#ifndef MANTID_CURVEFITTING_PAWLEYFIT_H_ +#define MANTID_CURVEFITTING_PAWLEYFIT_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidCurveFitting/PawleyFunction.h" +#include "MantidKernel/Unit.h" + +namespace Mantid { +namespace CurveFitting { + +/** PawleyFit + + This algorithm uses the Pawley-method to refine lattice parameters using a + powder diffractogram and a list of unique Miller indices. From the initial + lattice parameters, theoretical reflection positions are calculated. Each + reflection is described by the peak profile function supplied by the user and + all parameters except the one for location of the reflection are freely + refined. Available lattice parameters depend on the selected crystal system. + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 15/03/2015 + + Copyright © 2015 PSI-NXMM + + 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://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class DLLExport PawleyFit : public API::Algorithm { +public: + PawleyFit(); + virtual ~PawleyFit() {} + + const std::string name() const { return "PawleyFit"; } + int version() const { return 1; } + const std::string summary() const; + const std::string category() const { return "Diffraction"; } + +protected: + double getTransformedCenter(double d, const Kernel::Unit_sptr &unit) const; + + void addHKLsToFunction(PawleyFunction_sptr &pawleyFn, + const API::ITableWorkspace_sptr &tableWs, + const Kernel::Unit_sptr &unit, double startX, + double endX) const; + + Kernel::V3D getHKLFromColumn(size_t i, + const API::Column_const_sptr &hklColumn) const; + Kernel::V3D getHkl(const std::string &hklString) const; + + API::ITableWorkspace_sptr + getLatticeFromFunction(const PawleyFunction_sptr &pawleyFn) const; + API::ITableWorkspace_sptr + getPeakParametersFromFunction(const PawleyFunction_sptr &pawleyFn) const; + + API::IFunction_sptr + getCompositeFunction(const PawleyFunction_sptr &pawleyFn) const; + + void init(); + void exec(); + + Kernel::Unit_sptr m_dUnit; +}; + +} // namespace CurveFitting +} // namespace Mantid + +#endif /* MANTID_CURVEFITTING_PAWLEYFIT_H_ */ diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/PawleyFunction.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/PawleyFunction.h new file mode 100644 index 0000000000000000000000000000000000000000..cb0e9fb7acae149213d0e76acb2d45c81e135a4a --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/PawleyFunction.h @@ -0,0 +1,166 @@ +#ifndef MANTID_CURVEFITTING_PAWLEYFUNCTION_H_ +#define MANTID_CURVEFITTING_PAWLEYFUNCTION_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/CompositeFunction.h" +#include "MantidAPI/FunctionParameterDecorator.h" +#include "MantidAPI/MatrixWorkspace.h" +#include "MantidAPI/IPeakFunction.h" +#include "MantidAPI/ParamFunction.h" + +#include "MantidGeometry/Crystal/PointGroup.h" +#include "MantidGeometry/Crystal/UnitCell.h" + +namespace Mantid { +namespace CurveFitting { + +/** @class PawleyParameterFunction + + This function is used internally by PawleyFunction to hold the unit cell + parameters as well as the ZeroShift parameter. The function and functionDeriv- + methods have been implemented to do nothing, the calculation of the spectrum + that results from the unit cell is calculated in PawleyFunction. + + Additionally it stores the crystal system and the name of the profile function + that is used to model the Bragg peaks as attributes. +*/ +class DLLExport PawleyParameterFunction : virtual public API::IFunction, + virtual public API::ParamFunction { +public: + PawleyParameterFunction(); + virtual ~PawleyParameterFunction() {} + + /// Returns the function name + std::string name() const { return "PawleyParameterFunction"; } + + void setAttribute(const std::string &attName, const Attribute &attValue); + + Geometry::PointGroup::CrystalSystem getCrystalSystem() const; + Geometry::UnitCell getUnitCellFromParameters() const; + void setParametersFromUnitCell(const Geometry::UnitCell &cell); + + /// Returns the stored profile function name + std::string getProfileFunctionName() const { + return getAttribute("ProfileFunction").asString(); + } + + /// Returns the name of the stored function's center parameter + std::string getProfileFunctionCenterParameterName() const { + return m_profileFunctionCenterParameterName; + } + + void function(const API::FunctionDomain &domain, + API::FunctionValues &values) const; + void functionDeriv(const API::FunctionDomain &domain, + API::Jacobian &jacobian); + +protected: + void init(); + + void setProfileFunction(const std::string &profileFunction); + void setCrystalSystem(const std::string &crystalSystem); + + void createCrystalSystemParameters( + Geometry::PointGroup::CrystalSystem crystalSystem); + void setCenterParameterNameFromFunction( + const API::IPeakFunction_sptr &profileFunction); + + Geometry::PointGroup::CrystalSystem m_crystalSystem; + std::string m_profileFunctionCenterParameterName; +}; + +typedef boost::shared_ptr<PawleyParameterFunction> PawleyParameterFunction_sptr; + +/** @class PawleyFunction + + The Pawley approach to obtain lattice parameters from a powder diffractogram + works by placing peak profiles at d-values (which result from the lattice + parameters and the Miller indices of each peak) and fitting the total profile + to the recorded diffractogram. + + Depending on the chosen crystal system, this function exposes the appropriate + lattice parameters as parameters, as well as profile parameters of the + individual peak functions, except the peak locations, which are a direct + result of their HKLs in combination with the unit cell. + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 11/03/2015 + + Copyright © 2015 PSI-NXMM + + 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://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class DLLExport PawleyFunction : public API::FunctionParameterDecorator { +public: + PawleyFunction(); + virtual ~PawleyFunction() {} + + /// Returns the name of the function. + std::string name() const { return "PawleyFunction"; } + + void + setMatrixWorkspace(boost::shared_ptr<const API::MatrixWorkspace> workspace, + size_t wi, double startX, double endX); + + void setCrystalSystem(const std::string &crystalSystem); + void setProfileFunction(const std::string &profileFunction); + void setUnitCell(const std::string &unitCellString); + + void function(const API::FunctionDomain &domain, + API::FunctionValues &values) const; + + /// Derivates are calculated numerically. + void functionDeriv(const API::FunctionDomain &domain, + API::Jacobian &jacobian) { + calNumericalDeriv(domain, jacobian); + } + + void setPeaks(const std::vector<Kernel::V3D> &hkls, double fwhm, + double height); + void clearPeaks(); + + void addPeak(const Kernel::V3D &hkl, double fwhm, double height); + size_t getPeakCount() const; + API::IPeakFunction_sptr getPeakFunction(size_t i) const; + Kernel::V3D getPeakHKL(size_t i) const; + + PawleyParameterFunction_sptr getPawleyParameterFunction() const; + +protected: + double getTransformedCenter(double d) const; + + void init(); + void beforeDecoratedFunctionSet(const API::IFunction_sptr &fn); + + API::CompositeFunction_sptr m_compositeFunction; + PawleyParameterFunction_sptr m_pawleyParameterFunction; + API::CompositeFunction_sptr m_peakProfileComposite; + + std::vector<Kernel::V3D> m_hkls; + + Kernel::Unit_sptr m_dUnit; + Kernel::Unit_sptr m_wsUnit; +}; + +typedef boost::shared_ptr<PawleyFunction> PawleyFunction_sptr; + +} // namespace CurveFitting +} // namespace Mantid + +#endif /* MANTID_CURVEFITTING_PAWLEYFUNCTION_H_ */ diff --git a/Code/Mantid/Framework/CurveFitting/src/CalculateGammaBackground.cpp b/Code/Mantid/Framework/CurveFitting/src/CalculateGammaBackground.cpp index 6e1ab71224a5be1a6adb77ce010749bf8d57ee8d..d4dfeb2503d74d64dcf47b5655128fc95fc281c3 100644 --- a/Code/Mantid/Framework/CurveFitting/src/CalculateGammaBackground.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/CalculateGammaBackground.cpp @@ -21,7 +21,7 @@ using namespace Kernel; using namespace std; // Subscription -DECLARE_ALGORITHM(CalculateGammaBackground); +DECLARE_ALGORITHM(CalculateGammaBackground) namespace { /// Number of elements in theta direction integration diff --git a/Code/Mantid/Framework/CurveFitting/src/Chebyshev.cpp b/Code/Mantid/Framework/CurveFitting/src/Chebyshev.cpp index eb03305943833c56eee0155e06e057bce4d6b1f7..7da4e1d0b8837453722a2f6952a7becc1c442e98 100644 --- a/Code/Mantid/Framework/CurveFitting/src/Chebyshev.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/Chebyshev.cpp @@ -20,7 +20,7 @@ Chebyshev::Chebyshev() : m_n(0), m_StartX(-1.), m_EndX(1.) { declareAttribute("n", Attribute(m_n)); declareAttribute("StartX", Attribute(m_StartX)); declareAttribute("EndX", Attribute(m_EndX)); -}; +} void Chebyshev::function1D(double *out, const double *xValues, const size_t nData) const { diff --git a/Code/Mantid/Framework/CurveFitting/src/ComptonPeakProfile.cpp b/Code/Mantid/Framework/CurveFitting/src/ComptonPeakProfile.cpp index 45de68597850991a70f40e2fbf72f1234fe38862..92328afbcff11394c44d05d9cb3a90ac3948e574 100644 --- a/Code/Mantid/Framework/CurveFitting/src/ComptonPeakProfile.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/ComptonPeakProfile.cpp @@ -8,7 +8,7 @@ namespace Mantid { namespace CurveFitting { -DECLARE_FUNCTION(ComptonPeakProfile); +DECLARE_FUNCTION(ComptonPeakProfile) namespace { ///@cond diff --git a/Code/Mantid/Framework/CurveFitting/src/ComptonScatteringCountRate.cpp b/Code/Mantid/Framework/CurveFitting/src/ComptonScatteringCountRate.cpp index 7bb7dd9b2a5388347a6b074a9dcd6750e5919adf..c0862428093ef84d7da77547440ea1447c9383d8 100644 --- a/Code/Mantid/Framework/CurveFitting/src/ComptonScatteringCountRate.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/ComptonScatteringCountRate.cpp @@ -20,7 +20,7 @@ const char *BKGD_ORDER_ATTR_NAME = "BackgroundOrderAttr"; Logger g_log("ComptonScatteringCountRate"); } -DECLARE_FUNCTION(ComptonScatteringCountRate); +DECLARE_FUNCTION(ComptonScatteringCountRate) //---------------------------------------------------------------------------------------------- /** Constructor diff --git a/Code/Mantid/Framework/CurveFitting/src/ConvertToYSpace.cpp b/Code/Mantid/Framework/CurveFitting/src/ConvertToYSpace.cpp index 456d7355884fd03f59ebd77fdf2467a80bab194d..5cb55c3d2aa4d3de894c648b6f82a8ad171b9478 100644 --- a/Code/Mantid/Framework/CurveFitting/src/ConvertToYSpace.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/ConvertToYSpace.cpp @@ -10,7 +10,7 @@ namespace Mantid { namespace CurveFitting { // Register the algorithm into the AlgorithmFactory -DECLARE_ALGORITHM(ConvertToYSpace); +DECLARE_ALGORITHM(ConvertToYSpace) using namespace API; using namespace Kernel; diff --git a/Code/Mantid/Framework/CurveFitting/src/CubicSpline.cpp b/Code/Mantid/Framework/CurveFitting/src/CubicSpline.cpp index 893e0f59420f33cff2c973ed4df3971e7b75391f..6b0d2815989e52ae26cf5f7be2a1fe47f8df31e9 100644 --- a/Code/Mantid/Framework/CurveFitting/src/CubicSpline.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/CubicSpline.cpp @@ -41,7 +41,7 @@ CubicSpline::CubicSpline() declareParameter("y0", 0); declareParameter("y1", 0); declareParameter("y2", 0); -}; +} /** Execute the function * diff --git a/Code/Mantid/Framework/CurveFitting/src/DiffRotDiscreteCircle.cpp b/Code/Mantid/Framework/CurveFitting/src/DiffRotDiscreteCircle.cpp index 1c2042fbdeef39b2a7dc513ac55f977a8987c436..1d7fc6948be06c461bd548383d0c57af5a7f8f1b 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DiffRotDiscreteCircle.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DiffRotDiscreteCircle.cpp @@ -11,9 +11,9 @@ namespace Mantid { namespace CurveFitting { -DECLARE_FUNCTION(ElasticDiffRotDiscreteCircle); -DECLARE_FUNCTION(InelasticDiffRotDiscreteCircle); -DECLARE_FUNCTION(DiffRotDiscreteCircle); +DECLARE_FUNCTION(ElasticDiffRotDiscreteCircle) +DECLARE_FUNCTION(InelasticDiffRotDiscreteCircle) +DECLARE_FUNCTION(DiffRotDiscreteCircle) ElasticDiffRotDiscreteCircle::ElasticDiffRotDiscreteCircle() { // declareParameter("Height", 1.0); //parameter "Height" already declared in @@ -54,6 +54,7 @@ InelasticDiffRotDiscreteCircle::InelasticDiffRotDiscreteCircle() declareParameter("Decay", 1.0, "Inverse of transition rate, in nanoseconds " "if energy in micro-ev, or picoseconds if " "energy in mili-eV"); + declareParameter("Shift", 0.0, "Shift in domain"); declareAttribute("Q", API::IFunction::Attribute(0.5)); declareAttribute("N", API::IFunction::Attribute(3)); @@ -82,6 +83,7 @@ void InelasticDiffRotDiscreteCircle::function1D(double *out, const double rate = m_hbar / getParameter("Decay"); // micro-eV or mili-eV const double Q = getAttribute("Q").asDouble(); const int N = getAttribute("N").asInt(); + const double S = getParameter("Shift"); std::vector<double> sph(N); for (int k = 1; k < N; k++) { @@ -97,7 +99,7 @@ void InelasticDiffRotDiscreteCircle::function1D(double *out, } for (size_t i = 0; i < nData; i++) { - double w = xValues[i]; + double w = xValues[i] - S; double S = 0.0; for (int l = 1; l < N; l++) // l goes up to N-1 { @@ -166,6 +168,7 @@ void DiffRotDiscreteCircle::init() { setAlias("f1.Intensity", "Intensity"); setAlias("f1.Radius", "Radius"); setAlias("f1.Decay", "Decay"); + setAlias("f1.Shift", "Shift"); // Set the ties between Elastic and Inelastic parameters addDefaultTies("f0.Height=f1.Intensity,f0.Radius=f1.Radius"); diff --git a/Code/Mantid/Framework/CurveFitting/src/DiffSphere.cpp b/Code/Mantid/Framework/CurveFitting/src/DiffSphere.cpp index aafd90d88c51a38bd2ed7acb867c4e39198a0cdb..28688f243db34ff1ba578372fa6cfc0f6d0e48f2 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DiffSphere.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DiffSphere.cpp @@ -16,9 +16,9 @@ namespace CurveFitting { using namespace Kernel; using namespace API; -DECLARE_FUNCTION(ElasticDiffSphere); -DECLARE_FUNCTION(InelasticDiffSphere); -DECLARE_FUNCTION(DiffSphere); +DECLARE_FUNCTION(ElasticDiffSphere) +DECLARE_FUNCTION(InelasticDiffSphere) +DECLARE_FUNCTION(DiffSphere) ElasticDiffSphere::ElasticDiffSphere() { // declareParameter("Height", 1.0); //parameter "Height" already declared in @@ -145,6 +145,7 @@ InelasticDiffSphere::InelasticDiffSphere() declareParameter("Diffusion", 0.05, "Diffusion coefficient, in units of " "A^2*THz, if energy in meV, or A^2*PHz " "if energy in ueV"); + declareParameter("Shift", 0.0, "Shift in domain"); declareAttribute("Q", API::IFunction::Attribute(1.0)); } @@ -194,6 +195,7 @@ void InelasticDiffSphere::function1D(double *out, const double *xValues, const double R = getParameter("Radius"); const double D = getParameter("Diffusion"); const double Q = getAttribute("Q").asDouble(); + const double S = getParameter("Shift"); // // Penalize negative parameters if (I < std::numeric_limits<double>::epsilon() || @@ -216,7 +218,7 @@ void InelasticDiffSphere::function1D(double *out, const double *xValues, std::vector<double> YJ; YJ = LorentzianCoefficients(Q * R); // The (2l+1)*A_{n,l} for (size_t i = 0; i < nData; i++) { - double energy = xValues[i]; // from meV to THz (or from micro-eV to PHz) + double energy = xValues[i] - S; // from meV to THz (or from micro-eV to PHz) out[i] = 0.0; for (size_t n = 0; n < ncoeff; n++) { double L = (1.0 / M_PI) * HWHM[n] / @@ -272,6 +274,7 @@ void DiffSphere::init() { setAlias("f1.Intensity", "Intensity"); setAlias("f1.Radius", "Radius"); setAlias("f1.Diffusion", "Diffusion"); + setAlias("f1.Shift", "Shift"); // Set the ties between Elastic and Inelastic parameters addDefaultTies("f0.Height=f1.Intensity,f0.Radius=f1.Radius"); diff --git a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp index 4b7bae69801a1dceab858717f86c4fe29435abbd..d19e1e94fada5d6b90608c50aec635f484fcc093 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp @@ -24,6 +24,111 @@ void DynamicKuboToyabe::init() declareParameter("Nu", 0.0, "Hopping rate"); } + +//-------------------------------------------------------------------------------------------------------------------------------------- +// From Numerical Recipes + +// Midpoint method +double midpnt(double func(const double, const double, const double), + const double a, const double b, const int n, const double g, const double w0) { +// quote & modified from numerical recipe 2nd edtion (page147) + + static double s; + + if (n==1) { + s = (b-a)*func(0.5*(a+b),g,w0); + return (s); + } else { + double x, tnm, sum, del, ddel; + int it, j; + for (it=1,j=1;j<n-1;j++) it *= 3; + tnm = it; + del = (b-a)/(3*tnm); + ddel=del+del; + x = a+0.5*del; + sum =0.0; + for (j=1;j<=it;j++) { + sum += func(x,g,w0); + x += ddel; + sum += func(x,g,w0); + x += del; + } + s=(s+(b-a)*sum/tnm)/3.0; + return s; + } +} + +// Polynomial interpolation +void polint (double xa[], double ya[], int n, double x, double& y, double& dy) { + int i, m, ns = 1; + double dif; + + dif = fabs(x-xa[1]); + std::vector<double> c(n+1); + std::vector<double> d(n+1); + for (i=1;i<=n;i++){ + double dift; + if((dift=fabs(x-xa[i]))<dif) { + ns=i; + dif=dift; + } + c[i]=ya[i]; + d[i]=ya[i]; + } + y=ya[ns--]; + for (m=1;m<n;m++) { + for (i=1;i<=n-m;i++) { + double den, ho, hp, w; + ho=xa[i]-x; + hp=xa[i+m]-x; + w=c[i+1]-d[i]; + if((den=ho-hp)==0.0){ //error message!!! + throw std::runtime_error("Error in routin polint"); + } + den=w/den; + d[i]=hp*den; + c[i]=ho*den; + } + y += (dy=(2*(ns)<(n-m) ? c[ns+1] : d[ns--])); + + } + +} + +// Integration +double integral (double func(const double, const double, const double), + const double a, const double b, const double g, const double w0) { + + const int JMAX = 14; + const int JMAXP = JMAX + 1; + const int K = 5; + + int j; + double ss,dss; + double h[JMAXP+1], s[JMAXP]; + + h[1] = 1.0; + for (j=1; j<= JMAX; j++) { + s[j]=midpnt(func,a,b,j,g,w0); + if (j >= K) { + polint(&h[j-K],&s[j-K],K,0.0,ss,dss); + if (fabs(dss) <= fabs(ss)) return ss; + } + h[j+1]=h[j]/9.0; + } + throw std::runtime_error("Too many steps in routine integrate"); + return 0.0; +} + +// End of Numerical Recipes routines +//-------------------------------------------------------------------------------------------------------------------------------------- + + +// f1: function to integrate +double f1(const double x, const double G, const double w0) { + return( exp(-G*G*x*x/2)*sin(w0*x)); +} + // Static Zero Field Kubo Toyabe relaxation function double ZFKT (const double x, const double G){ @@ -31,33 +136,78 @@ double ZFKT (const double x, const double G){ return (0.3333333333 + 0.6666666667*exp(-0.5*q)*(1-q)); } +// Static non-zero field Kubo Toyabe relaxation function +double HKT (const double x, const double G, const double F) { + + const double q = G*G*x*x; + const double gm = 2*M_PI*0.01355342; // Muon gyromagnetic ratio * 2 * PI + + double w; + if (F>2*G) { + // Use F + w = gm * F; + } else { + // Use G + w = gm * 2 * G; + } + + const double r = G*G/w/w; + + double ig; + if ( x>0 && r>0 ) { + // Compute integral + ig = integral(f1,0.0,x,G,w); + } else { + // Integral is 0 + ig = 0; + } + + const double ktb=(1-2*r*(1-exp(-q/2)*cos(w*x))+2*r*r*w*ig); + + if ( F>2*G ) { + return ktb; + } else { + const double kz = ZFKT(x,G); + return kz+F/2/G*(ktb-kz); + } + +} + // Dynamic Kubo-Toyabe -double getDKT (double t, double G, double v){ +double getDKT (double t, double G, double F, double v){ const int tsmax = 656; // Length of the time axis, 32 us of valid data const double eps = 0.05; // Bin width for calculations - static double oldG=-1., oldV=-1.; + static double oldG=-1., oldV=-1., oldF=-1.; static std::vector<double> gStat(tsmax), gDyn(tsmax); - if ( (G != oldG) || (v != oldV) ){ + if ( (G != oldG) || (v != oldV) || (F != oldF) ){ - // If G or v have changed with respect to the + // If G or v or F have changed with respect to the // previous call, we need to re-do the computations - if ( G != oldG ){ + if ( G != oldG || (F != oldF) ){ // But we only need to - // re-compute gStat if G has changed + // re-compute gStat if G or F have changed // Generate static Kubo-Toyabe - for (int k=0; k<tsmax; k++){ - gStat[k]= ZFKT(k*eps,G); + if (F == 0) { + for (int k=0; k<tsmax; k++){ + gStat[k]= ZFKT(k*eps,G); + } + } else { + for (int k=0; k<tsmax; k++){ + gStat[k]= HKT(k*eps,G,F); + } } // Store new G value oldG =G; + // Store new F value + oldF =F; } // Store new v value @@ -105,26 +255,19 @@ void DynamicKuboToyabe::function1D(double* out, const double* xValues, const siz } // Non-zero external field else{ - throw std::runtime_error("HKT() not implemented yet"); + for (size_t i = 0; i < nData; i++) { + out[i] = A*HKT(xValues[i],G,F); + } } } // Non-zero hopping rate else { - if ( F==0.0 ) { - - for (size_t i = 0; i<nData; i++){ - out[i] = A*getDKT(xValues[i],G,v); - } - - } else { - - // Non-zero field - throw std::runtime_error("HKT() not implemented yet"); + for (size_t i = 0; i<nData; i++){ + out[i] = A*getDKT(xValues[i],G,F,v); } - - } // else hopping rate != 0 + } } diff --git a/Code/Mantid/Framework/CurveFitting/src/EstimatePeakErrors.cpp b/Code/Mantid/Framework/CurveFitting/src/EstimatePeakErrors.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a57f7e2cfd200cfcff18dfa2c7394723d8e7077d --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/src/EstimatePeakErrors.cpp @@ -0,0 +1,169 @@ +#include "MantidCurveFitting/EstimatePeakErrors.h" +#include "MantidCurveFitting/GSLMatrix.h" +#include "MantidCurveFitting/PeakParameterFunction.h" + +#include "MantidAPI/CompositeFunction.h" +#include "MantidAPI/FunctionProperty.h" +#include "MantidAPI/IPeakFunction.h" +#include "MantidAPI/ITableWorkspace.h" +#include "MantidAPI/TableRow.h" + +#include <boost/lexical_cast.hpp> + +namespace Mantid { +namespace CurveFitting { +using namespace API; +using namespace Kernel; +using namespace std; + +// Subscription +DECLARE_ALGORITHM(EstimatePeakErrors) + +//-------------------------------------------------------------------------------------------------------- +// Public members +//-------------------------------------------------------------------------------------------------------- + +/// Default constructor +EstimatePeakErrors::EstimatePeakErrors() : Algorithm() {} + +/// Summary of algorithms purpose +const std::string EstimatePeakErrors::summary() const { + return "Calculates error estimates for peak parameters: " + "centre, height, FWHM and intensity."; +} + +const std::string EstimatePeakErrors::name() const { + return "EstimatePeakErrors"; +} + +int EstimatePeakErrors::version() const { return 1; } + +const std::string EstimatePeakErrors::category() const { + return "Optimization"; +} + +//-------------------------------------------------------------------------------------------------------- +// Private members +//-------------------------------------------------------------------------------------------------------- +namespace { + +/// Calculate a Jacobian of transformations from the normal function's +/// parameters to the 4 general peak parameters: centre, height, FWHM and +/// intensity (integral). +/// Also calculate the values for the peak parameters. +/// @param peak :: The function for which the Jacobian to be calculated. +/// @param centre :: Output receiving value of peak centre. +/// @param height :: Output receiving value of peak height. +/// @param fwhm :: Output receiving value of peak FWHM. +/// @param intensity :: Output receiving value of peak intensity. +GSLMatrix makeJacobian(IPeakFunction &peak, double ¢re, double &height, + double &fwhm, double &intensity) { + GSLMatrix jacobian(4, peak.nParams()); + centre = peak.centre(); + height = peak.height(); + fwhm = peak.fwhm(); + intensity = peak.intensity(); + for (size_t ip = 0; ip < peak.nParams(); ++ip) { + double p = peak.getParameter(ip); + double dp = 1e-9; + if (p != 0.0) { + dp *= p; + } + peak.setParameter(ip, p + dp); + jacobian.set(0, ip, (peak.centre() - centre) / dp); + jacobian.set(1, ip, (peak.height() - height) / dp); + jacobian.set(2, ip, (peak.fwhm() - fwhm) / dp); + jacobian.set(3, ip, (peak.intensity() - intensity) / dp); + peak.setParameter(ip, p); + } + return jacobian; +} + +/// Calculate the errors for a peak and add them to the result table. +/// @param peak :: A function for which errors are calculated. +/// @param results :: The table with results +/// @param covariance :: The covariance matrix for the parameters of the peak. +/// @param prefix :: A prefix for the parameter names. +void calculatePeakValues(IPeakFunction &peak, ITableWorkspace &results, + const GSLMatrix covariance, + const std::string &prefix) { + double centre, height, fwhm, intensity; + GSLMatrix J = makeJacobian(peak, centre, height, fwhm, intensity); + // CHECK_OUT_GSL_MATRIX("J=", J); + + GSLMatrix JCJ = J * covariance * Tr(J); + // CHECK_OUT_GSL_MATRIX("JCJ=", JCJ); + + TableRow row = results.appendRow(); + row << prefix + "Centre" << centre << sqrt(JCJ.get(0, 0)); + row = results.appendRow(); + row << prefix + "Height" << height << sqrt(JCJ.get(1, 1)); + row = results.appendRow(); + row << prefix + "FWHM" << fwhm << sqrt(JCJ.get(2, 2)); + row = results.appendRow(); + row << prefix + "Intensity" << intensity << sqrt(JCJ.get(3, 3)); +} +} + +/// Initialize +void EstimatePeakErrors::init() { + + declareProperty( + new FunctionProperty("Function"), + "Fitting function containing peaks. Must have a covariance matrix attached."); + + declareProperty( + new API::WorkspaceProperty<API::ITableWorkspace>( + "OutputWorkspace", "", Kernel::Direction::Output), + "The name of the TableWorkspace with the output values and errors."); +} + +/// Execute +void EstimatePeakErrors::exec() { + + IFunction_sptr function = getProperty("Function"); + + ITableWorkspace_sptr results = + WorkspaceFactory::Instance().createTable("TableWorkspace"); + results->addColumn("str", "Parameter"); + results->addColumn("double", "Value"); + results->addColumn("double", "Error"); + + auto matrix = function->getCovarianceMatrix(); + if ( !matrix ) + { + g_log.warning() << "Function doesn't have covariance matrix." << std::endl; + setProperty("OutputWorkspace", results); + return; + } + + IPeakFunction *peak = dynamic_cast<IPeakFunction *>(function.get()); + + if (peak) { + GSLMatrix covariance(*matrix); + calculatePeakValues(*peak, *results, covariance, ""); + } else { + CompositeFunction *cf = dynamic_cast<CompositeFunction *>(function.get()); + if (cf) { + size_t ip = 0; + for (size_t i = 0; i < cf->nFunctions(); ++i) { + IFunction *fun = cf->getFunction(i).get(); + size_t np = fun->nParams(); + IPeakFunction *peak = dynamic_cast<IPeakFunction *>(fun); + if (peak) { + std::string prefix = "f" + boost::lexical_cast<std::string>(i) + "."; + GSLMatrix covariance(*matrix, ip, ip, np, np); + calculatePeakValues(*peak, *results, covariance, prefix); + } + ip += np; + } + } else { + g_log.warning() << "Function has no peaks." << std::endl; + } + } + + setProperty("OutputWorkspace", results); +} + +} // namespace CurveFitting +} // namespace Mantid diff --git a/Code/Mantid/Framework/CurveFitting/src/FABADAMinimizer.cpp b/Code/Mantid/Framework/CurveFitting/src/FABADAMinimizer.cpp index 96696fb9f968ab9b92dfeb4ce5bcc19e2f97dc4d..4fb27b06173e78b5e22ab8ee59ff7e9996818884 100644 --- a/Code/Mantid/Framework/CurveFitting/src/FABADAMinimizer.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/FABADAMinimizer.cpp @@ -37,41 +37,51 @@ namespace { Kernel::Logger g_log("FABADAMinimizer"); // absolute maximum number of iterations when fit must converge const size_t convergenceMaxIterations = 50000; -// histogram length for the PDF output workspace -const size_t pdf_length = 50; // number of iterations when convergence isn't expected const size_t lowerIterationLimit = 350; +// very large number +const double largeNumber = 1e100; +// jump checking rate +const size_t jumpCheckingRate = 200; +// low jump limit +const double lowJumpLimit = 1e-25; } DECLARE_FUNCMINIMIZER(FABADAMinimizer, FABADA) //---------------------------------------------------------------------------------------------- /// Constructor -FABADAMinimizer::FABADAMinimizer() : API::IFuncMinimizer(), m_conv_point(0) { +FABADAMinimizer::FABADAMinimizer() { declareProperty("ChainLength", static_cast<size_t>(10000), "Length of the converged chain."); + declareProperty("StepsBetweenValues", static_cast<size_t>(10), + "Steps realized between keeping each result."); declareProperty( - "ConvergenceCriteria", 0.0001, - "Variance in Chi square for considering convergence reached."); - declareProperty(new API::WorkspaceProperty<>("OutputWorkspacePDF", "pdf", - Kernel::Direction::Output), - "The name to give the output workspace"); - declareProperty(new API::WorkspaceProperty<>("OutputWorkspaceChain", "chain", + "ConvergenceCriteria", 0.01, + "Variance in Cost Function for considering convergence reached."); + declareProperty("JumpAcceptanceRate", 0.6666666, + "Desired jumping acceptance rate"); + declareProperty( + new API::WorkspaceProperty<>("PDF", "PDF", Kernel::Direction::Output), + "The name to give the output workspace"); + declareProperty(new API::WorkspaceProperty<>("Chains", "Chain", Kernel::Direction::Output), "The name to give the output workspace"); - declareProperty(new API::WorkspaceProperty<>("OutputWorkspaceConverged", "", - Kernel::Direction::Output, - API::PropertyMode::Optional), - "The name to give the output workspace"); - declareProperty(new API::WorkspaceProperty<API::ITableWorkspace>( - "ChiSquareTable", "chi2", Kernel::Direction::Output), + declareProperty(new API::WorkspaceProperty<>( + "ConvergedChain", "ConvergedChain", + Kernel::Direction::Output, API::PropertyMode::Optional), "The name to give the output workspace"); + declareProperty( + new API::WorkspaceProperty<API::ITableWorkspace>( + "CostFunctionTable", "CostFunction", Kernel::Direction::Output), + "The name to give the output workspace"); declareProperty(new API::WorkspaceProperty<API::ITableWorkspace>( - "PdfError", "pdfE", Kernel::Direction::Output), + "Parameters", "Parameters", Kernel::Direction::Output), "The name to give the output workspace"); } //---------------------------------------------------------------------------------------------- + /// Destructor FABADAMinimizer::~FABADAMinimizer() {} @@ -114,12 +124,12 @@ void FABADAMinimizer::initialize(API::ICostFunction_sptr function, if (bcon->hasLower()) { m_lower.push_back(bcon->lower()); } else { - m_lower.push_back(-10e100); + m_lower.push_back(-largeNumber); } if (bcon->hasUpper()) { m_upper.push_back(bcon->upper()); } else { - m_upper.push_back(10e100); + m_upper.push_back(largeNumber); } if (p < m_lower[i]) { p = m_lower[i]; @@ -130,10 +140,14 @@ void FABADAMinimizer::initialize(API::ICostFunction_sptr function, m_parameters.set(i, p); } } + } else { + m_lower.push_back(-largeNumber); + m_upper.push_back(largeNumber); } std::vector<double> v; v.push_back(p); m_chain.push_back(v); + m_max_iter = maxIterations; m_changes.push_back(0); m_par_converged.push_back(false); m_criteria.push_back(getProperty("ConvergenceCriteria")); @@ -148,6 +162,7 @@ void FABADAMinimizer::initialize(API::ICostFunction_sptr function, v.push_back(m_chi2); m_chain.push_back(v); m_converged = false; + m_max_iter = maxIterations; } /// Do one iteration. Returns true if iterations to be continued, false if they @@ -158,14 +173,14 @@ bool FABADAMinimizer::iterate(size_t) { throw std::runtime_error("Cost function isn't set up."); } - size_t n = m_leastSquares->nParams(); - size_t m = n; + size_t nParams = m_leastSquares->nParams(); + size_t m = nParams; // Just for the last iteration. For doing exactly the indicated number of // iterations. - if (m_converged && m_counter == (m_numberIterations)) { + if (m_converged && m_counter == m_numberIterations) { size_t t = getProperty("ChainLength"); - m = t % n; + m = t % nParams; } // Do one iteration of FABADA's algorithm for each parameter. @@ -174,25 +189,17 @@ bool FABADAMinimizer::iterate(size_t) { // Calculate the step, depending on convergence reached or not double step; - if (m_converged) { + if (m_converged || m_bound[i]) { boost::mt19937 mt; - mt.seed(123 * (int(m_counter) + 45 * int(i))); - + mt.seed(123 * (int(m_counter) + + 45 * int(i))); // Numeros inventados para la seed boost::normal_distribution<double> distr(0.0, std::abs(m_jump[i])); boost::variate_generator< boost::mt19937, boost::normal_distribution<double>> gen(mt, distr); - step = gen(); - } else { step = m_jump[i]; } - // Couts just for helping when developing when coding - /// std::cout << std::endl << m_counter << "." << i << - /// std::endl<<std::endl<< m_parameters.get(i)<<std::endl; //DELETE AT THE - /// END - /// std::cout << "Real step: " << step << " Due to the m_jump: " << - /// m_jump[i] << std::endl; //DELETE AT THE END // Calculate the new value of the parameter double new_value = m_parameters.get(i) + step; @@ -200,11 +207,25 @@ bool FABADAMinimizer::iterate(size_t) { // Comproves if it is inside the boundary constrinctions. If not, changes // it. if (m_bound[i]) { - if (new_value < m_lower[i]) { - new_value = m_lower[i] + (m_lower[i] - new_value) / 2; + while (new_value < m_lower[i]) { + if (std::abs(step) > m_upper[i] - m_lower[i]) { + new_value = m_parameters.get(i) + step / 10.0; + step = step / 10; + m_jump[i] = m_jump[i] / 10; + } else { + new_value = + m_lower[i] + std::abs(step) - (m_parameters.get(i) - m_lower[i]); + } } - if (new_value > m_upper[i]) { - new_value = m_upper[i] - (new_value - m_upper[i]) / 2; + while (new_value > m_upper[i]) { + if (std::abs(step) > m_upper[i] - m_lower[i]) { + new_value = m_parameters.get(i) + step / 10.0; + step = step / 10; + m_jump[i] = m_jump[i] / 10; + } else { + new_value = + m_upper[i] - (std::abs(step) + m_parameters.get(i) - m_upper[i]); + } } } @@ -216,102 +237,79 @@ bool FABADAMinimizer::iterate(size_t) { m_leastSquares->setParameter(i, new_value); double chi2_new = m_leastSquares->val(); - /// std::cout << "OLD Chi2: " << m_chi2 << " NEW Chi2: " << chi2_new - /// << std::endl; // DELETE AT THE END - // If new Chi square value is lower, jumping directly to new parameter if (chi2_new < m_chi2) { - for (size_t j = 0; j < n; j++) { + for (size_t j = 0; j < nParams; j++) { m_chain[j].push_back(new_parameters.get(j)); } - m_chain[n].push_back(chi2_new); + m_chain[nParams].push_back(chi2_new); m_parameters = new_parameters; m_chi2 = chi2_new; m_changes[i] += 1; - /// std::cout << "Salta directamente!!" << std::endl;// DELETE AT THE END + } // If new Chi square value is higher, it depends on the probability else { // Calculate probability of change double prob = exp((m_chi2 / 2.0) - (chi2_new / 2.0)); - /// std::cout << "PROBABILIDAD cambio: " << prob << std::endl;// DELETE - /// AT THE END // Decide if changing or not boost::mt19937 mt; mt.seed(int(time_t()) + 48 * (int(m_counter) + 76 * int(i))); boost::uniform_real<> distr(0.0, 1.0); double p = distr(mt); - /// std::cout << " Random number " << p << std::endl;// DELETE AT THE END if (p <= prob) { - for (size_t j = 0; j < n; j++) { + for (size_t j = 0; j < nParams; j++) { m_chain[j].push_back(new_parameters.get(j)); } - m_chain[n].push_back(chi2_new); + m_chain[nParams].push_back(chi2_new); m_parameters = new_parameters; m_chi2 = chi2_new; m_changes[i] += 1; - /// std::cout << "SI hay cambio" << std::endl;// DELETE AT THE END } else { - for (size_t j = 0; j < n; j++) { + for (size_t j = 0; j < nParams; j++) { m_chain[j].push_back(m_parameters.get(j)); } - m_chain[n].push_back(m_chi2); + m_chain[nParams].push_back(m_chi2); m_leastSquares->setParameter(i, new_value - m_jump[i]); m_jump[i] = -m_jump[i]; - /// std::cout << "NO hay cambio" << std::endl;// DELETE AT THE END } } - /// std::cout << std::endl << std::endl << std::endl;// DELETE AT THE END - - const size_t jumpCheckingRate = 200; - const double lowJumpLimit = 1e-15; + const double jumpAR = getProperty("JumpAcceptanceRate"); // Update the jump once each jumpCheckingRate iterations - if (m_counter % jumpCheckingRate == 150) { + if (m_counter % jumpCheckingRate == 150) // JUMP CHECKING RATE IS 200, BUT + // IS NOT CHECKED AT FIRST STEP, IT + // IS AT 150 + { double jnew; - // All this is just a temporal test... - std::vector<double>::const_iterator first = m_chain[n].end() - 41; - std::vector<double>::const_iterator last = m_chain[n].end(); - std::vector<double> test(first, last); - int c = 0; - for (int j = 0; j < 39; ++j) { - if (test[j] == test[j + 1]) { - c += 1; - } + if (m_changes[i] == 0.0) { + jnew = m_jump[i] / + 10.0; // JUST FOR THE CASE THERE HAS NOT BEEN ANY CHANGE. + } else { + double f = m_changes[i] / double(m_counter); + jnew = m_jump[i] * f / jumpAR; } - if (c > 38) { - jnew = m_jump[i] / 100; - } // ...untill here. - else { - if (m_changes[i] == 0.0) { - jnew = m_jump[i] / 10.0; - } else { - double f = m_changes[i] / double(m_counter); - jnew = m_jump[i] * f / 0.6666666666; - /// std::cout << f << " m_counter "<< m_counter << " m_changes - /// " << m_changes[i] << std::endl; // DELETE AT THE END - } - } m_jump[i] = jnew; // Check if the new jump is too small. It means that it has been a wrong // convergence. if (std::abs(m_jump[i]) < lowJumpLimit) { API::IFunction_sptr fun = m_leastSquares->getFittingFunction(); - throw std::runtime_error( - "Wrong convergence for parameter " + fun->parameterName(i) + - ". Try to set a proper initial value this parameter"); + g_log.warning() + << "Wrong convergence for parameter " + fun->parameterName(i) + + ". Try to set a proper initial value for this parameter" + << std::endl; } } // Check if the Chi square value has converged for parameter i. - if (!m_par_converged[i] && - m_counter > 350) // It only check since the iteration number 350 - { + const size_t startingPoint = + 350; // The iteration since it starts to check if convergence is reached + if (!m_par_converged[i] && m_counter > startingPoint) { if (chi2_new != m_chi2) { double chi2_quotient = std::abs(chi2_new - m_chi2) / m_chi2; if (chi2_quotient < m_criteria[i]) { @@ -319,28 +317,28 @@ bool FABADAMinimizer::iterate(size_t) { } } } - } + } // for i - m_counter += - 1; // Update the counter, after finishing the iteration for each parameter + // Update the counter, after finishing the iteration for each parameter + m_counter += 1; // Check if Chi square has converged for all the parameters. if (m_counter > lowerIterationLimit && !m_converged) { size_t t = 0; - for (size_t i = 0; i < n; i++) { + for (size_t i = 0; i < nParams; i++) { if (m_par_converged[i]) { t += 1; } } // If all parameters have converged: // It set up both the counter and the changes' vector to 0, in order to - // consider only the - // data of the converged part of the chain, when updating the jump. - if (t == n) { + // consider only the data of the converged part of the chain, when updating + // the jump. + if (t == nParams) { m_converged = true; - m_conv_point = m_counter * n + 1; + m_conv_point = m_counter * nParams + 1; m_counter = 0; - for (size_t i = 0; i < n; ++i) { + for (size_t i = 0; i < nParams; ++i) { m_changes[i] = 0; } } @@ -357,7 +355,7 @@ bool FABADAMinimizer::iterate(size_t) { else { API::IFunction_sptr fun = m_leastSquares->getFittingFunction(); std::string failed = ""; - for (size_t i = 0; i < n; ++i) { + for (size_t i = 0; i < nParams; ++i) { if (!m_par_converged[i]) { failed = failed + fun->parameterName(i) + ", "; } @@ -365,7 +363,7 @@ bool FABADAMinimizer::iterate(size_t) { failed.replace(failed.end() - 2, failed.end(), "."); throw std::runtime_error( "Convegence NOT reached after " + - boost::lexical_cast<std::string>(m_counter) + + boost::lexical_cast<std::string>(m_max_iter) + " iterations.\n Try to set better initial values for parameters: " + failed); } @@ -375,176 +373,262 @@ bool FABADAMinimizer::iterate(size_t) { if (m_counter <= m_numberIterations) { return true; } - // When the all the iterations have been done, calculate and show all the - // results. - else { - // Create the workspace for the Probability Density Functions - API::MatrixWorkspace_sptr ws = API::WorkspaceFactory::Instance().create( - "Workspace2D", n, pdf_length + 1, pdf_length); - - // Create the workspace for the parameters' value and errors. - API::ITableWorkspace_sptr wsPdfE = - API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - wsPdfE->addColumn("str", "Name"); - wsPdfE->addColumn("double", "Value"); - wsPdfE->addColumn("double", "Left's error"); - wsPdfE->addColumn("double", "Rigth's error"); - - std::vector<double>::iterator pos_min = std::min_element( - m_chain[n].begin() + m_conv_point, - m_chain[n] - .end()); // Calculate the position of the minimum Chi aquare value - m_chi2 = *pos_min; - // index of the minimum chi^2 - size_t minIndex = - static_cast<size_t>(std::distance(m_chain[n].begin(), pos_min)); - - std::vector<double> par_def(n); - API::IFunction_sptr fun = m_leastSquares->getFittingFunction(); + // If convergence has been reached, but the maximum of iterations have been + // reached before finishing the chain, stop and throw the error. + if (m_counter >= m_max_iter) { + throw std::length_error("Convegence reached but Max Iterations parameter " + "insufficient for creating the whole chain.\n " + "Increase Max Iterations"); + } + // nothing else to do, stop interations + return false; + } + // can we even get here? + return true; +} - // Do one iteration for each parameter. - for (size_t j = 0; j < n; ++j) { - // Calculate the parameter value and the errors - par_def[j] = m_chain[j][minIndex]; - std::vector<double>::const_iterator first = - m_chain[j].begin() + m_conv_point; - std::vector<double>::const_iterator last = m_chain[j].end(); - std::vector<double> conv_chain(first, last); - size_t conv_length = conv_chain.size(); - std::sort(conv_chain.begin(), conv_chain.end()); - std::vector<double>::const_iterator pos_par = - std::find(conv_chain.begin(), conv_chain.end(), par_def[j]); - int sigma = int(0.34 * double(conv_length)); - // make sure the iterator is valid in any case - std::vector<double>::const_iterator pos_left = conv_chain.begin(); - if (sigma < static_cast<int>(std::distance(pos_left, pos_par))) { - pos_left = pos_par - sigma; - } - // make sure the iterator is valid in any case - std::vector<double>::const_iterator pos_right = conv_chain.end() - 1; - if (sigma < static_cast<int>(std::distance(pos_par, pos_right))) { - pos_right = pos_par + sigma; - } - API::TableRow row = wsPdfE->appendRow(); - row << fun->parameterName(j) << par_def[j] << *pos_left - *pos_par - << *pos_right - *pos_par; - - // Calculate the Probability Density Function - std::vector<double> pdf_y(pdf_length, 0); - double start = conv_chain[0]; - double bin = (conv_chain[conv_length - 1] - start) / pdf_length; - size_t step = 0; - MantidVec &X = ws->dataX(j); - MantidVec &Y = ws->dataY(j); - X[0] = start; - for (size_t i = 1; i < pdf_length + 1; i++) { - double bin_end = start + static_cast<double>(i) * bin; - X[i] = bin_end; - while (step < conv_length && conv_chain[step] <= bin_end) { - pdf_y[i - 1] += 1; - ++step; - } - Y[i - 1] = pdf_y[i - 1] / (double(conv_length) * bin); - } +double FABADAMinimizer::costFunctionVal() { return m_chi2; } - // Calculate the most probable value, from the PDF. - std::vector<double>::iterator pos_MP = - std::max_element(pdf_y.begin(), pdf_y.end()); - double mostP = X[pos_MP - pdf_y.begin()] + (bin / 2.0); - m_leastSquares->setParameter(j, mostP); - } +/// When the all the iterations have been done, calculate and show all the +/// results. +void FABADAMinimizer::finalize() { + // Creating the reduced chain (considering only one each "Steps between + // values" values) + size_t cl = getProperty("ChainLength"); + size_t n_steps = getProperty("StepsBetweenValues"); + size_t conv_length = size_t(double(cl) / double(n_steps)); + std::vector<std::vector<double>> red_conv_chain; + size_t nParams = m_leastSquares->nParams(); + for (size_t e = 0; e <= nParams; ++e) { + std::vector<double> v; + v.push_back(m_chain[e][m_conv_point]); + red_conv_chain.push_back(v); + } - // Set and name the two workspaces already calculated. - setProperty("OutputWorkspacePDF", ws); - setProperty("PdfError", wsPdfE); - - // Create the workspace for the complete parameters' chain (the last - // histogram is for the Chi square). - size_t chain_length = m_chain[0].size(); - API::MatrixWorkspace_sptr wsC = API::WorkspaceFactory::Instance().create( - "Workspace2D", n + 1, chain_length, chain_length); - - // Do one iteration for each parameter plus one for Chi square. - for (size_t j = 0; j < n + 1; ++j) { - MantidVec &X = wsC->dataX(j); - MantidVec &Y = wsC->dataY(j); - for (size_t k = 0; k < chain_length; ++k) { - X[k] = double(k); - Y[k] = m_chain[j][k]; - } + // Calculate the red_conv_chain for the cost fuction. + auto first = m_chain[nParams].begin() + m_conv_point; + auto last = m_chain[nParams].end(); + std::vector<double> conv_chain(first, last); + for (size_t k = 1; k < conv_length; ++k) { + red_conv_chain[nParams].push_back(conv_chain[n_steps * k]); + } + + // Calculate the position of the minimum Chi square value + auto pos_min = std::min_element(red_conv_chain[nParams].begin(), + red_conv_chain[nParams].end()); + m_chi2 = *pos_min; + + std::vector<double> par_def(nParams); + std::vector<double> error_left(nParams); + std::vector<double> error_rigth(nParams); + API::IFunction_sptr fun = m_leastSquares->getFittingFunction(); + + // Do one iteration for each parameter. + for (size_t j = 0; j < nParams; ++j) { + // Calculate the parameter value and the errors + auto first = m_chain[j].begin() + m_conv_point; + auto last = m_chain[j].end(); + std::vector<double> conv_chain(first, last); + auto &rc_chain_j = red_conv_chain[j]; + for (size_t k = 0; k < conv_length; ++k) { + rc_chain_j.push_back(conv_chain[n_steps * k]); + } + par_def[j] = rc_chain_j[pos_min - red_conv_chain[nParams].begin()]; + std::sort(rc_chain_j.begin(), rc_chain_j.end()); + auto pos_par = std::find(rc_chain_j.begin(), rc_chain_j.end(), par_def[j]); + size_t sigma = static_cast<size_t>(0.34 * double(conv_length)); + + auto pos_left = rc_chain_j.begin(); + if (sigma < static_cast<size_t>(std::distance(pos_left, pos_par))) { + pos_left = pos_par - sigma; + } + // make sure the iterator is valid in any case + auto pos_right = rc_chain_j.end() - 1; + if (sigma < static_cast<size_t>(std::distance(pos_par, pos_right))) { + pos_right = pos_par + sigma; + } + error_left[j] = *pos_left - *pos_par; + error_rigth[j] = *pos_right - *pos_par; + } + + const bool outputParametersTable = !getPropertyValue("Parameters").empty(); + + if (outputParametersTable) { + + // Create the workspace for the parameters' value and errors. + API::ITableWorkspace_sptr wsPdfE = + API::WorkspaceFactory::Instance().createTable("TableWorkspace"); + wsPdfE->addColumn("str", "Name"); + wsPdfE->addColumn("double", "Value"); + wsPdfE->addColumn("double", "Left's error"); + wsPdfE->addColumn("double", "Rigth's error"); + + for (size_t j = 0; j < nParams; ++j) { + API::TableRow row = wsPdfE->appendRow(); + row << fun->parameterName(j) << par_def[j] << error_left[j] + << error_rigth[j]; + } + // Set and name the Parameter Errors workspace. + setProperty("Parameters", wsPdfE); + } + + // Set the best parameter values + for (size_t j = 0; j < nParams; ++j) { + m_leastSquares->setParameter(j, par_def[j]); + } + + double mostPchi2; + + // Create the workspace for the Probability Density Functions + size_t pdf_length = 20; // histogram length for the PDF output workspace + API::MatrixWorkspace_sptr ws = API::WorkspaceFactory::Instance().create( + "Workspace2D", nParams + 1, pdf_length + 1, pdf_length); + + // Calculate the cost function Probability Density Function + std::sort(red_conv_chain[nParams].begin(), red_conv_chain[nParams].end()); + std::vector<double> pdf_y(pdf_length, 0); + double start = red_conv_chain[nParams][0]; + double bin = + (red_conv_chain[nParams][conv_length - 1] - start) / double(pdf_length); + size_t step = 0; + MantidVec &X = ws->dataX(nParams); + MantidVec &Y = ws->dataY(nParams); + X[0] = start; + for (size_t i = 1; i < pdf_length + 1; i++) { + double bin_end = start + double(i) * bin; + X[i] = bin_end; + while (step < conv_length && red_conv_chain[nParams][step] <= bin_end) { + pdf_y[i - 1] += 1; + ++step; + } + Y[i - 1] = pdf_y[i - 1] / (double(conv_length) * bin); + } + + std::vector<double>::iterator pos_MPchi2 = + std::max_element(pdf_y.begin(), pdf_y.end()); + + if (pos_MPchi2 - pdf_y.begin() == 0) { + // mostPchi2 = X[pos_MPchi2-pdf_y.begin()]; + mostPchi2 = *pos_min; + } else { + mostPchi2 = X[pos_MPchi2 - pdf_y.begin()] + (bin / 2.0); + } + + // Do one iteration for each parameter. + for (size_t j = 0; j < nParams; ++j) { + // Calculate the Probability Density Function + std::vector<double> pdf_y(pdf_length, 0); + double start = red_conv_chain[j][0]; + double bin = + (red_conv_chain[j][conv_length - 1] - start) / double(pdf_length); + size_t step = 0; + MantidVec &X = ws->dataX(j); + MantidVec &Y = ws->dataY(j); + X[0] = start; + for (size_t i = 1; i < pdf_length + 1; i++) { + double bin_end = start + double(i) * bin; + X[i] = bin_end; + while (step < conv_length && red_conv_chain[j][step] <= bin_end) { + pdf_y[i - 1] += 1; + ++step; } + Y[i - 1] = pdf_y[i - 1] / (double(conv_length) * bin); + } - // Set and name the workspace for the complete chain - setProperty("OutputWorkspaceChain", wsC); - - // Read if necessary to show the workspace for the converged part of the - // chain. - const bool con = !getPropertyValue("OutputWorkspaceConverged").empty(); - - if (con) { - // Create the workspace for the converged part of the chain. - size_t conv_length = (m_counter - 1) * n + m; - API::MatrixWorkspace_sptr wsConv = - API::WorkspaceFactory::Instance().create("Workspace2D", n + 1, - conv_length, conv_length); - - // Do one iteration for each parameter plus one for Chi square. - for (size_t j = 0; j < n + 1; ++j) { - std::vector<double>::const_iterator first = - m_chain[j].begin() + m_conv_point; - std::vector<double>::const_iterator last = m_chain[j].end(); - std::vector<double> conv_chain(first, last); - MantidVec &X = wsConv->dataX(j); - MantidVec &Y = wsConv->dataY(j); - for (size_t k = 0; k < conv_length; ++k) { - X[k] = double(k); - Y[k] = conv_chain[k]; - } - } + // Calculate the most probable value, from the PDF. + std::vector<double>::iterator pos_MP = + std::max_element(pdf_y.begin(), pdf_y.end()); + double mostP = X[pos_MP - pdf_y.begin()] + (bin / 2.0); + m_leastSquares->setParameter(j, mostP); + } + + // Set and name the PDF workspace. + setProperty("PDF", ws); - // Set and name the workspace for the converged part of the chain. - setProperty("OutputWorkspaceConverged", wsConv); + const bool outputChains = !getPropertyValue("Chains").empty(); + + if (outputChains) { + + // Create the workspace for the complete parameters' chain (the last + // histogram is for the Chi square). + size_t chain_length = m_chain[0].size(); + API::MatrixWorkspace_sptr wsC = API::WorkspaceFactory::Instance().create( + "Workspace2D", nParams + 1, chain_length, chain_length); + + // Do one iteration for each parameter plus one for Chi square. + for (size_t j = 0; j < nParams + 1; ++j) { + MantidVec &X = wsC->dataX(j); + MantidVec &Y = wsC->dataY(j); + for (size_t k = 0; k < chain_length; ++k) { + X[k] = double(k); + Y[k] = m_chain[j][k]; } + } - // Create the workspace for the Chi square values. - API::ITableWorkspace_sptr wsChi2 = - API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - wsChi2->addColumn("double", "Chi2min"); - wsChi2->addColumn("double", "Chi2MP"); - wsChi2->addColumn("double", "Chi2min_red"); - wsChi2->addColumn("double", "Chi2MP_red"); - - // Calculate de Chi square most probable. - double Chi2MP = m_leastSquares->val(); - - // Reset the best parameter values ---> Si al final no se muestra la tabla - // que sale por defecto, esto se podra borrar... - for (size_t j = 0; j < n; ++j) { - m_leastSquares->setParameter(j, par_def[j]); + // Set and name the workspace for the complete chain + setProperty("Chains", wsC); + } + + // Read if necessary to show the workspace for the converged part of the + // chain. + const bool outputConvergedChains = !getPropertyValue("ConvergedChain").empty(); + + if (outputConvergedChains) { + // Create the workspace for the converged part of the chain. + API::MatrixWorkspace_sptr wsConv = API::WorkspaceFactory::Instance().create( + "Workspace2D", nParams + 1, conv_length, conv_length); + + // Do one iteration for each parameter plus one for Chi square. + for (size_t j = 0; j < nParams + 1; ++j) { + std::vector<double>::const_iterator first = + m_chain[j].begin() + m_conv_point; + std::vector<double>::const_iterator last = m_chain[j].end(); + std::vector<double> conv_chain(first, last); + MantidVec &X = wsConv->dataX(j); + MantidVec &Y = wsConv->dataY(j); + for (size_t k = 0; k < conv_length; ++k) { + X[k] = double(k); + Y[k] = conv_chain[n_steps * k]; } + } - // Obtain the quantity of the initial data. - API::FunctionDomain_sptr domain = m_leastSquares->getDomain(); - size_t data_number = domain->size(); + // Set and name the workspace for the converged part of the chain. + setProperty("ConvergedChain", wsConv); + } - // Calculate the value for the reduced Chi square. - double Chi2min_red = - *pos_min / (double(data_number - n)); // For de minimum value. - double Chi2MP_red = - Chi2MP / (double(data_number - n)); // For the most probable. + // Read if necessary to show the workspace for the Chi square values. + const bool outputCostFunctionTable = !getPropertyValue("CostFunctionTable").empty(); - // Add the information to the workspace and name it. - API::TableRow row = wsChi2->appendRow(); - row << *pos_min << Chi2MP << Chi2min_red << Chi2MP_red; - setProperty("ChiSquareTable", wsChi2); + if (outputCostFunctionTable) { - return false; - } + // Create the workspace for the Chi square values. + API::ITableWorkspace_sptr wsChi2 = + API::WorkspaceFactory::Instance().createTable("TableWorkspace"); + wsChi2->addColumn("double", "Chi2min"); + wsChi2->addColumn("double", "Chi2MP"); + wsChi2->addColumn("double", "Chi2min_red"); + wsChi2->addColumn("double", "Chi2MP_red"); + + // Obtain the quantity of the initial data. + API::FunctionDomain_sptr domain = m_leastSquares->getDomain(); + size_t data_number = domain->size(); + + // Calculate the value for the reduced Chi square. + double Chi2min_red = + m_chi2 / (double(data_number - nParams)); // For de minimum value. + double mostPchi2_red = mostPchi2 / (double(data_number - nParams)); + + // Add the information to the workspace and name it. + API::TableRow row = wsChi2->appendRow(); + row << m_chi2 << mostPchi2 << Chi2min_red << mostPchi2_red; + setProperty("CostFunctionTable", wsChi2); } - return true; + // Set the best parameter values + for (size_t j = 0; j < nParams; ++j) { + m_leastSquares->setParameter(j, par_def[j]); + } } -double FABADAMinimizer::costFunctionVal() { return m_chi2; } } // namespace CurveFitting } // namespace Mantid diff --git a/Code/Mantid/Framework/CurveFitting/src/Fit.cpp b/Code/Mantid/Framework/CurveFitting/src/Fit.cpp index b0e1c9b99b332dfb5a691440a0984ed531e29c7f..691c124409b3ae99a5e9cba7499b0da0d525bcd7 100644 --- a/Code/Mantid/Framework/CurveFitting/src/Fit.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/Fit.cpp @@ -445,6 +445,8 @@ void Fit::exec() { } g_log.debug() << "Number of minimizer iterations=" << iter << "\n"; + minimizer->finalize(); + if (iter >= maxIterations) { if (!errorString.empty()) { errorString += '\n'; diff --git a/Code/Mantid/Framework/CurveFitting/src/GaussianComptonProfile.cpp b/Code/Mantid/Framework/CurveFitting/src/GaussianComptonProfile.cpp index f1600c26fc8a0ddcb49939f64d5fc114381b5dfe..b77daafba109cacdcaa99a37c0f10d5291b8227a 100644 --- a/Code/Mantid/Framework/CurveFitting/src/GaussianComptonProfile.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/GaussianComptonProfile.cpp @@ -6,7 +6,7 @@ namespace Mantid { namespace CurveFitting { -DECLARE_FUNCTION(GaussianComptonProfile); +DECLARE_FUNCTION(GaussianComptonProfile) const char *WIDTH_PARAM = "Width"; const char *AMP_PARAM = "Intensity"; diff --git a/Code/Mantid/Framework/CurveFitting/src/GramCharlierComptonProfile.cpp b/Code/Mantid/Framework/CurveFitting/src/GramCharlierComptonProfile.cpp index c6a64b0fbb44308a177a2ad9d56b795ed331a548..fe20a841b14106e5149e0f1609f16423d7ede2ea 100644 --- a/Code/Mantid/Framework/CurveFitting/src/GramCharlierComptonProfile.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/GramCharlierComptonProfile.cpp @@ -14,7 +14,7 @@ namespace Mantid { namespace CurveFitting { // Register into factory -DECLARE_FUNCTION(GramCharlierComptonProfile); +DECLARE_FUNCTION(GramCharlierComptonProfile) namespace { ///@cond diff --git a/Code/Mantid/Framework/CurveFitting/src/IkedaCarpenterPV.cpp b/Code/Mantid/Framework/CurveFitting/src/IkedaCarpenterPV.cpp index e9d8a908511a5e0e01bf15bfe306c4955440bcc2..527a9c39698081e58d8acc3d322ee20b35585697 100644 --- a/Code/Mantid/Framework/CurveFitting/src/IkedaCarpenterPV.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/IkedaCarpenterPV.cpp @@ -49,7 +49,7 @@ void IkedaCarpenterPV::setHeight(const double h) { // The intensity is then estimated to be h/h0 setParameter("I", h / h0); -}; +} double IkedaCarpenterPV::height() const { // return the function value at centre() @@ -59,7 +59,7 @@ double IkedaCarpenterPV::height() const { toCentre[0] = centre(); constFunction(h0, toCentre, 1); return h0[0]; -}; +} double IkedaCarpenterPV::fwhm() const { double sigmaSquared = getParameter("SigmaSquared"); @@ -83,14 +83,14 @@ double IkedaCarpenterPV::fwhm() const { ; } return sqrt(8.0 * M_LN2 * sigmaSquared) + gamma; -}; +} void IkedaCarpenterPV::setFwhm(const double w) { setParameter("SigmaSquared", w * w / (32.0 * M_LN2)); // used 4.0 * 8.0 = 32.0 setParameter("Gamma", w / 2.0); -}; +} -void IkedaCarpenterPV::setCentre(const double c) { setParameter("X0", c); }; +void IkedaCarpenterPV::setCentre(const double c) { setParameter("X0", c); } void IkedaCarpenterPV::init() { declareParameter("I", 0.0, "The integrated intensity of the peak. I.e. " diff --git a/Code/Mantid/Framework/CurveFitting/src/Lorentzian.cpp b/Code/Mantid/Framework/CurveFitting/src/Lorentzian.cpp index 7791d92f6eabe6156ca93ac74b904da707e68de3..8d58c9a3915b9d7bd87d8d9da9be2a6f5ae70be0 100644 --- a/Code/Mantid/Framework/CurveFitting/src/Lorentzian.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/Lorentzian.cpp @@ -11,7 +11,7 @@ namespace CurveFitting { using namespace Kernel; using namespace API; -DECLARE_FUNCTION(Lorentzian); +DECLARE_FUNCTION(Lorentzian) void Lorentzian::init() { declareParameter("Amplitude", 1.0, "Intensity scaling"); diff --git a/Code/Mantid/Framework/CurveFitting/src/PawleyFit.cpp b/Code/Mantid/Framework/CurveFitting/src/PawleyFit.cpp new file mode 100644 index 0000000000000000000000000000000000000000..11a110f20013093857770a0b029f87931656e4a0 --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/src/PawleyFit.cpp @@ -0,0 +1,405 @@ +#include "MantidCurveFitting/PawleyFit.h" + +#include "MantidAPI/FunctionFactory.h" +#include "MantidCurveFitting/PawleyFunction.h" +#include "MantidAPI/TableRow.h" + +#include "MantidGeometry/Crystal/UnitCell.h" +#include "MantidKernel/ListValidator.h" +#include "MantidKernel/UnitFactory.h" +#include "MantidKernel/UnitConversion.h" + +#include <algorithm> + +namespace Mantid { +namespace CurveFitting { + +using namespace API; +using namespace Kernel; +using namespace Geometry; + +DECLARE_ALGORITHM(PawleyFit) + +/// Default constructor +PawleyFit::PawleyFit() : Algorithm(), m_dUnit() {} + +/// Returns the summary +const std::string PawleyFit::summary() const { + return "This algorithm performs a Pawley-fit on the supplied workspace."; +} + +/// Transforms the specified value from d-spacing to the supplied unit. +double PawleyFit::getTransformedCenter(double d, const Unit_sptr &unit) const { + if (boost::dynamic_pointer_cast<Units::Empty>(unit) || + boost::dynamic_pointer_cast<Units::dSpacing>(unit)) { + return d; + } + + return UnitConversion::run(*m_dUnit, *unit, d, 0, 0, 0, DeltaEMode::Elastic, + 0); +} + +/** + * Add HKLs from a TableWorkspace to the PawleyFunction. + * + * This method tries to extract reflections from the specified TableWorkspace. + * For the extraction to work properly it needs to have columns with the + * following labels: + * HKL, d, Intensity, FWHM (rel.) + * + * The latter three must be convertible to double, otherwise the there will be + * no peaks in the function. The value of d is converted to the unit of the + * workspace to obtain an absolute FWHM-value, since FWHM (rel.) is defined + * as FWHM / center. + * + * The HKLs can either be a column of V3D or a string column that contains 3 + * numbers separated by space, comma, semi-colon, or [ ] + * + * @param pawleyFn :: PawleyFunction which the HKLs should be added to. + * @param tableWs :: TableWorkspace that contains the reflection information. + * @param unit :: Unit of the workspace. + * @param startX :: Lowest allowed x-value for reflection position. + * @param endX :: Highest allowed x-value for reflection position. + */ +void PawleyFit::addHKLsToFunction(PawleyFunction_sptr &pawleyFn, + const ITableWorkspace_sptr &tableWs, + const Unit_sptr &unit, double startX, + double endX) const { + if (!tableWs || !pawleyFn) { + throw std::invalid_argument("Can only process non-null function & table."); + } + + pawleyFn->clearPeaks(); + + try { + Column_const_sptr hklColumn = tableWs->getColumn("HKL"); + Column_const_sptr dColumn = tableWs->getColumn("d"); + Column_const_sptr intensityColumn = tableWs->getColumn("Intensity"); + Column_const_sptr fwhmColumn = tableWs->getColumn("FWHM (rel.)"); + + for (size_t i = 0; i < tableWs->rowCount(); ++i) { + try { + V3D hkl = getHKLFromColumn(i, hklColumn); + + double d = (*dColumn)[i]; + double center = getTransformedCenter(d, unit); + double fwhm = (*fwhmColumn)[i] * center; + double height = (*intensityColumn)[i]; + + if (center > startX && center < endX) { + pawleyFn->addPeak(hkl, fwhm, height); + } + } + catch (std::bad_alloc) { + // do nothing. + } + } + } + catch (std::runtime_error) { + // Column does not exist + throw std::runtime_error("Can not process table, the following columns are " + "required: HKL, d, Intensity, FWHM (rel.)"); + } +} + +/// Tries to extract Miller indices as V3D from column. +V3D PawleyFit::getHKLFromColumn(size_t i, + const Column_const_sptr &hklColumn) const { + if (hklColumn->type() == "V3D") { + return hklColumn->cell<V3D>(i); + } + + return getHkl(hklColumn->cell<std::string>(i)); +} + +/// Try to extract a V3D from the given string with different separators. +V3D PawleyFit::getHkl(const std::string &hklString) const { + auto delimiters = boost::is_any_of(" ,[];"); + + std::string workingCopy = boost::trim_copy_if(hklString, delimiters); + std::vector<std::string> indicesStr; + boost::split(indicesStr, workingCopy, delimiters); + + if (indicesStr.size() != 3) { + throw std::invalid_argument("Input string cannot be parsed as HKL."); + } + + V3D hkl; + hkl.setX(boost::lexical_cast<double>(indicesStr[0])); + hkl.setY(boost::lexical_cast<double>(indicesStr[1])); + hkl.setZ(boost::lexical_cast<double>(indicesStr[2])); + + return hkl; +} + +/// Creates a table containing the cell parameters stored in the supplied +/// function. +ITableWorkspace_sptr +PawleyFit::getLatticeFromFunction(const PawleyFunction_sptr &pawleyFn) const { + if (!pawleyFn) { + throw std::invalid_argument( + "Cannot extract lattice parameters from null function."); + } + + ITableWorkspace_sptr latticeParameterTable = + WorkspaceFactory::Instance().createTable(); + + latticeParameterTable->addColumn("str", "Parameter"); + latticeParameterTable->addColumn("double", "Value"); + latticeParameterTable->addColumn("double", "Error"); + + PawleyParameterFunction_sptr parameters = + pawleyFn->getPawleyParameterFunction(); + + for (size_t i = 0; i < parameters->nParams(); ++i) { + TableRow newRow = latticeParameterTable->appendRow(); + newRow << parameters->parameterName(i) << parameters->getParameter(i) + << parameters->getError(i); + } + + return latticeParameterTable; +} + +/// Extracts all profile parameters from the supplied function. +ITableWorkspace_sptr PawleyFit::getPeakParametersFromFunction( + const PawleyFunction_sptr &pawleyFn) const { + if (!pawleyFn) { + throw std::invalid_argument( + "Cannot extract peak parameters from null function."); + } + + ITableWorkspace_sptr peakParameterTable = + WorkspaceFactory::Instance().createTable(); + + peakParameterTable->addColumn("int", "Peak"); + peakParameterTable->addColumn("V3D", "HKL"); + peakParameterTable->addColumn("str", "Parameter"); + peakParameterTable->addColumn("double", "Value"); + peakParameterTable->addColumn("double", "Error"); + + for (size_t i = 0; i < pawleyFn->getPeakCount(); ++i) { + + IPeakFunction_sptr currentPeak = pawleyFn->getPeakFunction(i); + + int peakNumber = static_cast<int>(i + 1); + V3D peakHKL = pawleyFn->getPeakHKL(i); + + for (size_t j = 0; j < currentPeak->nParams(); ++j) { + TableRow newRow = peakParameterTable->appendRow(); + newRow << peakNumber << peakHKL << currentPeak->parameterName(j) + << currentPeak->getParameter(j) << currentPeak->getError(j); + } + } + + return peakParameterTable; +} + +/// Returns a composite function consisting of the Pawley function and Chebyshev +/// background if enabled in the algorithm. +IFunction_sptr +PawleyFit::getCompositeFunction(const PawleyFunction_sptr &pawleyFn) const { + CompositeFunction_sptr composite = boost::make_shared<CompositeFunction>(); + composite->addFunction(pawleyFn); + + bool enableChebyshev = getProperty("EnableChebyshevBackground"); + if (enableChebyshev) { + int degree = getProperty("ChebyshevBackgroundDegree"); + IFunction_sptr chebyshev = + FunctionFactory::Instance().createFunction("Chebyshev"); + chebyshev->setAttributeValue("n", degree); + + composite->addFunction(chebyshev); + } + + return composite; +} + +/// Initialization of properties. +void PawleyFit::init() { + declareProperty(new WorkspaceProperty<MatrixWorkspace>("InputWorkspace", "", + Direction::Input), + "Input workspace that contains the spectrum on which to " + "perform the Pawley fit."); + + declareProperty("WorkspaceIndex", 0, + "Spectrum on which the fit should be performed."); + + declareProperty("StartX", 0.0, "Lower border of fitted data range."); + declareProperty("EndX", 0.0, "Upper border of fitted data range."); + + std::vector<std::string> crystalSystems; + crystalSystems.push_back("Cubic"); + crystalSystems.push_back("Tetragonal"); + crystalSystems.push_back("Hexagonal"); + crystalSystems.push_back("Trigonal"); + crystalSystems.push_back("Orthorhombic"); + crystalSystems.push_back("Monoclinic"); + crystalSystems.push_back("Triclinic"); + + auto crystalSystemValidator = + boost::make_shared<StringListValidator>(crystalSystems); + + declareProperty("CrystalSystem", crystalSystems.back(), + crystalSystemValidator, + "Crystal system to use for refinement."); + + declareProperty("InitialCell", "1.0 1.0 1.0 90.0 90.0 90.0", + "Specification of initial unit cell, given as 'a, b, c, " + "alpha, beta, gamma'."); + + declareProperty( + new WorkspaceProperty<ITableWorkspace>("PeakTable", "", Direction::Input), + "Table with peak information. Can be used instead of " + "supplying a list of indices for better starting parameters."); + + declareProperty("RefineZeroShift", false, "If checked, a zero-shift with the " + "same unit as the spectrum is " + "refined."); + + auto peakFunctionValidator = boost::make_shared<StringListValidator>( + FunctionFactory::Instance().getFunctionNames<IPeakFunction>()); + + declareProperty("PeakProfileFunction", "Gaussian", peakFunctionValidator, + "Profile function that is used for each peak."); + + declareProperty("EnableChebyshevBackground", false, + "If checked, a Chebyshev " + "polynomial will be added " + "to model the background."); + + declareProperty("ChebyshevBackgroundDegree", 0, + "Degree of the Chebyshev polynomial, if used as background."); + + declareProperty("CalculationOnly", false, "If enabled, no fit is performed, " + "the function is only evaluated " + "and output is generated."); + + declareProperty(new WorkspaceProperty<MatrixWorkspace>("OutputWorkspace", "", + Direction::Output), + "Workspace that contains measured spectrum, calculated " + "spectrum and difference curve."); + + declareProperty( + new WorkspaceProperty<ITableWorkspace>("RefinedCellTable", "", + Direction::Output), + "TableWorkspace with refined lattice parameters, including errors."); + + declareProperty( + new WorkspaceProperty<ITableWorkspace>("RefinedPeakParameterTable", "", + Direction::Output), + "TableWorkspace with refined peak parameters, including errors."); + + declareProperty("ReducedChiSquare", 0.0, "Outputs the reduced chi square " + "value as a measure for the quality " + "of the fit.", + Direction::Output); + + m_dUnit = UnitFactory::Instance().create("dSpacing"); +} + +/// Execution of algorithm. +void PawleyFit::exec() { + // Setup PawleyFunction with cell from input parameters + PawleyFunction_sptr pawleyFn = boost::dynamic_pointer_cast<PawleyFunction>( + FunctionFactory::Instance().createFunction("PawleyFunction")); + g_log.information() << "Setting up Pawley function..." << std::endl; + + std::string profileFunction = getProperty("PeakProfileFunction"); + pawleyFn->setProfileFunction(profileFunction); + g_log.information() << " Selected profile function: " << profileFunction + << std::endl; + + std::string crystalSystem = getProperty("CrystalSystem"); + pawleyFn->setCrystalSystem(crystalSystem); + g_log.information() << " Selected crystal system: " << crystalSystem + << std::endl; + + pawleyFn->setUnitCell(getProperty("InitialCell")); + PawleyParameterFunction_sptr pawleyParameterFunction = + pawleyFn->getPawleyParameterFunction(); + g_log.information() + << " Initial unit cell: " + << unitCellToStr(pawleyParameterFunction->getUnitCellFromParameters()) + << std::endl; + + // Get the input workspace with the data + MatrixWorkspace_const_sptr ws = getProperty("InputWorkspace"); + int wsIndex = getProperty("WorkspaceIndex"); + + // Get x-range start and end values, depending on user input + const MantidVec &xData = ws->readX(static_cast<size_t>(wsIndex)); + double startX = xData.front(); + double endX = xData.back(); + + Property *startXProperty = getPointerToProperty("StartX"); + if (!startXProperty->isDefault()) { + double startXInput = getProperty("StartX"); + startX = std::max(startX, startXInput); + } + + Property *endXProperty = getPointerToProperty("EndX"); + if (!endXProperty->isDefault()) { + double endXInput = getProperty("EndX"); + endX = std::min(endX, endXInput); + } + + g_log.information() << " Refined range: " << startX << " - " << endX + << std::endl; + + // Get HKLs from TableWorkspace + ITableWorkspace_sptr peakTable = getProperty("PeakTable"); + Axis *xAxis = ws->getAxis(0); + Unit_sptr xUnit = xAxis->unit(); + addHKLsToFunction(pawleyFn, peakTable, xUnit, startX, endX); + + g_log.information() << " Peaks in PawleyFunction: " + << pawleyFn->getPeakCount() << std::endl; + + // Determine if zero-shift should be refined + bool refineZeroShift = getProperty("RefineZeroShift"); + if (!refineZeroShift) { + pawleyFn->fix(pawleyFn->parameterIndex("f0.ZeroShift")); + } else { + g_log.information() << " Refining ZeroShift." << std::endl; + } + + pawleyFn->setMatrixWorkspace(ws, static_cast<size_t>(wsIndex), startX, endX); + + g_log.information() << "Setting up Fit..." << std::endl; + + // Generate Fit-algorithm with required properties. + Algorithm_sptr fit = createChildAlgorithm("Fit", -1, -1, true); + fit->setProperty("Function", getCompositeFunction(pawleyFn)); + fit->setProperty("InputWorkspace", + boost::const_pointer_cast<MatrixWorkspace>(ws)); + fit->setProperty("StartX", startX); + fit->setProperty("EndX", endX); + fit->setProperty("WorkspaceIndex", wsIndex); + + bool calculationOnly = getProperty("CalculationOnly"); + if (calculationOnly) { + fit->setProperty("MaxIterations", 0); + } + + fit->setProperty("CreateOutput", true); + + fit->execute(); + double chiSquare = fit->getProperty("OutputChi2overDoF"); + + g_log.information() << "Fit finished, reduced ChiSquare = " << chiSquare + << std::endl; + + g_log.information() << "Generating output..." << std::endl; + + // Create output + MatrixWorkspace_sptr output = fit->getProperty("OutputWorkspace"); + setProperty("OutputWorkspace", output); + setProperty("RefinedCellTable", getLatticeFromFunction(pawleyFn)); + setProperty("RefinedPeakParameterTable", + getPeakParametersFromFunction(pawleyFn)); + + setProperty("ReducedChiSquare", chiSquare); +} + +} // namespace CurveFitting +} // namespace Mantid diff --git a/Code/Mantid/Framework/CurveFitting/src/PawleyFunction.cpp b/Code/Mantid/Framework/CurveFitting/src/PawleyFunction.cpp new file mode 100644 index 0000000000000000000000000000000000000000..58f597657779b5a42010fba68d7f23a0acfd4a13 --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/src/PawleyFunction.cpp @@ -0,0 +1,498 @@ +#include "MantidCurveFitting/PawleyFunction.h" + +#include "MantidAPI/FunctionFactory.h" +#include "MantidKernel/UnitConversion.h" +#include "MantidKernel/UnitFactory.h" + +#include <boost/algorithm/string.hpp> +#include <boost/make_shared.hpp> + +namespace Mantid { +namespace CurveFitting { + +DECLARE_FUNCTION(PawleyParameterFunction) + +using namespace API; +using namespace Geometry; +using namespace Kernel; + +/// Constructor +PawleyParameterFunction::PawleyParameterFunction() + : ParamFunction(), m_crystalSystem(PointGroup::Triclinic), + m_profileFunctionCenterParameterName() {} + +/** + * @brief Sets the supplied attribute value + * + * The function calls ParamFunction::setAttribute, but performs additional + * actions for CrystalSystem and ProfileFunction. + * + * @param attName :: Name of the attribute + * @param attValue :: Value of the attribute + */ +void PawleyParameterFunction::setAttribute(const std::string &attName, + const Attribute &attValue) { + if (attName == "CrystalSystem") { + setCrystalSystem(attValue.asString()); + } else if (attName == "ProfileFunction") { + setProfileFunction(attValue.asString()); + } + + ParamFunction::setAttribute(attName, attValue); +} + +/// Returns the crystal system +PointGroup::CrystalSystem PawleyParameterFunction::getCrystalSystem() const { + return m_crystalSystem; +} + +/// Returns a UnitCell object constructed from the function's parameters. +UnitCell PawleyParameterFunction::getUnitCellFromParameters() const { + switch (m_crystalSystem) { + case PointGroup::Cubic: { + double a = getParameter("a"); + return UnitCell(a, a, a); + } + case PointGroup::Tetragonal: { + double a = getParameter("a"); + return UnitCell(a, a, getParameter("c")); + } + case PointGroup::Hexagonal: { + double a = getParameter("a"); + return UnitCell(a, a, getParameter("c"), 90, 90, 120); + } + case PointGroup::Trigonal: { + double a = getParameter("a"); + double alpha = getParameter("Alpha"); + return UnitCell(a, a, a, alpha, alpha, alpha); + } + case PointGroup::Orthorhombic: { + return UnitCell(getParameter("a"), getParameter("b"), getParameter("c")); + } + case PointGroup::Monoclinic: { + return UnitCell(getParameter("a"), getParameter("b"), getParameter("c"), 90, + getParameter("Beta"), 90); + } + case PointGroup::Triclinic: { + return UnitCell(getParameter("a"), getParameter("b"), getParameter("c"), + getParameter("Alpha"), getParameter("Beta"), + getParameter("Gamma")); + } + } + + return UnitCell(); +} + +/// Sets the function's parameters from the supplied UnitCell. +void PawleyParameterFunction::setParametersFromUnitCell(const UnitCell &cell) { + // Parameter "a" exists in all crystal systems. + setParameter("a", cell.a()); + + try { + setParameter("b", cell.b()); + } + catch (std::invalid_argument) { + // do nothing. + } + + try { + setParameter("c", cell.c()); + } + catch (std::invalid_argument) { + // do nothing + } + + try { + setParameter("Alpha", cell.alpha()); + } + catch (std::invalid_argument) { + // do nothing. + } + try { + setParameter("Beta", cell.beta()); + } + catch (std::invalid_argument) { + // do nothing. + } + try { + setParameter("Gamma", cell.gamma()); + } + catch (std::invalid_argument) { + // do nothing. + } +} + +/// This method does nothing. +void PawleyParameterFunction::function(const FunctionDomain &domain, + FunctionValues &values) const { + UNUSED_ARG(domain); + UNUSED_ARG(values); +} + +/// This method does nothing. +void PawleyParameterFunction::functionDeriv(const FunctionDomain &domain, + Jacobian &jacobian) { + UNUSED_ARG(domain) + UNUSED_ARG(jacobian); +} + +/// Declares attributes and generates parameters based on the defaults. +void PawleyParameterFunction::init() { + declareAttribute("CrystalSystem", IFunction::Attribute("Triclinic")); + declareAttribute("ProfileFunction", IFunction::Attribute("Gaussian")); + + setCrystalSystem("Triclinic"); + setProfileFunction("Gaussian"); +} + +/** + * Sets the profile function + * + * This method takes a function name and tries to create the corresponding + * function through FunctionFactory. Then it checks whether the function + * inherits from IPeakFunction and determines the centre parameter to store it. + * + * @param profileFunction :: Name of an IPeakFunction implementation. + */ +void PawleyParameterFunction::setProfileFunction( + const std::string &profileFunction) { + IPeakFunction_sptr peakFunction = boost::dynamic_pointer_cast<IPeakFunction>( + FunctionFactory::Instance().createFunction(profileFunction)); + + if (!peakFunction) { + throw std::invalid_argument("PawleyFunction can only use IPeakFunctions to " + "calculate peak profiles."); + } + + setCenterParameterNameFromFunction(peakFunction); +} + +/** + * Assigns the crystal system + * + * This method takes the name of a crystal system (case insensitive) and stores + * it. Furthermore it creates the necessary parameters, which means that after + * calling this function, PawleyParameterFunction potentially exposes a + * different number of parameters. + * + * @param crystalSystem :: Crystal system, case insensitive. + */ +void +PawleyParameterFunction::setCrystalSystem(const std::string &crystalSystem) { + std::string crystalSystemLC = boost::algorithm::to_lower_copy(crystalSystem); + + if (crystalSystemLC == "cubic") { + m_crystalSystem = PointGroup::Cubic; + } else if (crystalSystemLC == "tetragonal") { + m_crystalSystem = PointGroup::Tetragonal; + } else if (crystalSystemLC == "hexagonal") { + m_crystalSystem = PointGroup::Hexagonal; + } else if (crystalSystemLC == "trigonal") { + m_crystalSystem = PointGroup::Trigonal; + } else if (crystalSystemLC == "orthorhombic") { + m_crystalSystem = PointGroup::Orthorhombic; + } else if (crystalSystemLC == "monoclinic") { + m_crystalSystem = PointGroup::Monoclinic; + } else if (crystalSystemLC == "triclinic") { + m_crystalSystem = PointGroup::Triclinic; + } else { + throw std::invalid_argument("Not a valid crystal system: '" + + crystalSystem + "'."); + } + + createCrystalSystemParameters(m_crystalSystem); +} + +/// This method clears all parameters and declares parameters according to the +/// supplied crystal system. +void PawleyParameterFunction::createCrystalSystemParameters( + PointGroup::CrystalSystem crystalSystem) { + + clearAllParameters(); + switch (crystalSystem) { + case PointGroup::Cubic: + declareParameter("a", 1.0); + break; + + case PointGroup::Hexagonal: + case PointGroup::Tetragonal: + declareParameter("a", 1.0); + declareParameter("c", 1.0); + break; + + case PointGroup::Orthorhombic: + declareParameter("a", 1.0); + declareParameter("b", 1.0); + declareParameter("c", 1.0); + break; + + case PointGroup::Monoclinic: + declareParameter("a", 1.0); + declareParameter("b", 1.0); + declareParameter("c", 1.0); + declareParameter("Beta", 90.0); + break; + + case PointGroup::Trigonal: + declareParameter("a", 1.0); + declareParameter("Alpha", 90.0); + break; + + default: + // triclinic + declareParameter("a", 1.0); + declareParameter("b", 1.0); + declareParameter("c", 1.0); + + declareParameter("Alpha", 90.0); + declareParameter("Beta", 90.0); + declareParameter("Gamma", 90.0); + break; + } + + declareParameter("ZeroShift", 0.0); +} + +/// Tries to extract and store the center parameter name from the function. +void PawleyParameterFunction::setCenterParameterNameFromFunction( + const IPeakFunction_sptr &profileFunction) { + m_profileFunctionCenterParameterName.clear(); + if (profileFunction) { + m_profileFunctionCenterParameterName = + profileFunction->getCentreParameterName(); + } +} + +DECLARE_FUNCTION(PawleyFunction) + +/// Constructor +PawleyFunction::PawleyFunction() + : FunctionParameterDecorator(), m_compositeFunction(), + m_pawleyParameterFunction(), m_peakProfileComposite(), m_hkls(), + m_dUnit(), m_wsUnit() {} + +void PawleyFunction::setMatrixWorkspace( + boost::shared_ptr<const MatrixWorkspace> workspace, size_t wi, + double startX, double endX) { + if (workspace) { + Axis *xAxis = workspace->getAxis(wi); + Kernel::Unit_sptr wsUnit = xAxis->unit(); + + if (boost::dynamic_pointer_cast<Units::Empty>(wsUnit) || + boost::dynamic_pointer_cast<Units::dSpacing>(wsUnit)) { + m_wsUnit = m_dUnit; + } else { + double factor, power; + if (wsUnit->quickConversion(*m_dUnit, factor, power)) { + m_wsUnit = wsUnit; + } else { + throw std::invalid_argument("Can not use quick conversion for unit."); + } + } + } + + m_wrappedFunction->setMatrixWorkspace(workspace, wi, startX, endX); +} + +/// Sets the crystal system on the internal parameter function and updates the +/// exposed parameters +void PawleyFunction::setCrystalSystem(const std::string &crystalSystem) { + m_pawleyParameterFunction->setAttributeValue("CrystalSystem", crystalSystem); + m_compositeFunction->checkFunction(); +} + +/// Sets the profile function and replaces already existing functions in the +/// internally stored CompositeFunction. +void PawleyFunction::setProfileFunction(const std::string &profileFunction) { + m_pawleyParameterFunction->setAttributeValue("ProfileFunction", + profileFunction); + + /* At this point PawleyParameterFunction guarantees that it's an IPeakFunction + * and all existing profile functions are replaced. + */ + for (size_t i = 0; i < m_peakProfileComposite->nFunctions(); ++i) { + IPeakFunction_sptr oldFunction = boost::dynamic_pointer_cast<IPeakFunction>( + m_peakProfileComposite->getFunction(i)); + + IPeakFunction_sptr newFunction = boost::dynamic_pointer_cast<IPeakFunction>( + FunctionFactory::Instance().createFunction( + m_pawleyParameterFunction->getProfileFunctionName())); + + newFunction->setCentre(oldFunction->centre()); + try { + newFunction->setFwhm(oldFunction->fwhm()); + } + catch (...) { + // do nothing. + } + newFunction->setHeight(oldFunction->height()); + + m_peakProfileComposite->replaceFunction(i, newFunction); + } + + // Update exposed parameters. + m_compositeFunction->checkFunction(); +} + +/// Sets the unit cell from a string with either 6 or 3 space-separated numbers. +void PawleyFunction::setUnitCell(const std::string &unitCellString) { + m_pawleyParameterFunction->setParametersFromUnitCell( + strToUnitCell(unitCellString)); +} + +/// Transform d value to workspace unit +double PawleyFunction::getTransformedCenter(double d) const { + if ((m_dUnit && m_wsUnit) && m_dUnit != m_wsUnit) { + return UnitConversion::run(*m_dUnit, *m_wsUnit, d, 0, 0, 0, + DeltaEMode::Elastic, 0); + } + + return d; +} + +/** + * Calculates the function values on the supplied domain + * + * This function is the core of PawleyFunction. It calculates the d-value for + * each stored HKL from the unit cell that is the result of the parameters + * stored in the internal PawleyParameterFunction and adds the ZeroShift + * parameter. The value is set as center parameter on the internally stored + * PeakFunctions. + * + * @param domain :: Function domain. + * @param values :: Function values. + */ +void PawleyFunction::function(const FunctionDomain &domain, + FunctionValues &values) const { + UnitCell cell = m_pawleyParameterFunction->getUnitCellFromParameters(); + double zeroShift = m_pawleyParameterFunction->getParameter("ZeroShift"); + + for (size_t i = 0; i < m_hkls.size(); ++i) { + double centre = getTransformedCenter(cell.d(m_hkls[i])); + + m_peakProfileComposite->getFunction(i)->setParameter( + m_pawleyParameterFunction->getProfileFunctionCenterParameterName(), + centre + zeroShift); + } + + m_peakProfileComposite->function(domain, values); +} + +/// Removes all peaks from the function. +void PawleyFunction::clearPeaks() { + m_peakProfileComposite = boost::dynamic_pointer_cast<CompositeFunction>( + FunctionFactory::Instance().createFunction("CompositeFunction")); + m_compositeFunction->replaceFunction(1, m_peakProfileComposite); + m_hkls.clear(); +} + +/// Clears peaks and adds a peak for each hkl, all with the same FWHM and +/// height. +void PawleyFunction::setPeaks(const std::vector<Kernel::V3D> &hkls, double fwhm, + double height) { + clearPeaks(); + + for (size_t i = 0; i < hkls.size(); ++i) { + addPeak(hkls[i], fwhm, height); + } +} + +/// Adds a peak with the supplied FWHM and height. +void PawleyFunction::addPeak(const Kernel::V3D &hkl, double fwhm, + double height) { + m_hkls.push_back(hkl); + + IPeakFunction_sptr peak = boost::dynamic_pointer_cast<IPeakFunction>( + FunctionFactory::Instance().createFunction( + m_pawleyParameterFunction->getProfileFunctionName())); + + peak->fix(peak->parameterIndex( + m_pawleyParameterFunction->getProfileFunctionCenterParameterName())); + + try { + peak->setFwhm(fwhm); + } + catch (...) { + // do nothing. + } + + peak->setHeight(height); + + m_peakProfileComposite->addFunction(peak); + + m_compositeFunction->checkFunction(); +} + +/// Returns the number of peaks that are stored in the function. +size_t PawleyFunction::getPeakCount() const { return m_hkls.size(); } + +IPeakFunction_sptr PawleyFunction::getPeakFunction(size_t i) const { + if (i >= m_hkls.size()) { + throw std::out_of_range("Peak index out of range."); + } + + return boost::dynamic_pointer_cast<IPeakFunction>( + m_peakProfileComposite->getFunction(i)); +} + +/// Return the HKL of the i-th peak. +Kernel::V3D PawleyFunction::getPeakHKL(size_t i) const { + if (i >= m_hkls.size()) { + throw std::out_of_range("Peak index out of range."); + } + + return m_hkls[i]; +} + +/// Returns the internally stored PawleyParameterFunction. +PawleyParameterFunction_sptr +PawleyFunction::getPawleyParameterFunction() const { + return m_pawleyParameterFunction; +} + +void PawleyFunction::init() { + setDecoratedFunction("CompositeFunction"); + + if (!m_compositeFunction) { + throw std::runtime_error( + "PawleyFunction could not construct internal CompositeFunction."); + } + + m_dUnit = UnitFactory::Instance().create("dSpacing"); +} + +/// Checks that the decorated function has the correct structure. +void PawleyFunction::beforeDecoratedFunctionSet(const API::IFunction_sptr &fn) { + CompositeFunction_sptr composite = + boost::dynamic_pointer_cast<CompositeFunction>(fn); + + if (!composite) { + throw std::invalid_argument("PawleyFunction only works with " + "CompositeFunction. Selecting another " + "decorated function is not possible."); + } + + m_compositeFunction = composite; + + if (m_compositeFunction->nFunctions() == 0) { + m_peakProfileComposite = boost::dynamic_pointer_cast<CompositeFunction>( + FunctionFactory::Instance().createFunction("CompositeFunction")); + + m_pawleyParameterFunction = + boost::dynamic_pointer_cast<PawleyParameterFunction>( + FunctionFactory::Instance().createFunction( + "PawleyParameterFunction")); + + m_compositeFunction->addFunction(m_pawleyParameterFunction); + m_compositeFunction->addFunction(m_peakProfileComposite); + } else { + m_pawleyParameterFunction = + boost::dynamic_pointer_cast<PawleyParameterFunction>( + m_compositeFunction->getFunction(0)); + m_peakProfileComposite = boost::dynamic_pointer_cast<CompositeFunction>( + m_compositeFunction->getFunction(1)); + } +} + +} // namespace CurveFitting +} // namespace Mantid diff --git a/Code/Mantid/Framework/CurveFitting/src/PseudoVoigt.cpp b/Code/Mantid/Framework/CurveFitting/src/PseudoVoigt.cpp index 585d1d6eb8b025c6c5abd349ecbc3da5d1f0b1d4..a492df6add6514a4888fc8eb88b80719fd5c99dd 100644 --- a/Code/Mantid/Framework/CurveFitting/src/PseudoVoigt.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/PseudoVoigt.cpp @@ -9,7 +9,7 @@ namespace CurveFitting { using namespace API; -DECLARE_FUNCTION(PseudoVoigt); +DECLARE_FUNCTION(PseudoVoigt) void PseudoVoigt::functionLocal(double *out, const double *xValues, const size_t nData) const { diff --git a/Code/Mantid/Framework/CurveFitting/src/SplineInterpolation.cpp b/Code/Mantid/Framework/CurveFitting/src/SplineInterpolation.cpp index 266f44f7e91977c707b34efbc70cf5778c78fae1..d476c8013e8ae2d95eb1e43a4416990512d68a4f 100644 --- a/Code/Mantid/Framework/CurveFitting/src/SplineInterpolation.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/SplineInterpolation.cpp @@ -7,7 +7,7 @@ namespace Mantid { namespace CurveFitting { // Register the algorithm into the AlgorithmFactory -DECLARE_ALGORITHM(SplineInterpolation); +DECLARE_ALGORITHM(SplineInterpolation) using namespace API; using namespace Kernel; diff --git a/Code/Mantid/Framework/CurveFitting/src/SplineSmoothing.cpp b/Code/Mantid/Framework/CurveFitting/src/SplineSmoothing.cpp index 0d1f3d560a032830bfe1134b30b152e629e8a2b0..cd8f927f1b604c449bffd99f6cc62acc2d04dc88 100644 --- a/Code/Mantid/Framework/CurveFitting/src/SplineSmoothing.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/SplineSmoothing.cpp @@ -12,7 +12,7 @@ namespace Mantid { namespace CurveFitting { // Register the algorithm into the AlgorithmFactory -DECLARE_ALGORITHM(SplineSmoothing); +DECLARE_ALGORITHM(SplineSmoothing) using namespace API; using namespace Kernel; @@ -32,10 +32,10 @@ SplineSmoothing::~SplineSmoothing() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string SplineSmoothing::name() const { return "SplineSmoothing"; }; +const std::string SplineSmoothing::name() const { return "SplineSmoothing"; } /// Algorithm's version for identification. @see Algorithm::version -int SplineSmoothing::version() const { return 1; }; +int SplineSmoothing::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string SplineSmoothing::category() const { diff --git a/Code/Mantid/Framework/CurveFitting/src/VesuvioResolution.cpp b/Code/Mantid/Framework/CurveFitting/src/VesuvioResolution.cpp index d13a8297536cd0b4c8b449ed244b9839b2f9f03c..fac486c744a48fe86404b42778814178c39cf36a 100644 --- a/Code/Mantid/Framework/CurveFitting/src/VesuvioResolution.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/VesuvioResolution.cpp @@ -17,7 +17,7 @@ const double STDDEV_TO_HWHM = std::sqrt(std::log(4.0)); } // Register into factory -DECLARE_FUNCTION(VesuvioResolution); +DECLARE_FUNCTION(VesuvioResolution) //--------------------------------------------------------------------------- // Static functions diff --git a/Code/Mantid/Framework/CurveFitting/src/Voigt.cpp b/Code/Mantid/Framework/CurveFitting/src/Voigt.cpp index fd520534558927fcaa9c7774dec5890c1856bc39..9e006da4d314d97a44efe6c8f7f5bcc3b4b0a90a 100644 --- a/Code/Mantid/Framework/CurveFitting/src/Voigt.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/Voigt.cpp @@ -9,7 +9,7 @@ namespace Mantid { namespace CurveFitting { -DECLARE_FUNCTION(Voigt); +DECLARE_FUNCTION(Voigt) namespace { /// @cond diff --git a/Code/Mantid/Framework/CurveFitting/test/CompositeFunctionTest.h b/Code/Mantid/Framework/CurveFitting/test/CompositeFunctionTest.h index ec353f5b2a615980b91c14d425e3f1d7be850107..678334f2bd1977656e19c70810d8de5744224125 100644 --- a/Code/Mantid/Framework/CurveFitting/test/CompositeFunctionTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/CompositeFunctionTest.h @@ -135,8 +135,8 @@ public: }; -DECLARE_FUNCTION(CurveFittingLinear); -DECLARE_FUNCTION(CurveFittingGauss); +DECLARE_FUNCTION(CurveFittingLinear) +DECLARE_FUNCTION(CurveFittingGauss) class CompositeFunctionTest : public CxxTest::TestSuite { diff --git a/Code/Mantid/Framework/CurveFitting/test/ConvolutionTest.h b/Code/Mantid/Framework/CurveFitting/test/ConvolutionTest.h index afc285cfb1c4a223664573745554a39e2126ca52..c548fc16127312fb5a819bb7bfb6661fd06c9bba 100644 --- a/Code/Mantid/Framework/CurveFitting/test/ConvolutionTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/ConvolutionTest.h @@ -191,9 +191,9 @@ public: }; -DECLARE_FUNCTION(ConvolutionTest_Gauss); -DECLARE_FUNCTION(ConvolutionTest_Lorentz); -DECLARE_FUNCTION(ConvolutionTest_Linear); +DECLARE_FUNCTION(ConvolutionTest_Gauss) +DECLARE_FUNCTION(ConvolutionTest_Lorentz) +DECLARE_FUNCTION(ConvolutionTest_Linear) class ConvolutionTest : public CxxTest::TestSuite { diff --git a/Code/Mantid/Framework/CurveFitting/test/DiffRotDiscreteCircleTest.h b/Code/Mantid/Framework/CurveFitting/test/DiffRotDiscreteCircleTest.h index 8eeffacaaff2ee5a3ce466cc19c51a99599e4bdf..f0dba53f28f99738d4381d304362bf3ccdc9f5d1 100644 --- a/Code/Mantid/Framework/CurveFitting/test/DiffRotDiscreteCircleTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/DiffRotDiscreteCircleTest.h @@ -25,6 +25,7 @@ public: static DiffRotDiscreteCircleTest *createSuite() { return new DiffRotDiscreteCircleTest(); } static void destroySuite( DiffRotDiscreteCircleTest *suite ) { delete suite; } + // convolve the elastic part with a resolution function, here a Gaussian void testDiffRotDiscreteCircleElastic() { @@ -75,58 +76,17 @@ public: } // testDiffRotDiscreteCircleElastic - /// Fit the convolution of the inelastic part with a Gaussian resolution function void testDiffRotDiscreteCircleInelastic() { - /* Note: it turns out that parameters Intensity and Radius are highly covariant, so that more than one minimum exists. - * Thus, I tied parameter Radius. This is OK since one usually knows the radius of the circle of the jumping diffusion - */ - - // initialize the fitting function in a Fit algorithm - // Parameter units are assumed in micro-eV, Angstroms, Angstroms**(-1), and nano-seconds. Intensities have arbitrary units - std::string funtion_string = "(composite=Convolution,FixResolution=true,NumDeriv=true;name=Gaussian,Height=1.0,PeakCentre=0.0,Sigma=20.0,ties=(Height=1.0,PeakCentre=0.0,Sigma=20.0);name=InelasticDiffRotDiscreteCircle,N=3,Q=0.5,Intensity=47.014,Radius=1.567,Decay=7.567)"; - - // Initialize the fit function in the Fit algorithm - Mantid::CurveFitting::Fit fitalg; - TS_ASSERT_THROWS_NOTHING( fitalg.initialize() ); - TS_ASSERT( fitalg.isInitialized() ); - fitalg.setProperty( "Function", funtion_string ); - - // create the data workspace by evaluating the fit function in the Fit algorithm - auto data_workspace = generateWorkspaceFromFitAlgorithm( fitalg ); - //saveWorkspace( data_workspace, "/tmp/junk.nxs" ); // for debugging purposes only - - //override the function with new parameters, then do the Fit - funtion_string = "(composite=Convolution,FixResolution=true,NumDeriv=true;name=Gaussian,Height=1.0,PeakCentre=0.0,Sigma=20.0,ties=(Height=1.0,PeakCentre=0.0,Sigma=20.0);name=InelasticDiffRotDiscreteCircle,N=3,Q=0.5,Intensity=10.0,Radius=1.567,Decay=20.0,ties=(Radius=1.567))"; - fitalg.setProperty( "Function", funtion_string ); - fitalg.setProperty( "InputWorkspace", data_workspace ); - fitalg.setPropertyValue( "WorkspaceIndex", "0" ); - TS_ASSERT_THROWS_NOTHING( TS_ASSERT( fitalg.execute() ) ); - TS_ASSERT( fitalg.isExecuted() ); + runDiffRotDiscreteCircleInelasticTest(0.0); + } - // check Chi-square is small - const double chi_squared = fitalg.getProperty("OutputChi2overDoF"); - TS_ASSERT_LESS_THAN( chi_squared, 0.001 ); - //std::cout << "\nchi_squared = " << chi_squared << "\n"; // only for debugging purposes - // check the parameters of the resolution did not change - Mantid::API::IFunction_sptr fitalg_function = fitalg.getProperty( "Function" ); - auto fitalg_conv = boost::dynamic_pointer_cast<Mantid::CurveFitting::Convolution>( fitalg_function ) ; - Mantid::API::IFunction_sptr fitalg_resolution = fitalg_conv->getFunction( 0 ); - TS_ASSERT_DELTA( fitalg_resolution -> getParameter( "PeakCentre" ), 0.0, 0.00001 ); // allow for a small percent variation - TS_ASSERT_DELTA( fitalg_resolution -> getParameter( "Height" ), 1.0, 1.0 * 0.001 ); // allow for a small percent variation - TS_ASSERT_DELTA( fitalg_resolution -> getParameter( "Sigma" ), 20.0, 20.0* 0.001 ); // allow for a small percent variation - //std::cout << "\nPeakCentre = " << fitalg_resolution->getParameter("PeakCentre") << " Height= " << fitalg_resolution->getParameter("Height") << " Sigma=" << fitalg_resolution->getParameter("Sigma") << "\n"; // only for debugging purposes - - // check the parameters of the inelastic part - Mantid::API::IFunction_sptr fitalg_structure_factor = fitalg_conv->getFunction( 1 ); - TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Intensity" ), 47.014, 47.014 * 0.05 ); // allow for a small percent variation - TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Radius" ), 1.567, 1.567 * 0.05 ); // allow for a small percent variation - TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Decay" ), 7.567, 7.567 * 0.05 ); // allow for a small percent variation - //std::cout << "\nGOAL: Intensity = 47.014, Radius = 1.567, Decay = 7.567\n"; // only for debugging purposes - //std::cout << "OPTIMIZED: Intensity = " << fitalg_structure_factor->getParameter("Intensity") << " Radius = " << fitalg_structure_factor->getParameter("Radius") << " Decay = " << fitalg_structure_factor->getParameter("Decay") << "\n"; // only for debugging purposes + void testDiffRotDiscreteCircleInelasticWithShift() + { + runDiffRotDiscreteCircleInelasticTest(0.5); + } - } // testDiffRotDiscreteCircleElastic /* Check the particular case for N = 3 * In this case, the inelastic part should reduce to a single Lorentzian in 'w': @@ -293,6 +253,79 @@ public: private: + /// Fit the convolution of the inelastic part with a Gaussian resolution function + void runDiffRotDiscreteCircleInelasticTest(const double S) + { + /* Note: it turns out that parameters Intensity and Radius are highly covariant, so that more than one minimum exists. + * Thus, I tied parameter Radius. This is OK since one usually knows the radius of the circle of the jumping diffusion + */ + const double I(47.014); + const double R(1.567); + const double tao(7.567); + + // initialize the fitting function in a Fit algorithm + // Parameter units are assumed in micro-eV, Angstroms, Angstroms**(-1), and nano-seconds. Intensities have arbitrary units + std::ostringstream function_stream; + function_stream << "(composite=Convolution,FixResolution=true,NumDeriv=true;" + << "name=Gaussian,Height=1.0,PeakCentre=0.0,Sigma=20.0," + << "ties=(Height=1.0,PeakCentre=0.0,Sigma=20.0);" + << "name=InelasticDiffRotDiscreteCircle,N=3,Q=0.5," + << "Intensity=" << I + << ",Radius=" << R + << ",Decay=" << tao + << ",Shift=" << S << ")"; + + // Initialize the fit function in the Fit algorithm + Mantid::CurveFitting::Fit fitalg; + TS_ASSERT_THROWS_NOTHING( fitalg.initialize() ); + TS_ASSERT( fitalg.isInitialized() ); + fitalg.setProperty( "Function", function_stream.str() ); + + function_stream.str( std::string() ); + function_stream.clear(); + + // create the data workspace by evaluating the fit function in the Fit algorithm + auto data_workspace = generateWorkspaceFromFitAlgorithm( fitalg ); + //saveWorkspace( data_workspace, "/tmp/junk.nxs" ); // for debugging purposes only + + //override the function with new parameters, then do the Fit + function_stream << "(composite=Convolution,FixResolution=true,NumDeriv=true;" + << "name=Gaussian,Height=1.0,PeakCentre=0.0,Sigma=20.0," + << "ties=(Height=1.0,PeakCentre=0.0,Sigma=20.0);" + << "name=InelasticDiffRotDiscreteCircle,N=3,Q=0.5," + << "Intensity=10.0,Radius=1.567,Decay=20.0" + << ",ties=(Radius=" << R << "))"; + fitalg.setProperty( "Function", function_stream.str() ); + fitalg.setProperty( "InputWorkspace", data_workspace ); + fitalg.setPropertyValue( "WorkspaceIndex", "0" ); + TS_ASSERT_THROWS_NOTHING( TS_ASSERT( fitalg.execute() ) ); + TS_ASSERT( fitalg.isExecuted() ); + + // check Chi-square is small + const double chi_squared = fitalg.getProperty("OutputChi2overDoF"); + TS_ASSERT_LESS_THAN( chi_squared, 0.001 ); + //std::cout << "\nchi_squared = " << chi_squared << "\n"; // only for debugging purposes + + // check the parameters of the resolution did not change + Mantid::API::IFunction_sptr fitalg_function = fitalg.getProperty( "Function" ); + auto fitalg_conv = boost::dynamic_pointer_cast<Mantid::CurveFitting::Convolution>( fitalg_function ) ; + Mantid::API::IFunction_sptr fitalg_resolution = fitalg_conv->getFunction( 0 ); + TS_ASSERT_DELTA( fitalg_resolution -> getParameter( "PeakCentre" ), 0.0, 0.00001 ); // allow for a small percent variation + TS_ASSERT_DELTA( fitalg_resolution -> getParameter( "Height" ), 1.0, 1.0 * 0.001 ); // allow for a small percent variation + TS_ASSERT_DELTA( fitalg_resolution -> getParameter( "Sigma" ), 20.0, 20.0* 0.001 ); // allow for a small percent variation + //std::cout << "\nPeakCentre = " << fitalg_resolution->getParameter("PeakCentre") << " Height= " << fitalg_resolution->getParameter("Height") << " Sigma=" << fitalg_resolution->getParameter("Sigma") << "\n"; // only for debugging purposes + + // check the parameters of the inelastic part + Mantid::API::IFunction_sptr fitalg_structure_factor = fitalg_conv->getFunction( 1 ); + TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Intensity" ), I, I * 0.05 ); // allow for a small percent variation + TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Radius" ), R, R * 0.05 ); // allow for a small percent variation + TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Decay" ), tao, tao * 0.05 ); // allow for a small percent variation + TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Shift" ), S, 0.00001 ); // allow for a small percent variation + //std::cout << "\nGOAL: Intensity = 47.014, Radius = 1.567, Decay = 7.567\n"; // only for debugging purposes + //std::cout << "OPTIMIZED: Intensity = " << fitalg_structure_factor->getParameter("Intensity") << " Radius = " << fitalg_structure_factor->getParameter("Radius") << " Decay = " << fitalg_structure_factor->getParameter("Decay") << "\n"; // only for debugging purposes + + } // runDiffRotDiscreteCircleInelasticTest + /// returns a real value from a uniform distribution double random_value(const double & a, const double & b) diff --git a/Code/Mantid/Framework/CurveFitting/test/DiffSphereTest.h b/Code/Mantid/Framework/CurveFitting/test/DiffSphereTest.h index 6b0baeaf008b354ae2bb6877dafca59dda518ee1..9242cb31729d2bfc9737e255c02933353190efa4 100644 --- a/Code/Mantid/Framework/CurveFitting/test/DiffSphereTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/DiffSphereTest.h @@ -128,7 +128,17 @@ public: void testDiffSphereInelastic() { - // target fitting parameters + runDiffSphereInelasticTest(0.0); + } + + void testDiffSphereInelasticWithShift() + { + runDiffSphereInelasticTest(0.2); + } + + void testDiffSphere() + { + // target parameters const double I_0(47.014); const double R_0(2.1); const double D_0(0.049); @@ -141,14 +151,32 @@ public: std::ostringstream funtion_stream; funtion_stream << "(composite=Convolution,FixResolution=true,NumDeriv=true;name=Gaussian,Height=1.0," << "PeakCentre=0.0,Sigma=0.002,ties=(Height=1.0,PeakCentre=0.0,Sigma=0.002);" - << "name=InelasticDiffSphere,Q=" << boost::lexical_cast<std::string>( Q ) << ",Intensity=" + << "name=DiffSphere,Q=" << boost::lexical_cast<std::string>( Q ) << ",Intensity=" << boost::lexical_cast<std::string>( I_0 ) << ",Radius=" << boost::lexical_cast<std::string>( R_0 ) << ",Diffusion=" << boost::lexical_cast<std::string>( D_0 ) << ")"; fitalg.setProperty( "Function", funtion_stream.str() ); - // create the data workspace by evaluating the fit function in the Fit algorithm - auto data_workspace = generateWorkspaceFromFitAlgorithm( fitalg ); - //saveWorkspace( data_workspace, "/tmp/junk_data.nxs" ); // for debugging purposes only + // Find out whether ties were correctly applied + Mantid::API::IFunction_sptr fitalg_function = fitalg.getProperty( "Function" ); // main function + fitalg_function->initialize(); + auto fitalg_conv = boost::dynamic_pointer_cast<Mantid::CurveFitting::Convolution>( fitalg_function ) ; // cast to Convolution + fitalg_function = fitalg_conv->getFunction( 1 ); // DiffSphere + auto fitalg_structure_factor = boost::dynamic_pointer_cast<Mantid::CurveFitting::DiffSphere>( fitalg_function ); + + fitalg_function = fitalg_structure_factor->getFunction( 0 ); + auto fitalg_elastic = boost::dynamic_pointer_cast<Mantid::CurveFitting::ElasticDiffSphere>( fitalg_function ) ; + TS_ASSERT_DELTA( fitalg_elastic -> getParameter( "Height" ), I_0, std::numeric_limits<double>::epsilon() ); + TS_ASSERT_DELTA( fitalg_elastic -> getParameter( "Radius" ), R_0, std::numeric_limits<double>::epsilon() ); + TS_ASSERT_DELTA( fitalg_elastic -> getAttribute( "Q" ).asDouble(), Q, std::numeric_limits<double>::epsilon() ); + //std::cout << "Height=" << fitalg_elastic -> getParameter( "Height" ) << " Radius=" << fitalg_elastic -> getParameter( "Radius" ) << "\n"; // for debugging purposes only + + fitalg_function = fitalg_structure_factor->getFunction( 1 ); + auto fitalg_inelastic = boost::dynamic_pointer_cast<Mantid::CurveFitting::InelasticDiffSphere>( fitalg_function ) ; + TS_ASSERT_DELTA( fitalg_inelastic -> getParameter( "Intensity" ), I_0, std::numeric_limits<double>::epsilon() ); + TS_ASSERT_DELTA( fitalg_inelastic -> getParameter( "Radius" ), R_0, std::numeric_limits<double>::epsilon() ); + TS_ASSERT_DELTA( fitalg_inelastic -> getParameter( "Diffusion" ), D_0, std::numeric_limits<double>::epsilon() ); + TS_ASSERT_DELTA( fitalg_inelastic -> getAttribute( "Q" ).asDouble(), Q, std::numeric_limits<double>::epsilon() ); + //std::cout << "Intensity=" << fitalg_inelastic->getParameter( "Intensity" ) << " Radius=" << fitalg_inelastic->getParameter( "Radius" ) << " Diffusion=" << fitalg_inelastic->getParameter( "Diffusion" ) <<"\n"; // for debugging purposes only // override the function with new parameters, our initial guess. double I = I_0 * ( 0.75 + ( 0.5 * std::rand() ) / RAND_MAX ); @@ -158,20 +186,20 @@ public: funtion_stream.clear(); funtion_stream << "(composite=Convolution,FixResolution=true,NumDeriv=true;name=Gaussian,Height=1.0," << "PeakCentre=0.0,Sigma=0.002,ties=(Height=1.0,PeakCentre=0.0,Sigma=0.002);" - << "name=InelasticDiffSphere,Q=" << boost::lexical_cast<std::string>( Q ) << ",Intensity=" + << "name=DiffSphere,Q=" << boost::lexical_cast<std::string>( Q ) << ",Intensity=" << boost::lexical_cast<std::string>( I ) << ",Radius=" << boost::lexical_cast<std::string>( R ) << ",Diffusion=" << boost::lexical_cast<std::string>( D ) << ")"; fitalg.setProperty( "Function", funtion_stream.str() ); - //auto before_workspace = generateWorkspaceFromFitAlgorithm( fitalg ); // for debugging purposes only - //saveWorkspace( before_workspace, "/tmp/junk_before_fitting.nxs" ); // for debugging purposes only + + // create the data workspace by evaluating the fit function in the Fit algorithm + auto data_workspace = generateWorkspaceFromFitAlgorithm( fitalg ); + //saveWorkspace( data_workspace, "/tmp/junk_data.nxs" ); // for debugging purposes only // Do the fit fitalg.setProperty( "InputWorkspace", data_workspace ); fitalg.setPropertyValue( "WorkspaceIndex", "0" ); TS_ASSERT_THROWS_NOTHING( TS_ASSERT( fitalg.execute() ) ); TS_ASSERT( fitalg.isExecuted() ); - //auto after_workspace = generateWorkspaceFromFitAlgorithm( fitalg ); // for debugging purposes only - //saveWorkspace( after_workspace, "/tmp/junk_after_fitting.nxs" ); // for debugging purposes only // check Chi-square is small const double chi_squared = fitalg.getProperty("OutputChi2overDoF"); @@ -179,28 +207,25 @@ public: //std::cout << "\nchi_squared = " << chi_squared << "\n"; // only for debugging purposes // check the parameters of the resolution did not change - Mantid::API::IFunction_sptr fitalg_function = fitalg.getProperty( "Function" ); - auto fitalg_conv = boost::dynamic_pointer_cast<Mantid::CurveFitting::Convolution>( fitalg_function ) ; Mantid::API::IFunction_sptr fitalg_resolution = fitalg_conv->getFunction( 0 ); - TS_ASSERT_DELTA( fitalg_resolution -> getParameter( "PeakCentre" ), 0.0, 0.00001 ); // allow for a small percent variation TS_ASSERT_DELTA( fitalg_resolution -> getParameter( "Height" ), 1.0, 1.0 * 0.001 ); // allow for a small percent variation TS_ASSERT_DELTA( fitalg_resolution -> getParameter( "Sigma" ), 0.002, 0.002* 0.001 ); // allow for a small percent variation //std::cout << "\nPeakCentre = " << fitalg_resolution->getParameter("PeakCentre") << " Height= " << fitalg_resolution->getParameter("Height") << " Sigma=" << fitalg_resolution->getParameter("Sigma") << "\n"; // only for debugging purposes - // check the parameters of the inelastic part close to the target parameters - Mantid::API::IFunction_sptr fitalg_structure_factor = fitalg_conv->getFunction( 1 ); + // check the parameters of the DiffSphere close to the target parameters TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Intensity" ), I_0, I_0 * 0.05 ); // allow for a small percent variation - TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Radius" ), R_0, R_0 * 0.05 ); // allow for a small percent variation - TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Diffusion" ), D_0, D_0 * 0.05 ); // allow for a small percent variation + TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Radius" ), R_0, R_0 * 0.05 ); // allow for a small percent variation + TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Diffusion" ), D_0, D_0 * 0.05 ); // allow for a small percent variation //std::cout << "\nINITIAL GUESS: Intensity = "<<boost::lexical_cast<std::string>(I)<<", Radius ="<<boost::lexical_cast<std::string>(R)<<", Diffusion = "<<boost::lexical_cast<std::string>(D)<<"\n"; // only for debugging purposes //std::cout << "GOAL: Intensity = "<<boost::lexical_cast<std::string>(I_0)<<", Radius = "<<boost::lexical_cast<std::string>(R_0)<<", Diffusion = "<<boost::lexical_cast<std::string>(D_0)<<"\n"; // only for debugging purposes //std::cout << "OPTIMIZED: Intensity = " << fitalg_structure_factor->getParameter("Intensity") << " Radius = " << fitalg_structure_factor->getParameter("Radius") << " Diffusion = " << fitalg_structure_factor->getParameter("Diffusion") << "\n"; // only for debugging purposes } - void testDiffSphere() +private: + void runDiffSphereInelasticTest(const double S) { - // target parameters + // target fitting parameters const double I_0(47.014); const double R_0(2.1); const double D_0(0.049); @@ -212,33 +237,16 @@ public: TS_ASSERT( fitalg.isInitialized() ); std::ostringstream funtion_stream; funtion_stream << "(composite=Convolution,FixResolution=true,NumDeriv=true;name=Gaussian,Height=1.0," - << "PeakCentre=0.0,Sigma=0.002,ties=(Height=1.0,PeakCentre=0.0,Sigma=0.002);" - << "name=DiffSphere,Q=" << boost::lexical_cast<std::string>( Q ) << ",Intensity=" + << "PeakCentre=0.0,Sigma=0.002,ties=(Height=1.0,PeakCentre=" << S << ",Sigma=0.002);" + << "name=InelasticDiffSphere,Q=" << boost::lexical_cast<std::string>( Q ) << ",Intensity=" << boost::lexical_cast<std::string>( I_0 ) << ",Radius=" << boost::lexical_cast<std::string>( R_0 ) - << ",Diffusion=" << boost::lexical_cast<std::string>( D_0 ) << ")"; + << ",Diffusion=" << boost::lexical_cast<std::string>( D_0 ) + << ",Shift=" << boost::lexical_cast<std::string>(S) << ")"; fitalg.setProperty( "Function", funtion_stream.str() ); - // Find out whether ties were correctly applied - Mantid::API::IFunction_sptr fitalg_function = fitalg.getProperty( "Function" ); // main function - fitalg_function->initialize(); - auto fitalg_conv = boost::dynamic_pointer_cast<Mantid::CurveFitting::Convolution>( fitalg_function ) ; // cast to Convolution - fitalg_function = fitalg_conv->getFunction( 1 ); // DiffSphere - auto fitalg_structure_factor = boost::dynamic_pointer_cast<Mantid::CurveFitting::DiffSphere>( fitalg_function ); - - fitalg_function = fitalg_structure_factor->getFunction( 0 ); - auto fitalg_elastic = boost::dynamic_pointer_cast<Mantid::CurveFitting::ElasticDiffSphere>( fitalg_function ) ; - TS_ASSERT_DELTA( fitalg_elastic -> getParameter( "Height" ), I_0, std::numeric_limits<double>::epsilon() ); - TS_ASSERT_DELTA( fitalg_elastic -> getParameter( "Radius" ), R_0, std::numeric_limits<double>::epsilon() ); - TS_ASSERT_DELTA( fitalg_elastic -> getAttribute( "Q" ).asDouble(), Q, std::numeric_limits<double>::epsilon() ); - //std::cout << "Height=" << fitalg_elastic -> getParameter( "Height" ) << " Radius=" << fitalg_elastic -> getParameter( "Radius" ) << "\n"; // for debugging purposes only - - fitalg_function = fitalg_structure_factor->getFunction( 1 ); - auto fitalg_inelastic = boost::dynamic_pointer_cast<Mantid::CurveFitting::InelasticDiffSphere>( fitalg_function ) ; - TS_ASSERT_DELTA( fitalg_inelastic -> getParameter( "Intensity" ), I_0, std::numeric_limits<double>::epsilon() ); - TS_ASSERT_DELTA( fitalg_inelastic -> getParameter( "Radius" ), R_0, std::numeric_limits<double>::epsilon() ); - TS_ASSERT_DELTA( fitalg_inelastic -> getParameter( "Diffusion" ), D_0, std::numeric_limits<double>::epsilon() ); - TS_ASSERT_DELTA( fitalg_inelastic -> getAttribute( "Q" ).asDouble(), Q, std::numeric_limits<double>::epsilon() ); - //std::cout << "Intensity=" << fitalg_inelastic->getParameter( "Intensity" ) << " Radius=" << fitalg_inelastic->getParameter( "Radius" ) << " Diffusion=" << fitalg_inelastic->getParameter( "Diffusion" ) <<"\n"; // for debugging purposes only + // create the data workspace by evaluating the fit function in the Fit algorithm + auto data_workspace = generateWorkspaceFromFitAlgorithm( fitalg ); + //saveWorkspace( data_workspace, "/tmp/junk_data.nxs" ); // for debugging purposes only // override the function with new parameters, our initial guess. double I = I_0 * ( 0.75 + ( 0.5 * std::rand() ) / RAND_MAX ); @@ -247,21 +255,22 @@ public: funtion_stream.str( std::string() ); funtion_stream.clear(); funtion_stream << "(composite=Convolution,FixResolution=true,NumDeriv=true;name=Gaussian,Height=1.0," - << "PeakCentre=0.0,Sigma=0.002,ties=(Height=1.0,PeakCentre=0.0,Sigma=0.002);" - << "name=DiffSphere,Q=" << boost::lexical_cast<std::string>( Q ) << ",Intensity=" + << "PeakCentre=0.0,Sigma=0.002,ties=(Height=1.0,PeakCentre=" << S << ",Sigma=0.002);" + << "name=InelasticDiffSphere,Q=" << boost::lexical_cast<std::string>( Q ) << ",Intensity=" << boost::lexical_cast<std::string>( I ) << ",Radius=" << boost::lexical_cast<std::string>( R ) - << ",Diffusion=" << boost::lexical_cast<std::string>( D ) << ")"; + << ",Diffusion=" << boost::lexical_cast<std::string>( D ) + << ",Shift=" << boost::lexical_cast<std::string>(S) << ")"; fitalg.setProperty( "Function", funtion_stream.str() ); - - // create the data workspace by evaluating the fit function in the Fit algorithm - auto data_workspace = generateWorkspaceFromFitAlgorithm( fitalg ); - //saveWorkspace( data_workspace, "/tmp/junk_data.nxs" ); // for debugging purposes only + //auto before_workspace = generateWorkspaceFromFitAlgorithm( fitalg ); // for debugging purposes only + //saveWorkspace( before_workspace, "/tmp/junk_before_fitting.nxs" ); // for debugging purposes only // Do the fit fitalg.setProperty( "InputWorkspace", data_workspace ); fitalg.setPropertyValue( "WorkspaceIndex", "0" ); TS_ASSERT_THROWS_NOTHING( TS_ASSERT( fitalg.execute() ) ); TS_ASSERT( fitalg.isExecuted() ); + //auto after_workspace = generateWorkspaceFromFitAlgorithm( fitalg ); // for debugging purposes only + //saveWorkspace( after_workspace, "/tmp/junk_after_fitting.nxs" ); // for debugging purposes only // check Chi-square is small const double chi_squared = fitalg.getProperty("OutputChi2overDoF"); @@ -269,24 +278,26 @@ public: //std::cout << "\nchi_squared = " << chi_squared << "\n"; // only for debugging purposes // check the parameters of the resolution did not change + Mantid::API::IFunction_sptr fitalg_function = fitalg.getProperty( "Function" ); + auto fitalg_conv = boost::dynamic_pointer_cast<Mantid::CurveFitting::Convolution>( fitalg_function ) ; Mantid::API::IFunction_sptr fitalg_resolution = fitalg_conv->getFunction( 0 ); - TS_ASSERT_DELTA( fitalg_resolution -> getParameter( "PeakCentre" ), 0.0, 0.00001 ); // allow for a small percent variation + + TS_ASSERT_DELTA( fitalg_resolution -> getParameter( "PeakCentre" ), S, 0.00001 ); // allow for a small percent variation TS_ASSERT_DELTA( fitalg_resolution -> getParameter( "Height" ), 1.0, 1.0 * 0.001 ); // allow for a small percent variation TS_ASSERT_DELTA( fitalg_resolution -> getParameter( "Sigma" ), 0.002, 0.002* 0.001 ); // allow for a small percent variation //std::cout << "\nPeakCentre = " << fitalg_resolution->getParameter("PeakCentre") << " Height= " << fitalg_resolution->getParameter("Height") << " Sigma=" << fitalg_resolution->getParameter("Sigma") << "\n"; // only for debugging purposes - // check the parameters of the DiffSphere close to the target parameters + // check the parameters of the inelastic part close to the target parameters + Mantid::API::IFunction_sptr fitalg_structure_factor = fitalg_conv->getFunction( 1 ); TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Intensity" ), I_0, I_0 * 0.05 ); // allow for a small percent variation - TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Radius" ), R_0, R_0 * 0.05 ); // allow for a small percent variation - TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Diffusion" ), D_0, D_0 * 0.05 ); // allow for a small percent variation + TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Radius" ), R_0, R_0 * 0.05 ); // allow for a small percent variation + TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Diffusion" ), D_0, D_0 * 0.05 ); // allow for a small percent variation + TS_ASSERT_DELTA( fitalg_structure_factor -> getParameter( "Shift" ), S, 0.0005 ); // allow for a small percent variation //std::cout << "\nINITIAL GUESS: Intensity = "<<boost::lexical_cast<std::string>(I)<<", Radius ="<<boost::lexical_cast<std::string>(R)<<", Diffusion = "<<boost::lexical_cast<std::string>(D)<<"\n"; // only for debugging purposes //std::cout << "GOAL: Intensity = "<<boost::lexical_cast<std::string>(I_0)<<", Radius = "<<boost::lexical_cast<std::string>(R_0)<<", Diffusion = "<<boost::lexical_cast<std::string>(D_0)<<"\n"; // only for debugging purposes //std::cout << "OPTIMIZED: Intensity = " << fitalg_structure_factor->getParameter("Intensity") << " Radius = " << fitalg_structure_factor->getParameter("Radius") << " Diffusion = " << fitalg_structure_factor->getParameter("Diffusion") << "\n"; // only for debugging purposes - } -private: - /// save a worskapece to a nexus file void saveWorkspace( Mantid::DataObjects::Workspace2D_sptr &ws, const std::string &filename ) { diff --git a/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h b/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h index 74e8717d9fb958a023358c7834ef69926c86ead9..c3a78ecebf900dc31d7ac149254887cc0e358f18 100644 --- a/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h @@ -79,7 +79,7 @@ public: TS_ASSERT_DELTA( y[4], 0.323394, 0.000001); } - void xtestZNDKTFunction() + void testZNDKTFunction() { // Test Dynamic Kubo Toyabe (DKT) for non-zero Field and Zero Nu (ZN) const double asym = 1.0; @@ -107,7 +107,7 @@ public: TS_ASSERT_DELTA( y[4], 0.055052, 0.000001); } - void xtestDKTFunction() + void testDKTFunction() { // Test Dynamic Kubo Toyabe (DKT) (non-zero Field, non-zero Nu) const double asym = 1.0; @@ -129,10 +129,10 @@ public: TS_ASSERT_THROWS_NOTHING(dkt.function(x,y)); TS_ASSERT_DELTA( y[0], 1.000000, 0.000001); - TS_ASSERT_DELTA( y[1], 0.822498, 0.000001); - TS_ASSERT_DELTA( y[2], 0.518536, 0.000001); - TS_ASSERT_DELTA( y[3], 0.295988, 0.000001); - TS_ASSERT_DELTA( y[4], 0.175489, 0.000001); + TS_ASSERT_DELTA( y[1], 0.821663, 0.000001); + TS_ASSERT_DELTA( y[2], 0.518974, 0.000001); + TS_ASSERT_DELTA( y[3], 0.297548, 0.000001); + TS_ASSERT_DELTA( y[4], 0.177036, 0.000001); } diff --git a/Code/Mantid/Framework/CurveFitting/test/EstimatePeakErrorsTest.h b/Code/Mantid/Framework/CurveFitting/test/EstimatePeakErrorsTest.h new file mode 100644 index 0000000000000000000000000000000000000000..c867b424fb49b6b13607c9063a3b231724a7a546 --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/test/EstimatePeakErrorsTest.h @@ -0,0 +1,277 @@ +#ifndef ESTIMATEPEAKERRORSTEST_H_ +#define ESTIMATEPEAKERRORSTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidCurveFitting/EstimatePeakErrors.h" + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidAPI/AnalysisDataService.h" +#include "MantidAPI/MatrixWorkspace.h" +#include "MantidAPI/FunctionDomain1D.h" +#include "MantidAPI/FunctionFactory.h" +#include "MantidAPI/FunctionValues.h" +#include "MantidAPI/IFunction.h" +#include "MantidAPI/WorkspaceFactory.h" + +#include "MantidTestHelpers/WorkspaceCreationHelper.h" + +using namespace Mantid; +using namespace Mantid::API; +using namespace Mantid::CurveFitting; +using namespace WorkspaceCreationHelper; + +class EstimatePeakErrorsTest : public CxxTest::TestSuite +{ +public: + + void test_on_Gaussian() + { + auto fun = FunctionFactory::Instance().createInitialized("name=Gaussian,PeakCentre=0,Height=1,Sigma=2"); + auto ws = createWorkspace(*fun); + + auto fit = AlgorithmManager::Instance().create("Fit"); + fit->setProperty("Function",fun); + fit->setProperty("InputWorkspace",ws); + fit->setProperty("CalcErrors",true); + fit->execute(); + + EstimatePeakErrors alg; + alg.initialize(); + alg.setProperty("Function",fun); + alg.setPropertyValue("OutputWorkspace","Errors"); + alg.execute(); + + auto res = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("Errors"); + TS_ASSERT_EQUALS( res->rowCount(), 4 ); + + TS_ASSERT_EQUALS( res->cell<std::string>(0,0), "Centre" ); + TS_ASSERT_EQUALS( res->cell<std::string>(1,0), "Height" ); + TS_ASSERT_EQUALS( res->cell<std::string>(2,0), "FWHM" ); + TS_ASSERT_EQUALS( res->cell<std::string>(3,0), "Intensity" ); + + TS_ASSERT_DELTA( res->cell<double>(0,1), -0.0068, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(1,1), 1.0036, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(2,1), 4.8046, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(3,1), 5.1330, 1e-4 ); + + TS_ASSERT_DELTA( res->cell<double>(0,2), 0.7467, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(1,2), 0.3172, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(2,2), 1.7598, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(3,2), 1.6263, 1e-4 ); + + AnalysisDataService::Instance().clear(); + } + + void test_on_Gaussian_ties() + { + auto fun = FunctionFactory::Instance().createInitialized("name=Gaussian,PeakCentre=0,Height=1,Sigma=2,ties=(Sigma=2)"); + auto ws = createWorkspace(*fun); + + auto fit = AlgorithmManager::Instance().create("Fit"); + fit->setProperty("Function",fun); + fit->setProperty("InputWorkspace",ws); + fit->setProperty("CalcErrors",true); + fit->execute(); + + EstimatePeakErrors alg; + alg.initialize(); + alg.setProperty("Function",fun); + alg.setPropertyValue("OutputWorkspace","Errors"); + alg.execute(); + + auto res = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("Errors"); + TS_ASSERT_EQUALS( res->rowCount(), 4 ); + + TS_ASSERT_EQUALS( res->cell<std::string>(0,0), "Centre" ); + TS_ASSERT_EQUALS( res->cell<std::string>(1,0), "Height" ); + TS_ASSERT_EQUALS( res->cell<std::string>(2,0), "FWHM" ); + TS_ASSERT_EQUALS( res->cell<std::string>(3,0), "Intensity" ); + + TS_ASSERT_DELTA( res->cell<double>(0,1), -0.0071, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(1,1), 1.0136, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(2,1), 4.7096, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(3,1), 5.0816, 1e-4 ); + + TS_ASSERT_DELTA( res->cell<double>(0,2), 0.7327, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(1,2), 0.2625, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(2,2), 0.0000, 1e-14 ); + TS_ASSERT_DELTA( res->cell<double>(3,2), 1.3164, 1e-4 ); + + AnalysisDataService::Instance().clear(); + } + + void test_on_Gaussian_unfitted() + { + auto fun = FunctionFactory::Instance().createInitialized("name=Gaussian,PeakCentre=0,Height=1,Sigma=2"); + + EstimatePeakErrors alg; + alg.initialize(); + alg.setProperty("Function",fun); + alg.setPropertyValue("OutputWorkspace","Errors"); + alg.execute(); + + auto res = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("Errors"); + TS_ASSERT_EQUALS( res->rowCount(), 0 ); + + AnalysisDataService::Instance().clear(); + } + + + void test_on_Lorentzians() + { + std::string funStr = "name=Lorentzian,Amplitude=10,PeakCentre=-4,FWHM=2;" + "name=Lorentzian,Amplitude=10,PeakCentre=3,FWHM=3;" + "name=FlatBackground,A0=3"; + auto fun = FunctionFactory::Instance().createInitialized(funStr); + auto ws = createWorkspace(*fun); + + auto fit = AlgorithmManager::Instance().create("Fit"); + fit->setProperty("Function",fun); + fit->setProperty("InputWorkspace",ws); + fit->setProperty("CalcErrors",true); + fit->execute(); + + EstimatePeakErrors alg; + alg.initialize(); + alg.setProperty("Function",fun); + alg.setPropertyValue("OutputWorkspace","Errors"); + alg.execute(); + + auto res = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("Errors"); + TS_ASSERT_EQUALS( res->rowCount(), 8 ); + + TS_ASSERT_EQUALS( res->cell<std::string>(0,0), "f0.Centre" ); + TS_ASSERT_EQUALS( res->cell<std::string>(1,0), "f0.Height" ); + TS_ASSERT_EQUALS( res->cell<std::string>(2,0), "f0.FWHM" ); + TS_ASSERT_EQUALS( res->cell<std::string>(3,0), "f0.Intensity" ); + + TS_ASSERT_DELTA( res->cell<double>(0,1), -3.9865, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(1,1), 3.1881, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(2,1), 2.0011, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(3,1), 9.3859, 1e-4 ); + + TS_ASSERT_DELTA( res->cell<double>(0,2), 0.1764, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(1,2), 0.5690, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(2,2), 0.5969, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(3,2), 2.4468, 1e-4 ); + + TS_ASSERT_EQUALS( res->cell<std::string>(4,0), "f1.Centre" ); + TS_ASSERT_EQUALS( res->cell<std::string>(5,0), "f1.Height" ); + TS_ASSERT_EQUALS( res->cell<std::string>(6,0), "f1.FWHM" ); + TS_ASSERT_EQUALS( res->cell<std::string>(7,0), "f1.Intensity" ); + + TS_ASSERT_DELTA( res->cell<double>(4,1), 3.0064, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(5,1), 2.1327, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(6,1), 2.9908, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(7,1), 9.3838, 1e-4 ); + + TS_ASSERT_DELTA( res->cell<double>(4,2), 0.3234, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(5,2), 0.4756, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(6,2), 1.2002, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(7,2), 3.5530, 1e-4 ); + + AnalysisDataService::Instance().clear(); + } + + void test_on_Lorentzians_ties() + { + std::string funStr = "name=Lorentzian,Amplitude=10,FWHM=2,ties=(PeakCentre=-4);" + "name=Lorentzian,Amplitude=10,PeakCentre=3,FWHM=3;" + "name=FlatBackground,A0=3;ties=(f1.Amplitude=f0.Amplitude)"; + auto fun = FunctionFactory::Instance().createInitialized(funStr); + auto ws = createWorkspace(*fun); + + auto fit = AlgorithmManager::Instance().create("Fit"); + fit->setProperty("Function",fun); + fit->setProperty("InputWorkspace",ws); + fit->setProperty("CalcErrors",true); + fit->execute(); + + EstimatePeakErrors alg; + alg.initialize(); + alg.setProperty("Function",fun); + alg.setPropertyValue("OutputWorkspace","Errors"); + alg.execute(); + + auto res = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("Errors"); + TS_ASSERT_EQUALS( res->rowCount(), 8 ); + + TS_ASSERT_EQUALS( res->cell<std::string>(0,0), "f0.Centre" ); + TS_ASSERT_EQUALS( res->cell<std::string>(1,0), "f0.Height" ); + TS_ASSERT_EQUALS( res->cell<std::string>(2,0), "f0.FWHM" ); + TS_ASSERT_EQUALS( res->cell<std::string>(3,0), "f0.Intensity" ); + + TS_ASSERT_DELTA( res->cell<double>(0,1), -4.0000, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(1,1), 3.1877, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(2,1), 2.0012, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(3,1), 9.3849, 1e-4 ); + + TS_ASSERT_DELTA( res->cell<double>(0,2), 0.0000, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(1,2), 0.5609, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(2,2), 0.5797, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(3,2), 2.2561, 1e-4 ); + + TS_ASSERT_EQUALS( res->cell<std::string>(4,0), "f1.Centre" ); + TS_ASSERT_EQUALS( res->cell<std::string>(5,0), "f1.Height" ); + TS_ASSERT_EQUALS( res->cell<std::string>(6,0), "f1.FWHM" ); + TS_ASSERT_EQUALS( res->cell<std::string>(7,0), "f1.Intensity" ); + + TS_ASSERT_DELTA( res->cell<double>(4,1), 3.0056, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(5,1), 2.1320, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(6,1), 2.9921, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(7,1), 9.3849, 1e-4 ); + + TS_ASSERT_DELTA( res->cell<double>(4,2), 0.3231, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(5,2), 0.4668, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(6,2), 0.6551, 1e-4 ); + TS_ASSERT_DELTA( res->cell<double>(7,2), 0.0000, 1e-4 ); + + AnalysisDataService::Instance().clear(); + } + + + void test_no_peaks() + { + std::string funStr = "name=FlatBackground,A0=3"; + auto fun = FunctionFactory::Instance().createInitialized(funStr); + auto ws = createWorkspace(*fun); + + auto fit = AlgorithmManager::Instance().create("Fit"); + fit->setProperty("Function",fun); + fit->setProperty("InputWorkspace",ws); + fit->setProperty("CalcErrors",true); + fit->execute(); + + EstimatePeakErrors alg; + alg.initialize(); + alg.setProperty("Function",fun); + alg.setPropertyValue("OutputWorkspace","Errors"); + alg.execute(); + + auto res = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("Errors"); + TS_ASSERT_EQUALS( res->rowCount(), 0 ); + + AnalysisDataService::Instance().clear(); + } + +private: + + MatrixWorkspace_sptr createWorkspace(const IFunction& fun) const + { + size_t n = 100; + auto ws = WorkspaceFactory::Instance().create("Workspace2D", 1, n, n); + FunctionDomain1DVector x(-10,10,n); + FunctionValues y(x); + std::vector<double> e(n,1.0); + + fun.function(x,y); + ws->setX(0,x.toVector()); + ws->getSpectrum(0)->setData(y.toVector(),e); + addNoise(ws,0.1); + return ws; + } + +}; + +#endif /*CHEBYSHEVTEST_H_*/ diff --git a/Code/Mantid/Framework/CurveFitting/test/FABADAMinimizerTest.h b/Code/Mantid/Framework/CurveFitting/test/FABADAMinimizerTest.h index a8f1857f0f065c6b8cbb6b988828c70a02a36323..54ce15e4a07bfeecd967620864af4b4f26a2c64b 100644 --- a/Code/Mantid/Framework/CurveFitting/test/FABADAMinimizerTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/FABADAMinimizerTest.h @@ -13,171 +13,166 @@ #include "MantidTestHelpers/FakeObjects.h" #include "MantidKernel/Exception.h" - using Mantid::CurveFitting::FABADAMinimizer; using namespace Mantid::API; using namespace Mantid; using namespace Mantid::CurveFitting; -class FABADAMinimizerTest : public CxxTest::TestSuite -{ +class FABADAMinimizerTest : 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 FABADAMinimizerTest *createSuite() { return new FABADAMinimizerTest(); } - static void destroySuite( FABADAMinimizerTest *suite ) { delete suite; } - + static FABADAMinimizerTest *createSuite() { + return new FABADAMinimizerTest(); + } + static void destroySuite(FABADAMinimizerTest *suite) { delete suite; } - void test_expDecay() - { - const bool histogram(false); - auto ws2 = createTestWorkspace(histogram); + void test_expDecay() { + auto ws2 = createTestWorkspace(); API::IFunction_sptr fun(new ExpDecay); - fun->setParameter("Height",8.); - fun->setParameter("Lifetime",1.0); + fun->setParameter("Height", 8.); + fun->setParameter("Lifetime", 1.0); Fit fit; fit.initialize(); fit.setRethrows(true); - fit.setProperty("Function",fun); - fit.setProperty("InputWorkspace",ws2); - fit.setProperty("WorkspaceIndex",0); - fit.setProperty("CreateOutput",true); - fit.setProperty("MaxIterations",100000); - fit.setProperty("Minimizer", "FABADA,ChainLength=5000,ConvergenceCriteria = 0.1, OutputWorkspaceConverged=conv"); + fit.setProperty("Function", fun); + fit.setProperty("InputWorkspace", ws2); + fit.setProperty("WorkspaceIndex", 0); + fit.setProperty("CreateOutput", true); + fit.setProperty("MaxIterations", 100000); + fit.setProperty("Minimizer", "FABADA,ChainLength=5000,StepsBetweenValues=" + "10,ConvergenceCriteria = 0.1"); - TS_ASSERT_THROWS_NOTHING( fit.execute() ); + TS_ASSERT_THROWS_NOTHING(fit.execute()); TS_ASSERT(fit.isExecuted()); - TS_ASSERT_DELTA( fun->getParameter("Height"), 10.0, 1e-1); - TS_ASSERT_DELTA( fun->getParameter("Lifetime"), 0.5, 1e-2); + TS_ASSERT_DELTA(fun->getParameter("Height"), 10.0, 0.7); + TS_ASSERT_DELTA(fun->getParameter("Lifetime"), 0.5, 0.1); + TS_ASSERT_DELTA(fun->getError(0), 0.7, 1e-1); + TS_ASSERT_DELTA(fun->getError(1), 0.06, 1e-2); TS_ASSERT_EQUALS(fit.getPropertyValue("OutputStatus"), "success"); - size_t n = fun -> nParams(); + size_t n = fun->nParams(); - TS_ASSERT( AnalysisDataService::Instance().doesExist("pdf") ); + TS_ASSERT(AnalysisDataService::Instance().doesExist("PDF")); MatrixWorkspace_sptr wsPDF = boost::dynamic_pointer_cast<MatrixWorkspace>( - API::AnalysisDataService::Instance().retrieve("pdf")); + API::AnalysisDataService::Instance().retrieve("PDF")); TS_ASSERT(wsPDF); - TS_ASSERT_EQUALS(wsPDF->getNumberHistograms(),n); - - const Mantid::MantidVec& X = wsPDF->dataX(0); - const Mantid::MantidVec& Y = wsPDF->dataY(0); - TS_ASSERT_EQUALS(X.size(), 51); - TS_ASSERT_EQUALS(Y.size(), 50); - - TS_ASSERT( AnalysisDataService::Instance().doesExist("chi2") ); - ITableWorkspace_sptr chi2table = boost::dynamic_pointer_cast<ITableWorkspace>( - API::AnalysisDataService::Instance().retrieve("chi2")); - - TS_ASSERT(chi2table); - TS_ASSERT_EQUALS(chi2table->columnCount(), 4); - TS_ASSERT_EQUALS(chi2table->rowCount(), 1); - TS_ASSERT_EQUALS(chi2table->getColumn(0)->type(), "double"); - TS_ASSERT_EQUALS(chi2table->getColumn(0)->name(), "Chi2min"); - TS_ASSERT_EQUALS(chi2table->getColumn(1)->type(), "double"); - TS_ASSERT_EQUALS(chi2table->getColumn(1)->name(), "Chi2MP"); - TS_ASSERT_EQUALS(chi2table->getColumn(2)->type(), "double"); - TS_ASSERT_EQUALS(chi2table->getColumn(2)->name(), "Chi2min_red"); - TS_ASSERT_EQUALS(chi2table->getColumn(3)->type(), "double"); - TS_ASSERT_EQUALS(chi2table->getColumn(3)->name(), "Chi2MP_red"); - TS_ASSERT(chi2table->Double(0,0) <= chi2table->Double(0,1)); - TS_ASSERT(chi2table->Double(0,2) <= chi2table->Double(0,3)); - TS_ASSERT_DELTA(chi2table->Double(0,0), chi2table->Double(0,1), 1); - TS_ASSERT_DELTA(chi2table->Double(0,0), 0.0, 1.0); - - TS_ASSERT( AnalysisDataService::Instance().doesExist("conv") ); + TS_ASSERT_EQUALS(wsPDF->getNumberHistograms(), n + 1); + + const Mantid::MantidVec &X = wsPDF->dataX(0); + const Mantid::MantidVec &Y = wsPDF->dataY(0); + TS_ASSERT_EQUALS(X.size(), 21); + TS_ASSERT_EQUALS(Y.size(), 20); + + TS_ASSERT(AnalysisDataService::Instance().doesExist("CostFunction")); + ITableWorkspace_sptr CostFunctionTable = + boost::dynamic_pointer_cast<ITableWorkspace>( + API::AnalysisDataService::Instance().retrieve("CostFunction")); + + TS_ASSERT(CostFunctionTable); + TS_ASSERT_EQUALS(CostFunctionTable->columnCount(), 4); + TS_ASSERT_EQUALS(CostFunctionTable->rowCount(), 1); + TS_ASSERT_EQUALS(CostFunctionTable->getColumn(0)->type(), "double"); + TS_ASSERT_EQUALS(CostFunctionTable->getColumn(0)->name(), "Chi2min"); + TS_ASSERT_EQUALS(CostFunctionTable->getColumn(1)->type(), "double"); + TS_ASSERT_EQUALS(CostFunctionTable->getColumn(1)->name(), "Chi2MP"); + TS_ASSERT_EQUALS(CostFunctionTable->getColumn(2)->type(), "double"); + TS_ASSERT_EQUALS(CostFunctionTable->getColumn(2)->name(), "Chi2min_red"); + TS_ASSERT_EQUALS(CostFunctionTable->getColumn(3)->type(), "double"); + TS_ASSERT_EQUALS(CostFunctionTable->getColumn(3)->name(), "Chi2MP_red"); + TS_ASSERT(CostFunctionTable->Double(0, 0) <= + CostFunctionTable->Double(0, 1)); + TS_ASSERT(CostFunctionTable->Double(0, 2) <= + CostFunctionTable->Double(0, 3)); + //TS_ASSERT_DELTA(CostFunctionTable->Double(0, 0), + // CostFunctionTable->Double(0, 1), 1.5); + TS_ASSERT_DELTA(CostFunctionTable->Double(0, 0), 0.0, 1.0); + + TS_ASSERT(AnalysisDataService::Instance().doesExist("ConvergedChain")); MatrixWorkspace_sptr wsConv = boost::dynamic_pointer_cast<MatrixWorkspace>( - API::AnalysisDataService::Instance().retrieve("conv")); + API::AnalysisDataService::Instance().retrieve("ConvergedChain")); TS_ASSERT(wsConv); - TS_ASSERT_EQUALS(wsConv->getNumberHistograms(),n+1); + TS_ASSERT_EQUALS(wsConv->getNumberHistograms(), n + 1); - const Mantid::MantidVec& Xconv = wsConv->dataX(0); - TS_ASSERT_EQUALS(Xconv.size(), 5000); - TS_ASSERT_EQUALS(Xconv[2437], 2437); + const Mantid::MantidVec &Xconv = wsConv->dataX(0); + TS_ASSERT_EQUALS(Xconv.size(), 500); + TS_ASSERT_EQUALS(Xconv[437], 437); - TS_ASSERT( AnalysisDataService::Instance().doesExist("chain") ); + TS_ASSERT(AnalysisDataService::Instance().doesExist("chain")); MatrixWorkspace_sptr wsChain = boost::dynamic_pointer_cast<MatrixWorkspace>( - API::AnalysisDataService::Instance().retrieve("chain")); + API::AnalysisDataService::Instance().retrieve("chain")); TS_ASSERT(wsChain); - TS_ASSERT_EQUALS(wsChain->getNumberHistograms(),n+1); + TS_ASSERT_EQUALS(wsChain->getNumberHistograms(), n + 1); - const Mantid::MantidVec& Xchain = wsChain->dataX(0); - TS_ASSERT_EQUALS(Xchain.size(), 6881); + const Mantid::MantidVec &Xchain = wsChain->dataX(0); TS_ASSERT_EQUALS(Xchain[5000], 5000); TS_ASSERT(Xconv.size() < Xchain.size()); - TS_ASSERT( AnalysisDataService::Instance().doesExist("pdfE") ); - ITableWorkspace_sptr Etable = boost::dynamic_pointer_cast<ITableWorkspace>( - API::AnalysisDataService::Instance().retrieve("pdfE")); - - TS_ASSERT(Etable); - TS_ASSERT_EQUALS(Etable->columnCount(), 4); - TS_ASSERT_EQUALS(Etable->rowCount(), n); - TS_ASSERT_EQUALS(Etable->getColumn(0)->type(), "str"); - TS_ASSERT_EQUALS(Etable->getColumn(0)->name(), "Name"); - TS_ASSERT_EQUALS(Etable->getColumn(1)->type(), "double"); - TS_ASSERT_EQUALS(Etable->getColumn(1)->name(), "Value"); - TS_ASSERT_EQUALS(Etable->getColumn(2)->type(), "double"); - TS_ASSERT_EQUALS(Etable->getColumn(2)->name(), "Left's error"); - TS_ASSERT_EQUALS(Etable->getColumn(3)->type(), "double"); - TS_ASSERT_EQUALS(Etable->getColumn(3)->name(), "Rigth's error"); - TS_ASSERT(Etable->Double(0,1) == fun->getParameter("Height")); - TS_ASSERT(Etable->Double(1,1) == fun->getParameter("Lifetime")); - + TS_ASSERT(AnalysisDataService::Instance().doesExist("Parameters")); + ITableWorkspace_sptr Ptable = boost::dynamic_pointer_cast<ITableWorkspace>( + API::AnalysisDataService::Instance().retrieve("Parameters")); + + TS_ASSERT(Ptable); + TS_ASSERT_EQUALS(Ptable->columnCount(), 4); + TS_ASSERT_EQUALS(Ptable->rowCount(), n); + TS_ASSERT_EQUALS(Ptable->getColumn(0)->type(), "str"); + TS_ASSERT_EQUALS(Ptable->getColumn(0)->name(), "Name"); + TS_ASSERT_EQUALS(Ptable->getColumn(1)->type(), "double"); + TS_ASSERT_EQUALS(Ptable->getColumn(1)->name(), "Value"); + TS_ASSERT_EQUALS(Ptable->getColumn(2)->type(), "double"); + TS_ASSERT_EQUALS(Ptable->getColumn(2)->name(), "Left's error"); + TS_ASSERT_EQUALS(Ptable->getColumn(3)->type(), "double"); + TS_ASSERT_EQUALS(Ptable->getColumn(3)->name(), "Rigth's error"); + TS_ASSERT(Ptable->Double(0, 1) == fun->getParameter("Height")); + TS_ASSERT(Ptable->Double(1, 1) == fun->getParameter("Lifetime")); } - void test_low_MaxIterations() - { - const bool histogram(false); - auto ws2 = createTestWorkspace(histogram); + void test_low_MaxIterations() { + auto ws2 = createTestWorkspace(); API::IFunction_sptr fun(new ExpDecay); - fun->setParameter("Height",1.); - fun->setParameter("Lifetime",1.0); + fun->setParameter("Height", 1.); + fun->setParameter("Lifetime", 1.0); Fit fit; fit.initialize(); fit.setRethrows(true); - fit.setProperty("Function",fun); - fit.setProperty("InputWorkspace",ws2); - fit.setProperty("WorkspaceIndex",0); - fit.setProperty("CreateOutput",true); - fit.setProperty("MaxIterations",10); - fit.setProperty("Minimizer", "FABADA,ChainLength=5000,ConvergenceCriteria = 0.01, OutputWorkspaceConverged=conv"); - - TS_ASSERT_THROWS( fit.execute(), std::runtime_error ); + fit.setProperty("Function", fun); + fit.setProperty("InputWorkspace", ws2); + fit.setProperty("WorkspaceIndex", 0); + fit.setProperty("CreateOutput", true); + fit.setProperty("MaxIterations", 10); + fit.setProperty("Minimizer", "FABADA,ChainLength=5000,StepsBetweenValues=" + "10,ConvergenceCriteria = 0.01"); - TS_ASSERT( !fit.isExecuted() ); + TS_ASSERT_THROWS(fit.execute(), std::runtime_error); + TS_ASSERT(!fit.isExecuted()); } -private: - API::MatrixWorkspace_sptr createTestWorkspace(const bool histogram) - { +private: + API::MatrixWorkspace_sptr createTestWorkspace() { MatrixWorkspace_sptr ws2(new WorkspaceTester); - ws2->initialize(2,20,20); - - for(size_t is = 0; is < ws2->getNumberHistograms(); ++is) - { - Mantid::MantidVec& x = ws2->dataX(is); - Mantid::MantidVec& y = ws2->dataY(is); - for(size_t i = 0; i < ws2->blocksize(); ++i) - { + ws2->initialize(2, 20, 20); + + for (size_t is = 0; is < ws2->getNumberHistograms(); ++is) { + Mantid::MantidVec &x = ws2->dataX(is); + Mantid::MantidVec &y = ws2->dataY(is); + for (size_t i = 0; i < ws2->blocksize(); ++i) { x[i] = 0.1 * double(i); - y[i] = (10.0 + double(is)) * exp( -(x[i])/ (0.5*(1 + double(is))) ); + y[i] = (10.0 + double(is)) * exp(-(x[i]) / (0.5 * (1 + double(is)))); } - if(histogram) x.back() = x[x.size()-2] + 0.1; } return ws2; } }; - #endif /* MANTID_CURVEFITTING_FABADAMINIMIZERTEST_H_ */ diff --git a/Code/Mantid/Framework/CurveFitting/test/FunctionFactoryConstraintTest.h b/Code/Mantid/Framework/CurveFitting/test/FunctionFactoryConstraintTest.h index af5617975a9bbd3ab4f3da03571695fb070a6238..16b1c76cc47fcfeb36f6979a198dac6100d566f7 100644 --- a/Code/Mantid/Framework/CurveFitting/test/FunctionFactoryConstraintTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/FunctionFactoryConstraintTest.h @@ -134,10 +134,10 @@ public: }; -DECLARE_FUNCTION(FunctionFactoryConstraintTest_FunctA); -DECLARE_FUNCTION(FunctionFactoryConstraintTest_FunctB); -DECLARE_FUNCTION(FunctionFactoryConstraintTest_CompFunctA); -DECLARE_FUNCTION(FunctionFactoryConstraintTest_CompFunctB); +DECLARE_FUNCTION(FunctionFactoryConstraintTest_FunctA) +DECLARE_FUNCTION(FunctionFactoryConstraintTest_FunctB) +DECLARE_FUNCTION(FunctionFactoryConstraintTest_CompFunctA) +DECLARE_FUNCTION(FunctionFactoryConstraintTest_CompFunctB) class FunctionFactoryConstraintTest : public CxxTest::TestSuite { diff --git a/Code/Mantid/Framework/CurveFitting/test/FunctionParameterDecoratorFitTest.h b/Code/Mantid/Framework/CurveFitting/test/FunctionParameterDecoratorFitTest.h index 47cc259f355829cfec33c8e519944e3dd82abbe9..c7f60ebf936da427adc02bfe5a1b4a01c6b27288 100644 --- a/Code/Mantid/Framework/CurveFitting/test/FunctionParameterDecoratorFitTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/FunctionParameterDecoratorFitTest.h @@ -46,7 +46,7 @@ public: } }; -DECLARE_FUNCTION(SimpleFunctionParameterDecorator); +DECLARE_FUNCTION(SimpleFunctionParameterDecorator) class FunctionParameterDecoratorFitTest : public CxxTest::TestSuite { public: @@ -70,7 +70,7 @@ public: void testFit() { Workspace2D_sptr ws = - WorkspaceCreationHelper::Create1DWorkspaceConstant(20, 1.5, 1.5); + WorkspaceCreationHelper::Create1DWorkspaceConstant(20, 1.5, 0.5); FunctionParameterDecorator_sptr fn = boost::make_shared<SimpleFunctionParameterDecorator>(); diff --git a/Code/Mantid/Framework/CurveFitting/test/GSLMatrixTest.h b/Code/Mantid/Framework/CurveFitting/test/GSLMatrixTest.h index 9905d55c6e93a4cbd02383d4bc8eae5775e11b2f..0d652bdeb111fdc12567fddc3508b3bf2043481a 100644 --- a/Code/Mantid/Framework/CurveFitting/test/GSLMatrixTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/GSLMatrixTest.h @@ -173,6 +173,33 @@ public: TS_ASSERT_EQUALS(m.get(1,1), 0.5); } + void test_subMatrix() + { + GSLMatrix m(4,4); + m.set(0,0,0); m.set(0,1,1); m.set(0,2,2); m.set(0,3,3); + m.set(1,0,10);m.set(1,1,11);m.set(1,2,12);m.set(1,3,13); + m.set(2,0,20);m.set(2,1,21);m.set(2,2,22);m.set(2,3,23); + m.set(3,0,30);m.set(3,1,31);m.set(3,2,32);m.set(3,3,33); + + GSLMatrix subm(m, 1,1,2,2 ); + TS_ASSERT_EQUALS(subm.get(0,0), 11); + TS_ASSERT_EQUALS(subm.get(0,1), 12); + TS_ASSERT_EQUALS(subm.get(1,0), 21); + TS_ASSERT_EQUALS(subm.get(1,1), 22); + } + + void test_subMatrix_fail() + { + GSLMatrix m(4,4); + m.set(0,0,0); m.set(0,1,1); m.set(0,2,2); m.set(0,3,3); + m.set(1,0,10);m.set(1,1,11);m.set(1,2,12);m.set(1,3,13); + m.set(2,0,20);m.set(2,1,21);m.set(2,2,22);m.set(2,3,23); + m.set(3,0,30);m.set(3,1,31);m.set(3,2,32);m.set(3,3,33); + + TS_ASSERT_THROWS( + GSLMatrix subm(m, 2,2,3,3 ), std::runtime_error); + } + }; #endif /*GSLMATRIXTEST_H_*/ diff --git a/Code/Mantid/Framework/CurveFitting/test/GaussianTest.h b/Code/Mantid/Framework/CurveFitting/test/GaussianTest.h index 40a9a43251b517d4b975720cd8f004cde88ac909..dcbddf65af1e2cb10d52d4691d55bf1ec149ebbb 100644 --- a/Code/Mantid/Framework/CurveFitting/test/GaussianTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/GaussianTest.h @@ -51,7 +51,7 @@ protected: } }; -DECLARE_FUNCTION(SimplexGaussian); +DECLARE_FUNCTION(SimplexGaussian) class GaussianTest : public CxxTest::TestSuite { diff --git a/Code/Mantid/Framework/CurveFitting/test/PawleyFitTest.h b/Code/Mantid/Framework/CurveFitting/test/PawleyFitTest.h new file mode 100644 index 0000000000000000000000000000000000000000..30b0ca92e8d438ed7550f85384bfff6bb6d7469c --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/test/PawleyFitTest.h @@ -0,0 +1,261 @@ +#ifndef MANTID_CURVEFITTING_PAWLEYFITTEST_H_ +#define MANTID_CURVEFITTING_PAWLEYFITTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidCurveFitting/PawleyFit.h" +#include "MantidAPI/AlgorithmManager.h" +#include "MantidAPI/FunctionFactory.h" +#include "MantidAPI/TableRow.h" +#include "MantidAPI/WorkspaceFactory.h" +#include "MantidKernel/V3D.h" +#include "MantidTestHelpers/WorkspaceCreationHelper.h" + +using Mantid::CurveFitting::PawleyFit; +using namespace Mantid::API; +using namespace Mantid::Kernel; + +class PawleyFitTest : 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 PawleyFitTest *createSuite() { return new PawleyFitTest(); } + static void destroySuite(PawleyFitTest *suite) { delete suite; } + + void testGetHKL() { + TestablePawleyFit pfit; + + V3D referenceHKL(1, 2, 3); + + TS_ASSERT_EQUALS(pfit.getHkl("1 2 3"), referenceHKL); + TS_ASSERT_EQUALS(pfit.getHkl(" 1 2 3 "), referenceHKL); + TS_ASSERT_EQUALS(pfit.getHkl("1 2 3"), referenceHKL); + TS_ASSERT_EQUALS(pfit.getHkl("1,2,3"), referenceHKL); + TS_ASSERT_EQUALS(pfit.getHkl("1;2;3"), referenceHKL); + TS_ASSERT_EQUALS(pfit.getHkl("[1,2,3]"), referenceHKL); + TS_ASSERT_EQUALS(pfit.getHkl("[1;2 3]"), referenceHKL); + } + + void testFitHexagonalCellQ() { + /* Like in the PawleyFunctionTest, some reflections are needed. + * In this case, 5 reflections that belong to a hexagonal cell + * are used and stored in a TableWorkspace that has a suitable + * format for PawleyFit. The unit of the workspace is MomentumTransfer. + */ + + ITableWorkspace_sptr hkls = getHCPTable(); + MatrixWorkspace_sptr ws = + getWorkspace(getFunctionString(hkls, true), (2.0 * M_PI) / 2.1, + (2.0 * M_PI) / 1.0, 1000, "MomentumTransfer"); + + IAlgorithm_sptr pFit = AlgorithmManager::Instance().create("PawleyFit"); + pFit->setProperty("InputWorkspace", ws); + pFit->setProperty("WorkspaceIndex", 0); + pFit->setProperty("CrystalSystem", "Hexagonal"); + pFit->setProperty("InitialCell", "2.444 2.441 3.937 90 90 120"); + pFit->setProperty("PeakTable", hkls); + pFit->setProperty("OutputWorkspace", "HCP_output"); + pFit->setProperty("RefinedPeakParameterTable", "HCP_peaks"); + pFit->setProperty("RefinedCellTable", "HCP_cell"); + + TS_ASSERT_THROWS_NOTHING(pFit->execute()); + + // Examine table with cell parameters. + ITableWorkspace_sptr cellWs = + AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("HCP_cell"); + + // Three rows (a, c, ZeroShift) + TS_ASSERT_EQUALS(cellWs->rowCount(), 3); + + // Error of 'a' should be small + TS_ASSERT_LESS_THAN(fabs(cellWs->cell<double>(0, 2)), 1e-5); + // a should be almost equal to 2.45 + TS_ASSERT_DELTA(cellWs->cell<double>(0, 1), 2.45, 1e-5); + + // Error of 'c' should also be small + TS_ASSERT_LESS_THAN(fabs(cellWs->cell<double>(1, 2)), 1e-6); + // c should be almost equal to 3.93 + TS_ASSERT_DELTA(cellWs->cell<double>(1, 1), 3.93, 1e-6); + + // Check number of peak parameters. + ITableWorkspace_sptr peakWs = + AnalysisDataService::Instance().retrieveWS<ITableWorkspace>( + "HCP_peaks"); + TS_ASSERT_EQUALS(peakWs->rowCount(), 5 * 3); // 5 functions with 3 params. + + AnalysisDataService::Instance().remove("HCP_output"); + AnalysisDataService::Instance().remove("HCP_peaks"); + AnalysisDataService::Instance().remove("HCP_cell"); + } + + void testFitOrthorhombicCelld() { + /* In analogy to the above example, an orthorhombic cell is fitted, + * this time in dSpacing and with a FlatBackground added. + */ + + ITableWorkspace_sptr hkls = getOrthorhombicTable(); + MatrixWorkspace_sptr ws = getWorkspace(getFunctionString(hkls, false), 1.5, + 2.1, 1000, "dSpacing"); + + IAlgorithm_sptr pFit = AlgorithmManager::Instance().create("PawleyFit"); + pFit->setProperty("InputWorkspace", ws); + pFit->setProperty("WorkspaceIndex", 0); + pFit->setProperty("CrystalSystem", "Orthorhombic"); + pFit->setProperty("InitialCell", "2.44 3.13 4.07 90 90 90"); + pFit->setProperty("PeakTable", hkls); + pFit->setProperty("EnableChebyshevBackground", true); + pFit->setProperty("ChebyshevBackgroundDegree", 0); + pFit->setProperty("OutputWorkspace", "OP_output"); + pFit->setProperty("RefinedPeakParameterTable", "OP_peaks"); + pFit->setProperty("RefinedCellTable", "OP_cell"); + + pFit->execute(); + + // Examine table with cell parameters. + ITableWorkspace_sptr cellWs = + AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("OP_cell"); + + // Three rows (a, b, c, ZeroShift) + TS_ASSERT_EQUALS(cellWs->rowCount(), 4); + + // Error of 'a' should be small + TS_ASSERT_LESS_THAN(fabs(cellWs->cell<double>(0, 2)), 1e-4); + // a should be almost equal to 2.45 + TS_ASSERT_DELTA(cellWs->cell<double>(0, 1), 2.45, 2e-3); + + // Error of 'b' should also be small + TS_ASSERT_LESS_THAN(fabs(cellWs->cell<double>(1, 2)), 1e-4); + // b should be almost equal to 3.12 + TS_ASSERT_DELTA(cellWs->cell<double>(1, 1), 3.12, 2e-3); + + // Error of 'c' should also be small + TS_ASSERT_LESS_THAN(fabs(cellWs->cell<double>(2, 2)), 1e-4); + // b should be almost equal to 4.06 + TS_ASSERT_DELTA(cellWs->cell<double>(2, 1), 4.06, 2e-3); + + // Check number of peak parameters. + ITableWorkspace_sptr peakWs = + AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("OP_peaks"); + TS_ASSERT_EQUALS(peakWs->rowCount(), 7 * 3); // 5 functions with 3 params. + + AnalysisDataService::Instance().remove("OP_output"); + AnalysisDataService::Instance().remove("OP_peaks"); + AnalysisDataService::Instance().remove("OP_cell"); + } + +private: + class TestablePawleyFit : public PawleyFit { + friend class PawleyFitTest; + + public: + TestablePawleyFit() : PawleyFit() {} + ~TestablePawleyFit() {} + }; + + ITableWorkspace_sptr getHCPTable() { + ITableWorkspace_sptr tableWs = WorkspaceFactory::Instance().createTable(); + tableWs->addColumn("V3D", "HKL"); + tableWs->addColumn("double", "d"); + tableWs->addColumn("double", "FWHM (rel.)"); + // Check that string columns are converted if they contain numbers + tableWs->addColumn("str", "Intensity"); + + TableRow row0 = tableWs->appendRow(); + row0 << V3D(0, 0, 2) << 1.965 << 0.004 << "3800.0"; + + TableRow row1 = tableWs->appendRow(); + row1 << V3D(1, 0, 1) << 1.867037 << 0.004 << "16400.0"; + TableRow row2 = tableWs->appendRow(); + row2 << V3D(1, 0, 2) << 1.441702 << 0.005 << "3700.0"; + TableRow row3 = tableWs->appendRow(); + row3 << V3D(1, 0, 3) << 1.114663 << 0.006 << "5900.0"; + TableRow row4 = tableWs->appendRow(); + row4 << V3D(2, -1, 0) << 1.225 << 0.004 << "5100.0"; + + return tableWs; + } + + ITableWorkspace_sptr getOrthorhombicTable() { + ITableWorkspace_sptr tableWs = WorkspaceFactory::Instance().createTable(); + tableWs->addColumn("V3D", "HKL"); + tableWs->addColumn("double", "d"); + tableWs->addColumn("double", "FWHM (rel.)"); + // Check that string columns are converted if they contain numbers + tableWs->addColumn("str", "Intensity"); + + TableRow row0 = tableWs->appendRow(); + row0 << V3D(0, 0, 2) << 2.03000 << 0.004 << "110.628118"; + + TableRow row1 = tableWs->appendRow(); + row1 << V3D(0, 1, 2) << 1.701542 << 0.0042 << "180.646775"; + + TableRow row2 = tableWs->appendRow(); + row2 << V3D(0, 2, 0) << 1.560000 << 0.00483 << "79.365613"; + + TableRow row3 = tableWs->appendRow(); + row3 << V3D(1, 0, 1) << 2.097660 << 0.0041 << "228.086161"; + + TableRow row4 = tableWs->appendRow(); + row4 << V3D(1, 0, 2) << 1.563144 << 0.004 << "159.249424"; + + TableRow row5 = tableWs->appendRow(); + row5 << V3D(1, 1, 0) << 1.926908 << 0.004 << "209.913635"; + + TableRow row6 = tableWs->appendRow(); + row6 << V3D(1, 1, 1) << 1.740797 << 0.00472 << "372.446264"; + + return tableWs; + } + + std::string getFunctionString(const ITableWorkspace_sptr &table, bool useQ) { + std::vector<std::string> functionStrings; + + for (size_t i = 0; i < table->rowCount(); ++i) { + TableRow row = table->getRow(i); + std::ostringstream fn; + double d = row.Double(1); + double center = useQ ? (2.0 * M_PI) / d : d; + double fwhmAbs = row.Double(2) * center; + fn << "name=Gaussian,PeakCentre=" << center + << ",Sigma=" << fwhmAbs / (2.0 * sqrt(2.0 * log(2.0))) + << ",Height=" << row.String(3); + + functionStrings.push_back(fn.str()); + } + + return boost::join(functionStrings, ";"); + } + + MatrixWorkspace_sptr getWorkspace(const std::string &functionString, + double xMin, double xMax, size_t n, + const std::string &unit, double bg = 0.0) { + IFunction_sptr siFn = + FunctionFactory::Instance().createInitialized(functionString); + + auto ws = WorkspaceFactory::Instance().create("Workspace2D", 1, n, n); + + FunctionDomain1DVector xValues(xMin, xMax, n); + FunctionValues yValues(xValues); + std::vector<double> eValues(n, 1.0); + + siFn->function(xValues, yValues); + + std::vector<double> &xData = ws->dataX(0); + std::vector<double> &yData = ws->dataY(0); + std::vector<double> &eData = ws->dataE(0); + + for (size_t i = 0; i < n; ++i) { + xData[i] = xValues[i]; + yData[i] = yValues[i] + bg; + eData[i] = eValues[i]; + } + + WorkspaceCreationHelper::addNoise(ws, 0, -0.5, 0.5); + + ws->getAxis(0)->setUnit(unit); + + return ws; + } +}; + +#endif /* MANTID_CURVEFITTING_PAWLEYFITTEST_H_ */ diff --git a/Code/Mantid/Framework/CurveFitting/test/PawleyFunctionTest.h b/Code/Mantid/Framework/CurveFitting/test/PawleyFunctionTest.h new file mode 100644 index 0000000000000000000000000000000000000000..141f4d008e4764a8fdbb892a25f23da0b1f51422 --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/test/PawleyFunctionTest.h @@ -0,0 +1,523 @@ +#ifndef MANTID_CURVEFITTING_PAWLEYFUNCTIONTEST_H_ +#define MANTID_CURVEFITTING_PAWLEYFUNCTIONTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidCurveFitting/PawleyFunction.h" +#include "MantidGeometry/Crystal/PointGroup.h" +#include "MantidAPI/AlgorithmManager.h" +#include "MantidAPI/FunctionFactory.h" +#include "MantidAPI/WorkspaceFactory.h" +#include "MantidTestHelpers/WorkspaceCreationHelper.h" + +using namespace Mantid::CurveFitting; +using namespace Mantid::API; +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + +class PawleyFunctionTest : 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 PawleyFunctionTest *createSuite() { return new PawleyFunctionTest(); } + static void destroySuite(PawleyFunctionTest *suite) { delete suite; } + + void testCrystalSystem() { + PawleyParameterFunction fn; + fn.initialize(); + + TS_ASSERT(fn.hasAttribute("CrystalSystem")); + + // Cubic, check case insensitivity + TS_ASSERT_THROWS_NOTHING(fn.setAttributeValue("CrystalSystem", "cubic")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Cubic); + TS_ASSERT_THROWS_NOTHING(fn.setAttributeValue("CrystalSystem", "Cubic")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Cubic); + TS_ASSERT_THROWS_NOTHING(fn.setAttributeValue("CrystalSystem", "CUBIC")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Cubic); + + // Tetragonal + TS_ASSERT_THROWS_NOTHING( + fn.setAttributeValue("CrystalSystem", "tetragonal")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Tetragonal); + TS_ASSERT_THROWS_NOTHING( + fn.setAttributeValue("CrystalSystem", "Tetragonal")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Tetragonal); + TS_ASSERT_THROWS_NOTHING( + fn.setAttributeValue("CrystalSystem", "TETRAGONAL")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Tetragonal); + + // Hexagonal + TS_ASSERT_THROWS_NOTHING( + fn.setAttributeValue("CrystalSystem", "hexagonal")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Hexagonal); + TS_ASSERT_THROWS_NOTHING( + fn.setAttributeValue("CrystalSystem", "Hexagonal")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Hexagonal); + TS_ASSERT_THROWS_NOTHING( + fn.setAttributeValue("CrystalSystem", "HEXAGONAL")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Hexagonal); + + // Orthorhombic + TS_ASSERT_THROWS_NOTHING( + fn.setAttributeValue("CrystalSystem", "orthorhombic")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Orthorhombic); + TS_ASSERT_THROWS_NOTHING( + fn.setAttributeValue("CrystalSystem", "Orthorhombic")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Orthorhombic); + TS_ASSERT_THROWS_NOTHING( + fn.setAttributeValue("CrystalSystem", "ORTHORHOMBIC")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Orthorhombic); + + // Monoclinic + TS_ASSERT_THROWS_NOTHING( + fn.setAttributeValue("CrystalSystem", "monoclinic")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Monoclinic); + TS_ASSERT_THROWS_NOTHING( + fn.setAttributeValue("CrystalSystem", "Monoclinic")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Monoclinic); + TS_ASSERT_THROWS_NOTHING( + fn.setAttributeValue("CrystalSystem", "MONOCLINIC")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Monoclinic); + + // Triclinic + TS_ASSERT_THROWS_NOTHING( + fn.setAttributeValue("CrystalSystem", "triclinic")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Triclinic); + TS_ASSERT_THROWS_NOTHING( + fn.setAttributeValue("CrystalSystem", "Triclinic")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Triclinic); + TS_ASSERT_THROWS_NOTHING( + fn.setAttributeValue("CrystalSystem", "TRICLINIC")); + TS_ASSERT_EQUALS(fn.getCrystalSystem(), PointGroup::Triclinic); + + // invalid string + TS_ASSERT_THROWS(fn.setAttributeValue("CrystalSystem", "invalid"), + std::invalid_argument); + } + + void testCrystalSystemConstraintsCubic() { + PawleyParameterFunction fn; + fn.initialize(); + + fn.setAttributeValue("CrystalSystem", "Cubic"); + + TS_ASSERT_EQUALS(fn.nParams(), 2); + + fn.setParameter("a", 3.0); + TS_ASSERT_EQUALS(fn.getParameter("a"), 3.0); + + TS_ASSERT_THROWS(fn.getParameter("b"), std::invalid_argument); + TS_ASSERT_THROWS(fn.getParameter("c"), std::invalid_argument); + TS_ASSERT_THROWS(fn.getParameter("Alpha"), std::invalid_argument); + TS_ASSERT_THROWS(fn.getParameter("Beta"), std::invalid_argument); + TS_ASSERT_THROWS(fn.getParameter("Gamma"), std::invalid_argument); + + UnitCell cell = fn.getUnitCellFromParameters(); + cellParametersAre(cell, 3.0, 3.0, 3.0, 90.0, 90.0, 90.0); + } + + void testCrystalSystemConstraintsTetragonal() { + PawleyParameterFunction fn; + fn.initialize(); + + fn.setAttributeValue("CrystalSystem", "Tetragonal"); + + TS_ASSERT_EQUALS(fn.nParams(), 3); + + fn.setParameter("a", 3.0); + TS_ASSERT_EQUALS(fn.getParameter("a"), 3.0); + fn.setParameter("c", 5.0); + TS_ASSERT_EQUALS(fn.getParameter("c"), 5.0); + + TS_ASSERT_THROWS(fn.getParameter("b"), std::invalid_argument); + TS_ASSERT_THROWS(fn.getParameter("Alpha"), std::invalid_argument); + TS_ASSERT_THROWS(fn.getParameter("Beta"), std::invalid_argument); + TS_ASSERT_THROWS(fn.getParameter("Gamma"), std::invalid_argument); + + UnitCell cell = fn.getUnitCellFromParameters(); + cellParametersAre(cell, 3.0, 3.0, 5.0, 90.0, 90.0, 90.0); + } + + void testCrystalSystemConstraintsHexagonal() { + PawleyParameterFunction fn; + fn.initialize(); + + fn.setAttributeValue("CrystalSystem", "Hexagonal"); + + TS_ASSERT_EQUALS(fn.nParams(), 3); + + fn.setParameter("a", 3.0); + TS_ASSERT_EQUALS(fn.getParameter("a"), 3.0); + fn.setParameter("c", 5.0); + TS_ASSERT_EQUALS(fn.getParameter("c"), 5.0); + + TS_ASSERT_THROWS(fn.getParameter("b"), std::invalid_argument); + TS_ASSERT_THROWS(fn.getParameter("Alpha"), std::invalid_argument); + TS_ASSERT_THROWS(fn.getParameter("Beta"), std::invalid_argument); + TS_ASSERT_THROWS(fn.getParameter("Gamma"), std::invalid_argument); + + UnitCell cell = fn.getUnitCellFromParameters(); + cellParametersAre(cell, 3.0, 3.0, 5.0, 90.0, 90.0, 120.0); + } + + void testCrystalSystemConstraintsTrigonal() { + PawleyParameterFunction fn; + fn.initialize(); + + fn.setAttributeValue("CrystalSystem", "Trigonal"); + + TS_ASSERT_EQUALS(fn.nParams(), 3); + + fn.setParameter("a", 3.0); + TS_ASSERT_EQUALS(fn.getParameter("a"), 3.0); + fn.setParameter("Alpha", 101.0); + TS_ASSERT_EQUALS(fn.getParameter("Alpha"), 101.0); + + TS_ASSERT_THROWS(fn.getParameter("b"), std::invalid_argument); + TS_ASSERT_THROWS(fn.getParameter("c"), std::invalid_argument); + TS_ASSERT_THROWS(fn.getParameter("Beta"), std::invalid_argument); + TS_ASSERT_THROWS(fn.getParameter("Gamma"), std::invalid_argument); + + UnitCell cell = fn.getUnitCellFromParameters(); + cellParametersAre(cell, 3.0, 3.0, 3.0, 101.0, 101.0, 101.0); + } + + void testCrystalSystemConstraintsOrthorhombic() { + PawleyParameterFunction fn; + fn.initialize(); + + fn.setAttributeValue("CrystalSystem", "Orthorhombic"); + + TS_ASSERT_EQUALS(fn.nParams(), 4); + + fn.setParameter("a", 3.0); + TS_ASSERT_EQUALS(fn.getParameter("a"), 3.0); + fn.setParameter("b", 4.0); + TS_ASSERT_EQUALS(fn.getParameter("b"), 4.0); + fn.setParameter("c", 5.0); + TS_ASSERT_EQUALS(fn.getParameter("c"), 5.0); + + TS_ASSERT_THROWS(fn.getParameter("Alpha"), std::invalid_argument); + TS_ASSERT_THROWS(fn.getParameter("Beta"), std::invalid_argument); + TS_ASSERT_THROWS(fn.getParameter("Gamma"), std::invalid_argument); + + UnitCell cell = fn.getUnitCellFromParameters(); + cellParametersAre(cell, 3.0, 4.0, 5.0, 90.0, 90.0, 90.0); + } + + void testCrystalSystemConstraintsMonoclinic() { + PawleyParameterFunction fn; + fn.initialize(); + + fn.setAttributeValue("CrystalSystem", "Monoclinic"); + + TS_ASSERT_EQUALS(fn.nParams(), 5); + + fn.setParameter("a", 3.0); + TS_ASSERT_EQUALS(fn.getParameter("a"), 3.0); + fn.setParameter("b", 4.0); + TS_ASSERT_EQUALS(fn.getParameter("b"), 4.0); + fn.setParameter("c", 5.0); + TS_ASSERT_EQUALS(fn.getParameter("c"), 5.0); + fn.setParameter("Beta", 101.0); + TS_ASSERT_EQUALS(fn.getParameter("Beta"), 101.0); + + TS_ASSERT_THROWS(fn.getParameter("Alpha"), std::invalid_argument); + TS_ASSERT_THROWS(fn.getParameter("Gamma"), std::invalid_argument); + + UnitCell cell = fn.getUnitCellFromParameters(); + cellParametersAre(cell, 3.0, 4.0, 5.0, 90.0, 101.0, 90.0); + } + + void testCrystalSystemConstraintsTriclinic() { + PawleyParameterFunction fn; + fn.initialize(); + + fn.setAttributeValue("CrystalSystem", "Triclinic"); + + TS_ASSERT_EQUALS(fn.nParams(), 7); + + fn.setParameter("a", 3.0); + TS_ASSERT_EQUALS(fn.getParameter("a"), 3.0); + fn.setParameter("b", 4.0); + TS_ASSERT_EQUALS(fn.getParameter("b"), 4.0); + fn.setParameter("c", 5.0); + TS_ASSERT_EQUALS(fn.getParameter("c"), 5.0); + fn.setParameter("Alpha", 101.0); + TS_ASSERT_EQUALS(fn.getParameter("Alpha"), 101.0); + fn.setParameter("Beta", 111.0); + TS_ASSERT_EQUALS(fn.getParameter("Beta"), 111.0); + fn.setParameter("Gamma", 103.0); + TS_ASSERT_EQUALS(fn.getParameter("Gamma"), 103.0); + + UnitCell cell = fn.getUnitCellFromParameters(); + cellParametersAre(cell, 3.0, 4.0, 5.0, 101.0, 111.0, 103.0); + } + + void testSetParametersFromUnitCell() { + PawleyParameterFunction fn; + fn.initialize(); + + fn.setAttributeValue("CrystalSystem", "Triclinic"); + + UnitCell cell(3., 4., 5., 101., 111., 103.); + + TS_ASSERT_THROWS_NOTHING(fn.setParametersFromUnitCell(cell)); + + TS_ASSERT_EQUALS(fn.getParameter("a"), 3.0); + TS_ASSERT_EQUALS(fn.getParameter("b"), 4.0); + TS_ASSERT_EQUALS(fn.getParameter("c"), 5.0); + TS_ASSERT_EQUALS(fn.getParameter("Alpha"), 101.0); + TS_ASSERT_EQUALS(fn.getParameter("Beta"), 111.0); + TS_ASSERT_EQUALS(fn.getParameter("Gamma"), 103.0); + + fn.setAttributeValue("CrystalSystem", "Cubic"); + + cell.seta(5.43); + TS_ASSERT_THROWS_NOTHING(fn.setParametersFromUnitCell(cell)); + + TS_ASSERT_EQUALS(fn.getParameter("a"), 5.43); + } + + void testProfileFunctionName() { + PawleyParameterFunction fn; + fn.initialize(); + + TS_ASSERT_THROWS_NOTHING( + fn.setAttributeValue("ProfileFunction", "Gaussian")); + TS_ASSERT_EQUALS(fn.getProfileFunctionName(), "Gaussian"); + + // works only with IPeakFunctions + TS_ASSERT_THROWS(fn.setAttributeValue("ProfileFunction", "Chebyshev"), + std::invalid_argument); + + TS_ASSERT_THROWS(fn.setAttributeValue("ProfileFunction", "DoesNotExist"), + Exception::NotFoundError); + } + + void testPawleyFunctionInitialization() { + PawleyFunction fn; + fn.initialize(); + + TS_ASSERT(boost::dynamic_pointer_cast<CompositeFunction>( + fn.getDecoratedFunction())); + + // The base parameters of PawleyParameterFunction + TS_ASSERT_EQUALS(fn.nParams(), 7); + } + + void testPawleyFunctionSetCrystalSystem() { + PawleyFunction fn; + fn.initialize(); + + TS_ASSERT_EQUALS(fn.nParams(), 7); + + fn.setCrystalSystem("Cubic"); + + TS_ASSERT_EQUALS(fn.nParams(), 2); + } + + void testPawleyFunctionAddPeak() { + PawleyFunction fn; + fn.initialize(); + TS_ASSERT_EQUALS(fn.getPeakCount(), 0); + + TS_ASSERT_EQUALS(fn.nParams(), 7); + + fn.addPeak(V3D(), 3.0, 4.0); + + TS_ASSERT_EQUALS(fn.nParams(), 10); + TS_ASSERT_EQUALS(fn.getPeakCount(), 1); + } + + void testPawleyFunctionClearPeaks() { + PawleyFunction fn; + fn.initialize(); + + fn.addPeak(V3D(), 3.0, 4.0); + TS_ASSERT_EQUALS(fn.getPeakCount(), 1); + TS_ASSERT_THROWS_NOTHING(fn.clearPeaks()); + TS_ASSERT_EQUALS(fn.getPeakCount(), 0); + } + + void testPawleyFunctionGetPeakHKL() { + PawleyFunction fn; + fn.initialize(); + + fn.addPeak(V3D(1, 1, 1), 3.0, 4.0); + TS_ASSERT_EQUALS(fn.getPeakCount(), 1); + TS_ASSERT_EQUALS(fn.getPeakHKL(0), V3D(1, 1, 1)); + } + + void testPawleyFunctionGetPeakFunction() { + PawleyFunction fn; + fn.initialize(); + + fn.addPeak(V3D(1, 1, 1), 3.0, 4.0); + TS_ASSERT_EQUALS(fn.getPeakCount(), 1); + + IPeakFunction_sptr peak = fn.getPeakFunction(0); + TS_ASSERT(peak); + TS_ASSERT_EQUALS(peak->fwhm(), 3.0); + TS_ASSERT_EQUALS(peak->height(), 4.0); + } + + void testPawleyFunctionSetProfileFunction() { + PawleyFunction fn; + fn.initialize(); + + TS_ASSERT_EQUALS(fn.nParams(), 7); + + fn.addPeak(V3D(), 3.0, 4.0); + + TS_ASSERT_EQUALS(fn.nParams(), 10); + + fn.setProfileFunction("PseudoVoigt"); + + TS_ASSERT_EQUALS(fn.nParams(), 11); + } + + void testPawleyFunctionGetParameterFunction() { + PawleyFunction fn; + fn.initialize(); + + TS_ASSERT(fn.getPawleyParameterFunction()); + } + + void testPawleyFunctionSetUnitCell() { + PawleyFunction fn; + fn.initialize(); + + TS_ASSERT_THROWS_NOTHING(fn.setUnitCell("1.0 2.0 3.0 90 91 92")); + + PawleyParameterFunction_sptr parameters = fn.getPawleyParameterFunction(); + TS_ASSERT_EQUALS(parameters->getParameter("a"), 1.0); + TS_ASSERT_EQUALS(parameters->getParameter("b"), 2.0); + TS_ASSERT_EQUALS(parameters->getParameter("c"), 3.0); + TS_ASSERT_EQUALS(parameters->getParameter("Alpha"), 90.0); + TS_ASSERT_EQUALS(parameters->getParameter("Beta"), 91.0); + TS_ASSERT_EQUALS(parameters->getParameter("Gamma"), 92.0); + + TS_ASSERT_THROWS_NOTHING(fn.setUnitCell("2.0 3.0 4.0")); + + TS_ASSERT_EQUALS(parameters->getParameter("a"), 2.0); + TS_ASSERT_EQUALS(parameters->getParameter("b"), 3.0); + TS_ASSERT_EQUALS(parameters->getParameter("c"), 4.0); + TS_ASSERT_EQUALS(parameters->getParameter("Alpha"), 90.0); + TS_ASSERT_EQUALS(parameters->getParameter("Beta"), 90.0); + TS_ASSERT_EQUALS(parameters->getParameter("Gamma"), 90.0); + } + + void testFunctionFitSi() { + /* This example generates a spectrum with the first two reflections + * of Silicon with lattice parameter a = 5.4311946 Angstr. + * hkl d height fwhm + * 1 1 1 3.13570 40.0 0.006 + * 2 2 0 1.92022 110.0 0.004 + */ + auto ws = getWorkspace( + "name=Gaussian,PeakCentre=3.13570166,Height=40.0,Sigma=0.003;name=" + "Gaussian,PeakCentre=1.92021727,Height=110.0,Sigma=0.002", + 1.85, 3.2, 400); + + PawleyFunction_sptr pawleyFn = boost::make_shared<PawleyFunction>(); + pawleyFn->initialize(); + pawleyFn->setCrystalSystem("Cubic"); + pawleyFn->addPeak(V3D(1, 1, 1), 0.0065, 35.0); + pawleyFn->addPeak(V3D(2, 2, 0), 0.0045, 110.0); + pawleyFn->setUnitCell("5.4295 5.4295 5.4295"); + + // fix ZeroShift + pawleyFn->fix(pawleyFn->parameterIndex("f0.ZeroShift")); + + IAlgorithm_sptr fit = AlgorithmManager::Instance().create("Fit"); + fit->setProperty("Function", + boost::dynamic_pointer_cast<IFunction>(pawleyFn)); + fit->setProperty("InputWorkspace", ws); + fit->execute(); + + PawleyParameterFunction_sptr parameters = + pawleyFn->getPawleyParameterFunction(); + + TS_ASSERT_DELTA(parameters->getParameter("a"), 5.4311946, 1e-6); + } + + void testFunctionFitSiZeroShift() { + /* This example generates a spectrum with the first three reflections + * of Silicon with lattice parameter a = 5.4311946 Angstr. + * hkl d height ca. fwhm + * 1 1 1 3.13570 40.0 0.006 + * 2 2 0 1.92022 110.0 0.004 + * 3 1 1 1.63757 101.0 0.003 + */ + auto ws = getWorkspace( + "name=Gaussian,PeakCentre=3.13870166,Height=40.0,Sigma=0.003;name=" + "Gaussian,PeakCentre=1.92321727,Height=110.0,Sigma=0.002;name=Gaussian," + "PeakCentre=1.6405667,Height=105.0,Sigma=0.0016", + 1.6, 3.2, 800); + + PawleyFunction_sptr pawleyFn = boost::make_shared<PawleyFunction>(); + pawleyFn->initialize(); + pawleyFn->setCrystalSystem("Cubic"); + pawleyFn->addPeak(V3D(1, 1, 1), 0.0065, 35.0); + pawleyFn->addPeak(V3D(2, 2, 0), 0.0045, 115.0); + pawleyFn->addPeak(V3D(3, 1, 1), 0.0035, 115.0); + pawleyFn->setUnitCell("5.433 5.433 5.433"); + pawleyFn->setParameter("f0.ZeroShift", 0.001); + + IAlgorithm_sptr fit = AlgorithmManager::Instance().create("Fit"); + fit->setProperty("Function", + boost::dynamic_pointer_cast<IFunction>(pawleyFn)); + fit->setProperty("InputWorkspace", ws); + fit->execute(); + + PawleyParameterFunction_sptr parameters = + pawleyFn->getPawleyParameterFunction(); + + TS_ASSERT_DELTA(parameters->getParameter("a"), 5.4311946, 1e-5); + TS_ASSERT_DELTA(parameters->getParameter("ZeroShift"), 0.003, 1e-4); + } + +private: + MatrixWorkspace_sptr getWorkspace(const std::string &functionString, + double xMin, double xMax, size_t n) { + IFunction_sptr siFn = + FunctionFactory::Instance().createInitialized(functionString); + + auto ws = WorkspaceFactory::Instance().create("Workspace2D", 1, n, n); + + FunctionDomain1DVector xValues(xMin, xMax, n); + FunctionValues yValues(xValues); + std::vector<double> eValues(n, 1.0); + + siFn->function(xValues, yValues); + + std::vector<double> &xData = ws->dataX(0); + std::vector<double> &yData = ws->dataY(0); + std::vector<double> &eData = ws->dataE(0); + + for (size_t i = 0; i < n; ++i) { + xData[i] = xValues[i]; + yData[i] = yValues[i]; + eData[i] = eValues[i]; + } + + WorkspaceCreationHelper::addNoise(ws, 0, -0.1, 0.1); + + return ws; + } + + void cellParametersAre(const UnitCell &cell, double a, double b, double c, + double alpha, double beta, double gamma) { + TS_ASSERT_DELTA(cell.a(), a, 1e-9); + TS_ASSERT_DELTA(cell.b(), b, 1e-9); + TS_ASSERT_DELTA(cell.c(), c, 1e-9); + + TS_ASSERT_DELTA(cell.alpha(), alpha, 1e-9); + TS_ASSERT_DELTA(cell.beta(), beta, 1e-9); + TS_ASSERT_DELTA(cell.gamma(), gamma, 1e-9); + } +}; + +#endif /* MANTID_CURVEFITTING_PAWLEYFUNCTIONTEST_H_ */ diff --git a/Code/Mantid/Framework/CurveFitting/test/ProductFunctionTest.h b/Code/Mantid/Framework/CurveFitting/test/ProductFunctionTest.h index 3232dc248cbc82932e3ed07c8c3c5065a61dcd1d..22833a6a4bf158d9044885bdd06438cca8207db2 100644 --- a/Code/Mantid/Framework/CurveFitting/test/ProductFunctionTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/ProductFunctionTest.h @@ -121,8 +121,8 @@ public: }; -DECLARE_FUNCTION(ProductFunctionMWTest_Gauss); -DECLARE_FUNCTION(ProductFunctionMWTest_Linear); +DECLARE_FUNCTION(ProductFunctionMWTest_Gauss) +DECLARE_FUNCTION(ProductFunctionMWTest_Linear) class ProductFunctionTest : public CxxTest::TestSuite { diff --git a/Code/Mantid/Framework/CurveFitting/test/ResolutionTest.h b/Code/Mantid/Framework/CurveFitting/test/ResolutionTest.h index ea03a3aa012327a415cd0723ccea367063ee515e..e4df7ce1a5caaa6594be10b9c6575a082f272bc3 100644 --- a/Code/Mantid/Framework/CurveFitting/test/ResolutionTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/ResolutionTest.h @@ -99,7 +99,7 @@ public: } }; -DECLARE_FUNCTION(ResolutionTest_Gauss); +DECLARE_FUNCTION(ResolutionTest_Gauss) class ResolutionTest : public CxxTest::TestSuite { diff --git a/Code/Mantid/Framework/DataHandling/CMakeLists.txt b/Code/Mantid/Framework/DataHandling/CMakeLists.txt index f5fd052bfe041b80ef1d13676f1ade6293aa1aab..af53459069106a5d60fb422bba839acda00fc1a5 100644 --- a/Code/Mantid/Framework/DataHandling/CMakeLists.txt +++ b/Code/Mantid/Framework/DataHandling/CMakeLists.txt @@ -465,22 +465,9 @@ endif () # Add to the 'Framework' group in VS set_property ( TARGET DataHandling PROPERTY FOLDER "MantidFramework" ) -IF (${CMAKE_SYSTEM_NAME} MATCHES "Windows" OR OSX_VERSION VERSION_LESS 10.9) - SET (HDF5_DIR "${CMAKE_MODULE_PATH}") - find_package ( HDF5 COMPONENTS HL REQUIRED - CONFIGS hdf5-config.cmake ) -ELSE() - find_package ( HDF5 COMPONENTS HL REQUIRED ) -ENDIF() - -#message (STATUS "HDF5_INCLUDE_DIRS:" ${HDF5_INCLUDE_DIRS}) -#message (STATUS "HDF5_LIBRARIES:" ${HDF5_LIBRARIES}) - include_directories ( inc ../Nexus/inc ${HDF5_INCLUDE_DIRS}) -#include_directories ( inc ../Nexus/inc) target_link_libraries ( DataHandling ${MANTIDLIBS} Nexus ${NEXUS_LIBRARIES} ${HDF5_LIBRARIES}) -#target_link_libraries ( DataHandling ${MANTIDLIBS} Nexus) # Add the unit tests directory add_subdirectory ( test ) diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/ISISRunLogs.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/ISISRunLogs.h index f1e2f3064e395a835a5490d48a72bca983f1e9bc..a939a0aa63dc00541a5fa73cae18ce5c690e6a93 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/ISISRunLogs.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/ISISRunLogs.h @@ -54,7 +54,7 @@ public: void addPeriodLogs(const int period, API::Run &exptRun); private: - DISABLE_DEFAULT_CONSTRUCT(ISISRunLogs); + DISABLE_DEFAULT_CONSTRUCT(ISISRunLogs) /// A LogParser object boost::scoped_ptr<Kernel::LogParser> m_logParser; diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadISISNexus2.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadISISNexus2.h index 144387c539a9e2da30873bee5def332ee4e08e96..d36c8c4739622875c8e999bdaec1fe98471089bc 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadISISNexus2.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadISISNexus2.h @@ -159,7 +159,8 @@ private: Mantid::NeXus::NXEntry &entry); // Load a given period into the workspace void loadPeriodData(int64_t period, Mantid::NeXus::NXEntry &entry, - DataObjects::Workspace2D_sptr &local_workspace); + DataObjects::Workspace2D_sptr &local_workspace, + bool update_spectra2det_mapping=false); // Load a data block void loadBlock(Mantid::NeXus::NXDataSetTyped<int> &data, int64_t blocksize, int64_t period, int64_t start, int64_t &hist, diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h index e45648f676320b605ab93438ba85c60105516340..c734b5d9383ea97ffaa29d690be6d50204d186bf 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h @@ -117,6 +117,9 @@ private: /// Name of the instrument std::string m_instName; + + /// Mutex to avoid simultaneous access + static Poco::Mutex m_mutex; }; } // namespace DataHandling diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadSINQFocus.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadSINQFocus.h index caa363519fdd502a4e9086b6030fef20c2983876..10e6588a8a0d6397c58326f5faaca7896b630cbc 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadSINQFocus.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadSINQFocus.h @@ -77,7 +77,6 @@ private: std::vector<std::string> m_supportedInstruments; std::string m_instrumentName; std::string m_instrumentPath; - ; API::MatrixWorkspace_sptr m_localWorkspace; size_t m_numberOfTubes; // number of tubes - X size_t m_numberOfPixelsPerTube; // number of pixels per tube - Y diff --git a/Code/Mantid/Framework/DataHandling/src/CreateChopperModel.cpp b/Code/Mantid/Framework/DataHandling/src/CreateChopperModel.cpp index b3284c6ee7f134f89d6691611dd3bf7b2f5efca4..48274f1aa5f6cb83df567e3ac082d132a2b9a08d 100644 --- a/Code/Mantid/Framework/DataHandling/src/CreateChopperModel.cpp +++ b/Code/Mantid/Framework/DataHandling/src/CreateChopperModel.cpp @@ -7,7 +7,7 @@ namespace Mantid { namespace DataHandling { // Register the algorithm into the AlgorithmFactory -DECLARE_ALGORITHM(CreateChopperModel); +DECLARE_ALGORITHM(CreateChopperModel) using Kernel::Direction; using API::WorkspaceProperty; @@ -21,10 +21,10 @@ using Kernel::MandatoryValidator; /// Algorithm's name for identification. @see Algorithm::name const std::string CreateChopperModel::name() const { return "CreateChopperModel"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int CreateChopperModel::version() const { return 1; }; +int CreateChopperModel::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string CreateChopperModel::category() const { diff --git a/Code/Mantid/Framework/DataHandling/src/CreateChunkingFromInstrument.cpp b/Code/Mantid/Framework/DataHandling/src/CreateChunkingFromInstrument.cpp index d19f7f04c25ae52a1352913368899e0b478a630d..49ef716f071d41ff1d2f6e2e7f59f2814cfb4634 100644 --- a/Code/Mantid/Framework/DataHandling/src/CreateChunkingFromInstrument.cpp +++ b/Code/Mantid/Framework/DataHandling/src/CreateChunkingFromInstrument.cpp @@ -57,10 +57,10 @@ CreateChunkingFromInstrument::~CreateChunkingFromInstrument() {} /// Algorithm's name for identification. @see Algorithm::name const string CreateChunkingFromInstrument::name() const { return "CreateChunkingFromInstrument"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int CreateChunkingFromInstrument::version() const { return 1; }; +int CreateChunkingFromInstrument::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const string CreateChunkingFromInstrument::category() const { diff --git a/Code/Mantid/Framework/DataHandling/src/CreateModeratorModel.cpp b/Code/Mantid/Framework/DataHandling/src/CreateModeratorModel.cpp index a1f51bbddd71bdddd769112276e59dbb49c68262..d2008b1d47e5b5ed07d14a9153538feb51e8325b 100644 --- a/Code/Mantid/Framework/DataHandling/src/CreateModeratorModel.cpp +++ b/Code/Mantid/Framework/DataHandling/src/CreateModeratorModel.cpp @@ -19,10 +19,10 @@ DECLARE_ALGORITHM(CreateModeratorModel) /// Algorithm's name for identification. @see Algorithm::name const std::string CreateModeratorModel::name() const { return "CreateModeratorModel"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int CreateModeratorModel::version() const { return 1; }; +int CreateModeratorModel::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string CreateModeratorModel::category() const { diff --git a/Code/Mantid/Framework/DataHandling/src/CreateSimulationWorkspace.cpp b/Code/Mantid/Framework/DataHandling/src/CreateSimulationWorkspace.cpp index 3652a1d48ce00a2b86da4395e051fed90283be22..512b02efd72c4da9ddaca485502f26319f65a346 100644 --- a/Code/Mantid/Framework/DataHandling/src/CreateSimulationWorkspace.cpp +++ b/Code/Mantid/Framework/DataHandling/src/CreateSimulationWorkspace.cpp @@ -19,7 +19,7 @@ namespace Mantid { namespace DataHandling { // Register the algorithm into the AlgorithmFactory -DECLARE_ALGORITHM(CreateSimulationWorkspace); +DECLARE_ALGORITHM(CreateSimulationWorkspace) using namespace API; @@ -27,10 +27,10 @@ using namespace API; /// Algorithm's name for identification. @see Algorithm::name const std::string CreateSimulationWorkspace::name() const { return "CreateSimulationWorkspace"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int CreateSimulationWorkspace::version() const { return 1; }; +int CreateSimulationWorkspace::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string CreateSimulationWorkspace::category() const { diff --git a/Code/Mantid/Framework/DataHandling/src/DeleteTableRows.cpp b/Code/Mantid/Framework/DataHandling/src/DeleteTableRows.cpp index 84502532b0a1296f735499703d7f0b58b3f6e514..3a9b1c3bbb4c034c2bb6dff9d20d186847f51303 100644 --- a/Code/Mantid/Framework/DataHandling/src/DeleteTableRows.cpp +++ b/Code/Mantid/Framework/DataHandling/src/DeleteTableRows.cpp @@ -13,7 +13,7 @@ namespace Mantid { namespace DataHandling { // Register the algorithm into the algorithm factory -DECLARE_ALGORITHM(DeleteTableRows); +DECLARE_ALGORITHM(DeleteTableRows) using namespace Kernel; using namespace API; diff --git a/Code/Mantid/Framework/DataHandling/src/DownloadInstrument.cpp b/Code/Mantid/Framework/DataHandling/src/DownloadInstrument.cpp index 045818331a7eb791ecdb78026e61c278714b5cf7..b8688ae24b9853e727e69c9603c32b3130602e95 100644 --- a/Code/Mantid/Framework/DataHandling/src/DownloadInstrument.cpp +++ b/Code/Mantid/Framework/DataHandling/src/DownloadInstrument.cpp @@ -25,7 +25,7 @@ #endif // jsoncpp -#include <jsoncpp/json/json.h> +#include <json/json.h> // std #include <fstream> diff --git a/Code/Mantid/Framework/DataHandling/src/ExtractMonitorWorkspace.cpp b/Code/Mantid/Framework/DataHandling/src/ExtractMonitorWorkspace.cpp index ca9a49e80fee57370f31605bc292f4b96dfece88..3461ebea7d901c66b8f82f1bcf787994741e3235 100644 --- a/Code/Mantid/Framework/DataHandling/src/ExtractMonitorWorkspace.cpp +++ b/Code/Mantid/Framework/DataHandling/src/ExtractMonitorWorkspace.cpp @@ -15,10 +15,10 @@ ExtractMonitorWorkspace::~ExtractMonitorWorkspace() {} /// Algorithm's name for identification. @see Algorithm::name const std::string ExtractMonitorWorkspace::name() const { return "ExtractMonitorWorkspace"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int ExtractMonitorWorkspace::version() const { return 1; }; +int ExtractMonitorWorkspace::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string ExtractMonitorWorkspace::category() const { diff --git a/Code/Mantid/Framework/DataHandling/src/FindDetectorsPar.cpp b/Code/Mantid/Framework/DataHandling/src/FindDetectorsPar.cpp index a0babedbc04b5f05580597ad4943add6a36f7a30..0a01cab4a09f1f9fdf716f31e76586986ea91fe4 100644 --- a/Code/Mantid/Framework/DataHandling/src/FindDetectorsPar.cpp +++ b/Code/Mantid/Framework/DataHandling/src/FindDetectorsPar.cpp @@ -23,8 +23,8 @@ DECLARE_ALGORITHM(FindDetectorsPar) using namespace Kernel; using namespace API; // nothing here according to mantid -FindDetectorsPar::FindDetectorsPar() : m_SizesAreLinear(false){}; -FindDetectorsPar::~FindDetectorsPar(){}; +FindDetectorsPar::FindDetectorsPar() : m_SizesAreLinear(false){} +FindDetectorsPar::~FindDetectorsPar(){} void FindDetectorsPar::init() { auto wsValidator = boost::make_shared<CompositeValidator>(); diff --git a/Code/Mantid/Framework/DataHandling/src/ISISDataArchive.cpp b/Code/Mantid/Framework/DataHandling/src/ISISDataArchive.cpp index df3faa501c68e359b2b64c085669c828c9bf5ea4..4e5f2d69d3f2470067cf3f65ccb48de9d4f37a9a 100644 --- a/Code/Mantid/Framework/DataHandling/src/ISISDataArchive.cpp +++ b/Code/Mantid/Framework/DataHandling/src/ISISDataArchive.cpp @@ -21,7 +21,7 @@ namespace { Kernel::Logger g_log("ISISDataArchive"); } -DECLARE_ARCHIVESEARCH(ISISDataArchive, ISISDataSearch); +DECLARE_ARCHIVESEARCH(ISISDataArchive, ISISDataSearch) namespace { #ifdef _WIN32 diff --git a/Code/Mantid/Framework/DataHandling/src/Load.cpp b/Code/Mantid/Framework/DataHandling/src/Load.cpp index 9ca1b7ac270d7571d3e15a73e6e64352a4a0b345..cc23bd0ae14bec92e59e082e6d165985802265c9 100644 --- a/Code/Mantid/Framework/DataHandling/src/Load.cpp +++ b/Code/Mantid/Framework/DataHandling/src/Load.cpp @@ -85,7 +85,7 @@ flattenVecOfVec(std::vector<std::vector<std::string>> vecOfVec) { namespace Mantid { namespace DataHandling { // Register the algorithm into the algorithm factory -DECLARE_ALGORITHM(Load); +DECLARE_ALGORITHM(Load) // The mutex Poco::Mutex Load::m_mutex; diff --git a/Code/Mantid/Framework/DataHandling/src/LoadAscii.cpp b/Code/Mantid/Framework/DataHandling/src/LoadAscii.cpp index 6beb06f3fbfbdb0a81e14e93ef91e3235d1dc322..747bd5422b98555db8ceb6e6bff37a5245f66abe 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadAscii.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadAscii.cpp @@ -18,7 +18,7 @@ namespace Mantid { namespace DataHandling { -DECLARE_FILELOADER_ALGORITHM(LoadAscii); +DECLARE_FILELOADER_ALGORITHM(LoadAscii) using namespace Kernel; using namespace API; diff --git a/Code/Mantid/Framework/DataHandling/src/LoadAscii2.cpp b/Code/Mantid/Framework/DataHandling/src/LoadAscii2.cpp index 37dc4a4e6436c5c696a87e04a93244f4c93cdfc9..3d603570fc4db2416cdf474ce3925954efeac76f 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadAscii2.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadAscii2.cpp @@ -19,7 +19,7 @@ namespace Mantid { namespace DataHandling { -DECLARE_FILELOADER_ALGORITHM(LoadAscii2); +DECLARE_FILELOADER_ALGORITHM(LoadAscii2) using namespace Kernel; using namespace API; diff --git a/Code/Mantid/Framework/DataHandling/src/LoadBBY.cpp b/Code/Mantid/Framework/DataHandling/src/LoadBBY.cpp index 6794b27e1190685a1b6840878c5a60703c3da7c9..daddef4a35dc07e9151e09bdd0a0f243f0064e5d 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadBBY.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadBBY.cpp @@ -14,7 +14,7 @@ namespace Mantid { namespace DataHandling { // register the algorithm into the AlgorithmFactory -DECLARE_FILELOADER_ALGORITHM(LoadBBY); +DECLARE_FILELOADER_ALGORITHM(LoadBBY) // consts static const size_t HISTO_BINS_X = 240; diff --git a/Code/Mantid/Framework/DataHandling/src/LoadCanSAS1D.cpp b/Code/Mantid/Framework/DataHandling/src/LoadCanSAS1D.cpp index 1d07a5bb7525094b53b2215b695abc560cc4a5b5..b30663623408975b408f1ecd0b98185a1efe5872 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadCanSAS1D.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadCanSAS1D.cpp @@ -35,7 +35,7 @@ using namespace Mantid::DataObjects; namespace Mantid { namespace DataHandling { -DECLARE_FILELOADER_ALGORITHM(LoadCanSAS1D); +DECLARE_FILELOADER_ALGORITHM(LoadCanSAS1D) /// constructor LoadCanSAS1D::LoadCanSAS1D() : m_groupNumber(0) {} diff --git a/Code/Mantid/Framework/DataHandling/src/LoadCanSAS1D2.cpp b/Code/Mantid/Framework/DataHandling/src/LoadCanSAS1D2.cpp index 7dff9888a52e2ca1eb62666d6b7ef981ed1b8b72..378569dbbbb06142d61ab97386d7ff39eb5f1535 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadCanSAS1D2.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadCanSAS1D2.cpp @@ -33,7 +33,7 @@ using namespace Mantid::DataObjects; namespace Mantid { namespace DataHandling { -DECLARE_FILELOADER_ALGORITHM(LoadCanSAS1D2); +DECLARE_FILELOADER_ALGORITHM(LoadCanSAS1D2) /// constructor LoadCanSAS1D2::LoadCanSAS1D2() : LoadCanSAS1D() {} diff --git a/Code/Mantid/Framework/DataHandling/src/LoadDaveGrp.cpp b/Code/Mantid/Framework/DataHandling/src/LoadDaveGrp.cpp index 8ceabc67d96453729b3d49fbe7d28f351879c6d2..45ddef1b6dcfb71749e2649ed8207bacd7b6f61b 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadDaveGrp.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadDaveGrp.cpp @@ -12,7 +12,7 @@ namespace Mantid { namespace DataHandling { -DECLARE_FILELOADER_ALGORITHM(LoadDaveGrp); +DECLARE_FILELOADER_ALGORITHM(LoadDaveGrp) LoadDaveGrp::LoadDaveGrp() : ifile(), line(), nGroups(0), xLength(0) {} diff --git a/Code/Mantid/Framework/DataHandling/src/LoadEventPreNexus.cpp b/Code/Mantid/Framework/DataHandling/src/LoadEventPreNexus.cpp index d8d0ab699c667f3896bb82767d5941d303cc1df8..6fa76790f67189be3c17020ca1887e08b5a8f060 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadEventPreNexus.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadEventPreNexus.cpp @@ -36,7 +36,7 @@ namespace Mantid { namespace DataHandling { -DECLARE_FILELOADER_ALGORITHM(LoadEventPreNexus); +DECLARE_FILELOADER_ALGORITHM(LoadEventPreNexus) using namespace Kernel; using namespace API; diff --git a/Code/Mantid/Framework/DataHandling/src/LoadFITS.cpp b/Code/Mantid/Framework/DataHandling/src/LoadFITS.cpp index 5d21f759abc30c40a8b8401cef8ff1b21774b5c5..c147984dc309b96d04e74125cca22c1dd1bf87b3 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadFITS.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadFITS.cpp @@ -38,7 +38,7 @@ bool IsNotFits(std::string s) { namespace Mantid { namespace DataHandling { // Register the algorithm into the AlgorithmFactory -DECLARE_FILELOADER_ALGORITHM(LoadFITS); +DECLARE_FILELOADER_ALGORITHM(LoadFITS) /** * Constructor. Just initialize everything to prevent issues. @@ -88,9 +88,11 @@ void LoadFITS::init() { "OutputWorkspace", "", Kernel::Direction::Output)); declareProperty( - new PropertyWithValue<int>("ImageKey", -1, Kernel::Direction::Input), + new PropertyWithValue<int>("ImageKey", 0, Kernel::Direction::Input), "Image type to set these files as. 0=data image, 1=flat field, 2=open " - "field, -1=use the value from FITS header."); + "field, -1=use the value from FITS header. At present, if this is not " + "specified and an IMAGEKEY entry is not found in the FITS header, the " + "loader will show an error message and stop."); declareProperty(new PropertyWithValue<string>(BIT_DEPTH_NAME, "BITPIX", Kernel::Direction::Input), diff --git a/Code/Mantid/Framework/DataHandling/src/LoadILL.cpp b/Code/Mantid/Framework/DataHandling/src/LoadILL.cpp index 783927212fdd755e45003d4f900e5f9c6476570e..0f84c252a6f86a32fa9d6b811cc2a0ead98442ae 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadILL.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadILL.cpp @@ -25,7 +25,7 @@ using namespace Kernel; using namespace API; using namespace NeXus; -DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadILL); +DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadILL) //--------------------------------------------------- // Private member functions diff --git a/Code/Mantid/Framework/DataHandling/src/LoadILLIndirect.cpp b/Code/Mantid/Framework/DataHandling/src/LoadILLIndirect.cpp index 8309a686e68a6f556286e52688cb3cb71d9aa791..37e810ffae287c8bf3b17a2708fc86ed08c746de 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadILLIndirect.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadILLIndirect.cpp @@ -18,7 +18,7 @@ using namespace API; using namespace NeXus; // Register the algorithm into the AlgorithmFactory -DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadILLIndirect); +DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadILLIndirect) //---------------------------------------------------------------------------------------------- /** Constructor @@ -37,10 +37,10 @@ LoadILLIndirect::~LoadILLIndirect() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string LoadILLIndirect::name() const { return "LoadILLIndirect"; }; +const std::string LoadILLIndirect::name() const { return "LoadILLIndirect"; } /// Algorithm's version for identification. @see Algorithm::version -int LoadILLIndirect::version() const { return 1; }; +int LoadILLIndirect::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string LoadILLIndirect::category() const { return "DataHandling"; } diff --git a/Code/Mantid/Framework/DataHandling/src/LoadILLReflectometry.cpp b/Code/Mantid/Framework/DataHandling/src/LoadILLReflectometry.cpp index 331795f61c3fe79a675b1563f68ea4b32ffb8160..739c5f9a6f6c5c4be0a09d7c26fbdb8fd658d810 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadILLReflectometry.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadILLReflectometry.cpp @@ -23,7 +23,7 @@ using namespace API; using namespace NeXus; // Register the algorithm into the AlgorithmFactory -DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadILLReflectometry); +DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadILLReflectometry) //---------------------------------------------------------------------------------------------- /** Constructor @@ -47,10 +47,10 @@ LoadILLReflectometry::~LoadILLReflectometry() {} /// Algorithm's name for identification. @see Algorithm::name const std::string LoadILLReflectometry::name() const { return "LoadILLReflectometry"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int LoadILLReflectometry::version() const { return 1; }; +int LoadILLReflectometry::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string LoadILLReflectometry::category() const { diff --git a/Code/Mantid/Framework/DataHandling/src/LoadILLSANS.cpp b/Code/Mantid/Framework/DataHandling/src/LoadILLSANS.cpp index 6c3b96b5807bb7166dcf8636eb81754336c117f9..b29c361ef19f901b4182ec410740afc2bd51270a 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadILLSANS.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadILLSANS.cpp @@ -30,10 +30,10 @@ LoadILLSANS::~LoadILLSANS() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string LoadILLSANS::name() const { return "LoadILLSANS"; }; +const std::string LoadILLSANS::name() const { return "LoadILLSANS"; } /// Algorithm's version for identification. @see Algorithm::version -int LoadILLSANS::version() const { return 1; }; +int LoadILLSANS::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string LoadILLSANS::category() const { return "DataHandling"; } diff --git a/Code/Mantid/Framework/DataHandling/src/LoadISISNexus2.cpp b/Code/Mantid/Framework/DataHandling/src/LoadISISNexus2.cpp index ca7d7a0dcf2b03cb260e4d541dec65f37bb800d2..fddfef1e1385a8439e317da6dff4302b0a858ae6 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadISISNexus2.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadISISNexus2.cpp @@ -9,7 +9,7 @@ #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/ConfigService.h" #include "MantidKernel/ListValidator.h" -#include "MantidKernel/LogParser.h" +//#include "MantidKernel/LogParser.h" #include "MantidKernel/LogFilter.h" #include "MantidKernel/TimeSeriesProperty.h" #include "MantidKernel/UnitFactory.h" @@ -38,7 +38,7 @@ namespace Mantid { namespace DataHandling { -DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadISISNexus2); +DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadISISNexus2) using namespace Kernel; using namespace API; @@ -232,8 +232,13 @@ void LoadISISNexus2::exec() { if (m_load_selected_spectra) m_spec2det_map = SpectrumDetectorMapping(spec(), udet(), udet.dim0()); else - local_workspace->updateSpectraUsing( + if (bseparateMonitors) { + m_spec2det_map = SpectrumDetectorMapping(spec(), udet(), udet.dim0()); + local_workspace->updateSpectraUsing(m_spec2det_map); + }else{ + local_workspace->updateSpectraUsing( SpectrumDetectorMapping(spec(), udet(), udet.dim0())); + } if (!foundInstrument) { runLoadInstrument(local_workspace); @@ -258,7 +263,7 @@ void LoadISISNexus2::exec() { m_tof_data.reset(new MantidVec(timeBins(), timeBins() + x_length)); } int64_t firstentry = (m_entrynumber > 0) ? m_entrynumber : 1; - loadPeriodData(firstentry, entry, local_workspace); + loadPeriodData(firstentry, entry, local_workspace,m_load_selected_spectra); // Clone the workspace at this point to provide a base object for future // workspace generation. @@ -284,7 +289,7 @@ void LoadISISNexus2::exec() { if (p > 1) { local_workspace = boost::dynamic_pointer_cast<DataObjects::Workspace2D>( WorkspaceFactory::Instance().create(period_free_workspace)); - loadPeriodData(p, entry, local_workspace); + loadPeriodData(p, entry, local_workspace,m_load_selected_spectra); createPeriodLogs(p, local_workspace); // Check consistency of logs data for multi-period workspaces and raise // warnings where necessary. @@ -345,7 +350,7 @@ void LoadISISNexus2::exec() { prepareSpectraBlocks(m_monitors, m_specInd2specNum_map, m_monBlockInfo); int64_t firstentry = (m_entrynumber > 0) ? m_entrynumber : 1; - loadPeriodData(firstentry, entry, monitor_workspace); + loadPeriodData(firstentry, entry, monitor_workspace,true); std::string monitorwsName = wsName + "_monitors"; declareProperty(new WorkspaceProperty<Workspace>( @@ -690,10 +695,13 @@ size_t LoadISISNexus2::prepareSpectraBlocks( * @param entry :: The opened root entry node for accessing the monitor and data * nodes * @param local_workspace :: The workspace to place the data in +* @param update_spectra_det_map :: reset spectra-detector map to the one +* calculated earlier. (Warning! -- this map has to be calculated correctly!) */ void LoadISISNexus2::loadPeriodData(int64_t period, NXEntry &entry, - DataObjects::Workspace2D_sptr &local_workspace) { + DataObjects::Workspace2D_sptr &local_workspace, + bool update_spectra2det_mapping) { int64_t hist_index = 0; int64_t period_index(period - 1); // int64_t first_monitor_spectrum = 0; @@ -710,7 +718,7 @@ LoadISISNexus2::loadPeriodData(int64_t period, NXEntry &entry, MantidVec &E = local_workspace->dataE(hist_index); std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt); - if (m_load_selected_spectra) { + if (update_spectra2det_mapping) { // local_workspace->getAxis(1)->setValue(hist_index, // static_cast<specid_t>(it->first)); auto spec = local_workspace->getSpectrum(hist_index); diff --git a/Code/Mantid/Framework/DataHandling/src/LoadInstrument.cpp b/Code/Mantid/Framework/DataHandling/src/LoadInstrument.cpp index 943e218a753f8b9c21de497249fdb71b548ed59f..673586cdad50c2699162bff71e1b55b66b14f010 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadInstrument.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadInstrument.cpp @@ -51,6 +51,8 @@ using namespace Kernel; using namespace API; using namespace Geometry; +Poco::Mutex LoadInstrument::m_mutex; + /// Empty default constructor LoadInstrument::LoadInstrument() : Algorithm() {} @@ -171,19 +173,23 @@ void LoadInstrument::exec() { Instrument_sptr instrument; // Check whether the instrument is already in the InstrumentDataService - if (InstrumentDataService::Instance().doesExist(instrumentNameMangled)) { - // If it does, just use the one from the one stored there - instrument = + { + // Make InstrumentService access thread-safe + Poco::Mutex::ScopedLock lock(m_mutex); + + if (InstrumentDataService::Instance().doesExist(instrumentNameMangled)) { + // If it does, just use the one from the one stored there + instrument = InstrumentDataService::Instance().retrieve(instrumentNameMangled); - } else { - // Really create the instrument - Progress *prog = new Progress(this, 0, 1, 100); - instrument = parser.parseXML(prog); - delete prog; - // Add to data service for later retrieval - InstrumentDataService::Instance().add(instrumentNameMangled, instrument); + } else { + // Really create the instrument + Progress *prog = new Progress(this, 0, 1, 100); + instrument = parser.parseXML(prog); + delete prog; + // Add to data service for later retrieval + InstrumentDataService::Instance().add(instrumentNameMangled, instrument); + } } - // Add the instrument to the workspace m_workspace->setInstrument(instrument); diff --git a/Code/Mantid/Framework/DataHandling/src/LoadLLB.cpp b/Code/Mantid/Framework/DataHandling/src/LoadLLB.cpp index b6fa8df3d966a372fa19105b3ac5be23ab3fc22f..ab280168840e54b2927a14a617903fb082e70f6b 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadLLB.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadLLB.cpp @@ -18,7 +18,7 @@ using namespace Kernel; using namespace API; using namespace NeXus; -DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadLLB); +DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadLLB) //---------------------------------------------------------------------------------------------- /** Constructor @@ -36,10 +36,10 @@ LoadLLB::~LoadLLB() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string LoadLLB::name() const { return "LoadLLB"; }; +const std::string LoadLLB::name() const { return "LoadLLB"; } /// Algorithm's version for identification. @see Algorithm::version -int LoadLLB::version() const { return 1; }; +int LoadLLB::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string LoadLLB::category() const { return "DataHandling"; } diff --git a/Code/Mantid/Framework/DataHandling/src/LoadMask.cpp b/Code/Mantid/Framework/DataHandling/src/LoadMask.cpp index 18b3017942cc2b38e8ce15cb4a32bfe2d5cfb882..732ae455b6e9376f954467a78038655a23d2d09b 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadMask.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadMask.cpp @@ -833,8 +833,9 @@ void LoadMask::parseISISStringToVector(string ins, /** Initialize the Mask Workspace with instrument */ void LoadMask::intializeMaskWorkspace() { + const bool ignoreDirs(true); const std::string idfPath = - API::FileFinder::Instance().getFullPath(m_instrumentPropValue); + API::FileFinder::Instance().getFullPath(m_instrumentPropValue, ignoreDirs); MatrixWorkspace_sptr tempWs(new DataObjects::Workspace2D()); diff --git a/Code/Mantid/Framework/DataHandling/src/LoadMcStas.cpp b/Code/Mantid/Framework/DataHandling/src/LoadMcStas.cpp index 027c60f08be6c6407a67e6500e53ee7846a15fe8..26c18005d8804a3aaa9ca2e9827f32ed5f407d01 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadMcStas.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadMcStas.cpp @@ -24,7 +24,7 @@ using namespace API; using namespace DataObjects; // Register the algorithm into the AlgorithmFactory -DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadMcStas); +DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadMcStas) //---------------------------------------------------------------------------------------------- /** Constructor @@ -38,10 +38,10 @@ LoadMcStas::~LoadMcStas() {} //---------------------------------------------------------------------------------------------- // Algorithm's name for identification. @see Algorithm::name -const std::string LoadMcStas::name() const { return "LoadMcStas"; }; +const std::string LoadMcStas::name() const { return "LoadMcStas"; } // Algorithm's version for identification. @see Algorithm::version -int LoadMcStas::version() const { return 1; }; +int LoadMcStas::version() const { return 1; } // Algorithm's category for identification. @see Algorithm::category const std::string LoadMcStas::category() const { return "DataHandling"; } diff --git a/Code/Mantid/Framework/DataHandling/src/LoadMcStasNexus.cpp b/Code/Mantid/Framework/DataHandling/src/LoadMcStasNexus.cpp index ca5c88515d928b1c537a884f6a825e2336bab7f5..b9d6986d76df11859f2e33e73ec4d7494efd176e 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadMcStasNexus.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadMcStasNexus.cpp @@ -15,7 +15,7 @@ namespace DataHandling { using namespace Kernel; using namespace API; -DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadMcStasNexus); +DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadMcStasNexus) //---------------------------------------------------------------------------------------------- /** Constructor @@ -29,10 +29,10 @@ LoadMcStasNexus::~LoadMcStasNexus() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string LoadMcStasNexus::name() const { return "LoadMcStasNexus"; }; +const std::string LoadMcStasNexus::name() const { return "LoadMcStasNexus"; } /// Algorithm's version for identification. @see Algorithm::version -int LoadMcStasNexus::version() const { return 1; }; +int LoadMcStasNexus::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string LoadMcStasNexus::category() const { return "DataHandling"; } diff --git a/Code/Mantid/Framework/DataHandling/src/LoadMuonLog.cpp b/Code/Mantid/Framework/DataHandling/src/LoadMuonLog.cpp index efcf09a27060b771c23abcb77184648573264f74..2cb1e7f47756176348b6fd98e5107b997e181eee 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadMuonLog.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadMuonLog.cpp @@ -6,7 +6,7 @@ #include "MantidKernel/TimeSeriesProperty.h" #include "MantidAPI/FileProperty.h" #include "MantidDataObjects/Workspace2D.h" -#include "MantidKernel/LogParser.h" +//#include "MantidKernel/LogParser.h" #include <ctime> diff --git a/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus1.cpp b/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus1.cpp index 7a71f4f24f5df76c8a8dfbd31f1d5eadc5ad1ffb..6f59be7278a4eb1fd693a87b332f46917f7f4928 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus1.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus1.cpp @@ -30,7 +30,7 @@ namespace DataHandling { using namespace DataObjects; // Register the algorithm into the algorithm factory -DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadMuonNexus1); +DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadMuonNexus1) using namespace Kernel; using namespace API; diff --git a/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus2.cpp b/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus2.cpp index d3876404a28394f0a79fc3a964d3ee0197813194..a885a97ada66770bf67dbc0881379dc97c852705 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus2.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus2.cpp @@ -27,7 +27,7 @@ namespace Mantid { namespace DataHandling { // Register the algorithm into the algorithm factory -DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadMuonNexus2); +DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadMuonNexus2) using namespace Kernel; using namespace API; diff --git a/Code/Mantid/Framework/DataHandling/src/LoadNXSPE.cpp b/Code/Mantid/Framework/DataHandling/src/LoadNXSPE.cpp index 5c5b4dc64163caa882dcd0a28b5588ce04f826f5..e9da8a302a8cd51cff2db16d893e394deaa811ab 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadNXSPE.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadNXSPE.cpp @@ -22,7 +22,7 @@ namespace Mantid { namespace DataHandling { -DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadNXSPE); +DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadNXSPE) using namespace Mantid::Kernel; using namespace Mantid::API; diff --git a/Code/Mantid/Framework/DataHandling/src/LoadNexusLogs.cpp b/Code/Mantid/Framework/DataHandling/src/LoadNexusLogs.cpp index ebbde7d28c0d39da3eff9fc7892d63c914965f0b..a2c2054368e659b6331ef4d876899e07f280c1eb 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadNexusLogs.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadNexusLogs.cpp @@ -4,7 +4,7 @@ #include "MantidDataHandling/LoadNexusLogs.h" #include <nexus/NeXusException.hpp> #include "MantidKernel/TimeSeriesProperty.h" -#include "MantidKernel/LogParser.h" +//#include "MantidKernel/LogParser.h" #include "MantidAPI/FileProperty.h" #include <cctype> diff --git a/Code/Mantid/Framework/DataHandling/src/LoadNexusProcessed.cpp b/Code/Mantid/Framework/DataHandling/src/LoadNexusProcessed.cpp index 8eca6314f4b8fc7b1a5b7ca47f970f23723098fc..21f97ef9eb2d0d4bc86556be5dc5fac2a3854825 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadNexusProcessed.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadNexusProcessed.cpp @@ -37,11 +37,13 @@ #include "MantidDataObjects/PeakShapeSphericalFactory.h" #include "MantidDataObjects/PeakShapeEllipsoidFactory.h" +#include <nexus/NeXusException.hpp> + namespace Mantid { namespace DataHandling { // Register the algorithm into the algorithm factory -DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadNexusProcessed); +DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadNexusProcessed) using namespace Mantid::NeXus; using namespace DataObjects; @@ -714,7 +716,8 @@ LoadNexusProcessed::loadEventEntry(NXData &wksp_cls, NXDouble &xbins, boost::shared_array<int64_t> indices = indices_data.sharedBuffer(); // Create all the event lists PARALLEL_FOR_NO_WSP_CHECK() - for (int64_t j = 0; j < static_cast<int64_t>(m_filtered_spec_idxs.size()); j++) { + for (int64_t j = 0; j < static_cast<int64_t>(m_filtered_spec_idxs.size()); + j++) { PARALLEL_START_INTERUPT_REGION size_t wi = m_filtered_spec_idxs[j] - 1; int64_t index_start = indices[wi]; @@ -754,8 +757,8 @@ LoadNexusProcessed::loadEventEntry(NXData &wksp_cls, NXDouble &xbins, } } - progress(progressStart + progressRange * - (1.0 / static_cast<double>(numspec))); + progress(progressStart + + progressRange * (1.0 / static_cast<double>(numspec))); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION @@ -1005,8 +1008,8 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) { // Get information from all but data group std::string parameterStr; - // Hop to the right point - m_cppFile->openPath(entry.path()); + // Hop to the right point /mantid_workspace_1 + m_cppFile->openPath(entry.path()); // This is try { // This loads logs, sample, and instrument. peakWS->loadExperimentInfoNexus(m_cppFile, parameterStr); @@ -1015,7 +1018,30 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) { g_log.information(e.what()); } - // std::vector<API::IPeak*> p; + // Coordinates - Older versions did not have the separate field but used a log + // value + uint32_t loadCoord(0); + m_cppFile->openGroup("peaks_workspace", "NXentry"); + try { + m_cppFile->readData("coordinate_system", loadCoord); + peakWS->setCoordinateSystem( + static_cast<Kernel::SpecialCoordinateSystem>(loadCoord)); + } catch (::NeXus::Exception &) { + // Check for a log value + auto logs = peakWS->logs(); + if (logs->hasProperty("CoordinateSystem")) { + auto *prop = dynamic_cast<PropertyWithValue<int> *>( + logs->getProperty("CoordinateSystem")); + if (prop) { + int value((*prop)()); + peakWS->setCoordinateSystem( + static_cast<Kernel::SpecialCoordinateSystem>(value)); + } + } + } + // peaks_workspace + m_cppFile->closeGroup(); + for (int r = 0; r < numberPeaks; r++) { Kernel::V3D v3d; v3d[2] = 1.0; @@ -1137,9 +1163,12 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) { // Read shape information using namespace Mantid::DataObjects; - PeakShapeFactory_sptr peakFactoryEllipsoid = boost::make_shared<PeakShapeEllipsoidFactory>(); - PeakShapeFactory_sptr peakFactorySphere = boost::make_shared<PeakShapeSphericalFactory>(); - PeakShapeFactory_sptr peakFactoryNone = boost::make_shared<PeakNoShapeFactory>(); + PeakShapeFactory_sptr peakFactoryEllipsoid = + boost::make_shared<PeakShapeEllipsoidFactory>(); + PeakShapeFactory_sptr peakFactorySphere = + boost::make_shared<PeakShapeSphericalFactory>(); + PeakShapeFactory_sptr peakFactoryNone = + boost::make_shared<PeakNoShapeFactory>(); peakFactoryEllipsoid->setSuccessor(peakFactorySphere); peakFactorySphere->setSuccessor(peakFactoryNone); @@ -1157,16 +1186,16 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) { boost::trim_right(shapeJSON); // Make the shape - Mantid::Geometry::PeakShape* peakShape = peakFactoryEllipsoid->create(shapeJSON); + Mantid::Geometry::PeakShape *peakShape = + peakFactoryEllipsoid->create(shapeJSON); // Set the shape peakWS->getPeak(i).setPeakShape(peakShape); - } } } -return boost::static_pointer_cast<API::Workspace>(peakWS); + return boost::static_pointer_cast<API::Workspace>(peakWS); } //------------------------------------------------------------------------------------------------- @@ -1179,18 +1208,15 @@ return boost::static_pointer_cast<API::Workspace>(peakWS); * @param progressRange progress made after loading an entry * @param mtd_entry Nexus entry for "mantid_workspace_..." * @param xlength bins in the "X" axis (xbins) - * @param workspaceType Takes values like "Workspace2D", "RebinnedOutput", etc. + * @param workspaceType Takes values like "Workspace2D", "RebinnedOutput", + *etc. * * @return workspace object containing loaded data */ -API::MatrixWorkspace_sptr -LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls, - NXDouble &xbins, - const double &progressStart, - const double &progressRange, - const NXEntry &mtd_entry, - const int xlength, - std::string &workspaceType) { +API::MatrixWorkspace_sptr LoadNexusProcessed::loadNonEventEntry( + NXData &wksp_cls, NXDouble &xbins, const double &progressStart, + const double &progressRange, const NXEntry &mtd_entry, const int xlength, + std::string &workspaceType) { // Filter the list of spectra to process, applying min/max/list options NXDataSetTyped<double> data = wksp_cls.openDoubleData(); int64_t nchannels = data.dim1(); @@ -1212,8 +1238,8 @@ LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls, API::MatrixWorkspace_sptr local_workspace = boost::dynamic_pointer_cast<API::MatrixWorkspace>( - WorkspaceFactory::Instance().create(workspaceType, total_specs, xlength, - nchannels)); + WorkspaceFactory::Instance().create(workspaceType, total_specs, + xlength, nchannels)); try { local_workspace->setTitle(mtd_entry.getString("title")); } catch (std::runtime_error &) { @@ -1264,16 +1290,16 @@ LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls, for (; hist_index < read_stop;) { progress(progressBegin + - progressScaler * static_cast<double>(hist_index) / - static_cast<double>(read_stop), + progressScaler * static_cast<double>(hist_index) / + static_cast<double>(read_stop), "Reading workspace data..."); loadBlock(data, errors, fracarea, hasFracArea, blocksize, nchannels, hist_index, wsIndex, local_workspace); } int64_t finalblock = m_spec_max - 1 - read_stop; if (finalblock > 0) { - loadBlock(data, errors, fracarea, hasFracArea, finalblock, - nchannels, hist_index, wsIndex, local_workspace); + loadBlock(data, errors, fracarea, hasFracArea, finalblock, nchannels, + hist_index, wsIndex, local_workspace); } } // if spectrum list property is set read each spectrum separately by @@ -1283,8 +1309,8 @@ LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls, for (; itr != m_spec_list.end(); ++itr) { int64_t specIndex = (*itr) - 1; progress(progressBegin + - progressScaler * static_cast<double>(specIndex) / - static_cast<double>(m_spec_list.size()), + progressScaler * static_cast<double>(specIndex) / + static_cast<double>(m_spec_list.size()), "Reading workspace data..."); loadBlock(data, errors, fracarea, hasFracArea, static_cast<int64_t>(1), nchannels, specIndex, wsIndex, @@ -1294,8 +1320,8 @@ LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls, } else { for (; hist_index < read_stop;) { progress(progressBegin + - progressScaler * static_cast<double>(hist_index) / - static_cast<double>(read_stop), + progressScaler * static_cast<double>(hist_index) / + static_cast<double>(read_stop), "Reading workspace data..."); loadBlock(data, errors, fracarea, hasFracArea, blocksize, nchannels, hist_index, wsIndex, local_workspace); @@ -1322,8 +1348,8 @@ LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls, for (; hist_index < read_stop;) { progress(progressBegin + - progressScaler * static_cast<double>(hist_index) / - static_cast<double>(read_stop), + progressScaler * static_cast<double>(hist_index) / + static_cast<double>(read_stop), "Reading workspace data..."); loadBlock(data, errors, fracarea, hasFracArea, xbins, blocksize, nchannels, hist_index, wsIndex, local_workspace); @@ -1340,8 +1366,8 @@ LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls, for (; itr != m_spec_list.end(); ++itr) { int64_t specIndex = (*itr) - 1; progress(progressBegin + - progressScaler * static_cast<double>(specIndex) / - static_cast<double>(read_stop), + progressScaler * static_cast<double>(specIndex) / + static_cast<double>(read_stop), "Reading workspace data..."); loadBlock(data, errors, fracarea, hasFracArea, xbins, 1, nchannels, specIndex, wsIndex, local_workspace); @@ -1350,8 +1376,8 @@ LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls, } else { for (; hist_index < read_stop;) { progress(progressBegin + - progressScaler * static_cast<double>(hist_index) / - static_cast<double>(read_stop), + progressScaler * static_cast<double>(hist_index) / + static_cast<double>(read_stop), "Reading workspace data..."); loadBlock(data, errors, fracarea, hasFracArea, xbins, blocksize, nchannels, hist_index, wsIndex, local_workspace); @@ -1372,7 +1398,8 @@ LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls, * * @param root :: The opened root node * @param entry_name :: The entry name - * @param progressStart :: The percentage value to start the progress reporting + * @param progressStart :: The percentage value to start the progress + *reporting * for this entry * @param progressRange :: The percentage range that the progress reporting * should cover @@ -1457,7 +1484,8 @@ API::Workspace_sptr LoadNexusProcessed::loadEntry(NXRoot &root, label->setLabel(ax.attributes("caption"), ax.attributes("label")); } - // If this doesn't throw then it is a numeric access so grab the data so we + // If this doesn't throw then it is a numeric access so grab the data so + // we // can set it later axis2.load(); if (static_cast<size_t>(axis2.size()) == nspectra + 1) @@ -1593,7 +1621,8 @@ void LoadNexusProcessed::readInstrumentGroup( //------------------------------------------------------------------------------------------------- /** - * Loads the information contained in non-Spectra (ie, Text or Numeric) axis in + * Loads the information contained in non-Spectra (ie, Text or Numeric) axis + * in * the Nexus * file into the workspace. * @param local_workspace :: pointer to workspace object @@ -1713,7 +1742,8 @@ void LoadNexusProcessed::getWordsInString(const std::string &words4, //------------------------------------------------------------------------------------------------- /** - * Read the bin masking information from the mantid_workspace_i/workspace group. + * Read the bin masking information from the mantid_workspace_i/workspace + * group. * @param wksp_cls :: The data group * @param local_workspace :: The workspace to read into */ @@ -1742,7 +1772,8 @@ LoadNexusProcessed::readBinMasking(NXData &wksp_cls, } /** - * Perform a call to nxgetslab, via the NexusClasses wrapped methods for a given + * Perform a call to nxgetslab, via the NexusClasses wrapped methods for a + * given * blocksize. This assumes that the * xbins have alread been cached * @param data :: The NXDataSet object of y values @@ -1797,7 +1828,8 @@ void LoadNexusProcessed::loadBlock(NXDataSetTyped<double> &data, } /** - * Perform a call to nxgetslab, via the NexusClasses wrapped methods for a given + * Perform a call to nxgetslab, via the NexusClasses wrapped methods for a + * given * blocksize. This assumes that the * xbins have alread been cached * @param data :: The NXDataSet object of y values @@ -1855,7 +1887,8 @@ void LoadNexusProcessed::loadBlock(NXDataSetTyped<double> &data, } /** - * Perform a call to nxgetslab, via the NexusClasses wrapped methods for a given + * Perform a call to nxgetslab, via the NexusClasses wrapped methods for a + * given * blocksize. The xbins are read along with * each call to the data/error loading * @param data :: The NXDataSet object of y values @@ -1993,7 +2026,7 @@ LoadNexusProcessed::calculateWorkspaceSize(const std::size_t numberofspectra, if (gen_filtered_list) { m_filtered_spec_idxs.resize(total_specs); size_t j = 0; - for(int64_t si = m_spec_min; si < m_spec_max; si++, j++) + for (int64_t si = m_spec_min; si < m_spec_max; si++, j++) m_filtered_spec_idxs[j] = si; } } else { @@ -2018,8 +2051,7 @@ LoadNexusProcessed::calculateWorkspaceSize(const std::size_t numberofspectra, // example: min: 2, max: 8, list: 3,4,5,10,12; // result: 2,3,...,7,8,10,12 m_filtered_spec_idxs.insert(m_filtered_spec_idxs.end(), - m_spec_list.begin(), - m_spec_list.end()); + m_spec_list.begin(), m_spec_list.end()); } } } else { @@ -2029,8 +2061,8 @@ LoadNexusProcessed::calculateWorkspaceSize(const std::size_t numberofspectra, if (gen_filtered_list) { m_filtered_spec_idxs.resize(total_specs, 0); - for(int64_t j = 0; j < total_specs; j++) - m_filtered_spec_idxs[j] = m_spec_min+j; + for (int64_t j = 0; j < total_specs; j++) + m_filtered_spec_idxs[j] = m_spec_min + j; } } return total_specs; diff --git a/Code/Mantid/Framework/DataHandling/src/LoadPDFgetNFile.cpp b/Code/Mantid/Framework/DataHandling/src/LoadPDFgetNFile.cpp index a0f89f59619488f5f3e3186367ac5c82da474eb8..108723a73f579972fed3aeb289ce79a5753dd7d4 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadPDFgetNFile.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadPDFgetNFile.cpp @@ -25,7 +25,7 @@ using namespace boost; namespace Mantid { namespace DataHandling { -DECLARE_FILELOADER_ALGORITHM(LoadPDFgetNFile); +DECLARE_FILELOADER_ALGORITHM(LoadPDFgetNFile) //---------------------------------------------------------------------------------------------- /** Constructor diff --git a/Code/Mantid/Framework/DataHandling/src/LoadPreNexus.cpp b/Code/Mantid/Framework/DataHandling/src/LoadPreNexus.cpp index 55090665c0930d3ac885075a750738830b38dfa2..4d076651853278122196019d7cbb5de86ae9240f 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadPreNexus.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadPreNexus.cpp @@ -31,7 +31,7 @@ using std::vector; namespace Mantid { namespace DataHandling { -DECLARE_FILELOADER_ALGORITHM(LoadPreNexus); +DECLARE_FILELOADER_ALGORITHM(LoadPreNexus) static const string RUNINFO_PARAM("Filename"); static const string MAP_PARAM("MappingFilename"); diff --git a/Code/Mantid/Framework/DataHandling/src/LoadQKK.cpp b/Code/Mantid/Framework/DataHandling/src/LoadQKK.cpp index cee4c47b1cd1dea67a6f5fd9594f977a03f9612c..859b592c087dcf441b7443d5963c1562b2e607eb 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadQKK.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadQKK.cpp @@ -26,7 +26,7 @@ namespace Mantid { namespace DataHandling { // Register the algorithm into the AlgorithmFactory -DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadQKK); +DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadQKK) /** * Return the confidence with with this algorithm can load the file diff --git a/Code/Mantid/Framework/DataHandling/src/LoadRKH.cpp b/Code/Mantid/Framework/DataHandling/src/LoadRKH.cpp index 453b4745c08fc3adfb78aff3e999ce7f0dc4b953..6ee8786c72d63f3509a54a30fa83296af7899a76 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadRKH.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadRKH.cpp @@ -24,7 +24,7 @@ namespace DataHandling { using namespace Mantid::API; using namespace Mantid::Kernel; -DECLARE_FILELOADER_ALGORITHM(LoadRKH); +DECLARE_FILELOADER_ALGORITHM(LoadRKH) /** * Return the confidence with with this algorithm can load the file diff --git a/Code/Mantid/Framework/DataHandling/src/LoadRaw3.cpp b/Code/Mantid/Framework/DataHandling/src/LoadRaw3.cpp index 421add0dc04143d32b98b07b8237e4a230b200cc..9d95242111e22c35c71091919e346fafd473602f 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadRaw3.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadRaw3.cpp @@ -24,7 +24,7 @@ namespace Mantid { namespace DataHandling { -DECLARE_FILELOADER_ALGORITHM(LoadRaw3); +DECLARE_FILELOADER_ALGORITHM(LoadRaw3) using namespace Kernel; using namespace API; diff --git a/Code/Mantid/Framework/DataHandling/src/LoadRawHelper.cpp b/Code/Mantid/Framework/DataHandling/src/LoadRawHelper.cpp index 7be90aaaf9eb15686295b9bdf3c5ae1dbf2aea5b..cd4c235958d145013d2f5b550cb8832fe327a62c 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadRawHelper.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadRawHelper.cpp @@ -1197,13 +1197,15 @@ LoadRawHelper::searchForLogFiles(const std::string &pathToRawFile) { try { Kernel::Glob::glob(Poco::Path(dir).resolve(pattern), potentialLogFiles); - // push potential log files from set to list. - potentialLogFilesList.insert(potentialLogFilesList.begin(), - potentialLogFiles.begin(), - potentialLogFiles.end()); } catch (std::exception &) { } } + + // push potential log files from set to list. + potentialLogFilesList.insert(potentialLogFilesList.begin(), + potentialLogFiles.begin(), + potentialLogFiles.end()); + // Remove extension from path, and append .log to path. std::string logName = pathToRawFile.substr(0, pathToRawFile.rfind('.')) + ".log"; diff --git a/Code/Mantid/Framework/DataHandling/src/LoadReflTBL.cpp b/Code/Mantid/Framework/DataHandling/src/LoadReflTBL.cpp index bdbd87357b8329efe248b47f720674b8234587ed..31c713233a6be537bc695a59af78761ed44075fe 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadReflTBL.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadReflTBL.cpp @@ -15,7 +15,7 @@ namespace Mantid { namespace DataHandling { -DECLARE_FILELOADER_ALGORITHM(LoadReflTBL); +DECLARE_FILELOADER_ALGORITHM(LoadReflTBL) using namespace Kernel; using namespace API; diff --git a/Code/Mantid/Framework/DataHandling/src/LoadSINQFocus.cpp b/Code/Mantid/Framework/DataHandling/src/LoadSINQFocus.cpp index 482729016aae5107ef241005e219e519c729358f..c06cdf04b68cb7a759f28ce0a0b1715c163c50a7 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadSINQFocus.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadSINQFocus.cpp @@ -18,7 +18,7 @@ using namespace Kernel; using namespace API; using namespace NeXus; -DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadSINQFocus); +DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadSINQFocus) //---------------------------------------------------------------------------------------------- /** Constructor @@ -38,10 +38,10 @@ LoadSINQFocus::~LoadSINQFocus() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string LoadSINQFocus::name() const { return "LoadSINQFocus"; }; +const std::string LoadSINQFocus::name() const { return "LoadSINQFocus"; } /// Algorithm's version for identification. @see Algorithm::version -int LoadSINQFocus::version() const { return 1; }; +int LoadSINQFocus::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string LoadSINQFocus::category() const { return "DataHandling"; } diff --git a/Code/Mantid/Framework/DataHandling/src/LoadSNSspec.cpp b/Code/Mantid/Framework/DataHandling/src/LoadSNSspec.cpp index a1c3ffd90e60f0da5cecb6d24462fcff7c2773e8..bbef0ccaf558350d2b7719dfe85b8670f73defa5 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadSNSspec.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadSNSspec.cpp @@ -13,7 +13,7 @@ namespace Mantid { namespace DataHandling { -DECLARE_FILELOADER_ALGORITHM(LoadSNSspec); +DECLARE_FILELOADER_ALGORITHM(LoadSNSspec) /** * Return the confidence with with this algorithm can load the file diff --git a/Code/Mantid/Framework/DataHandling/src/LoadSPE.cpp b/Code/Mantid/Framework/DataHandling/src/LoadSPE.cpp index 25e3b4c72b7904abe9aa591beaebaa8af88ac3df..004b48b0a2b14b393b2d511b3f405a4d221ebf2f 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadSPE.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadSPE.cpp @@ -18,7 +18,7 @@ namespace DataHandling { using namespace Kernel; using namespace API; -DECLARE_FILELOADER_ALGORITHM(LoadSPE); +DECLARE_FILELOADER_ALGORITHM(LoadSPE) /** * Return the confidence with with this algorithm can load the file diff --git a/Code/Mantid/Framework/DataHandling/src/LoadSassena.cpp b/Code/Mantid/Framework/DataHandling/src/LoadSassena.cpp index e1f23f9bd4b95665aaf40e0e5793babd69ffbebe..2f749d8a0784a85acbf2d1bd419044ba6cf13a20 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadSassena.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadSassena.cpp @@ -15,7 +15,7 @@ namespace Mantid { namespace DataHandling { -DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadSassena); +DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadSassena) /** * Return the confidence with with this algorithm can load the file diff --git a/Code/Mantid/Framework/DataHandling/src/LoadSavuTomoConfig.cpp b/Code/Mantid/Framework/DataHandling/src/LoadSavuTomoConfig.cpp index 172ca4b47c5b4a373244e945e0630b1477410e2e..50184d1d4eabd559a6f52a27ec9367de916e7ce9 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadSavuTomoConfig.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadSavuTomoConfig.cpp @@ -12,7 +12,7 @@ namespace Mantid { namespace DataHandling { // Register the algorithm into the algorithm factory -DECLARE_ALGORITHM(LoadSavuTomoConfig); +DECLARE_ALGORITHM(LoadSavuTomoConfig) using namespace Mantid::API; diff --git a/Code/Mantid/Framework/DataHandling/src/LoadSpice2D.cpp b/Code/Mantid/Framework/DataHandling/src/LoadSpice2D.cpp index 1d8a877675e97446cd538081a4e6c5590e0980ce..49b271ef922119cdc8cc72c0aa813f1c0de1d7e0 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadSpice2D.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadSpice2D.cpp @@ -36,7 +36,7 @@ using Poco::XML::Text; namespace Mantid { namespace DataHandling { // Register the algorithm into the AlgorithmFactory -DECLARE_FILELOADER_ALGORITHM(LoadSpice2D); +DECLARE_FILELOADER_ALGORITHM(LoadSpice2D) // Parse string and convert to numeric type template <class T> diff --git a/Code/Mantid/Framework/DataHandling/src/LoadSpiceAscii.cpp b/Code/Mantid/Framework/DataHandling/src/LoadSpiceAscii.cpp index 55c0d34ca3a5f0f9a6a94a44071c7f7f7706e7fa..879dbb975bc098b5d2bee65f0eb49c26a7f2b51f 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadSpiceAscii.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadSpiceAscii.cpp @@ -129,8 +129,16 @@ void LoadSpiceAscii::init() { "Otherwise, any log name is not listed will be treated as " "string property."); - declareProperty(new ArrayProperty<std::string>("DateAndTimeLog"), - "Name and format for date and time"); + // date: MM/DD/YYYY,time: HH:MM:SS AM is the standard SPICE date time log name + // and format + std::vector<std::string> defaultlogformat(4); + defaultlogformat[0] = "date"; + defaultlogformat[1] = "MM/DD/YYYY"; + defaultlogformat[2] = "time"; + defaultlogformat[3] = "HH:MM:SS AM"; + declareProperty( + new ArrayProperty<std::string>("DateAndTimeLog", defaultlogformat), + "Name and format for date and time"); // Output declareProperty(new WorkspaceProperty<ITableWorkspace>("OutputWorkspace", "", @@ -461,8 +469,10 @@ void LoadSpiceAscii::setupRunStartTime( runinfows->run().hasProperty(timelogname))) { std::stringstream errss; errss << "Unable to locate user specified date and time sample logs " - << datelogname << " and " << timelogname << "."; - throw std::runtime_error(errss.str()); + << datelogname << " and " << timelogname << "." + << "run_start will not be set up."; + g_log.error(errss.str()); + return; } const std::string &rawdatestring = diff --git a/Code/Mantid/Framework/DataHandling/src/LoadTOFRawNexus.cpp b/Code/Mantid/Framework/DataHandling/src/LoadTOFRawNexus.cpp index 549ddc74278a518606f4cb0ebbc658b4458b78f8..d477812c6246b63b64ccbc44663244ff6fc77008 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadTOFRawNexus.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadTOFRawNexus.cpp @@ -13,7 +13,7 @@ namespace Mantid { namespace DataHandling { -DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadTOFRawNexus); +DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadTOFRawNexus) using namespace Kernel; using namespace API; diff --git a/Code/Mantid/Framework/DataHandling/src/NexusTester.cpp b/Code/Mantid/Framework/DataHandling/src/NexusTester.cpp index 19657640086df1581cee9546912b6ff62935b102..2f1ed8f0471bad14b3da57c3519f3b60f07b7ef1 100644 --- a/Code/Mantid/Framework/DataHandling/src/NexusTester.cpp +++ b/Code/Mantid/Framework/DataHandling/src/NexusTester.cpp @@ -30,10 +30,10 @@ NexusTester::~NexusTester() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string NexusTester::name() const { return "NexusTester"; }; +const std::string NexusTester::name() const { return "NexusTester"; } /// Algorithm's version for identification. @see Algorithm::version -int NexusTester::version() const { return 1; }; +int NexusTester::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string NexusTester::category() const { diff --git a/Code/Mantid/Framework/DataHandling/src/PDLoadCharacterizations.cpp b/Code/Mantid/Framework/DataHandling/src/PDLoadCharacterizations.cpp index 8e73ca0e825ca6bbaee6c6189b2d0e39c78def58..34b98ec08a15d88aba364ceb50b426f5ee4d9796 100644 --- a/Code/Mantid/Framework/DataHandling/src/PDLoadCharacterizations.cpp +++ b/Code/Mantid/Framework/DataHandling/src/PDLoadCharacterizations.cpp @@ -36,10 +36,10 @@ PDLoadCharacterizations::~PDLoadCharacterizations() {} /// Algorithm's name for identification. @see Algorithm::name const std::string PDLoadCharacterizations::name() const { return "PDLoadCharacterizations"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int PDLoadCharacterizations::version() const { return 1; }; +int PDLoadCharacterizations::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string PDLoadCharacterizations::category() const { diff --git a/Code/Mantid/Framework/DataHandling/src/SNSDataArchive.cpp b/Code/Mantid/Framework/DataHandling/src/SNSDataArchive.cpp index 2ecc8bd1680a20f885d9b5069ae09a00ce6ea10e..ca088cab0faf7f1a46a733d9e0cc0f011b7f01b5 100644 --- a/Code/Mantid/Framework/DataHandling/src/SNSDataArchive.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SNSDataArchive.cpp @@ -32,7 +32,7 @@ const std::string BASE_URL("http://icat.sns.gov:2080/icat-rest-ws/datafile/filename/"); } -DECLARE_ARCHIVESEARCH(SNSDataArchive, SNSDataSearch); +DECLARE_ARCHIVESEARCH(SNSDataArchive, SNSDataSearch) /** * @param filenames : List of files to search diff --git a/Code/Mantid/Framework/DataHandling/src/SavePAR.cpp b/Code/Mantid/Framework/DataHandling/src/SavePAR.cpp index 8d2ff9739bf65717d79b92706161be8b4b2ac64d..d318f94f549b5072121b412dc0b0a41673fd668e 100644 --- a/Code/Mantid/Framework/DataHandling/src/SavePAR.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SavePAR.cpp @@ -14,7 +14,7 @@ namespace Mantid { namespace DataHandling { // Register the algorithm into the AlgorithmFactory -DECLARE_ALGORITHM(SavePAR); +DECLARE_ALGORITHM(SavePAR) using namespace Mantid::Kernel; using namespace Mantid::API; diff --git a/Code/Mantid/Framework/DataHandling/src/SavePHX.cpp b/Code/Mantid/Framework/DataHandling/src/SavePHX.cpp index ecb428de9af8c914a3d67370f576a163e171cc45..7c221896f8be4c88e1ae055a6dfd1bfad7bb027c 100644 --- a/Code/Mantid/Framework/DataHandling/src/SavePHX.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SavePHX.cpp @@ -14,7 +14,7 @@ namespace Mantid { namespace DataHandling { // Register the algorithm into the AlgorithmFactory -DECLARE_ALGORITHM(SavePHX); +DECLARE_ALGORITHM(SavePHX) using namespace Mantid::Kernel; using namespace Mantid::API; diff --git a/Code/Mantid/Framework/DataHandling/src/SaveParameterFile.cpp b/Code/Mantid/Framework/DataHandling/src/SaveParameterFile.cpp index 9bee776e07f29f407e307f90680778acd8ca74fa..931538cbb9488116d9dcb0211b5061077e7df773 100644 --- a/Code/Mantid/Framework/DataHandling/src/SaveParameterFile.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SaveParameterFile.cpp @@ -36,10 +36,10 @@ SaveParameterFile::~SaveParameterFile() {} /// Algorithm's name for identification. @see Algorithm::name const std::string SaveParameterFile::name() const { return "SaveParameterFile"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int SaveParameterFile::version() const { return 1; }; +int SaveParameterFile::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string SaveParameterFile::category() const { diff --git a/Code/Mantid/Framework/DataHandling/src/SaveSPE.cpp b/Code/Mantid/Framework/DataHandling/src/SaveSPE.cpp index 772c8674974938d2aaa5fc8c68ebcb55f9ead60d..6b6878a8e8905a6483fac81e4740712a6629264c 100644 --- a/Code/Mantid/Framework/DataHandling/src/SaveSPE.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SaveSPE.cpp @@ -25,12 +25,34 @@ DECLARE_ALGORITHM(SaveSPE) * @throws std::runtime_error :: throws when there is a problem writing to disk, * usually disk space or permissions based */ + +// use macro on platforms without variadic templates. +#if defined(__INTEL_COMPILER) || ( defined(_MSC_VER) && _MSC_VER < 1800 ) + #define FPRINTF_WITH_EXCEPTION(stream, format, ...) \ if (fprintf(stream, format, ##__VA_ARGS__) <= 0) { \ throw std::runtime_error( \ "Error writing to file. Check folder permissions and disk space."); \ } +#else +namespace { + +template <typename... vargs> +void FPRINTF_WITH_EXCEPTION(FILE *stream, const char *format, vargs... args) { + if (fprintf(stream, format, args...) <= 0) { + throw std::runtime_error( + "Error writing to file. Check folder permissions and disk space."); + } +} + +// special case needed for case with only two arguments. +void FPRINTF_WITH_EXCEPTION(FILE *stream, const char *format) { + FPRINTF_WITH_EXCEPTION(stream, format, ""); +} +} +#endif + using namespace Kernel; using namespace API; diff --git a/Code/Mantid/Framework/DataHandling/src/SortTableWorkspace.cpp b/Code/Mantid/Framework/DataHandling/src/SortTableWorkspace.cpp index 98b38f0fe8e429fd254b84090fbf81e155d44fab..6909250252c266fa1beccde46125ffdb2ff58c81 100644 --- a/Code/Mantid/Framework/DataHandling/src/SortTableWorkspace.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SortTableWorkspace.cpp @@ -24,7 +24,7 @@ SortTableWorkspace::~SortTableWorkspace() {} //---------------------------------------------------------------------------------------------- /// Algorithm's version for identification. @see Algorithm::version -int SortTableWorkspace::version() const { return 1; }; +int SortTableWorkspace::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string SortTableWorkspace::category() const { return "Utility"; } @@ -32,7 +32,7 @@ const std::string SortTableWorkspace::category() const { return "Utility"; } /// Algorithm's summary for use in the GUI and help. @see Algorithm::summary const std::string SortTableWorkspace::summary() const { return "Sort a TableWorkspace."; -}; +} //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. diff --git a/Code/Mantid/Framework/DataHandling/test/LoadFullprofResolutionTest.h b/Code/Mantid/Framework/DataHandling/test/LoadFullprofResolutionTest.h index 878ab8807fecc309c1adb50c1062dad5cbca615e..b8d36d13bb2420598394a4f053662b4e913beeea 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadFullprofResolutionTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadFullprofResolutionTest.h @@ -328,7 +328,7 @@ public: void test_workspace() { // Generate file - string filename("TestWorskpace.irf"); + string filename("FullprofResolutionTest_TestWorkspace.irf"); generate1BankIrfFile(filename); // Load workspace group wsName with one workspace @@ -412,7 +412,7 @@ public: } // Clean - Poco::File("TestWorskpace.irf").remove(); + Poco::File(filename).remove(); } //---------------------------------------------------------------------------------------------- diff --git a/Code/Mantid/Framework/DataHandling/test/LoadGSASInstrumentFileTest.h b/Code/Mantid/Framework/DataHandling/test/LoadGSASInstrumentFileTest.h index 0ae94946fa50e830bd34562a0b1203b50a0b03e0..65d102d5c492aaeff5f8d6524b98a18d7c23e500 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadGSASInstrumentFileTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadGSASInstrumentFileTest.h @@ -208,7 +208,7 @@ public: void test_workspace() { // Generate file with two banks - string filename("TestWorskpace.irf"); + string filename("GSASInstrumentFileTest_TestWorkspace.irf"); generate2BankPrmFile(filename); // Create workspace group to put parameters into @@ -308,7 +308,7 @@ public: TS_ASSERT_EQUALS( fitParam.getValue( 0.0 ), 0.0); // Clean - Poco::File("TestWorskpace.irf").remove(); + Poco::File(filename).remove(); AnalysisDataService::Instance().remove("loadGSASInstrumentFileWorkspace"); } diff --git a/Code/Mantid/Framework/DataHandling/test/LoadISISNexusTest.h b/Code/Mantid/Framework/DataHandling/test/LoadISISNexusTest.h index 9335317a294e01f4ed22140c9937f645d32f9967..6c300c5785e0849c6931fff17419e315b69c4815 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadISISNexusTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadISISNexusTest.h @@ -633,8 +633,40 @@ public: AnalysisDataService::Instance().remove("outWS"); } + void xestExecMonExcludedInTheEnd() + { + Mantid::API::FrameworkManager::Instance(); + LoadISISNexus2 ld; + ld.initialize(); + ld.setPropertyValue("Filename","MAPS00018314.nxs"); + ld.setPropertyValue("SpectrumMin","2"); + ld.setPropertyValue("SpectrumMax","10"); + ld.setPropertyValue("OutputWorkspace","outWS"); + ld.setPropertyValue("LoadMonitors","Separate"); // + TS_ASSERT_THROWS_NOTHING(ld.execute()); + TS_ASSERT(ld.isExecuted()); + + + MatrixWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("outWS"); + TS_ASSERT_EQUALS(ws->blocksize(),2000); + TS_ASSERT_EQUALS(ws->getNumberHistograms(),9); + + MatrixWorkspace_sptr ws_mon = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("outWS_monitors"); + TS_ASSERT(ws_mon) + + TS_ASSERT_EQUALS(ws_mon->blocksize(),2000); + TS_ASSERT_EQUALS(ws_mon->getNumberHistograms(),4); + TS_ASSERT_DELTA(ws_mon->readX(0)[0],10,1.e-8); + + + TS_ASSERT_EQUALS(ws_mon->getSpectrum(0)->getSpectrumNo(),41473); + TS_ASSERT_EQUALS(ws_mon->getSpectrum(3)->getSpectrumNo(),41476); + AnalysisDataService::Instance().remove("outWS"); + AnalysisDataService::Instance().remove("outWS_monitors"); + } + }; //------------------------------------------------------------------------------ diff --git a/Code/Mantid/Framework/DataHandling/test/LoadNexusProcessedTest.h b/Code/Mantid/Framework/DataHandling/test/LoadNexusProcessedTest.h index 0f5665b673813c0435671360a77bbb627e4b3591..c2b5c23bab104197643cb04a67f4b2669f9b40c1 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadNexusProcessedTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadNexusProcessedTest.h @@ -2,26 +2,34 @@ #define LOADNEXUSPROCESSEDTEST_H_ #include "MantidAPI/AlgorithmManager.h" +#include "MantidAPI/FileFinder.h" #include "MantidAPI/AnalysisDataService.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/WorkspaceGroup.h" -#include "MantidDataHandling/LoadInstrument.h" #include "MantidDataObjects/EventWorkspace.h" +#include "MantidDataObjects/PeakShapeSpherical.h" +#include "MantidDataObjects/Peak.h" +#include "MantidDataObjects/PeaksWorkspace.h" +#include "MantidGeometry/IDTypes.h" #include "MantidGeometry/Instrument.h" +#include "MantidGeometry/Instrument/InstrumentDefinitionParser.h" #include "MantidDataHandling/LoadNexusProcessed.h" #include "MantidDataHandling/SaveNexusProcessed.h" #include "MantidDataHandling/Load.h" +#include "MantidDataHandling/LoadInstrument.h" +#include "MantidTestHelpers/WorkspaceCreationHelper.h" + #include "SaveNexusProcessedTest.h" + +#include <boost/lexical_cast.hpp> + #include <cxxtest/TestSuite.h> -#include <iostream> + +#include <hdf5.h> + #include <Poco/File.h> -#include <boost/lexical_cast.hpp> -#include "MantidGeometry/IDTypes.h" -#include "MantidTestHelpers/WorkspaceCreationHelper.h" -#include "MantidDataObjects/PeakShapeSpherical.h" -#include "MantidDataObjects/Peak.h" -#include "MantidDataObjects/PeaksWorkspace.h" +using namespace Mantid::Geometry; using namespace Mantid::Kernel; using namespace Mantid::DataObjects; using namespace Mantid::API; @@ -813,9 +821,111 @@ public: Workspace_sptr ws = loadAlg.getProperty("OutputWorkspace"); auto peakWS = boost::dynamic_pointer_cast<Mantid::DataObjects::PeaksWorkspace>(ws); TS_ASSERT(peakWS); + } + void test_coordinates_saved_and_loaded_on_peaks_workspace() + { + auto peaksTestWS = WorkspaceCreationHelper::createPeaksWorkspace(); + // Loading a peaks workspace without a instrument from an IDF doesn't work ... + const std::string filename = FileFinder::Instance().getFullPath( + "IDFs_for_UNIT_TESTING/MINITOPAZ_Definition.xml"); + InstrumentDefinitionParser parser; + parser.initialize(filename, "MINITOPAZ", Strings::loadFile(filename)); + auto instrument = parser.parseXML(NULL); + peaksTestWS->populateInstrumentParameters(); + peaksTestWS->setInstrument(instrument); + + const SpecialCoordinateSystem appliedCoordinateSystem = QSample; + peaksTestWS->setCoordinateSystem(appliedCoordinateSystem); + + SaveNexusProcessed saveAlg; + saveAlg.setChild(true); + saveAlg.initialize(); + saveAlg.setProperty("InputWorkspace", peaksTestWS); + saveAlg.setPropertyValue("Filename", "LoadAndSaveNexusProcessedCoordinateSystem.nxs"); + saveAlg.execute(); + std::string filePath = saveAlg.getPropertyValue("Filename"); + + LoadNexusProcessed loadAlg; + loadAlg.setChild(true); + loadAlg.initialize(); + loadAlg.setPropertyValue("Filename", filePath); + loadAlg.setPropertyValue("OutputWorkspace", "__unused"); + loadAlg.execute(); + + Mantid::API::Workspace_sptr loadedWS = loadAlg.getProperty("OutputWorkspace"); + auto loadedPeaksWS = + boost::dynamic_pointer_cast<Mantid::API::IPeaksWorkspace>(loadedWS); + Poco::File testFile(filePath); + if(testFile.exists()) + { + testFile.remove(); + } + + TS_ASSERT_EQUALS(appliedCoordinateSystem, loadedPeaksWS->getSpecialCoordinateSystem()); + } + + // backwards compatability check + void test_coordinates_saved_and_loaded_on_peaks_workspace_from_expt_info() + { + auto peaksTestWS = WorkspaceCreationHelper::createPeaksWorkspace(); + // Loading a peaks workspace without a instrument from an IDF doesn't work ... + const std::string filename = FileFinder::Instance().getFullPath( + "IDFs_for_UNIT_TESTING/MINITOPAZ_Definition.xml"); + InstrumentDefinitionParser parser; + parser.initialize(filename, "MINITOPAZ", Strings::loadFile(filename)); + auto instrument = parser.parseXML(NULL); + peaksTestWS->populateInstrumentParameters(); + peaksTestWS->setInstrument(instrument); + + // simulate old-style file with "CoordinateSystem" log + const SpecialCoordinateSystem appliedCoordinateSystem = QSample; + peaksTestWS->logs()->addProperty("CoordinateSystem", + static_cast<int>(appliedCoordinateSystem)); + + SaveNexusProcessed saveAlg; + saveAlg.setChild(true); + saveAlg.initialize(); + saveAlg.setProperty("InputWorkspace", peaksTestWS); + saveAlg.setPropertyValue("Filename", "LoadAndSaveNexusProcessedCoordinateSystemOldFormat.nxs"); + saveAlg.execute(); + std::string filePath = saveAlg.getPropertyValue("Filename"); + + // Remove the coordinate_system entry so it falls back on the log. NeXus + // can't do this so use the HDF5 API directly + auto fid = H5Fopen(filePath.c_str(), H5F_ACC_RDWR, H5P_DEFAULT); + auto mantid_id = H5Gopen(fid, "mantid_workspace_1", H5P_DEFAULT); + auto peaks_id = H5Gopen(mantid_id, "peaks_workspace", H5P_DEFAULT); + if (peaks_id > 0) { + H5Ldelete(peaks_id, "coordinate_system", H5P_DEFAULT); + H5Gclose(peaks_id); + H5Gclose(mantid_id); + } else { + TS_FAIL("Cannot unlink coordinate_system group. Test file has unexpected " + "structure."); + } + H5Fclose(fid); + + LoadNexusProcessed loadAlg; + loadAlg.setChild(true); + loadAlg.initialize(); + loadAlg.setPropertyValue("Filename", filePath); + loadAlg.setPropertyValue("OutputWorkspace", "__unused"); + loadAlg.execute(); + + Mantid::API::Workspace_sptr loadedWS = loadAlg.getProperty("OutputWorkspace"); + auto loadedPeaksWS = + boost::dynamic_pointer_cast<Mantid::API::IPeaksWorkspace>(loadedWS); + Poco::File testFile(filePath); + if(testFile.exists()) + { + testFile.remove(); + } + + TS_ASSERT_EQUALS(appliedCoordinateSystem, loadedPeaksWS->getSpecialCoordinateSystem()); } + void testTableWorkspace_vectorColumn() { // Create a table we will save diff --git a/Code/Mantid/Framework/DataHandling/test/LoadRaw3Test.h b/Code/Mantid/Framework/DataHandling/test/LoadRaw3Test.h index 77b4a90852d1f9f667907e332dc6acf449c3ad07..30aea2518a58723a9fa055aa22734f8b4750273f 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadRaw3Test.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadRaw3Test.h @@ -115,6 +115,7 @@ public: // boost::shared_ptr<Sample> sample = output2D->getSample(); Property *l_property = output2D->run().getLogData( std::string("TEMP1") ); TimeSeriesProperty<double> *l_timeSeriesDouble = dynamic_cast<TimeSeriesProperty<double>*>(l_property); + std::string timeSeriesString = l_timeSeriesDouble->value(); TS_ASSERT_EQUALS( timeSeriesString.substr(0,23), "2007-Nov-13 15:16:20 0" ); diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h index f9d769181bc3ca0142218e0b93ddbec352d43707..67c05c5c1ab64e1a02b121ead5e3e2c5edf65b09 100644 --- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h +++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h @@ -3,6 +3,7 @@ #include "MantidKernel/System.h" #include "MantidKernel/V3D.h" +#include "MantidKernel/Matrix.h" #include "MantidDataObjects/PeakShapeBase.h" @@ -56,7 +57,9 @@ namespace DataObjects std::vector<double> abcRadiiBackgroundOuter() const; /// Get ellipsoid directions std::vector<Mantid::Kernel::V3D> directions() const; - + /// Get ellipsoid directions in a specified frame + std::vector<Kernel::V3D> getDirectionInSpecificFrame(Kernel::Matrix<double>& invertedGoniometerMatrix) const; + /// PeakShape interface std::string toJSON() const; /// Clone ellipsoid diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h index 4c4efe464c89031e206768176af300b50e34cb9d..4a4d217689ee12fc645cb24bd3e2d469a5c101b1 100644 --- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h +++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h @@ -109,11 +109,11 @@ public: const Peak &getPeak(int peakNum) const; API::IPeak *createPeak(Kernel::V3D QFrame, - boost::optional<double> detectorDistance = boost::optional<double>()) const; + boost::optional<double> detectorDistance = + boost::optional<double>()) const; std::vector<std::pair<std::string, std::string>> peakInfo(Kernel::V3D qFrame, bool labCoords) const; - Peak *createPeakHKL(Kernel::V3D HKL) const; int peakInfoNumber(Kernel::V3D qFrame, bool labCoords) const; @@ -129,12 +129,11 @@ public: API::ITableWorkspace_sptr createDetectorTable() const; /// Set the special coordinate system. - virtual void setCoordinateSystem( - const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem); + virtual void + setCoordinateSystem(const Kernel::SpecialCoordinateSystem coordinateSystem); /// Get the special coordinate system. - virtual Mantid::Kernel::SpecialCoordinateSystem - getSpecialCoordinateSystem() const; + Kernel::SpecialCoordinateSystem getSpecialCoordinateSystem() const; // ====================================== ITableWorkspace Methods // ================================== @@ -183,15 +182,6 @@ public: void saveNexus(::NeXus::File *file) const; private: - /** Vector of Peak contained within. */ - std::vector<Peak> peaks; - - /** Column shared pointers. */ - std::vector<boost::shared_ptr<Mantid::DataObjects::PeakColumn>> columns; - - /** Column names */ - std::vector<std::string> columnNames; - /// Initialize the table structure void initColumns(); /// Adds a new PeakColumn of the given type @@ -275,6 +265,18 @@ private: // ====================================== End ITableWorkspace Methods // ================================== + /** Vector of Peak contained within. */ + std::vector<Peak> peaks; + + /** Column shared pointers. */ + std::vector<boost::shared_ptr<Mantid::DataObjects::PeakColumn>> columns; + + /** Column names */ + std::vector<std::string> columnNames; + + /// Coordinates + Kernel::SpecialCoordinateSystem m_coordSystem; + // adapter for logs() function, which create reference to this class itself // and does not allow to delete the shared pointers, // returned by logs() function when they go out of scope diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/VectorColumn.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/VectorColumn.h index 72c1e5031354f69b0d4b8a92d91acdff1f3e77b9..54952d823c76a4f5510ed1f61dd3237367f07970 100644 --- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/VectorColumn.h +++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/VectorColumn.h @@ -171,7 +171,7 @@ private: #define DECLARE_VECTORCOLUMN(Type, TypeName) \ template <> std::string VectorColumn<Type>::typeName() { \ return #TypeName; \ - }; \ + } \ Kernel::RegistrationHelper register_column_##TypeName(( \ API::ColumnFactory::Instance().subscribe<VectorColumn<Type>>(#TypeName), \ 0)); diff --git a/Code/Mantid/Framework/DataObjects/src/NoShape.cpp b/Code/Mantid/Framework/DataObjects/src/NoShape.cpp index 7250ffebbaa9525a0f42427b26ad21178e953d63..eb4a249bed5d37b8c28eeab81d30a7f0da7ced48 100644 --- a/Code/Mantid/Framework/DataObjects/src/NoShape.cpp +++ b/Code/Mantid/Framework/DataObjects/src/NoShape.cpp @@ -1,6 +1,6 @@ #include "MantidDataObjects/NoShape.h" #include <stdexcept> -#include <jsoncpp/json/json.h> +#include <json/json.h> namespace Mantid { namespace DataObjects { diff --git a/Code/Mantid/Framework/DataObjects/src/PeakColumn.cpp b/Code/Mantid/Framework/DataObjects/src/PeakColumn.cpp index b844cf39687756221a4f123a5f437883d64714d5..b3d7e129cc927636043721605c3517a80c4892a8 100644 --- a/Code/Mantid/Framework/DataObjects/src/PeakColumn.cpp +++ b/Code/Mantid/Framework/DataObjects/src/PeakColumn.cpp @@ -67,7 +67,7 @@ const std::string typeFromName(const std::string &name) { "\"" "Peak column names/types must be explicitly marked in PeakColumn.cpp"); } -}; +} } //---------------------------------------------------------------------------------------------- diff --git a/Code/Mantid/Framework/DataObjects/src/PeakShapeBase.cpp b/Code/Mantid/Framework/DataObjects/src/PeakShapeBase.cpp index c42c6efbe7eaee9d7462da99f285e810d0045314..559757ebadf122bd1038a61e130513257071dd36 100644 --- a/Code/Mantid/Framework/DataObjects/src/PeakShapeBase.cpp +++ b/Code/Mantid/Framework/DataObjects/src/PeakShapeBase.cpp @@ -1,6 +1,6 @@ #include "MantidDataObjects/PeakShapeBase.h" #include "MantidKernel/SpecialCoordinateSystem.h" -#include <jsoncpp/json/json.h> +#include <json/json.h> namespace Mantid { namespace DataObjects { diff --git a/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoid.cpp b/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoid.cpp index 6a3db09207e54cfe6fb588fe46bef90ba774808e..c3e0a131080c6fc17678ceddc1ad63deb7738ae3 100644 --- a/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoid.cpp +++ b/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoid.cpp @@ -1,6 +1,6 @@ #include "MantidDataObjects/PeakShapeEllipsoid.h" #include "MantidKernel/cow_ptr.h" -#include <jsoncpp/json/json.h> +#include <json/json.h> namespace Mantid { namespace DataObjects { @@ -72,6 +72,22 @@ std::vector<Kernel::V3D> PeakShapeEllipsoid::directions() const { return m_directions; } +std::vector<Kernel::V3D> PeakShapeEllipsoid::getDirectionInSpecificFrame(Kernel::Matrix<double>& invertedGoniometerMatrix) const{ + std::vector<Kernel::V3D> directionsInFrame; + + if ((invertedGoniometerMatrix.numCols() != m_directions.size())|| + (invertedGoniometerMatrix.numRows() != m_directions.size())){ + throw std::invalid_argument("The inverted goniometer matrix is not compatible with the direction vector"); + } + + for (std::vector<Kernel::V3D>::const_iterator it = m_directions.begin(); it != m_directions.end(); ++it){ + directionsInFrame.push_back(invertedGoniometerMatrix*(*it)); + Mantid::Kernel::V3D d = invertedGoniometerMatrix*(*it); + } + + return directionsInFrame; +} + std::string PeakShapeEllipsoid::toJSON() const { Json::Value root; PeakShapeBase::buildCommon(root); diff --git a/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoidFactory.cpp b/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoidFactory.cpp index 2d487feee536c2734b76bbf9b4dfcdb8cd5b338c..da25c4df97fa3b296311838393d3b3b06ccaaf8e 100644 --- a/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoidFactory.cpp +++ b/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoidFactory.cpp @@ -2,7 +2,7 @@ #include "MantidDataObjects/PeakShapeEllipsoid.h" #include "MantidKernel/SpecialCoordinateSystem.h" -#include <jsoncpp/json/json.h> +#include <json/json.h> #include <stdexcept> using namespace Mantid::Kernel; diff --git a/Code/Mantid/Framework/DataObjects/src/PeakShapeSpherical.cpp b/Code/Mantid/Framework/DataObjects/src/PeakShapeSpherical.cpp index b3403dbee16e637a4cae399e3f61bfd8c63dc185..9bad26ff086ce04bb970a54ea82042a9709879c2 100644 --- a/Code/Mantid/Framework/DataObjects/src/PeakShapeSpherical.cpp +++ b/Code/Mantid/Framework/DataObjects/src/PeakShapeSpherical.cpp @@ -1,6 +1,6 @@ #include "MantidDataObjects/PeakShapeSpherical.h" #include <stdexcept> -#include <jsoncpp/json/json.h> +#include <json/json.h> namespace Mantid { namespace DataObjects { diff --git a/Code/Mantid/Framework/DataObjects/src/PeakShapeSphericalFactory.cpp b/Code/Mantid/Framework/DataObjects/src/PeakShapeSphericalFactory.cpp index 90793d60166075eba1960af7ad7ad57eb56ca87c..0c62e5a145d6a5341ba794e6820e4788d0dcb603 100644 --- a/Code/Mantid/Framework/DataObjects/src/PeakShapeSphericalFactory.cpp +++ b/Code/Mantid/Framework/DataObjects/src/PeakShapeSphericalFactory.cpp @@ -1,7 +1,7 @@ #include "MantidDataObjects/PeakShapeSphericalFactory.h" #include "MantidDataObjects/PeakShapeSpherical.h" #include "MantidKernel/SpecialCoordinateSystem.h" -#include <jsoncpp/json/json.h> +#include <json/json.h> #include <MantidKernel/VMD.h> namespace Mantid { diff --git a/Code/Mantid/Framework/DataObjects/src/PeaksWorkspace.cpp b/Code/Mantid/Framework/DataObjects/src/PeaksWorkspace.cpp index 83aabf18e3fdf7604ed698c848e8a0013651d7c5..890e3e1e447ee7a078764edb120aceaedfc763d0 100644 --- a/Code/Mantid/Framework/DataObjects/src/PeaksWorkspace.cpp +++ b/Code/Mantid/Framework/DataObjects/src/PeaksWorkspace.cpp @@ -36,17 +36,18 @@ using namespace Mantid::Geometry; namespace Mantid { namespace DataObjects { /// Register the workspace as a type -DECLARE_WORKSPACE(PeaksWorkspace); - -// Kernel::Logger& PeaksWorkspace::g_log = -// Kernel::Logger::get("PeaksWorkspace"); +DECLARE_WORKSPACE(PeaksWorkspace) //--------------------------------------------------------------------------------------------- /** Constructor. Create a table with all the required columns. * * @return PeaksWorkspace object */ -PeaksWorkspace::PeaksWorkspace() : IPeaksWorkspace() { initColumns(); } +PeaksWorkspace::PeaksWorkspace() + : IPeaksWorkspace(), peaks(), columns(), columnNames(), + m_coordSystem(None) { + initColumns(); +} //--------------------------------------------------------------------------------------------- /** Virtual constructor. Clone method to duplicate the peaks workspace. @@ -65,7 +66,8 @@ PeaksWorkspace *PeaksWorkspace::clone() const { * @return */ PeaksWorkspace::PeaksWorkspace(const PeaksWorkspace &other) - : IPeaksWorkspace(other), peaks(other.peaks) { + : IPeaksWorkspace(other), peaks(other.peaks), columns(), columnNames(), + m_coordSystem(other.m_coordSystem) { initColumns(); } @@ -199,11 +201,13 @@ const Peak &PeaksWorkspace::getPeak(const int peakNum) const { //--------------------------------------------------------------------------------------------- /** Creates an instance of a Peak BUT DOES NOT ADD IT TO THE WORKSPACE * @param QLabFrame :: Q of the center of the peak, in reciprocal space - * @param detectorDistance :: optional distance between the sample and the detector. You do NOT need to explicitly provide this distance. + * @param detectorDistance :: optional distance between the sample and the + * detector. You do NOT need to explicitly provide this distance. * @return a pointer to a new Peak object. */ -API::IPeak *PeaksWorkspace::createPeak(Kernel::V3D QLabFrame, - boost::optional<double> detectorDistance) const { +API::IPeak * +PeaksWorkspace::createPeak(Kernel::V3D QLabFrame, + boost::optional<double> detectorDistance) const { return new Peak(this->getInstrument(), QLabFrame, detectorDistance); } @@ -395,31 +399,33 @@ PeaksWorkspace::peakInfo(Kernel::V3D qFrame, bool labCoords) const { * @param HKL : reciprocal lattice vector coefficients * @return Fully formed peak. */ -Peak *PeaksWorkspace::createPeakHKL(V3D HKL) const -{ - /* - The following allows us to add peaks where we have a single UB to work from. - */ +Peak *PeaksWorkspace::createPeakHKL(V3D HKL) const { + /* + The following allows us to add peaks where we have a single UB to work from. + */ - Geometry::OrientedLattice lattice = this->sample().getOrientedLattice(); - Geometry::Goniometer goniometer = this->run().getGoniometer(); + Geometry::OrientedLattice lattice = this->sample().getOrientedLattice(); + Geometry::Goniometer goniometer = this->run().getGoniometer(); - // Calculate qLab from q HKL. As per Busing and Levy 1967, q_lab_frame = 2pi * Goniometer * UB * HKL - V3D qLabFrame = goniometer.getR() * lattice.getUB() * HKL * 2 * M_PI; + // Calculate qLab from q HKL. As per Busing and Levy 1967, q_lab_frame = 2pi * + // Goniometer * UB * HKL + V3D qLabFrame = goniometer.getR() * lattice.getUB() * HKL * 2 * M_PI; - // create a peak using the qLab frame - auto peak = new Peak(this->getInstrument(), qLabFrame); // This should calculate the detector positions too. + // create a peak using the qLab frame + auto peak = + new Peak(this->getInstrument(), + qLabFrame); // This should calculate the detector positions too. - // We need to set HKL separately to keep things consistent. - peak->setHKL(HKL[0], HKL[1], HKL[2]); + // We need to set HKL separately to keep things consistent. + peak->setHKL(HKL[0], HKL[1], HKL[2]); - // Set the goniometer - peak->setGoniometerMatrix(goniometer.getR()); + // Set the goniometer + peak->setGoniometerMatrix(goniometer.getR()); - // Take the run number from this - peak->setRunNumber(this->getRunNumber()); + // Take the run number from this + peak->setRunNumber(this->getRunNumber()); - return peak; + return peak; } /** @@ -652,9 +658,8 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const { } const std::string shapeJSON = p.getPeakShape().toJSON(); shapes[i] = shapeJSON; - if(shapeJSON.size() > maxShapeJSONLength) - { - maxShapeJSONLength = shapeJSON.size(); + if (shapeJSON.size() > maxShapeJSONLength) { + maxShapeJSONLength = shapeJSON.size(); } } @@ -665,6 +670,9 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const { file->makeGroup("peaks_workspace", "NXentry", true); // For when peaksWorkspace can be loaded + // Coordinate system + file->writeData("coordinate_system", static_cast<uint32_t>(m_coordSystem)); + // Detectors column file->writeData("column_1", detectorID); file->openData("column_1"); @@ -801,7 +809,8 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const { std::string rowStr = shapes[ii]; for (size_t ic = 0; ic < rowStr.size(); ic++) toNexus[ii * maxShapeJSONLength + ic] = rowStr[ic]; - for (size_t ic = rowStr.size(); ic < static_cast<size_t>(maxShapeJSONLength); ic++) + for (size_t ic = rowStr.size(); + ic < static_cast<size_t>(maxShapeJSONLength); ic++) toNexus[ii * maxShapeJSONLength + ic] = ' '; } @@ -813,7 +822,6 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const { file->putAttr("interpret_as", specifyString); file->closeData(); - // QLab & QSample are calculated and do not need to be saved file->closeGroup(); // end of peaks workpace @@ -824,25 +832,16 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const { * @param coordinateSystem : Option to set. */ void PeaksWorkspace::setCoordinateSystem( - const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem) { - this->mutableRun().addProperty("CoordinateSystem", (int)coordinateSystem, - true); + const Kernel::SpecialCoordinateSystem coordinateSystem) { + m_coordSystem = coordinateSystem; } /** * @return the special Q3D coordinate system. */ -Mantid::Kernel::SpecialCoordinateSystem +Kernel::SpecialCoordinateSystem PeaksWorkspace::getSpecialCoordinateSystem() const { - Mantid::Kernel::SpecialCoordinateSystem result = None; - try { - Property *prop = this->run().getProperty("CoordinateSystem"); - PropertyWithValue<int> *p = dynamic_cast<PropertyWithValue<int> *>(prop); - int temp = *p; - result = (SpecialCoordinateSystem)temp; - } catch (Mantid::Kernel::Exception::NotFoundError &) { - } - return result; + return m_coordSystem; } // prevent shared pointer from deleting this diff --git a/Code/Mantid/Framework/DataObjects/src/TableWorkspace.cpp b/Code/Mantid/Framework/DataObjects/src/TableWorkspace.cpp index 138856ae152e5e5b9214c7c67379e19cbe1033d3..d2eac12677952e2456f05e6a57f03a5735562a3d 100644 --- a/Code/Mantid/Framework/DataObjects/src/TableWorkspace.cpp +++ b/Code/Mantid/Framework/DataObjects/src/TableWorkspace.cpp @@ -204,7 +204,7 @@ TableWorkspace *TableWorkspace::clone() const { // copy logs/properties. copy->m_LogManager = boost::make_shared<API::LogManager>(*this->m_LogManager); return copy; -}; +} /** * Sort. diff --git a/Code/Mantid/Framework/DataObjects/test/NoShapeTest.h b/Code/Mantid/Framework/DataObjects/test/NoShapeTest.h index e005dd877aefe1e2cbc71e9f361f2f1647bca32a..113c6969021f165bd380b5587512b79c196b7933 100644 --- a/Code/Mantid/Framework/DataObjects/test/NoShapeTest.h +++ b/Code/Mantid/Framework/DataObjects/test/NoShapeTest.h @@ -6,7 +6,7 @@ #endif #include <cxxtest/TestSuite.h> -#include <jsoncpp/json/json.h> +#include <json/json.h> #include "MantidDataObjects/NoShape.h" #include "MantidKernel/V3D.h" #include "MantidKernel/SpecialCoordinateSystem.h" diff --git a/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidFactoryTest.h b/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidFactoryTest.h index 217290bdb610a6d329f6f3f715b1b20df4892714..1912779723d4e8d2e910b31812e228ede8d3cbc0 100644 --- a/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidFactoryTest.h +++ b/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidFactoryTest.h @@ -7,7 +7,7 @@ #include <cxxtest/TestSuite.h> #include <gmock/gmock.h> -#include <jsoncpp/json/json.h> +#include <json/json.h> #include <boost/assign/list_of.hpp> #include "MantidDataObjects/PeakShapeEllipsoid.h" diff --git a/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidTest.h b/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidTest.h index d844798a82551f8d9cebfdf09ac6948152d7ce88..74438548220d15fc4571f497ea4e1ab05565d6ff 100644 --- a/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidTest.h +++ b/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidTest.h @@ -6,9 +6,10 @@ #include "MantidDataObjects/PeakShapeEllipsoid.h" #include "MantidKernel/cow_ptr.h" #include "MantidKernel/V3D.h" +#include "MantidKernel/Matrix.h" #include <vector> #include <boost/assign/list_of.hpp> -#include <jsoncpp/json/json.h> +#include <json/json.h> using Mantid::DataObjects::PeakShapeEllipsoid; using Mantid::Kernel::SpecialCoordinateSystem; @@ -173,8 +174,88 @@ public: } + + void test_directionsInSpecificFrameThrowsForMatrixWithInvalidDimensions(){ + auto directions = list_of(V3D(1, 0, 0))(V3D(0, 1, 0))(V3D(0, 0, 1)) + .convert_to_container<std::vector<V3D>>(); + const MantidVec abcRadii = list_of(2)(3)(4); + const MantidVec abcInnerRadii = list_of(5)(6)(7); + const MantidVec abcOuterRadii = list_of(8)(9)(10); + const SpecialCoordinateSystem frame = Mantid::Kernel::QLab; + const std::string algorithmName = "foo"; + const int algorithmVersion = 3; + + // Construct it. + PeakShapeEllipsoid a(directions, abcRadii, abcInnerRadii, abcOuterRadii, + frame, algorithmName, algorithmVersion); + Mantid::Kernel::Matrix<double> matrix(3,2); + std::vector<double> column1; + column1.push_back(1.0); + column1.push_back(1.0); + column1.push_back(1.0); + std::vector<double> column2; + column2.push_back(1.0); + column2.push_back(1.0); + column2.push_back(1.0); + + matrix.setColumn(0, column1); + matrix.setColumn(1, column2); + + TSM_ASSERT_THROWS("Should throw, bad goniometer matrix", + a.getDirectionInSpecificFrame(matrix) , std::invalid_argument &); + } + void test_directionsInSepcificFrame(){ + auto directions = list_of(V3D(1, 0, 0))(V3D(0, 1, 0))(V3D(0, 0, 1)) + .convert_to_container<std::vector<V3D>>(); + const MantidVec abcRadii = list_of(2)(3)(4); + const MantidVec abcInnerRadii = list_of(5)(6)(7); + const MantidVec abcOuterRadii = list_of(8)(9)(10); + const SpecialCoordinateSystem frame = Mantid::Kernel::QLab; + const std::string algorithmName = "foo"; + const int algorithmVersion = 3; + + // Construct it. + PeakShapeEllipsoid a(directions, abcRadii, abcInnerRadii, abcOuterRadii, + frame, algorithmName, algorithmVersion); + // 90 degree rotation around the z axis + Mantid::Kernel::Matrix<double> matrix(3,3); + std::vector<double> column1; + column1.push_back(0.0); + column1.push_back(1.0); + column1.push_back(0.0); + std::vector<double> column2; + column2.push_back(-1.0); + column2.push_back(0.0); + column2.push_back(0.0); + + std::vector<double> column3; + column3.push_back(0.0); + column3.push_back(0.0); + column3.push_back(1.0); + + matrix.setColumn(0, column1); + matrix.setColumn(1, column2); + matrix.setColumn(2, column3); + + std::vector<Mantid::Kernel::V3D> directionInNewFrame(3); + TSM_ASSERT_THROWS_NOTHING("Should throw nothing, valid goniometer matrix", + directionInNewFrame = a.getDirectionInSpecificFrame(matrix)); + + const double delta = 1e-6; + TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[0][0], 0.0, delta); + TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[0][1], 1.0, delta); + TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[0][2], 0.0, delta); + + TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[1][0], -1.0, delta); + TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[1][1], 0.0, delta); + TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[1][2], 0.0, delta); + + TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[2][0], 0.0, delta); + TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[2][1], 0.0, delta); + TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[2][2], 1.0, delta); + } }; #endif /* MANTID_DATAOBJECTS_PEAKSHAPEELLIPSOIDTEST_H_ */ diff --git a/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalFactoryTest.h b/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalFactoryTest.h index 6b7a809f17bd450ad0d346d9e24def6d9e0b0a7d..9ecc33fbdf7cb56df988edfa7e6edf34069d136e 100644 --- a/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalFactoryTest.h +++ b/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalFactoryTest.h @@ -7,7 +7,7 @@ #include <cxxtest/TestSuite.h> #include <gmock/gmock.h> -#include <jsoncpp/json/json.h> +#include <json/json.h> #include "MantidDataObjects/PeakShapeSphericalFactory.h" #include "MantidDataObjects/PeakShapeSpherical.h" diff --git a/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalTest.h b/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalTest.h index 7001da81978bc669081756ff856e2d0b8ab74ddc..f6b990bd0ebdee6f97b83cb9f30f35051b502ec6 100644 --- a/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalTest.h +++ b/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalTest.h @@ -6,7 +6,7 @@ #endif #include <cxxtest/TestSuite.h> -#include <jsoncpp/json/json.h> +#include <json/json.h> #include "MantidDataObjects/PeakShapeSpherical.h" #include "MantidKernel/V3D.h" diff --git a/Code/Mantid/Framework/Geometry/CMakeLists.txt b/Code/Mantid/Framework/Geometry/CMakeLists.txt index cac42359c3d50c3b32fd96d2867bac1ca95687ea..00426282450bf274d76e8d6a0a785f1755835512 100644 --- a/Code/Mantid/Framework/Geometry/CMakeLists.txt +++ b/Code/Mantid/Framework/Geometry/CMakeLists.txt @@ -350,12 +350,11 @@ if ( NOT OPENGL_FOUND ) endif () # ===================== Open Cascade =================== -if (NOT NO_OPENCASCADE) +if (ENABLE_OPENCASCADE) find_package ( OpenCascade REQUIRED ) include_directories ( system ${OPENCASCADE_INCLUDE_DIR} ) set (SRC_FILES ${SRC_FILES} ${OPENCASCADE_SRC} ) -else () - add_definitions ( -DNO_OPENCASCADE ) + add_definitions ( -DENABLE_OPENCASCADE ) endif () # A few defines needed for OpenCascade on the Mac diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h index 248dca7b95ddbed494484890ab1a289ec9eb3fe9..dba8a798bac88bbb80932ffb5edd1388f1e73432 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h @@ -109,6 +109,11 @@ namespace Geometry { */ class MANTID_GEOMETRY_DLL Group { public: + enum CoordinateSystem { + Orthogonal, + Hexagonal + }; + Group(); Group(const std::string &symmetryOperationString); Group(const std::vector<SymmetryOperation> &symmetryOperations); @@ -118,6 +123,7 @@ public: virtual ~Group() {} size_t order() const; + CoordinateSystem getCoordinateSystem() const; std::vector<SymmetryOperation> getSymmetryOperations() const; Group operator*(const Group &other) const; @@ -131,8 +137,12 @@ protected: void setSymmetryOperations( const std::vector<SymmetryOperation> &symmetryOperations); + CoordinateSystem getCoordinateSystemFromOperations( + const std::vector<SymmetryOperation> &symmetryOperations) const; + std::vector<SymmetryOperation> m_allOperations; std::set<SymmetryOperation> m_operationSet; + CoordinateSystem m_axisSystem; }; typedef boost::shared_ptr<Group> Group_sptr; diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h index 29056aed36fa9283a4b2daac55eccc06fb35804d..238947b38c49fcb825ae0f1fed0c67fe2d6e0c8c 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h @@ -4,6 +4,7 @@ #include "MantidGeometry/DllConfig.h" #include "MantidKernel/SingletonHolder.h" #include "MantidGeometry/Crystal/PointGroup.h" +#include "MantidGeometry/Crystal/SpaceGroup.h" #include "MantidKernel/RegistrationHelper.h" #include <boost/regex.hpp> @@ -81,7 +82,9 @@ class MANTID_GEOMETRY_DLL PointGroupFactoryImpl { public: PointGroup_sptr createPointGroup(const std::string &hmSymbol); PointGroup_sptr - createPointGroupFromSpaceGroupSymbol(const std::string &spaceGroupSymbol); + createPointGroupFromSpaceGroup(const SpaceGroup_const_sptr &spaceGroup); + PointGroup_sptr + createPointGroupFromSpaceGroup(const SpaceGroup &spaceGroup); bool isSubscribed(const std::string &hmSymbol) const; diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/CrystalStructure.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/CrystalStructure.cpp index 25e266f9ada45a8242a9eabef1f51182a0d25c60..22dd7a91ae6cef5f0a6224b938921f96634a3de3 100644 --- a/Code/Mantid/Framework/Geometry/src/Crystal/CrystalStructure.cpp +++ b/Code/Mantid/Framework/Geometry/src/Crystal/CrystalStructure.cpp @@ -247,9 +247,10 @@ void CrystalStructure::setPointGroupFromSpaceGroup( if (spaceGroup) { try { m_pointGroup = - PointGroupFactory::Instance().createPointGroupFromSpaceGroupSymbol( - spaceGroup->hmSymbol()); - } catch (...) { + PointGroupFactory::Instance().createPointGroupFromSpaceGroup( + spaceGroup); + } + catch (...) { // do nothing - point group will be null } } diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/Group.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/Group.cpp index f39708dfa465853c71176e6682ae496f1c2e25de..687ea943cbd1fe8f3dfa10072ee5b3060972b0f4 100644 --- a/Code/Mantid/Framework/Geometry/src/Crystal/Group.cpp +++ b/Code/Mantid/Framework/Geometry/src/Crystal/Group.cpp @@ -6,7 +6,7 @@ namespace Mantid { namespace Geometry { /// Default constructor. Creates a group with one symmetry operation (identity). -Group::Group() : m_allOperations(), m_operationSet() { +Group::Group() : m_allOperations(), m_operationSet(), m_axisSystem() { std::vector<SymmetryOperation> operation(1); setSymmetryOperations(operation); } @@ -14,7 +14,7 @@ Group::Group() : m_allOperations(), m_operationSet() { /// Uses SymmetryOperationFactory to create a vector of symmetry operations from /// the string. Group::Group(const std::string &symmetryOperationString) - : m_allOperations(), m_operationSet() { + : m_allOperations(), m_operationSet(), m_axisSystem() { setSymmetryOperations(SymmetryOperationFactory::Instance().createSymOps( symmetryOperationString)); } @@ -22,19 +22,20 @@ Group::Group(const std::string &symmetryOperationString) /// Constructs a group from the symmetry operations in the vector, duplicates /// are removed. Group::Group(const std::vector<SymmetryOperation> &symmetryOperations) - : m_allOperations(), m_operationSet() { + : m_allOperations(), m_operationSet(), m_axisSystem() { setSymmetryOperations(symmetryOperations); } /// Copy constructor. Group::Group(const Group &other) : m_allOperations(other.m_allOperations), - m_operationSet(other.m_operationSet) {} + m_operationSet(other.m_operationSet), m_axisSystem(other.m_axisSystem) {} /// Assignment operator. Group &Group::operator=(const Group &other) { m_allOperations = other.m_allOperations; m_operationSet = other.m_operationSet; + m_axisSystem = other.m_axisSystem; return *this; } @@ -42,6 +43,9 @@ Group &Group::operator=(const Group &other) { /// Returns the order of the group, which is the number of symmetry operations. size_t Group::order() const { return m_allOperations.size(); } +/// Returns the axis system of the group (either orthogonal or hexagonal). +Group::CoordinateSystem Group::getCoordinateSystem() const { return m_axisSystem; } + /// Returns a vector with all symmetry operations. std::vector<SymmetryOperation> Group::getSymmetryOperations() const { return m_allOperations; @@ -105,6 +109,22 @@ void Group::setSymmetryOperations( symmetryOperations.end()); m_allOperations = std::vector<SymmetryOperation>(m_operationSet.begin(), m_operationSet.end()); + m_axisSystem = getCoordinateSystemFromOperations(m_allOperations); +} + +/// Returns the axis system based on the given symmetry operations. Hexagonal +/// systems have 4 non-zero elements in the matrix, orthogonal have 6. +Group::CoordinateSystem Group::getCoordinateSystemFromOperations( + const std::vector<SymmetryOperation> &symmetryOperations) const { + for (auto op = symmetryOperations.begin(); op != symmetryOperations.end(); + ++op) { + std::vector<int> matrix = (*op).matrix(); + if (std::count(matrix.begin(), matrix.end(), 0) == 5) { + return Group::Hexagonal; + } + } + + return Group::Orthogonal; } /// Convenience operator* for directly multiplying groups using shared pointers. diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/PointGroupFactory.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/PointGroupFactory.cpp index 3d8289fdb508f3448b4ed9a8b60519dcd14cf4f1..928c3f214579a9019729ed7d488f551c5db0a14c 100644 --- a/Code/Mantid/Framework/Geometry/src/Crystal/PointGroupFactory.cpp +++ b/Code/Mantid/Framework/Geometry/src/Crystal/PointGroupFactory.cpp @@ -1,4 +1,5 @@ #include "MantidGeometry/Crystal/PointGroupFactory.h" +#include "MantidGeometry/Crystal/SpaceGroup.h" #include "MantidKernel/LibraryManager.h" #include <boost/algorithm/string.hpp> @@ -18,10 +19,35 @@ PointGroupFactoryImpl::createPointGroup(const std::string &hmSymbol) { return constructFromPrototype(getPrototype(hmSymbol)); } -PointGroup_sptr PointGroupFactoryImpl::createPointGroupFromSpaceGroupSymbol( - const std::string &spaceGroupSymbol) { - return createPointGroup( - pointGroupSymbolFromSpaceGroupSymbol(spaceGroupSymbol)); +PointGroup_sptr PointGroupFactoryImpl::createPointGroupFromSpaceGroup( + const SpaceGroup_const_sptr &spaceGroup) { + return createPointGroupFromSpaceGroup(*spaceGroup); +} + +PointGroup_sptr PointGroupFactoryImpl::createPointGroupFromSpaceGroup( + const SpaceGroup &spaceGroup) { + std::string pointGroupSymbol = + pointGroupSymbolFromSpaceGroupSymbol(spaceGroup.hmSymbol()); + + try { + PointGroup_sptr pointGroup = createPointGroup(pointGroupSymbol); + + // If the crystal system is trigonal, we need to do more. + if (pointGroup->crystalSystem() == PointGroup::Trigonal) { + throw std::invalid_argument( + "Trigonal space groups need to be processed differently."); + } + + return pointGroup; + } + catch (std::invalid_argument) { + if (spaceGroup.getCoordinateSystem() != + Group::CoordinateSystem::Hexagonal) { + pointGroupSymbol.append(" r"); + } + + return createPointGroup(pointGroupSymbol); + } } bool PointGroupFactoryImpl::isSubscribed(const std::string &hmSymbol) const { @@ -187,8 +213,8 @@ DECLARE_POINTGROUP("-42m", "y,-x,-z; x,-y,-z", "Tetragonal") DECLARE_POINTGROUP("-4m2", "y,-x,-z; y,x,-z", "Tetragonal") DECLARE_POINTGROUP("4/mmm", "-y,x,z; x,y,-z; x,-y,-z", "Tetragonal") -DECLARE_POINTGROUP("3 h", "-y,x-y,z", "Trigonal - Hexagonal") -DECLARE_POINTGROUP("-3 h", "y,y-x,-z", "Trigonal - Hexagonal") +DECLARE_POINTGROUP("3", "-y,x-y,z", "Trigonal - Hexagonal") +DECLARE_POINTGROUP("-3", "y,y-x,-z", "Trigonal - Hexagonal") DECLARE_POINTGROUP("321", "-y,x-y,z; x-y,-y,-z", "Trigonal - Hexagonal") DECLARE_POINTGROUP("312", "-y,x-y,z; x,x-y,-z", "Trigonal - Hexagonal") DECLARE_POINTGROUP("3m1", "-y,x-y,z; y-x,y,z", "Trigonal - Hexagonal") @@ -196,11 +222,11 @@ DECLARE_POINTGROUP("31m", "-y,x-y,z; -x,y-x,z", "Trigonal - Hexagonal") DECLARE_POINTGROUP("-3m1", "y,y-x,-z; x-y,-y,-z", "Trigonal - Hexagonal") DECLARE_POINTGROUP("-31m", "y,y-x,-z; x,x-y,-z", "Trigonal - Hexagonal") -DECLARE_POINTGROUP("3", "z,x,y", "Trigonal - Rhombohedral") -DECLARE_POINTGROUP("-3", "-z,-x,-y", "Trigonal - Rhombohedral") -DECLARE_POINTGROUP("32", "z,x,y; -y,-x,-z", "Trigonal - Rhombohedral") -DECLARE_POINTGROUP("3m", "z,x,y; y,x,z", "Trigonal - Rhombohedral") -DECLARE_POINTGROUP("-3m", "-z,-x,-y; y,x,z", "Trigonal - Rhombohedral") +DECLARE_POINTGROUP("3 r", "z,x,y", "Trigonal - Rhombohedral") +DECLARE_POINTGROUP("-3 r", "-z,-x,-y", "Trigonal - Rhombohedral") +DECLARE_POINTGROUP("32 r", "z,x,y; -y,-x,-z", "Trigonal - Rhombohedral") +DECLARE_POINTGROUP("3m r", "z,x,y; y,x,z", "Trigonal - Rhombohedral") +DECLARE_POINTGROUP("-3m r", "-z,-x,-y; y,x,z", "Trigonal - Rhombohedral") DECLARE_POINTGROUP("6", "x-y,x,z", "Hexagonal") DECLARE_POINTGROUP("-6", "y-x,-x,-z", "Hexagonal") @@ -211,7 +237,6 @@ DECLARE_POINTGROUP("-62m", "y-x,-x,-z; x-y,-y,-z", "Hexagonal") DECLARE_POINTGROUP("-6m2", "y-x,-x,-z; y-x,y,z", "Hexagonal") DECLARE_POINTGROUP("6/mmm", "x-y,x,z; x-y,-y,-z; -x,-y,-z", "Hexagonal") - DECLARE_POINTGROUP("23", "z,x,y; -x,-y,z; x,-y,-z", "Cubic") DECLARE_POINTGROUP("m-3", "-z,-x,-y; -x,-y,z; x,-y,-z", "Cubic") DECLARE_POINTGROUP("432", "z,x,y; -y,x,z; x,-y,-z", "Cubic") diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryElementFactory.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryElementFactory.cpp index 40b6ba8c633af7940f6bea9f6aa494915b45385e..cdf42076ca548f067a1222773ab16a2499d99b68 100644 --- a/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryElementFactory.cpp +++ b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryElementFactory.cpp @@ -425,11 +425,11 @@ void SymmetryElementFactoryImpl::insertPrototype( m_prototypes.insert(std::make_pair(identifier, prototype)); } -DECLARE_SYMMETRY_ELEMENT_GENERATOR(SymmetryElementIdentityGenerator); -DECLARE_SYMMETRY_ELEMENT_GENERATOR(SymmetryElementTranslationGenerator); -DECLARE_SYMMETRY_ELEMENT_GENERATOR(SymmetryElementInversionGenerator); -DECLARE_SYMMETRY_ELEMENT_GENERATOR(SymmetryElementRotationGenerator); -DECLARE_SYMMETRY_ELEMENT_GENERATOR(SymmetryElementMirrorGenerator); +DECLARE_SYMMETRY_ELEMENT_GENERATOR(SymmetryElementIdentityGenerator) +DECLARE_SYMMETRY_ELEMENT_GENERATOR(SymmetryElementTranslationGenerator) +DECLARE_SYMMETRY_ELEMENT_GENERATOR(SymmetryElementInversionGenerator) +DECLARE_SYMMETRY_ELEMENT_GENERATOR(SymmetryElementRotationGenerator) +DECLARE_SYMMETRY_ELEMENT_GENERATOR(SymmetryElementMirrorGenerator) } // namespace Geometry } // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Rendering/CacheGeometryGenerator.cpp b/Code/Mantid/Framework/Geometry/src/Rendering/CacheGeometryGenerator.cpp index 01493f328c7124728787400ba1e875dc7cff1f9e..dcb1b8b6c9a8e46d585e4a5f0393472ff7fe03b9 100644 --- a/Code/Mantid/Framework/Geometry/src/Rendering/CacheGeometryGenerator.cpp +++ b/Code/Mantid/Framework/Geometry/src/Rendering/CacheGeometryGenerator.cpp @@ -31,7 +31,7 @@ void CacheGeometryGenerator::Generate() { if (mNoOfVertices <= 0) // There are no triangles defined to use OpenCascade handler { -#ifndef NO_OPENCASCADE +#ifdef ENABLE_OPENCASCADE OCGeometryHandler h(Obj); mNoOfVertices = h.NumberOfPoints(); mNoOfTriangles = h.NumberOfTriangles(); diff --git a/Code/Mantid/Framework/Geometry/test/GroupTest.h b/Code/Mantid/Framework/Geometry/test/GroupTest.h index 324ba41309a535ed242f0aa825931ea746dd7cb5..12566f10e5ee3e21cf9d665422001d9c1ecd38e4 100644 --- a/Code/Mantid/Framework/Geometry/test/GroupTest.h +++ b/Code/Mantid/Framework/Geometry/test/GroupTest.h @@ -9,195 +9,230 @@ using namespace Mantid::Geometry; -class GroupTest : public CxxTest::TestSuite -{ +class GroupTest : 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 GroupTest *createSuite() { return new GroupTest(); } - static void destroySuite( GroupTest *suite ) { delete suite; } - - void testDefaultConstructor() - { - Group group; - TS_ASSERT_EQUALS(group.order(), 1); - TS_ASSERT(group.getSymmetryOperations().front().isIdentity()); - } - - void testStringConstructor() - { - Group group("x,y,z; -x,-y,-z"); - - TS_ASSERT_EQUALS(group.order(), 2); - } - - void testConstructor() - { - std::vector<SymmetryOperation> symOps; - symOps.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,z")); - symOps.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); - - TS_ASSERT_THROWS_NOTHING(Group group(symOps)); - - Group group(symOps); - - std::vector<SymmetryOperation> groupOps = group.getSymmetryOperations(); - TS_ASSERT_EQUALS(groupOps.size(), 2); - - std::vector<SymmetryOperation> empty; - TS_ASSERT_THROWS(Group group(empty), std::invalid_argument); - } - - void testCopyConstructor() - { - std::vector<SymmetryOperation> symOps; - symOps.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,z")); - symOps.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); - - Group group(symOps); - Group otherGroup(group); - - TS_ASSERT_EQUALS(group.order(), otherGroup.order()); - TS_ASSERT_EQUALS(group.getSymmetryOperations(), otherGroup.getSymmetryOperations()); - } - - void testAssignmentOperator() - { - std::vector<SymmetryOperation> symOps; - symOps.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,z")); - symOps.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); - - Group otherGroup(symOps); - - Group group; - TS_ASSERT_DIFFERS(group.order(), otherGroup.order()); - TS_ASSERT_DIFFERS(group.getSymmetryOperations(), otherGroup.getSymmetryOperations()); - - group = otherGroup; - TS_ASSERT_EQUALS(group.order(), otherGroup.order()); - TS_ASSERT_EQUALS(group.getSymmetryOperations(), otherGroup.getSymmetryOperations()); - } - - void testOrder() - { - Group defaultGroup; - TS_ASSERT_EQUALS(defaultGroup.order(), 1); - - // Making a group of two operations gives order 2 - std::vector<SymmetryOperation> symOps; - symOps.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,z")); - symOps.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); - - Group biggerGroup(symOps); - TS_ASSERT_EQUALS(biggerGroup.order(), 2); - - // Adding another one results in 3 - symOps.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,y,z")); - Group evenBiggerGroup(symOps); - TS_ASSERT_EQUALS(evenBiggerGroup.order(), 3); - - // Multiple occurences of the same operation do not count - symOps.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); - Group sameAsBefore(symOps); - TS_ASSERT_EQUALS(sameAsBefore.order(), 3); - } - - void testComparison() - { - std::vector<SymmetryOperation> symOps; - symOps.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,z")); - symOps.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); - - Group groupOne(symOps); - Group groupTwo(symOps); - - TS_ASSERT(groupOne == groupTwo); - TS_ASSERT(groupTwo == groupOne); - - Group defaultGroup; - TS_ASSERT(!(groupOne == defaultGroup)); - TS_ASSERT(!(defaultGroup == groupOne)); - TS_ASSERT(groupOne != defaultGroup); - TS_ASSERT(defaultGroup != groupOne); - } - - void testMultiplicationOperator() - { - // We take pointgroup -1 - std::vector<SymmetryOperation> inversion; - inversion.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,z")); - inversion.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); - - // And 2 (b-axis unique) - std::vector<SymmetryOperation> twoFoldY; - twoFoldY.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,z")); - twoFoldY.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,y,-z")); - - Group one(inversion); - Group two(twoFoldY); - - // Multiplication results in 2/m - Group three = one * two; - TS_ASSERT_EQUALS(three.order(), 4); - - // The multiplication created m perpendicular to b (x,-y,-z) - SymmetryOperation mirrorY = SymmetryOperationFactory::Instance().createSymOp("x,-y,z"); - std::vector<SymmetryOperation> opsOfThree = three.getSymmetryOperations(); - - // Check that it is found in the list of symmetry operations of the new group - TS_ASSERT_DIFFERS(std::find(opsOfThree.begin(), opsOfThree.end(), mirrorY), opsOfThree.end()); - - Group four = two * one; - TS_ASSERT(three == four); - } - - void testSmartPointerOperators() - { - // We take pointgroup -1 - std::vector<SymmetryOperation> inversion; - inversion.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,z")); - inversion.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); - - // And 2 (b-axis unique) - std::vector<SymmetryOperation> twoFoldY; - twoFoldY.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,z")); - twoFoldY.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,y,-z")); - - Group_const_sptr one = boost::make_shared<const Group>(inversion); - Group_const_sptr two = boost::make_shared<const Group>(twoFoldY); - - Group_const_sptr three = one * two; - TS_ASSERT_EQUALS(three->order(), 4); - - SymmetryOperation mirrorY = SymmetryOperationFactory::Instance().createSymOp("x,-y,z"); - std::vector<SymmetryOperation> opsOfThree = three->getSymmetryOperations(); - - // Check that it is found in the list of symmetry operations of the new group - TS_ASSERT_DIFFERS(std::find(opsOfThree.begin(), opsOfThree.end(), mirrorY), opsOfThree.end()); - - // Make sure that null-pointer do not work - Group_const_sptr null; - - TS_ASSERT_THROWS(null * null, std::invalid_argument); - //AppleClang gives a warning if we don't use the result + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static GroupTest *createSuite() { return new GroupTest(); } + static void destroySuite(GroupTest *suite) { delete suite; } + + void testDefaultConstructor() { + Group group; + TS_ASSERT_EQUALS(group.order(), 1); + TS_ASSERT(group.getSymmetryOperations().front().isIdentity()); + } + + void testStringConstructor() { + Group group("x,y,z; -x,-y,-z"); + + TS_ASSERT_EQUALS(group.order(), 2); + } + + void testConstructor() { + std::vector<SymmetryOperation> symOps; + symOps.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,z")); + symOps.push_back( + SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); + + TS_ASSERT_THROWS_NOTHING(Group group(symOps)); + + Group group(symOps); + + std::vector<SymmetryOperation> groupOps = group.getSymmetryOperations(); + TS_ASSERT_EQUALS(groupOps.size(), 2); + + std::vector<SymmetryOperation> empty; + TS_ASSERT_THROWS(Group group(empty), std::invalid_argument); + } + + void testCopyConstructor() { + std::vector<SymmetryOperation> symOps; + symOps.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,z")); + symOps.push_back( + SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); + + Group group(symOps); + Group otherGroup(group); + + TS_ASSERT_EQUALS(group.order(), otherGroup.order()); + TS_ASSERT_EQUALS(group.getSymmetryOperations(), + otherGroup.getSymmetryOperations()); + } + + void testAssignmentOperator() { + std::vector<SymmetryOperation> symOps; + symOps.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,z")); + symOps.push_back( + SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); + + Group otherGroup(symOps); + + Group group; + TS_ASSERT_DIFFERS(group.order(), otherGroup.order()); + TS_ASSERT_DIFFERS(group.getSymmetryOperations(), + otherGroup.getSymmetryOperations()); + + group = otherGroup; + TS_ASSERT_EQUALS(group.order(), otherGroup.order()); + TS_ASSERT_EQUALS(group.getSymmetryOperations(), + otherGroup.getSymmetryOperations()); + } + + void testOrder() { + Group defaultGroup; + TS_ASSERT_EQUALS(defaultGroup.order(), 1); + + // Making a group of two operations gives order 2 + std::vector<SymmetryOperation> symOps; + symOps.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,z")); + symOps.push_back( + SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); + + Group biggerGroup(symOps); + TS_ASSERT_EQUALS(biggerGroup.order(), 2); + + // Adding another one results in 3 + symOps.push_back( + SymmetryOperationFactory::Instance().createSymOp("-x,y,z")); + Group evenBiggerGroup(symOps); + TS_ASSERT_EQUALS(evenBiggerGroup.order(), 3); + + // Multiple occurences of the same operation do not count + symOps.push_back( + SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); + Group sameAsBefore(symOps); + TS_ASSERT_EQUALS(sameAsBefore.order(), 3); + } + + void testComparison() { + std::vector<SymmetryOperation> symOps; + symOps.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,z")); + symOps.push_back( + SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); + + Group groupOne(symOps); + Group groupTwo(symOps); + + TS_ASSERT(groupOne == groupTwo); + TS_ASSERT(groupTwo == groupOne); + + Group defaultGroup; + TS_ASSERT(!(groupOne == defaultGroup)); + TS_ASSERT(!(defaultGroup == groupOne)); + TS_ASSERT(groupOne != defaultGroup); + TS_ASSERT(defaultGroup != groupOne); + } + + void testMultiplicationOperator() { + // We take pointgroup -1 + std::vector<SymmetryOperation> inversion; + inversion.push_back( + SymmetryOperationFactory::Instance().createSymOp("x,y,z")); + inversion.push_back( + SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); + + // And 2 (b-axis unique) + std::vector<SymmetryOperation> twoFoldY; + twoFoldY.push_back( + SymmetryOperationFactory::Instance().createSymOp("x,y,z")); + twoFoldY.push_back( + SymmetryOperationFactory::Instance().createSymOp("-x,y,-z")); + + Group one(inversion); + Group two(twoFoldY); + + // Multiplication results in 2/m + Group three = one * two; + TS_ASSERT_EQUALS(three.order(), 4); + + // The multiplication created m perpendicular to b (x,-y,-z) + SymmetryOperation mirrorY = + SymmetryOperationFactory::Instance().createSymOp("x,-y,z"); + std::vector<SymmetryOperation> opsOfThree = three.getSymmetryOperations(); + + // Check that it is found in the list of symmetry operations of the new + // group + TS_ASSERT_DIFFERS(std::find(opsOfThree.begin(), opsOfThree.end(), mirrorY), + opsOfThree.end()); + + Group four = two * one; + TS_ASSERT(three == four); + } + + void testAxisSystemOrthogonal() { + std::vector<SymmetryOperation> orthogonal; + orthogonal.push_back( + SymmetryOperationFactory::Instance().createSymOp("x,y,z")); + orthogonal.push_back( + SymmetryOperationFactory::Instance().createSymOp("-x,y,-z")); + + Group two(orthogonal); + + TS_ASSERT_EQUALS(two.getCoordinateSystem(), Group::Orthogonal); + } + + void testAxisSystemHexagonal() { + std::vector<SymmetryOperation> hexagonal; + hexagonal.push_back( + SymmetryOperationFactory::Instance().createSymOp("-y,x-y,z")); + hexagonal.push_back( + SymmetryOperationFactory::Instance().createSymOp("y,x,-z+1/2")); + + Group two(hexagonal); + + TS_ASSERT_EQUALS(two.getCoordinateSystem(), Group::Hexagonal); + } + + void testSmartPointerOperators() { + // We take pointgroup -1 + std::vector<SymmetryOperation> inversion; + inversion.push_back( + SymmetryOperationFactory::Instance().createSymOp("x,y,z")); + inversion.push_back( + SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); + + // And 2 (b-axis unique) + std::vector<SymmetryOperation> twoFoldY; + twoFoldY.push_back( + SymmetryOperationFactory::Instance().createSymOp("x,y,z")); + twoFoldY.push_back( + SymmetryOperationFactory::Instance().createSymOp("-x,y,-z")); + + Group_const_sptr one = boost::make_shared<const Group>(inversion); + Group_const_sptr two = boost::make_shared<const Group>(twoFoldY); + + Group_const_sptr three = one * two; + TS_ASSERT_EQUALS(three->order(), 4); + + SymmetryOperation mirrorY = + SymmetryOperationFactory::Instance().createSymOp("x,-y,z"); + std::vector<SymmetryOperation> opsOfThree = three->getSymmetryOperations(); + + // Check that it is found in the list of symmetry operations of the new + // group + TS_ASSERT_DIFFERS(std::find(opsOfThree.begin(), opsOfThree.end(), mirrorY), + opsOfThree.end()); + + // Make sure that null-pointer do not work + Group_const_sptr null; + + TS_ASSERT_THROWS(null * null, std::invalid_argument); +// AppleClang gives a warning if we don't use the result #if __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-comparison" #endif - TS_ASSERT_THROWS(null == null, std::invalid_argument); - TS_ASSERT_THROWS(null != null, std::invalid_argument); + TS_ASSERT_THROWS(null == null, std::invalid_argument); + TS_ASSERT_THROWS(null != null, std::invalid_argument); #if __clang__ #pragma clang diagnostic pop #endif - TS_ASSERT_THROWS(three * null, std::invalid_argument); - TS_ASSERT_THROWS(null * three, std::invalid_argument); - - Mantid::Kernel::V3D coords(0.4, 0.3, 0.1); - TS_ASSERT_THROWS(null * coords, std::invalid_argument); - } - + TS_ASSERT_THROWS(three * null, std::invalid_argument); + TS_ASSERT_THROWS(null * three, std::invalid_argument); + Mantid::Kernel::V3D coords(0.4, 0.3, 0.1); + TS_ASSERT_THROWS(null * coords, std::invalid_argument); + } }; - #endif /* MANTID_GEOMETRY_GROUPTEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/PointGroupFactoryTest.h b/Code/Mantid/Framework/Geometry/test/PointGroupFactoryTest.h index c525c1e9101eb058084d2c0e19fcbe3e4d87e12d..ada6ff46fbf341f3d52e96c0a7a7e2da182371d1 100644 --- a/Code/Mantid/Framework/Geometry/test/PointGroupFactoryTest.h +++ b/Code/Mantid/Framework/Geometry/test/PointGroupFactoryTest.h @@ -12,111 +12,129 @@ using Mantid::Geometry::PointGroupFactoryImpl; using namespace Mantid::Geometry; - /* For testing the factory, three fake point groups are defined * and registered in the factory (see below). * * When the test is destroyed, these are explicitly unregistered, * so they don't interfere with other tests. */ -class PointGroupFactoryTest : public CxxTest::TestSuite -{ +class PointGroupFactoryTest : 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 PointGroupFactoryTest *createSuite() { return new PointGroupFactoryTest(); } - static void destroySuite( PointGroupFactoryTest *suite ) { delete suite; } - - PointGroupFactoryTest() - { - PointGroupFactory::Instance().subscribePointGroup("monoclinicA", "x,y,-z", "test"); - PointGroupFactory::Instance().subscribePointGroup("monoclinicB", "x,-y,-z", "test"); - PointGroupFactory::Instance().subscribePointGroup("triclinic", "-x,-y,-z", "test"); + static PointGroupFactoryTest *createSuite() { + return new PointGroupFactoryTest(); + } + static void destroySuite(PointGroupFactoryTest *suite) { delete suite; } + + PointGroupFactoryTest() { + PointGroupFactory::Instance().subscribePointGroup("monoclinicA", "x,y,-z", + "test"); + PointGroupFactory::Instance().subscribePointGroup("monoclinicB", "x,-y,-z", + "test"); + PointGroupFactory::Instance().subscribePointGroup("triclinic", "-x,-y,-z", + "test"); } - ~PointGroupFactoryTest() - { - // Unsubscribing the fake point groups - PointGroupFactory::Instance().unsubscribePointGroup("monoclinicA"); - PointGroupFactory::Instance().unsubscribePointGroup("monoclinicB"); - PointGroupFactory::Instance().unsubscribePointGroup("triclinic"); + ~PointGroupFactoryTest() { + // Unsubscribing the fake point groups + PointGroupFactory::Instance().unsubscribePointGroup("monoclinicA"); + PointGroupFactory::Instance().unsubscribePointGroup("monoclinicB"); + PointGroupFactory::Instance().unsubscribePointGroup("triclinic"); } - void testCreatePointGroup() - { - TS_ASSERT_THROWS_NOTHING(PointGroupFactory::Instance().createPointGroup("monoclinicA")); - TS_ASSERT_THROWS_NOTHING(PointGroupFactory::Instance().createPointGroup("monoclinicB")); - TS_ASSERT_THROWS_NOTHING(PointGroupFactory::Instance().createPointGroup("triclinic")); + void testCreatePointGroup() { + TS_ASSERT_THROWS_NOTHING( + PointGroupFactory::Instance().createPointGroup("monoclinicA")); + TS_ASSERT_THROWS_NOTHING( + PointGroupFactory::Instance().createPointGroup("monoclinicB")); + TS_ASSERT_THROWS_NOTHING( + PointGroupFactory::Instance().createPointGroup("triclinic")); - TS_ASSERT_THROWS(PointGroupFactory::Instance().createPointGroup("cubicC"), std::invalid_argument); + TS_ASSERT_THROWS(PointGroupFactory::Instance().createPointGroup("cubicC"), + std::invalid_argument); } - void testGetAllPointGroupSymbols() - { - std::vector<std::string> symbols = PointGroupFactory::Instance().getAllPointGroupSymbols(); + void testGetAllPointGroupSymbols() { + std::vector<std::string> symbols = + PointGroupFactory::Instance().getAllPointGroupSymbols(); - TS_ASSERT_DIFFERS(findString(symbols, "monoclinicA"), symbols.end()); - TS_ASSERT_DIFFERS(findString(symbols, "monoclinicB"), symbols.end()); - TS_ASSERT_DIFFERS(findString(symbols, "triclinic"), symbols.end()); + TS_ASSERT_DIFFERS(findString(symbols, "monoclinicA"), symbols.end()); + TS_ASSERT_DIFFERS(findString(symbols, "monoclinicB"), symbols.end()); + TS_ASSERT_DIFFERS(findString(symbols, "triclinic"), symbols.end()); } - void testGetAllPointGroupSymbolsCrystalSystems() - { - std::vector<std::string> cubic = PointGroupFactory::Instance().getPointGroupSymbols(PointGroup::Monoclinic); + void testGetAllPointGroupSymbolsCrystalSystems() { + std::vector<std::string> cubic = + PointGroupFactory::Instance().getPointGroupSymbols( + PointGroup::Monoclinic); - TS_ASSERT_DIFFERS(findString(cubic, "monoclinicA"), cubic.end()); - TS_ASSERT_DIFFERS(findString(cubic, "monoclinicB"), cubic.end()); + TS_ASSERT_DIFFERS(findString(cubic, "monoclinicA"), cubic.end()); + TS_ASSERT_DIFFERS(findString(cubic, "monoclinicB"), cubic.end()); - std::vector<std::string> triclinic = PointGroupFactory::Instance().getPointGroupSymbols(PointGroup::Triclinic); - TS_ASSERT_DIFFERS(findString(triclinic, "triclinic"), triclinic.end()); + std::vector<std::string> triclinic = + PointGroupFactory::Instance().getPointGroupSymbols( + PointGroup::Triclinic); + TS_ASSERT_DIFFERS(findString(triclinic, "triclinic"), triclinic.end()); } - void testUnsubscribePointGroup() - { - TS_ASSERT_THROWS_NOTHING(PointGroupFactory::Instance().createPointGroup("monoclinicA")); + void testUnsubscribePointGroup() { + TS_ASSERT_THROWS_NOTHING( + PointGroupFactory::Instance().createPointGroup("monoclinicA")); - PointGroupFactory::Instance().unsubscribePointGroup("monoclinicA"); + PointGroupFactory::Instance().unsubscribePointGroup("monoclinicA"); - std::vector<std::string> allSymbols = PointGroupFactory::Instance().getAllPointGroupSymbols(); - TS_ASSERT_EQUALS(findString(allSymbols, "monoclinicA"), allSymbols.end()); + std::vector<std::string> allSymbols = + PointGroupFactory::Instance().getAllPointGroupSymbols(); + TS_ASSERT_EQUALS(findString(allSymbols, "monoclinicA"), allSymbols.end()); - TS_ASSERT_THROWS(PointGroupFactory::Instance().createPointGroup("monoclinicA"), std::invalid_argument); + TS_ASSERT_THROWS( + PointGroupFactory::Instance().createPointGroup("monoclinicA"), + std::invalid_argument); - PointGroupFactory::Instance().subscribePointGroup("monoclinicA", "x,y,-z", "test"); - TS_ASSERT_THROWS_NOTHING(PointGroupFactory::Instance().createPointGroup("monoclinicA")); + PointGroupFactory::Instance().subscribePointGroup("monoclinicA", "x,y,-z", + "test"); + TS_ASSERT_THROWS_NOTHING( + PointGroupFactory::Instance().createPointGroup("monoclinicA")); } - void testPointGroupSymbolCreation() - { - TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("P -1")); - TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("P 1 2/m 1")); - TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("P 1 1 2/m")); - TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("F d d d")); - TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("C m c a")); - TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("P 43/a m d")); - TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("I 41/c c n")); - TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("P 63/m m c")); - TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("F d -3 m")); - TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("P -3 c 1")); - TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("P -3 1 d")); - TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("P 4/a")); - TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("P 62/d")); - TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("I d -3")); - TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("I 4/c")); + void testPointGroupSymbolCreation() { + TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("P -1")); + TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("P 1 2/m 1")); + TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("F d d d")); + TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("C m c e")); + TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("P 42/n b c")); + TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("I 41/a m d")); + TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("P 63/m m c")); + TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("F d -3 m")); + TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("P 42/m")); + TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("P 63/m")); + TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("F d -3")); + TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("I 4 2 2")); + + TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("P -3 c 1")); + TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("P -3 1 c")); + TS_ASSERT_THROWS_NOTHING(checkSpaceGroupSymbol("R 32")); + + PointGroup_sptr pointGroup = checkSpaceGroupSymbol("R 3"); + TS_ASSERT_EQUALS(pointGroup->getCoordinateSystem(), + Group::CoordinateSystem::Hexagonal); + TS_ASSERT_EQUALS(pointGroup->getSymbol(), "3"); } - private: - std::vector<std::string>::const_iterator findString(const std::vector<std::string> &vector, const std::string &searchString) - { - return std::find(vector.begin(), vector.end(), searchString); + std::vector<std::string>::const_iterator + findString(const std::vector<std::string> &vector, + const std::string &searchString) { + return std::find(vector.begin(), vector.end(), searchString); } - void checkSpaceGroupSymbol(const std::string &symbol) - { - PointGroupFactory::Instance().createPointGroupFromSpaceGroupSymbol(symbol); + PointGroup_sptr checkSpaceGroupSymbol(const std::string &symbol) { + SpaceGroup_const_sptr spaceGroup = + SpaceGroupFactory::Instance().createSpaceGroup(symbol); + return PointGroupFactory::Instance().createPointGroupFromSpaceGroup( + spaceGroup); } }; - #endif /* MANTID_GEOMETRY_POINTGROUPFACTORYTEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/PointGroupTest.h b/Code/Mantid/Framework/Geometry/test/PointGroupTest.h index 414802c6e8a355cdd143f970fe00c0f21744822e..ffaac8d2e1ceb61b7ff0137a5be0663749a74bd2 100644 --- a/Code/Mantid/Framework/Geometry/test/PointGroupTest.h +++ b/Code/Mantid/Framework/Geometry/test/PointGroupTest.h @@ -63,7 +63,7 @@ public: { V3D equiv[] = {V3D(1,2,3),V3D(-1,-2,3), V3D(-2,1,3), V3D(2,-1,3), V3D(-1,2,-3), V3D(1,-2,-3), V3D(2,1,-3), V3D(-2,-1,-3), V3D(-1,-2,-3), V3D(1,2,-3), V3D(2,-1,-3), V3D(-2,1,-3), V3D(1,-2,3), V3D(-1,2,3),V3D(-2,-1,3), V3D(2,1,3)}; check_point_group("4/mmm", V3D(1,2,3), 16, equiv); } { V3D equiv[] = {V3D(1,2,3),V3D(2,-3,3),V3D(-3,1,3), V3D(-1,-2,-3),V3D(-2,3,-3),V3D(3,-1,-3)}; - check_point_group("-3 h", V3D(1,2,3), 6, equiv); } + check_point_group("-3", V3D(1,2,3), 6, equiv); } { V3D equiv[] = {V3D(1,2,3),V3D(2,-3,3),V3D(-3,1,3),V3D(2,1,-3),V3D(1,-3,-3),V3D(-3,2,-3),V3D(-1,-2,-3),V3D(-2,3,-3),V3D(3,-1,-3),V3D(-2,-1,3),V3D(-1,3,3),V3D(3,-2,3)}; check_point_group("-3m1", V3D(1,2,3), 12, equiv); } { V3D equiv[] = {V3D(1,2,3),V3D(2,-3,3),V3D(-3,1,3),V3D(-2,-1,-3),V3D(-1,3,-3),V3D(3,-2,-3),V3D(-1,-2,-3),V3D(-2,3,-3),V3D(3,-1,-3),V3D(2,1,3),V3D(1,-3,3),V3D(-3,2,3),}; @@ -128,19 +128,19 @@ public: crystalSystemsMap["-4m2"] = PointGroup::Tetragonal; crystalSystemsMap["4/mmm"] = PointGroup::Tetragonal; - crystalSystemsMap["3 h"] = PointGroup::Trigonal; - crystalSystemsMap["-3 h"] = PointGroup::Trigonal; + crystalSystemsMap["3"] = PointGroup::Trigonal; + crystalSystemsMap["-3"] = PointGroup::Trigonal; crystalSystemsMap["321"] = PointGroup::Trigonal; crystalSystemsMap["312"] = PointGroup::Trigonal; crystalSystemsMap["3m1"] = PointGroup::Trigonal; crystalSystemsMap["31m"] = PointGroup::Trigonal; crystalSystemsMap["-3m1"] = PointGroup::Trigonal; crystalSystemsMap["-31m"] = PointGroup::Trigonal; - crystalSystemsMap["3"] = PointGroup::Trigonal; - crystalSystemsMap["-3"] = PointGroup::Trigonal; - crystalSystemsMap["32"] = PointGroup::Trigonal; - crystalSystemsMap["3m"] = PointGroup::Trigonal; - crystalSystemsMap["-3m"] = PointGroup::Trigonal; + crystalSystemsMap["3 r"] = PointGroup::Trigonal; + crystalSystemsMap["-3 r"] = PointGroup::Trigonal; + crystalSystemsMap["32 r"] = PointGroup::Trigonal; + crystalSystemsMap["3m r"] = PointGroup::Trigonal; + crystalSystemsMap["-3m r"] = PointGroup::Trigonal; crystalSystemsMap["6"] = PointGroup::Hexagonal; crystalSystemsMap["-6"] = PointGroup::Hexagonal; diff --git a/Code/Mantid/Framework/ISISLiveData/src/FakeISISEventDAE.cpp b/Code/Mantid/Framework/ISISLiveData/src/FakeISISEventDAE.cpp index 6d5a6fa75c92e107e1d93ce31776ece6adf035b2..c699dfb941193e5c54e70e3187967bd923ac0a01 100644 --- a/Code/Mantid/Framework/ISISLiveData/src/FakeISISEventDAE.cpp +++ b/Code/Mantid/Framework/ISISLiveData/src/FakeISISEventDAE.cpp @@ -19,7 +19,7 @@ namespace Mantid { namespace ISISLiveData { // Register the algorithm into the algorithm factory -DECLARE_ALGORITHM(FakeISISEventDAE); +DECLARE_ALGORITHM(FakeISISEventDAE) using namespace Kernel; using namespace API; diff --git a/Code/Mantid/Framework/Kernel/CMakeLists.txt b/Code/Mantid/Framework/Kernel/CMakeLists.txt index 887bba0271579674dd2aff16e4107f268ffe51ac..07d6f10edbb7529ecaf9e15a95a7d554e653a20e 100644 --- a/Code/Mantid/Framework/Kernel/CMakeLists.txt +++ b/Code/Mantid/Framework/Kernel/CMakeLists.txt @@ -8,6 +8,7 @@ set ( SRC_FILES src/CPUTimer.cpp src/CatalogInfo.cpp src/CompositeValidator.cpp + src/ComputeResourceInfo.cpp src/ConfigService.cpp src/ChecksumHelper.cpp src/DataItem.cpp @@ -128,6 +129,7 @@ set ( INC_FILES inc/MantidKernel/Cache.h inc/MantidKernel/CatalogInfo.h inc/MantidKernel/CompositeValidator.h + inc/MantidKernel/ComputeResourceInfo.h inc/MantidKernel/ConfigService.h inc/MantidKernel/ChecksumHelper.h inc/MantidKernel/DataItem.h @@ -264,6 +266,7 @@ set ( TEST_FILES CacheTest.h CatalogInfoTest.h CompositeValidatorTest.h + ComputeResourceInfoTest.h ConfigServiceTest.h ChecksumHelperTest.h DataServiceTest.h diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ChecksumHelper.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ChecksumHelper.h index 5a4f70794fe35eca19023c28a7ba59c495173de0..54a6b5fcf22e78c4d73b20cfa446924512861f84 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ChecksumHelper.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ChecksumHelper.h @@ -40,7 +40,7 @@ MANTID_KERNEL_DLL std::string sha1FromString(const std::string &input); MANTID_KERNEL_DLL std::string sha1FromFile(const std::string &filepath); /// create a git checksum from a file (these match the git hash-object command) MANTID_KERNEL_DLL std::string gitSha1FromFile(const std::string &filepath); -}; +} } // namespace Kernel } // namespace Mantid diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ComputeResourceInfo.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ComputeResourceInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..db27c93ed68e8bcaaf1e7434fc1dca88b3bd1483 --- /dev/null +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ComputeResourceInfo.h @@ -0,0 +1,82 @@ +#ifndef MANTID_KERNEL_COMPUTERESOURCEINFO_H_ +#define MANTID_KERNEL_COMPUTERESOURCEINFO_H_ + +#include <string> + +#include "MantidKernel/DllConfig.h" + +namespace Poco { +namespace XML { +class Element; +} +} + +namespace Mantid { +namespace Kernel { + +class FacilityInfo; + +/** +ComputeResourceInfo holds information about / represents a compute +resource present in a facility. + +At the moment (remote) compute resources are defined by their name, +the URL they can be accessed at, and the type of remote job manager +that they use/require (Mantid web service API, LSF, etc.). + +Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge +National Laboratory & European Spallation Source + +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://github.com/mantidproject/mantid>. +Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_KERNEL_DLL ComputeResourceInfo { +public: + /// constructor - from facility info and the element for this resource + ComputeResourceInfo(const FacilityInfo *f, const Poco::XML::Element *elem); + + /// Equality operator + bool operator==(const ComputeResourceInfo &rhs) const; + + /// Name of the compute resource + std::string name() const; + + /// Base URL the compute resource + std::string baseURL() const ; + + /// Type/class of remote job manager required to handle this resource + std::string remoteJobManagerType() const; + + /// The facility where this compute resource is avalable + const FacilityInfo &facility() const; + +private: + const FacilityInfo *m_facility; ///< Facility + std::string m_name; ///< Cluster/resource name + std::string m_baseURL; ///< access URL (first authentication, etc.) + std::string m_managerType; ///< specific remote job manager class +}; + +/// output to stream operator for compute resource info objects +MANTID_KERNEL_DLL std::ostream & +operator<<(std::ostream &buffer, const ComputeResourceInfo &cr); + +} // namespace Kernel +} // namespace Mantid + +#endif /* MANTID_KERNEL_COMPUTERESOURCEINFO_H_ */ diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/FacilityInfo.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/FacilityInfo.h index 2d5976003305abfd697f2a52eb653a3accad0891..20c5d7172471f2ceb0367e185e410cbadf8a26f3 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/FacilityInfo.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/FacilityInfo.h @@ -6,6 +6,7 @@ //---------------------------------------------------------------------- #include "MantidKernel/DllConfig.h" #include "MantidKernel/CatalogInfo.h" +#include "MantidKernel/ComputeResourceInfo.h" #include "MantidKernel/InstrumentInfo.h" #include "MantidKernel/RemoteJobManager.h" #ifndef Q_MOC_RUN @@ -80,7 +81,13 @@ public: std::vector<InstrumentInfo> instruments(const std::string &tech) const; /// Returns instruments with given name const InstrumentInfo &instrument(std::string iName = "") const; - /// Returns a vector of the available compute resources + + /// Returns a vector of available compute resources + std::vector<ComputeResourceInfo> computeResInfos() const; + /// Returns a compute resource identified by name + const ComputeResourceInfo &computeResource(const std::string &name) const; + + /// Returns a vector of the names of the available compute resources std::vector<std::string> computeResources() const; /// Returns the RemoteJobManager for the named compute resource boost::shared_ptr<RemoteJobManager> @@ -113,12 +120,18 @@ private: std::vector<InstrumentInfo> m_instruments; ///< list of instruments of this facility std::string m_liveListener; ///< name of the default live listener + + std::vector<ComputeResourceInfo> m_computeResInfos; ///< (remote) compute + /// resources available in + /// this facility + + // TODO: remove RemoteJobManager form here (trac ticket #11373) typedef std::map<std::string, boost::shared_ptr<RemoteJobManager>> ComputeResourcesMap; ComputeResourcesMap m_computeResources; ///< list of compute resources ///(clusters, etc...) available at - /// this facility - // (Sorted by their names) + /// this facility + // (Sorted by their names) }; } // namespace Kernel diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/FileDescriptor.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/FileDescriptor.h index bb5a73ee5e12545a400d890c7a5ae54bd245a535..ec76acae46bbbf443194dbfddf673ca0bf6dba40 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/FileDescriptor.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/FileDescriptor.h @@ -78,8 +78,8 @@ public: void resetStreamToStart(); private: - DISABLE_DEFAULT_CONSTRUCT(FileDescriptor); - DISABLE_COPY_AND_ASSIGN(FileDescriptor); + DISABLE_DEFAULT_CONSTRUCT(FileDescriptor) + DISABLE_COPY_AND_ASSIGN(FileDescriptor) /// Open the file and cache description elements void initialize(const std::string &filename); diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/FilteredTimeSeriesProperty.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/FilteredTimeSeriesProperty.h index 74a31555811dca4fad720203c27cc37d3c13a397..6c4d23a45cabb514d3d0a1be448335ad9f62965b 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/FilteredTimeSeriesProperty.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/FilteredTimeSeriesProperty.h @@ -49,7 +49,7 @@ public: const TimeSeriesProperty<HeldType> *unfiltered() const; private: - DISABLE_DEFAULT_CONSTRUCT(FilteredTimeSeriesProperty); + DISABLE_DEFAULT_CONSTRUCT(FilteredTimeSeriesProperty) /// The original unfiltered property as an owned pointer const TimeSeriesProperty<HeldType> *m_unfiltered; diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/LogFilter.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/LogFilter.h index e9384a4ea1aa095cd2febd67f198b766fddde406..7f5b755c62191f5f4dac5a1c3b425b2b7dd63cd0 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/LogFilter.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/LogFilter.h @@ -68,8 +68,8 @@ public: void clear(); private: - DISABLE_DEFAULT_CONSTRUCT(LogFilter); - DISABLE_COPY_AND_ASSIGN(LogFilter); + DISABLE_DEFAULT_CONSTRUCT(LogFilter) + DISABLE_COPY_AND_ASSIGN(LogFilter) /// Converts the given property to a TimeSeriesProperty<double>, throws if /// invalid. diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/MagneticFormFactorTable.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/MagneticFormFactorTable.h index 0e21199f3feddcc2e4b413f58ac1281f5663f466..00bd8c8e67bd386c601ce057e5039c2d4c269520 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/MagneticFormFactorTable.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/MagneticFormFactorTable.h @@ -45,8 +45,8 @@ public: double value(const double qsqr) const; private: - DISABLE_DEFAULT_CONSTRUCT(MagneticFormFactorTable); - DISABLE_COPY_AND_ASSIGN(MagneticFormFactorTable); + DISABLE_DEFAULT_CONSTRUCT(MagneticFormFactorTable) + DISABLE_COPY_AND_ASSIGN(MagneticFormFactorTable) /// Setup the table with the values void setup(const MagneticIon &ion, const uint16_t j, const uint16_t l); diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Math/Optimization/SLSQPMinimizer.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Math/Optimization/SLSQPMinimizer.h index f536e4caebba98537b31216971a78afe79fcc9b2..193b623fcfc47c2c9441db272c47cac7889e7317 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Math/Optimization/SLSQPMinimizer.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Math/Optimization/SLSQPMinimizer.h @@ -106,8 +106,8 @@ public: std::vector<double> minimize(const std::vector<double> &x0) const; private: - DISABLE_DEFAULT_CONSTRUCT(SLSQPMinimizer); - DISABLE_COPY_AND_ASSIGN(SLSQPMinimizer); + DISABLE_DEFAULT_CONSTRUCT(SLSQPMinimizer) + DISABLE_COPY_AND_ASSIGN(SLSQPMinimizer) /** * Compute the value of the objective function diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/MersenneTwister.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/MersenneTwister.h index 3b08e05e46c4a2a165f938ea058ae41786db42bb..5764a762678e9237d57737596836aef70c02042b 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/MersenneTwister.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/MersenneTwister.h @@ -80,8 +80,8 @@ public: virtual void restore(); private: - DISABLE_DEFAULT_CONSTRUCT(MersenneTwister); - DISABLE_COPY_AND_ASSIGN(MersenneTwister); + DISABLE_DEFAULT_CONSTRUCT(MersenneTwister) + DISABLE_COPY_AND_ASSIGN(MersenneTwister) /// The boost Mersenne Twister generator boost::mt19937 m_generator; diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/NDPseudoRandomNumberGenerator.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/NDPseudoRandomNumberGenerator.h index b751348788955cbbf9c9e242488cb7b5684cc1f8..29066b78b3b7b8e20db114761c0010f09ed51f62 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/NDPseudoRandomNumberGenerator.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/NDPseudoRandomNumberGenerator.h @@ -65,8 +65,8 @@ public: void restore(); private: - DISABLE_DEFAULT_CONSTRUCT(NDPseudoRandomNumberGenerator); - DISABLE_COPY_AND_ASSIGN(NDPseudoRandomNumberGenerator); + DISABLE_DEFAULT_CONSTRUCT(NDPseudoRandomNumberGenerator) + DISABLE_COPY_AND_ASSIGN(NDPseudoRandomNumberGenerator) /// The single value generator SingleValueGenerator m_singleValueGen; diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/NDRandomNumberGenerator.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/NDRandomNumberGenerator.h index 4d62f842c9507537e8a597dc542d95deac671c58..cbeae096e625fe1d1a77eab3df89487713dd4cc9 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/NDRandomNumberGenerator.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/NDRandomNumberGenerator.h @@ -72,8 +72,8 @@ protected: inline std::vector<double> &getNextPointCache() { return m_nextPoint; } private: - DISABLE_DEFAULT_CONSTRUCT(NDRandomNumberGenerator); - DISABLE_COPY_AND_ASSIGN(NDRandomNumberGenerator); + DISABLE_DEFAULT_CONSTRUCT(NDRandomNumberGenerator) + DISABLE_COPY_AND_ASSIGN(NDRandomNumberGenerator) /// The number of dimensions const unsigned int m_ndims; diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/NexusDescriptor.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/NexusDescriptor.h index 5ae344033873922bad8c1083e9d9e53eb5d94ffe..f46774eebf53aea807b0107ba22d4e8e51cdeb7f 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/NexusDescriptor.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/NexusDescriptor.h @@ -98,8 +98,8 @@ public: bool classTypeExists(const std::string &classType) const; private: - DISABLE_DEFAULT_CONSTRUCT(NexusDescriptor); - DISABLE_COPY_AND_ASSIGN(NexusDescriptor); + DISABLE_DEFAULT_CONSTRUCT(NexusDescriptor) + DISABLE_COPY_AND_ASSIGN(NexusDescriptor) /// Initialize object with filename void initialize(const std::string &filename); diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h index 85f67ac066da8f40144ae9bc5470bf9bd423c71e..bd55cf9b501cfb9a25f7b2a5365b562425a675fa 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h @@ -198,10 +198,10 @@ void toValue(const std::string &strvalue, std::vector<std::vector<T>> &value, } \ } -PROPERTYWITHVALUE_TOVALUE(int); -PROPERTYWITHVALUE_TOVALUE(long); -PROPERTYWITHVALUE_TOVALUE(uint32_t); -PROPERTYWITHVALUE_TOVALUE(uint64_t); +PROPERTYWITHVALUE_TOVALUE(int) +PROPERTYWITHVALUE_TOVALUE(long) +PROPERTYWITHVALUE_TOVALUE(uint32_t) +PROPERTYWITHVALUE_TOVALUE(uint64_t) #if defined(__APPLE__) PROPERTYWITHVALUE_TOVALUE(unsigned long); #endif diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PseudoRandomNumberGenerator.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PseudoRandomNumberGenerator.h index c6c1805f493815661e0d0b0cea4299d36cd5a015..06d1c067c571893d6af827a8b9db2fbdae3684c6 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PseudoRandomNumberGenerator.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PseudoRandomNumberGenerator.h @@ -51,7 +51,7 @@ public: virtual void generateNextPoint(); private: - DISABLE_COPY_AND_ASSIGN(PseudoRandomNumberGenerator); + DISABLE_COPY_AND_ASSIGN(PseudoRandomNumberGenerator) }; } } diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/SobolSequence.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/SobolSequence.h index 4d0be933d00fd7b5f3b847ac156c300ff95dc1a0..b45ed71c2deeb540e73ff280f736fbae1675e2f8 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/SobolSequence.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/SobolSequence.h @@ -57,8 +57,8 @@ public: void restore(); private: - DISABLE_DEFAULT_CONSTRUCT(SobolSequence); - DISABLE_COPY_AND_ASSIGN(SobolSequence); + DISABLE_DEFAULT_CONSTRUCT(SobolSequence) + DISABLE_COPY_AND_ASSIGN(SobolSequence) /// Set the number of dimensions void setNumberOfDimensions(const unsigned int ndims); diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Unit.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Unit.h index f29c7b254576573bb455279ca1a55833e22722e4..6f563faea76bc1aea63fd2d4aab427a164ad9a00 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Unit.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Unit.h @@ -616,11 +616,17 @@ protected: class MANTID_KERNEL_DLL Degrees : public Empty { public: Degrees(); - const std::string unitID() const { return ""; } - virtual const std::string caption() const { return "Scattering angle"; } + const std::string unitID() const; /// < Degrees + const std::string caption() const { return "Scattering angle"; } const UnitLabel label() const; - virtual Unit *clone() const { return new Degrees(*this); } + virtual void init(); + virtual Unit *clone() const; + + virtual double singleToTOF(const double x) const; + virtual double singleFromTOF(const double tof) const; + virtual double conversionTOFMin() const; + virtual double conversionTOFMax() const; private: UnitLabel m_label; diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/UnitLabel.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/UnitLabel.h index 6cb1eb6cdc357bc652b0b1b21650f7fd65746ee0..0cd9829df37de1a85768d7f76f3e28775150af05 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/UnitLabel.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/UnitLabel.h @@ -80,7 +80,7 @@ public: operator std::string() const; private: - DISABLE_DEFAULT_CONSTRUCT(UnitLabel); + DISABLE_DEFAULT_CONSTRUCT(UnitLabel) /// Value of plain-text label std::string m_ascii; diff --git a/Code/Mantid/Framework/Kernel/src/ComputeResourceInfo.cpp b/Code/Mantid/Framework/Kernel/src/ComputeResourceInfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6669c1f228310ec4bcba078f3f79a072f96cad77 --- /dev/null +++ b/Code/Mantid/Framework/Kernel/src/ComputeResourceInfo.cpp @@ -0,0 +1,115 @@ +#include "MantidKernel/ComputeResourceInfo.h" +#include "MantidKernel/FacilityInfo.h" +#include "MantidKernel/Logger.h" + +#include <Poco/DOM/AutoPtr.h> +#include <Poco/DOM/Element.h> +#include <Poco/DOM/NodeList.h> +#include <Poco/DOM/Text.h> + +namespace Mantid { +namespace Kernel { +namespace { +// static logger object +Logger g_log("ComputeResourceInfo"); +} + +/** + * Construct a compute resource from information found in a facilities + * definition file. + * + * @param fac Facility where this (remote) compute resource is available + * @param elem A (Poco::XML::) Element to read the data from + * + * @throw std::runtime_error if name or required attributes are not + * found + */ +ComputeResourceInfo::ComputeResourceInfo(const FacilityInfo *fac, + const Poco::XML::Element *elem) + : m_facility(fac) { + + m_name = elem->getAttribute("name"); + if (m_name.empty()) { + std::string elemStr = ""; + if (elem) + elemStr = elem->innerText(); + throw std::runtime_error( + "The compute resource name is not defined, at element: " + elemStr); + } + + // default: Mantid web service API: + // http://www.mantidproject.org/Remote_Job_Submission_API + m_managerType = "MantidWebServiceAPIJobManager"; + std::string type = elem->getAttribute("JobManagerType"); + if (!type.empty()) { + m_managerType = type; + } + + const std::string baseTag = "baseURL"; + Poco::AutoPtr<Poco::XML::NodeList> nl = elem->getElementsByTagName(baseTag); + if (!nl || nl->length() != 1 || !nl->item(0) || !nl->item(0)->childNodes()) { + g_log.error("Failed to get base URL for remote compute resource '" + + m_name + "'"); + throw std::runtime_error("Remote compute resources must have exactly one " + "baseURL tag. It was not found for the resource " + "'" + + m_name + "'"); + } else { + nl = nl->item(0)->childNodes(); + if (nl->length() > 0) { + Poco::XML::Text *txt = dynamic_cast<Poco::XML::Text *>(nl->item(0)); + if (txt) { + m_baseURL = txt->getData(); + } else { + g_log.error("Failed to get base URL for remote compute resource '" + + m_name + "'. The " + baseTag + " tag seems empty!"); + throw std::runtime_error( + "Remote compute resources must have exactly one " + "baseURL tag containing a URL string. A tag was found for the " + "resource " + "'" + + m_name + "', but it seems empty!"); + } + } + } +} + +/** +* Equality operator. Two different resources cannot have the same name +* +* @param rhs object to compare this with +* +* @return True if the objects (names) are equal +*/ +bool ComputeResourceInfo::operator==(const ComputeResourceInfo &rhs) const { + return (this->name() == rhs.name()); +} + +std::string ComputeResourceInfo::name() const { return m_name; } + +std::string ComputeResourceInfo::baseURL() const { return m_baseURL; } + +std::string ComputeResourceInfo::remoteJobManagerType() const { + return m_managerType; +} + +const FacilityInfo &ComputeResourceInfo::facility() const { + return *m_facility; +} + +/** + * Prints the instrument name into an output stream + * + * @param buffer an output stream being written to + * @param cr a ComputeResourceInfo object to print + * + * @return reference to the output stream being written to + */ +std::ostream &operator<<(std::ostream &buffer, const ComputeResourceInfo &cr) { + buffer << "'" + cr.name() + "', at '" + cr.baseURL() + "', of type '" + + cr.remoteJobManagerType() + "'"; + return buffer; +} + +} // namespace Kernel +} // namespace Mantid diff --git a/Code/Mantid/Framework/Kernel/src/FacilityInfo.cpp b/Code/Mantid/Framework/Kernel/src/FacilityInfo.cpp index 7346c52307c62fe54291b6032c56f89309ff623a..dad72eec268239254af844eda8d20fd5d268cf1c 100644 --- a/Code/Mantid/Framework/Kernel/src/FacilityInfo.cpp +++ b/Code/Mantid/Framework/Kernel/src/FacilityInfo.cpp @@ -154,10 +154,24 @@ void FacilityInfo::fillComputeResources(const Poco::XML::Element *elem) { for (unsigned long i = 0; i < n; i++) { Poco::XML::Element *elem = dynamic_cast<Poco::XML::Element *>(pNL_compute->item(i)); - std::string name = elem->getAttribute("name"); - m_computeResources.insert(std::make_pair( - name, boost::shared_ptr<RemoteJobManager>(new RemoteJobManager(elem)))); + if (elem) { + try { + ComputeResourceInfo cr(this, elem); + m_computeResInfos.push_back(cr); + + g_log.debug() << "Compute resource found: " << cr << std::endl; + } catch (...) { // next resource... + } + + std::string name = elem->getAttribute("name"); + // TODO: this is a bit of duplicate effort at the moment, until + // RemoteJobManager goes away from here (then this would be + // removed), see header for details. + m_computeResources.insert(std::make_pair( + name, + boost::shared_ptr<RemoteJobManager>(new RemoteJobManager(elem)))); + } } } @@ -202,14 +216,22 @@ const InstrumentInfo &FacilityInfo::instrument(std::string iName) const { } /** - * Returns a list of instruments of given technique - * @param tech :: Technique name - * @return a list of instrument information objects + * Get the vector of available compute resources + * @return vector of ComputeResourInfo for the current facility */ +std::vector<ComputeResourceInfo> FacilityInfo::computeResInfos() const { + return m_computeResInfos; +} + +/** +* Returns a list of instruments of given technique +* @param tech :: Technique name +* @return a list of instrument information objects +*/ std::vector<InstrumentInfo> FacilityInfo::instruments(const std::string &tech) const { std::vector<InstrumentInfo> out; - std::vector<InstrumentInfo>::const_iterator it = m_instruments.begin(); + auto it = m_instruments.begin(); for (; it != m_instruments.end(); ++it) { if (it->techniques().count(tech)) { out.push_back(*it); @@ -219,7 +241,7 @@ FacilityInfo::instruments(const std::string &tech) const { } /** - * Returns a vector of the available compute resources + * Returns a vector of the names of the available compute resources * @return vector of strings of the compute resource names */ std::vector<std::string> FacilityInfo::computeResources() const { @@ -233,6 +255,39 @@ std::vector<std::string> FacilityInfo::computeResources() const { return names; } +/** + * Get a compute resource by name + * + * @param name Name as specified in the facilities definition file + * + * @return the named compute resource + * + * @throws NotFoundError if the resource is not found/available. + */ +const ComputeResourceInfo & +FacilityInfo::computeResource(const std::string &name) const { + if (name.empty()) { + g_log.debug("Cannot find a compute resource without name " + "(empty)."); + throw Exception::NotFoundError("FacilityInfo, empty compute resource name", + name); + } + + auto it = m_computeResInfos.begin(); + for (; it != m_computeResInfos.end(); ++it) { + if (it->name() == name) { + g_log.debug() << "Compute resource '" << name << "' found at facility " + << this->name() << "." << std::endl; + return *it; + } + } + + g_log.debug() << "Could not find requested compute resource: " << name + << " in facility " << this->name() << "." << std::endl; + throw Exception::NotFoundError("FacilityInfo, missing compute resource", + name); +} + /** * Returns a reference to the requested remote job manager * @param name :: Name of the cluster we want to submit jobs to diff --git a/Code/Mantid/Framework/Kernel/src/FilteredTimeSeriesProperty.cpp b/Code/Mantid/Framework/Kernel/src/FilteredTimeSeriesProperty.cpp index 07d01c24be0b4cf1b5bdaaac8e22b2c1032160e4..52a8e817ddbf20788717bb5f012aedc036f702a0 100644 --- a/Code/Mantid/Framework/Kernel/src/FilteredTimeSeriesProperty.cpp +++ b/Code/Mantid/Framework/Kernel/src/FilteredTimeSeriesProperty.cpp @@ -53,16 +53,16 @@ FilteredTimeSeriesProperty<HeldType>::unfiltered() const { // -------------------------- Concrete instantiation // ----------------------------------------------- -INSTANTIATE(int); -INSTANTIATE(long); -INSTANTIATE(long long); -INSTANTIATE(unsigned int); -INSTANTIATE(unsigned long); -INSTANTIATE(unsigned long long); -INSTANTIATE(float); -INSTANTIATE(double); -INSTANTIATE(std::string); -INSTANTIATE(bool); +INSTANTIATE(int) +INSTANTIATE(long) +INSTANTIATE(long long) +INSTANTIATE(unsigned int) +INSTANTIATE(unsigned long) +INSTANTIATE(unsigned long long) +INSTANTIATE(float) +INSTANTIATE(double) +INSTANTIATE(std::string) +INSTANTIATE(bool) ///@endcond diff --git a/Code/Mantid/Framework/Kernel/src/IPropertyManager.cpp b/Code/Mantid/Framework/Kernel/src/IPropertyManager.cpp index 0d1730b581d78219392fb0204e49437f5bcdcfe4..36961d43915405e62d2d90412392bc68b81b579b 100644 --- a/Code/Mantid/Framework/Kernel/src/IPropertyManager.cpp +++ b/Code/Mantid/Framework/Kernel/src/IPropertyManager.cpp @@ -7,23 +7,23 @@ #include <algorithm> ///@cond -DEFINE_IPROPERTYMANAGER_GETVALUE(int16_t); -DEFINE_IPROPERTYMANAGER_GETVALUE(uint16_t); -DEFINE_IPROPERTYMANAGER_GETVALUE(int32_t); -DEFINE_IPROPERTYMANAGER_GETVALUE(uint32_t); -DEFINE_IPROPERTYMANAGER_GETVALUE(int64_t); -DEFINE_IPROPERTYMANAGER_GETVALUE(uint64_t); -DEFINE_IPROPERTYMANAGER_GETVALUE(bool); -DEFINE_IPROPERTYMANAGER_GETVALUE(double); -DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<int16_t>); -DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<uint16_t>); -DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<int32_t>); -DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<uint32_t>); -DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<int64_t>); -DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<uint64_t>); -DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<double>); -DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<std::string>); -DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<std::vector<std::string>>); +DEFINE_IPROPERTYMANAGER_GETVALUE(int16_t) +DEFINE_IPROPERTYMANAGER_GETVALUE(uint16_t) +DEFINE_IPROPERTYMANAGER_GETVALUE(int32_t) +DEFINE_IPROPERTYMANAGER_GETVALUE(uint32_t) +DEFINE_IPROPERTYMANAGER_GETVALUE(int64_t) +DEFINE_IPROPERTYMANAGER_GETVALUE(uint64_t) +DEFINE_IPROPERTYMANAGER_GETVALUE(bool) +DEFINE_IPROPERTYMANAGER_GETVALUE(double) +DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<int16_t>) +DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<uint16_t>) +DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<int32_t>) +DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<uint32_t>) +DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<int64_t>) +DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<uint64_t>) +DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<double>) +DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<std::string>) +DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<std::vector<std::string>>) namespace Mantid { namespace Kernel { diff --git a/Code/Mantid/Framework/Kernel/src/InstrumentInfo.cpp b/Code/Mantid/Framework/Kernel/src/InstrumentInfo.cpp index 60e610a0169609d84eb875d85918293bad4963b9..9b0f8bc57aced45671c461b6f8666ddd10a9832c 100644 --- a/Code/Mantid/Framework/Kernel/src/InstrumentInfo.cpp +++ b/Code/Mantid/Framework/Kernel/src/InstrumentInfo.cpp @@ -7,10 +7,10 @@ #include "MantidKernel/Logger.h" #include "MantidKernel/Strings.h" +#include <Poco/DOM/AutoPtr.h> #include <Poco/DOM/Element.h> #include <Poco/DOM/NodeList.h> #include <Poco/DOM/Text.h> -#include <Poco/DOM/AutoPtr.h> #include <boost/lexical_cast.hpp> diff --git a/Code/Mantid/Framework/Kernel/src/LogParser.cpp b/Code/Mantid/Framework/Kernel/src/LogParser.cpp index c58b0d77155598a97376c45d293a07e36cc9faad..e88d7f883f308beaf3c98e47d179f04d5cf0e866 100644 --- a/Code/Mantid/Framework/Kernel/src/LogParser.cpp +++ b/Code/Mantid/Framework/Kernel/src/LogParser.cpp @@ -45,7 +45,7 @@ Kernel::Property *LogParser::createLogProperty(const std::string &logFName, } // Change times and new values read from file - std::map<std::string, std::string> change_times; + std::multimap<std::string, std::string> change_times; // Read in the data and determin if it is numeric std::string str, old_data; @@ -70,8 +70,16 @@ Kernel::Property *LogParser::createLogProperty(const std::string &logFName, g_log.error(mess); throw std::logic_error(mess); } - change_times[stime] += std::string(" ") + str; - continue; + auto range = change_times.equal_range(stime); + if ( range.first != range.second ){ + auto last = range.first; + for(auto it = last; it != range.second; ++it){ + last = it; + } + last->second += std::string(" ") + str; + old_data = last->second; + continue; + } } stime = str.substr(0, 19); sdata = str.substr(19); @@ -86,12 +94,7 @@ Kernel::Property *LogParser::createLogProperty(const std::string &logFName, isNumeric = !istr.fail(); old_data = sdata; - // if time is repeated and the data aren't numeric append the new string to - // the old one - if (!isNumeric && change_times[stime].size() > 0) - change_times[stime] += std::string(" ") + sdata; - else - change_times[stime] = sdata; + change_times.insert( std::make_pair(stime,sdata) ); } if (change_times.empty()) @@ -100,7 +103,7 @@ Kernel::Property *LogParser::createLogProperty(const std::string &logFName, if (isNumeric) { Kernel::TimeSeriesProperty<double> *logv = new Kernel::TimeSeriesProperty<double>(name); - std::map<std::string, std::string>::iterator it = change_times.begin(); + auto it = change_times.begin(); for (; it != change_times.end(); ++it) { std::istringstream istr(it->second); double d; @@ -111,7 +114,7 @@ Kernel::Property *LogParser::createLogProperty(const std::string &logFName, } else { Kernel::TimeSeriesProperty<std::string> *logv = new Kernel::TimeSeriesProperty<std::string>(name); - std::map<std::string, std::string>::iterator it = change_times.begin(); + auto it = change_times.begin(); for (; it != change_times.end(); ++it) { logv->addValue(it->first, it->second); } @@ -218,7 +221,7 @@ LogParser::LogParser(const Kernel::Property *log) : m_nOfPeriods(1) { m_nOfPeriods = 1; - std::map<Kernel::DateAndTime, std::string>::const_iterator it = logm.begin(); + auto it = logm.begin(); for (; it != logm.end(); ++it) { std::string scom; @@ -253,7 +256,7 @@ Kernel::TimeSeriesProperty<bool> *LogParser::createPeriodLog(int period) const { Kernel::TimeSeriesProperty<bool> *p = new Kernel::TimeSeriesProperty<bool>("period " + ostr.str()); std::map<Kernel::DateAndTime, int> pMap = periods->valueAsMap(); - std::map<Kernel::DateAndTime, int>::const_iterator it = pMap.begin(); + auto it = pMap.begin(); if (it->second != period) p->addValue(it->first, false); for (; it != pMap.end(); ++it) diff --git a/Code/Mantid/Framework/Kernel/src/Matrix.cpp b/Code/Mantid/Framework/Kernel/src/Matrix.cpp index e6a50066fe5d10dbc4869ed96bb4b2dcc958b05b..425b07ab4f3d66e5371bf822f4ec65b6e729ff9c 100644 --- a/Code/Mantid/Framework/Kernel/src/Matrix.cpp +++ b/Code/Mantid/Framework/Kernel/src/Matrix.cpp @@ -351,11 +351,15 @@ V3D Matrix<T>::operator*(const V3D &Vx) const @return Matrix(This * A) */ { - if (ny != 3 || nx != 3) + if (ny != 3 || nx > 3) throw Kernel::Exception::MisMatch<size_t>(ny, 3, "Matrix::operator*(V3D)"); - return V3D(V[0][0] * Vx.X() + V[0][1] * Vx.Y() + V[0][2] * Vx.Z(), - V[1][0] * Vx.X() + V[1][1] * Vx.Y() + V[1][2] * Vx.Z(), - V[2][0] * Vx.X() + V[2][1] * Vx.Y() + V[2][2] * Vx.Z()); + + V3D v; + for(size_t i = 0; i < nx; ++i) { + v[i] = V[i][0] * Vx.X() + V[i][1] * Vx.Y() + V[i][2] * Vx.Z(); + } + + return v; } template <typename T> diff --git a/Code/Mantid/Framework/Kernel/src/MatrixProperty.cpp b/Code/Mantid/Framework/Kernel/src/MatrixProperty.cpp index 3ff63a07bf748f1a15397d4b1add81652b56a9c2..ddd680bdac9ea217da6fab7c7c783134e2d069ef 100644 --- a/Code/Mantid/Framework/Kernel/src/MatrixProperty.cpp +++ b/Code/Mantid/Framework/Kernel/src/MatrixProperty.cpp @@ -43,7 +43,7 @@ template class MANTID_KERNEL_DLL MatrixProperty<float>; /** * IPropertyManager::getValue definitions */ -DEFINE_IPROPERTYMANAGER_GETVALUE(Mantid::Kernel::DblMatrix); -DEFINE_IPROPERTYMANAGER_GETVALUE(Mantid::Kernel::IntMatrix); -DEFINE_IPROPERTYMANAGER_GETVALUE(Mantid::Kernel::Matrix<float>); +DEFINE_IPROPERTYMANAGER_GETVALUE(Mantid::Kernel::DblMatrix) +DEFINE_IPROPERTYMANAGER_GETVALUE(Mantid::Kernel::IntMatrix) +DEFINE_IPROPERTYMANAGER_GETVALUE(Mantid::Kernel::Matrix<float>) ///@endcond diff --git a/Code/Mantid/Framework/Kernel/src/PropertyWithValue.cpp b/Code/Mantid/Framework/Kernel/src/PropertyWithValue.cpp index e087f25a23fc04c8bfb66fd04dbf795c27b0b703..038a26cc359abd12083be4e8546b336ab48bf427 100644 --- a/Code/Mantid/Framework/Kernel/src/PropertyWithValue.cpp +++ b/Code/Mantid/Framework/Kernel/src/PropertyWithValue.cpp @@ -10,16 +10,16 @@ namespace Kernel { template DLLExport class PropertyWithValue<std::vector<Type>>; // Explicit instantiations -INSTANTIATE(int); -INSTANTIATE(long); -INSTANTIATE(long long); -INSTANTIATE(unsigned short int); -INSTANTIATE(unsigned int); -INSTANTIATE(unsigned long); -INSTANTIATE(unsigned long long); -INSTANTIATE(bool); -INSTANTIATE(double); -INSTANTIATE(std::string); +INSTANTIATE(int) +INSTANTIATE(long) +INSTANTIATE(long long) +INSTANTIATE(unsigned short int) +INSTANTIATE(unsigned int) +INSTANTIATE(unsigned long) +INSTANTIATE(unsigned long long) +INSTANTIATE(bool) +INSTANTIATE(double) +INSTANTIATE(std::string) /// @endcond } // namespace Kernel diff --git a/Code/Mantid/Framework/Kernel/src/Statistics.cpp b/Code/Mantid/Framework/Kernel/src/Statistics.cpp index 9af3f0335c5d2e0436d1ee3694dd5fbe7a2e412a..6a021e757806d99a549b69131b44c37009466422 100644 --- a/Code/Mantid/Framework/Kernel/src/Statistics.cpp +++ b/Code/Mantid/Framework/Kernel/src/Statistics.cpp @@ -405,14 +405,14 @@ std::vector<double> getMomentsAboutMean(const std::vector<TYPE> &x, // --------------------------- Concrete instantiations // --------------------------------------------- -INSTANTIATE(float); -INSTANTIATE(double); -INSTANTIATE(int); -INSTANTIATE(long); -INSTANTIATE(long long); -INSTANTIATE(unsigned int); -INSTANTIATE(unsigned long); -INSTANTIATE(unsigned long long); +INSTANTIATE(float) +INSTANTIATE(double) +INSTANTIATE(int) +INSTANTIATE(long) +INSTANTIATE(long long) +INSTANTIATE(unsigned int) +INSTANTIATE(unsigned long) +INSTANTIATE(unsigned long long) } // namespace Kernel } // namespace Mantid diff --git a/Code/Mantid/Framework/Kernel/src/TimeSeriesProperty.cpp b/Code/Mantid/Framework/Kernel/src/TimeSeriesProperty.cpp index e129b7010c2853e88c459f3db86c216a68bb4519..c6057895d5fdfca2f4ac6aaac52b913364003493 100644 --- a/Code/Mantid/Framework/Kernel/src/TimeSeriesProperty.cpp +++ b/Code/Mantid/Framework/Kernel/src/TimeSeriesProperty.cpp @@ -2026,16 +2026,16 @@ TimeSeriesProperty<TYPE>::setValueFromProperty(const Property &right) { // -------------------------- Concrete instantiation // ----------------------------------------------- -INSTANTIATE(int); -INSTANTIATE(long); -INSTANTIATE(long long); -INSTANTIATE(unsigned int); -INSTANTIATE(unsigned long); -INSTANTIATE(unsigned long long); -INSTANTIATE(float); -INSTANTIATE(double); -INSTANTIATE(std::string); -INSTANTIATE(bool); +INSTANTIATE(int) +INSTANTIATE(long) +INSTANTIATE(long long) +INSTANTIATE(unsigned int) +INSTANTIATE(unsigned long) +INSTANTIATE(unsigned long long) +INSTANTIATE(float) +INSTANTIATE(double) +INSTANTIATE(std::string) +INSTANTIATE(bool) /// @endcond diff --git a/Code/Mantid/Framework/Kernel/src/Unit.cpp b/Code/Mantid/Framework/Kernel/src/Unit.cpp index c9e0c0ead29fe50920ca69fdf962033676d407f7..8495405f2101f53e4c70c3ac2b7bc88348d3c81a 100644 --- a/Code/Mantid/Framework/Kernel/src/Unit.cpp +++ b/Code/Mantid/Framework/Kernel/src/Unit.cpp @@ -1108,10 +1108,10 @@ double Time::singleFromTOF(const double tof) const { double Time::conversionTOFMax() const { return std::numeric_limits<double>::quiet_NaN(); -}; +} double Time::conversionTOFMin() const { return std::numeric_limits<double>::quiet_NaN(); -}; +} Unit *Time::clone() const { return new Time(*this); } @@ -1122,10 +1122,36 @@ Unit *Time::clone() const { return new Time(*this); } * Degrees prints degrees as a label */ +DECLARE_UNIT(Degrees) + Degrees::Degrees() : Empty(), m_label("degrees") {} const UnitLabel Degrees::label() const { return m_label; } +void Degrees::init() {} + +double Degrees::singleToTOF(const double x) const { + UNUSED_ARG(x); + throw std::runtime_error("Degrees is not allowed to be convert to TOF. "); + return 0.0; +} + +double Degrees::singleFromTOF(const double tof) const { + UNUSED_ARG(tof); + throw std::runtime_error("Degrees is not allwed to be converted from TOF. "); + return 0.0; +} + +double Degrees::conversionTOFMax() const { + return std::numeric_limits<double>::quiet_NaN(); +} + +double Degrees::conversionTOFMin() const { + return std::numeric_limits<double>::quiet_NaN(); +} + +Unit *Degrees::clone() const { return new Degrees(*this); } + } // namespace Units } // namespace Kernel diff --git a/Code/Mantid/Framework/Kernel/test/ComputeResourceInfoTest.h b/Code/Mantid/Framework/Kernel/test/ComputeResourceInfoTest.h new file mode 100644 index 0000000000000000000000000000000000000000..213a98ed2098662b0748101000aaaa992a0a8cc0 --- /dev/null +++ b/Code/Mantid/Framework/Kernel/test/ComputeResourceInfoTest.h @@ -0,0 +1,269 @@ +#ifndef COMPUTERESOURCEINFOTEST_H_ +#define COMPUTERESOURCEINFOTEST_H_ + +#include "MantidKernel/Exception.h" +#include "MantidKernel/FacilityInfo.h" + +#include <Poco/DOM/AutoPtr.h> +#include <Poco/DOM/Document.h> +#include <Poco/DOM/DOMParser.h> +#include <Poco/XML/XMLException.h> + +using namespace Mantid::Kernel; + +class ComputeResourceInfoTest : public CxxTest::TestSuite { +public: + void test_allMissing() { + FacilityInfo *fac = NULL; + TS_ASSERT_THROWS_NOTHING(fac = + createCRInfoInMinimalFacility(simpleInstStr)); + TS_ASSERT(fac); + std::vector<ComputeResourceInfo> cri; + TS_ASSERT_THROWS_NOTHING(cri = fac->computeResInfos()); + TS_ASSERT_EQUALS(cri.size(), 0); + + delete fac; + fac = NULL; + TS_ASSERT_THROWS(fac = createCRInfoInMinimalFacility( + "<computeResource fooAtt=\"barVal\"/>"), + std::runtime_error); + TS_ASSERT(!fac); + delete fac; + } + + void test_noURLTag() { + const std::string crTxt = "<computeResource name=\"foo\">" + "<u>" + + fermiURL + "</u>" + "</computeResource>"; + FacilityInfo *fac = NULL; + TS_ASSERT_THROWS(fac = createCRInfoInMinimalFacility(crTxt), + std::runtime_error); + TS_ASSERT(!fac); + delete fac; + } + + void test_wrongXML() { + const std::string crTxt = "<computeResource name=\"foo\">" + "<u_foo>" + + fermiURL + "</u_bar>" + "</compResource>"; + FacilityInfo *fac = NULL; + TS_ASSERT_THROWS(fac = createCRInfoInMinimalFacility(crTxt), + Poco::XML::XMLException); + TS_ASSERT(!fac); + delete fac; + } + + void test_normalFermi() { + const std::string fermi = "<computeResource name=\"" + fermiName + + "\">" + "<baseURL>" + + fermiURL + "</baseURL>" + "</computeResource>"; + + FacilityInfo *fac = NULL; + TS_ASSERT_THROWS_NOTHING(fac = createCRInfoInMinimalFacility(fermi)); + TS_ASSERT(fac); + TS_ASSERT_EQUALS(fac->name(), this->testFacilityName); + + std::vector<ComputeResourceInfo> cri; + TS_ASSERT_THROWS_NOTHING(cri = fac->computeResInfos()); + TS_ASSERT_EQUALS(cri.size(), 1); + + ComputeResourceInfo cr = fac->computeResInfos().front(); + TS_ASSERT_THROWS(ComputeResourceInfo fail = fac->computeResource(scarfName), + Mantid::Kernel::Exception::NotFoundError); + ComputeResourceInfo cr2 = fac->computeResource(fermiName); + TS_ASSERT_EQUALS(cr, cr2); + TS_ASSERT_EQUALS(cr, cri.front()); + TS_ASSERT_EQUALS(cr2, cri.front()); + TS_ASSERT_EQUALS(cr.name(), fermiName); + TS_ASSERT_EQUALS(cr2.name(), fermiName); + TS_ASSERT_EQUALS(cr.baseURL(), fermiURL); + TS_ASSERT_EQUALS(cr2.baseURL(), fermiURL); + TS_ASSERT_EQUALS(cr.remoteJobManagerType(), defaultType); + TS_ASSERT_EQUALS(cr2.remoteJobManagerType(), defaultType); + TS_ASSERT_EQUALS(cr.facility().name(), fac->name()); + TS_ASSERT_EQUALS(cr2.facility().name(), fac->name()); + } + + void test_brokenFermi() { + // wrong 'baseURL' tag + const std::string fermi = "<computeResource name=\"" + fermiName + "\">" + "<URL>" + + fermiURL + "</URL>" + "</computeResource>"; + + FacilityInfo *fac = NULL; + TS_ASSERT_THROWS(fac = createCRInfoInMinimalFacility(fermi), + std::runtime_error); + + TS_ASSERT(!fac); + delete fac; + } + + void test_normalSCARF() { + const std::string scarf = "<computeResource name=\"" + scarfName + + "\" JobManagerType=\"" + scarfType + "\">" + "<baseURL>" + + scarfURL + "</baseURL>" + "</computeResource>"; + + FacilityInfo *fac = NULL; + TS_ASSERT_THROWS_NOTHING(fac = createCRInfoInMinimalFacility(scarf)); + TS_ASSERT(fac); + TS_ASSERT_EQUALS(fac->name(), this->testFacilityName); + std::vector<ComputeResourceInfo> cri; + TS_ASSERT_THROWS_NOTHING(cri = fac->computeResInfos()); + TS_ASSERT_EQUALS(cri.size(), 1); + + ComputeResourceInfo cr = fac->computeResInfos().front(); + TS_ASSERT_THROWS(ComputeResourceInfo fail = fac->computeResource("inexistent!"), + Mantid::Kernel::Exception::NotFoundError); + ComputeResourceInfo cr2 = fac->computeResource(scarfName); + TS_ASSERT_EQUALS(cr, cr2); + TS_ASSERT_EQUALS(cri.front(), cr); + TS_ASSERT_EQUALS(cri.front(), cr2); + TS_ASSERT_EQUALS(scarfName, cr.name()); + TS_ASSERT_EQUALS(scarfName, cr2.name()); + TS_ASSERT_EQUALS(scarfURL, cr.baseURL()); + TS_ASSERT_EQUALS(scarfURL, cr2.baseURL()); + TS_ASSERT_EQUALS(scarfType, cr.remoteJobManagerType()); + TS_ASSERT_EQUALS(scarfType, cr2.remoteJobManagerType()); + TS_ASSERT_EQUALS(fac->name(), cr.facility().name()); + TS_ASSERT_EQUALS(fac->name(), cr2.facility().name()); + delete fac; + } + + void test_brokenSCARF() { + const std::string type = "SCARFLSFJobManager"; + const std::string err = "<computeResource foo=\"" + scarfName + + "\" JobManagerType=\"" + type + "\">" + "<URL>" + + scarfURL + "</URL>" + "</computeResource>"; + FacilityInfo *fac = NULL; + TS_ASSERT_THROWS(fac = createCRInfoInMinimalFacility(err), + std::runtime_error); + TS_ASSERT(!fac); + delete fac; + } + + void test_equals() { + const std::string otherName = "other"; + const std::string otherURL = "www.example.com/foo/baz"; + const std::string thirdName = "third"; + const std::string rep = "<computeResource name=\"" + fermiName + + "\">" + "<baseURL>" + + fermiURL + "</baseURL>" + "</computeResource>" + + "<computeResource name=\"" + + otherName + "\">" + "<baseURL>" + + otherURL + "</baseURL>" + "</computeResource>" + + "<computeResource name=\"" + + thirdName + "\">" + "<baseURL>" + + fermiURL + "</baseURL>" + "</computeResource>" + + "<computeResource name=\"" + + fermiName + "\">" + "<baseURL>" + + fermiURL + "</baseURL>" + "</computeResource>"; + + FacilityInfo *fac = NULL; + TS_ASSERT_THROWS_NOTHING(fac = createCRInfoInMinimalFacility(rep)); + TS_ASSERT(fac); + TS_ASSERT_EQUALS(fac->computeResources().size(), 3); + TS_ASSERT_EQUALS(fac->computeResInfos().size(), 4); + + // compare names + TS_ASSERT(fac->computeResources()[0] == fac->computeResources()[0]); + TS_ASSERT(!(fac->computeResources()[0] == fac->computeResources()[1])); + TS_ASSERT(!(fac->computeResources()[0] == fac->computeResources()[2])); + TS_ASSERT(!(fac->computeResources()[1] == fac->computeResources()[2])); + + // compare full comp resource info + TS_ASSERT(fac->computeResInfos()[0] == fac->computeResInfos()[0]); + TS_ASSERT(!(fac->computeResInfos()[0] == fac->computeResInfos()[1])); + TS_ASSERT(!(fac->computeResInfos()[0] == fac->computeResInfos()[2])); + TS_ASSERT(!(fac->computeResInfos()[1] == fac->computeResInfos()[2])); + TS_ASSERT(!(fac->computeResInfos()[2] == fac->computeResInfos()[3])); + TS_ASSERT(fac->computeResInfos()[0] == fac->computeResInfos()[3]); + + // compare comp resource info retrieved by names + TS_ASSERT( + !(fac->computeResource(fermiName) == fac->computeResource(otherName))); + TS_ASSERT( + !(fac->computeResource(fermiName) == fac->computeResource(thirdName))); + TS_ASSERT( + !(fac->computeResource(otherName) == fac->computeResource(thirdName))); + delete fac; + } + +private: + /// make a minimal facilities file/xml string includin the compute resource + /// passed + FacilityInfo *createCRInfoInMinimalFacility(const std::string &crStr) { + const std::string xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<facilities>" + " <facility name=\"" + + testFacilityName + + "\" FileExtensions=\".xyz\">" + simpleInstStr + + crStr + " </facility>" + "</facilities>"; + + return createFacility(xmlStr); + } + + FacilityInfo *createFacility(const std::string &xml) { + Poco::XML::DOMParser parser; + Poco::AutoPtr<Poco::XML::Document> pDoc = parser.parseString(xml); + Poco::XML::Element *pRootElem = pDoc->documentElement(); + Poco::XML::Element *elem = pRootElem->getChildElement("facility"); + + return new FacilityInfo(elem); + } + +private: + // a minimal instrument to create a facility info + static const std::string simpleInstStr; + + // default remote job manager type + static const std::string defaultType; + + static const std::string testFacilityName; + + static const std::string fermiName; + static const std::string fermiURL; + static const std::string scarfName; + static const std::string scarfURL; + static const std::string scarfType; +}; + +const std::string ComputeResourceInfoTest::simpleInstStr = + "<instrument name=\"AnInst\">" + " <technique>Measuring Stuff</technique>" + "</instrument>"; + +const std::string ComputeResourceInfoTest::defaultType = + "MantidWebServiceAPIJobManager"; + +const std::string ComputeResourceInfoTest::testFacilityName = "ATestFacility"; + +const std::string ComputeResourceInfoTest::fermiURL = + "https://fermi.ornl.gov/MantidRemote"; +const std::string ComputeResourceInfoTest::fermiName = "Fermi"; +const std::string ComputeResourceInfoTest::scarfURL = + "https://portal.scarf.rl.ac.uk"; +const std::string ComputeResourceInfoTest::scarfName = "SCARF@STFC"; +const std::string ComputeResourceInfoTest::scarfType = "SCARFLSFJobManager"; + +#endif // COMPUTERESOURCEINFOTEST_H_ diff --git a/Code/Mantid/Framework/Kernel/test/LogParserTest.h b/Code/Mantid/Framework/Kernel/test/LogParserTest.h index 790a09ecef129005ab240ca231af12dc70a9345a..5894835816cb4ff9274bc8695f25352917d005ea 100644 --- a/Code/Mantid/Framework/Kernel/test/LogParserTest.h +++ b/Code/Mantid/Framework/Kernel/test/LogParserTest.h @@ -21,24 +21,28 @@ public: static LogParserTest *createSuite() { return new LogParserTest(); } static void destroySuite(LogParserTest *suite) { delete suite; } + + class TmpFile{ + Poco::File m_file; + public: + TmpFile(const std::string& fname):m_file(fname){} + ~TmpFile(){remove();} + const std::string& path() const {return m_file.path();} + bool exists() const {return m_file.exists();} + void remove() {if (m_file.exists()) m_file.remove();} + }; + LogParserTest() :log_num_good("TST000000_good.txt"), log_num_late("TST000000_late.txt"), log_num_early("TST000000_early.txt"), log_num_single("TST000000_single.txt"), log_str("TST000000_str.txt"), - icp_file("TST000000_icpevent.txt") - { - } - - ~LogParserTest() + icp_file("TST000000_icpevent.txt"), + log_str_repeat("TST000000_repeat.txt"), + log_num_repeat("TST000000_num_repeat.txt"), + log_str_continuations("TST000000_str_continue.txt") { - if ( log_num_good.exists() ) log_num_good.remove(); - if ( log_num_late.exists() ) log_num_late.remove(); - if ( log_num_early.exists() ) log_num_early.remove(); - if ( log_num_single.exists() ) log_num_single.remove(); - if ( log_str.exists() ) log_str.remove(); - if ( icp_file.exists() ) icp_file.remove(); } void testGood() @@ -515,7 +519,70 @@ public: delete log; } -//*/ + void test_str_repeat() + { + mkStrRepeat(); + Property *prop = LogParser::createLogProperty(log_str_repeat.path(),"log"); + const auto *log = dynamic_cast<const TimeSeriesProperty<std::string>*>(prop); + TS_ASSERT(log); + auto logm = log->valueAsMultiMap(); + auto it = logm.begin(); + TS_ASSERT_EQUALS( it->first.toISO8601String(), "2000-09-05T12:22:34"); + TS_ASSERT_EQUALS( it->second, " First line"); ++it; + TS_ASSERT_EQUALS( it->first.toISO8601String(), "2000-09-05T12:22:34"); + TS_ASSERT_EQUALS( it->second, " Second line"); ++it; + TS_ASSERT_EQUALS( it->first.toISO8601String(), "2000-09-05T12:23:33"); + TS_ASSERT_EQUALS( it->second, " First line"); ++it; + TS_ASSERT_EQUALS( it->first.toISO8601String(), "2000-09-05T12:23:33"); + TS_ASSERT_EQUALS( it->second, " Second line"); ++it; + TS_ASSERT_EQUALS( it->first.toISO8601String(), "2000-09-05T12:23:33"); + TS_ASSERT_EQUALS( it->second, " Third line"); ++it; + TS_ASSERT_EQUALS( it->first.toISO8601String(), "2000-09-05T12:23:33"); + TS_ASSERT_EQUALS( it->second, " Fourth line"); ++it; + delete prop; + } + + void test_num_repeat() + { + mkNumRepeat(); + Property *prop = LogParser::createLogProperty(log_str_repeat.path(),"log"); + const auto *log = dynamic_cast<const TimeSeriesProperty<double>*>(prop); + TS_ASSERT(log); + auto logm = log->valueAsMultiMap(); + auto it = logm.begin(); + TS_ASSERT_EQUALS( it->first.toISO8601String(), "2000-09-05T12:22:34"); + TS_ASSERT_EQUALS( it->second, 1); ++it; + TS_ASSERT_EQUALS( it->first.toISO8601String(), "2000-09-05T12:22:34"); + TS_ASSERT_EQUALS( it->second, 2); ++it; + TS_ASSERT_EQUALS( it->first.toISO8601String(), "2000-09-05T12:23:33"); + TS_ASSERT_EQUALS( it->second, 3); ++it; + TS_ASSERT_EQUALS( it->first.toISO8601String(), "2000-09-05T12:23:33"); + TS_ASSERT_EQUALS( it->second, 4); ++it; + TS_ASSERT_EQUALS( it->first.toISO8601String(), "2000-09-05T12:23:33"); + TS_ASSERT_EQUALS( it->second, 5); ++it; + TS_ASSERT_EQUALS( it->first.toISO8601String(), "2000-09-05T12:23:33"); + TS_ASSERT_EQUALS( it->second, 6); ++it; + delete prop; + } + + void test_str_continuation() + { + mkStrContinuations(); + Property *prop = LogParser::createLogProperty(log_str_continuations.path(),"log"); + const auto *log = dynamic_cast<const TimeSeriesProperty<std::string>*>(prop); + TS_ASSERT(log); + auto logm = log->valueAsMultiMap(); + auto it = logm.begin(); + TS_ASSERT_EQUALS( it->first.toISO8601String(), "2000-09-05T12:22:31"); + TS_ASSERT_EQUALS( it->second, " First line Second line"); ++it; + TS_ASSERT_EQUALS( it->first.toISO8601String(), "2000-09-05T12:22:34"); + TS_ASSERT_EQUALS( it->second, " First line"); ++it; + TS_ASSERT_EQUALS( it->first.toISO8601String(), "2000-09-05T12:22:34"); + TS_ASSERT_EQUALS( it->second, " Second line Third line"); ++it; + delete prop; + } + + private: /// Helper method to run common test code for checking period logs. @@ -646,13 +713,52 @@ private: f << "2000-09-05T14:03:56 line "<<9<<'\n'; f.close(); } -//*/ - Poco::File log_num_good;// run time interval is within first - last times of the log - Poco::File log_num_late;// first time is later than run start - Poco::File log_num_early;// last time is earlier than run ends - Poco::File log_num_single;// single value - Poco::File log_str;// file of strings - Poco::File icp_file;// icpevent file + + void mkStrContinuations() + { + std::ofstream f( log_str_continuations.path().c_str() ); + f << "2000-09-05T12:22:31 First line" << std::endl; + f << "Second line" << std::endl; + f << "2000-09-05T12:22:34 First line" << std::endl; + f << "2000-09-05T12:22:34 Second line" << std::endl; + f << "Third line" << std::endl; + f.close(); + } + + void mkStrRepeat() + { + std::ofstream f( log_str_repeat.path().c_str() ); + f << "2000-09-05T12:22:34 First line" << std::endl; + f << "2000-09-05T12:22:34 Second line" << std::endl; + f << "2000-09-05T12:23:33 First line" << std::endl; + f << "2000-09-05T12:23:33 Second line" << std::endl; + f << "2000-09-05T12:23:33 Third line" << std::endl; + f << "2000-09-05T12:23:33 Fourth line" << std::endl; + f.close(); + } + + void mkNumRepeat() + { + std::ofstream f( log_str_repeat.path().c_str() ); + f << "2000-09-05T12:22:34 1" << std::endl; + f << "2000-09-05T12:22:34 2" << std::endl; + f << "2000-09-05T12:23:33 3" << std::endl; + f << "2000-09-05T12:23:33 4" << std::endl; + f << "2000-09-05T12:23:33 5" << std::endl; + f << "2000-09-05T12:23:33 6" << std::endl; + f.close(); + } + + TmpFile log_num_good;// run time interval is within first - last times of the log + TmpFile log_num_late;// first time is later than run start + TmpFile log_num_early;// last time is earlier than run ends + TmpFile log_num_single;// single value + TmpFile log_str;// file of strings + TmpFile icp_file;// icpevent file + TmpFile log_str_repeat;// string log with repeating lines + TmpFile log_num_repeat;// num log with repeating lines + TmpFile log_str_continuations;// string log with continuation lines + tm ti_data; tm * ti; diff --git a/Code/Mantid/Framework/Kernel/test/MatrixTest.h b/Code/Mantid/Framework/Kernel/test/MatrixTest.h index f504f2436584fd6ddbb0407757b79181d011cd9e..d27c2752545a5db01a97b8d5f1eaa373d09d14bc 100644 --- a/Code/Mantid/Framework/Kernel/test/MatrixTest.h +++ b/Code/Mantid/Framework/Kernel/test/MatrixTest.h @@ -429,6 +429,18 @@ public: DblMatrix M4(4,4, true); TS_ASSERT_THROWS(M4.operator *(v), Mantid::Kernel::Exception::MisMatch<size_t>); + + DblMatrix M23 = boost::lexical_cast<DblMatrix>("Matrix(2,3)-0.23,0.55,5.22,2.96,4.2,0.1"); + TS_ASSERT_THROWS_NOTHING(M23.operator *(v)); + + nv = M23 * v; + + TS_ASSERT_DELTA(nv.X(), -0.403000000000000, 1e-15); + TS_ASSERT_DELTA(nv.Y(), 25.663000000000000, 1e-15); + TS_ASSERT_EQUALS(nv.Z(), 0); + + DblMatrix M43 = boost::lexical_cast<DblMatrix>("Matrix(4,3)-0.23,0.55,5.22,2.96,4.2,0.1,-0.23,0.55,5.22,2.96,4.2,0.1"); + TS_ASSERT_THROWS(M43.operator *(v), Mantid::Kernel::Exception::MisMatch<size_t>); } private: diff --git a/Code/Mantid/Framework/Kernel/test/TypedValidatorTest.h b/Code/Mantid/Framework/Kernel/test/TypedValidatorTest.h index 79693e0335b907b382276d7af79fe0d79df1b35e..124c4655af43968e5e8870184ca6d14dc11447ef 100644 --- a/Code/Mantid/Framework/Kernel/test/TypedValidatorTest.h +++ b/Code/Mantid/Framework/Kernel/test/TypedValidatorTest.h @@ -24,8 +24,8 @@ namespace /// Dummy object to hold in a shared_ptr for test struct Holder {}; - DECLARE_TEST_VALIDATOR(SharedPtrTypedValidator, boost::shared_ptr<Holder>); - DECLARE_TEST_VALIDATOR(PODTypedValidator, double); + DECLARE_TEST_VALIDATOR(SharedPtrTypedValidator, boost::shared_ptr<Holder>) + DECLARE_TEST_VALIDATOR(PODTypedValidator, double) class FakeDataItem : public Mantid::Kernel::DataItem { public: @@ -34,7 +34,7 @@ namespace virtual bool threadSafe() const { return true; } virtual const std::string toString() const { return "FakeDataItem{}"; } }; - DECLARE_TEST_VALIDATOR(DataItemSptrTypedValidator, boost::shared_ptr<FakeDataItem>); + DECLARE_TEST_VALIDATOR(DataItemSptrTypedValidator, boost::shared_ptr<FakeDataItem>) } class TypedValidatorTest : public CxxTest::TestSuite diff --git a/Code/Mantid/Framework/Kernel/test/UnitTest.h b/Code/Mantid/Framework/Kernel/test/UnitTest.h index 6439181b2c1e141354443e7179ffda7c5ee1e2b4..cfa80847cb10dd05449934c00c7d56ab6a62cf47 100644 --- a/Code/Mantid/Framework/Kernel/test/UnitTest.h +++ b/Code/Mantid/Framework/Kernel/test/UnitTest.h @@ -1325,6 +1325,11 @@ public: } + /// Test unit Degress + void testDegress() { + TS_ASSERT_EQUALS(degrees.caption(), "Scattering angle"); + TS_ASSERT_EQUALS(degrees.unitID(), "Degrees"); + } private: Units::Label label; @@ -1340,6 +1345,7 @@ private: Units::Momentum k_i; Units::SpinEchoLength delta; Units::SpinEchoTime tau; + Units::Degrees degrees; }; #endif /*UNITTEST_H_*/ diff --git a/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARA.h b/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARA.h index a6a6afb3ab1174cde48df20cd7fe88262f914229..97757097758d85b050ce3f1a78373f04c0422f3b 100644 --- a/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARA.h +++ b/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARA.h @@ -29,7 +29,7 @@ enum Enum { DEVICE_DESC_V0 = ADARA_PKT_TYPE(0x8000, 0), VAR_VALUE_U32_V0 = ADARA_PKT_TYPE(0x8001, 0), VAR_VALUE_DOUBLE_V0 = ADARA_PKT_TYPE(0x8002, 0), - VAR_VALUE_STRING_V0 = ADARA_PKT_TYPE(0x8003, 0), + VAR_VALUE_STRING_V0 = ADARA_PKT_TYPE(0x8003, 0) }; } @@ -57,7 +57,7 @@ enum Enum { RUN_EOF = 2, RUN_BOF = 3, END_RUN = 4, - STATE = 5, + STATE = 5 }; } @@ -86,7 +86,7 @@ enum Enum { READ_PERMISSION = 20, WRITE_PERMISSION = 21, UPSTREAM_DISCONNECTED = 0xfffe, - NOT_REPORTED = 0xffff, + NOT_REPORTED = 0xffff }; } @@ -96,7 +96,7 @@ enum Enum { MINOR_ALARM = 1, MAJOR_ALARM = 2, INVALID = 3, - NOT_REPORTED = 0xffff, + NOT_REPORTED = 0xffff }; } @@ -107,7 +107,7 @@ enum Enum { SCAN_STOP, PAUSE, RESUME, - OVERALL_RUN_COMMENT, + OVERALL_RUN_COMMENT }; } diff --git a/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARAPackets.h b/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARAPackets.h index a331a294c25be99a9d50e658c62709bdafcda8ed..9a616c43892aa2a1c6b4dd1beba99e4ca39b8a34 100644 --- a/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARAPackets.h +++ b/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ADARA/ADARAPackets.h @@ -162,7 +162,7 @@ public: PULSE_VETO = 0x0004, MISSING_RTDL = 0x0008, MAPPING_ERROR = 0x0010, - DUPLICATE_PULSE = 0x0020, + DUPLICATE_PULSE = 0x0020 }; uint32_t pulseCharge(void) const { return m_fields[0]; } diff --git a/Code/Mantid/Framework/LiveData/src/MonitorLiveData.cpp b/Code/Mantid/Framework/LiveData/src/MonitorLiveData.cpp index 8262af09878fcd413bb35dd9f0e4ab68a3f1991c..8491c3d349bd8ed0a88cac9f96dca443b0751c40 100644 --- a/Code/Mantid/Framework/LiveData/src/MonitorLiveData.cpp +++ b/Code/Mantid/Framework/LiveData/src/MonitorLiveData.cpp @@ -27,7 +27,7 @@ MonitorLiveData::~MonitorLiveData() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string MonitorLiveData::name() const { return "MonitorLiveData"; }; +const std::string MonitorLiveData::name() const { return "MonitorLiveData"; } /// Algorithm's category for identification. @see Algorithm::category const std::string MonitorLiveData::category() const { @@ -35,7 +35,7 @@ const std::string MonitorLiveData::category() const { } /// Algorithm's version for identification. @see Algorithm::version -int MonitorLiveData::version() const { return 1; }; +int MonitorLiveData::version() const { return 1; } //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. diff --git a/Code/Mantid/Framework/LiveData/src/SNSLiveEventDataListener.cpp b/Code/Mantid/Framework/LiveData/src/SNSLiveEventDataListener.cpp index 50b2621e222a875ff79329ac62cbbd9eea9042fa..b70faa984ea971d86863d6abf400c57b43878652 100644 --- a/Code/Mantid/Framework/LiveData/src/SNSLiveEventDataListener.cpp +++ b/Code/Mantid/Framework/LiveData/src/SNSLiveEventDataListener.cpp @@ -54,7 +54,7 @@ Mantid::Kernel::DateAndTime timeFromPacket(const ADARA::PacketHeader &hdr) { namespace Mantid { namespace LiveData { -DECLARE_LISTENER(SNSLiveEventDataListener); +DECLARE_LISTENER(SNSLiveEventDataListener) // The DECLARE_LISTENER macro seems to confuse some editors' syntax checking. // The semi-colon limits the complaints to one line. It has no actual effect // on the code. diff --git a/Code/Mantid/Framework/LiveData/src/StartLiveData.cpp b/Code/Mantid/Framework/LiveData/src/StartLiveData.cpp index c890cac2ab60164159a93dfc879f7b6d09ae08b1..49338ad3a41d5354587d1086600e12dd764cbca0 100644 --- a/Code/Mantid/Framework/LiveData/src/StartLiveData.cpp +++ b/Code/Mantid/Framework/LiveData/src/StartLiveData.cpp @@ -37,10 +37,10 @@ StartLiveData::~StartLiveData() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string StartLiveData::name() const { return "StartLiveData"; }; +const std::string StartLiveData::name() const { return "StartLiveData"; } /// Algorithm's version for identification. @see Algorithm::version -int StartLiveData::version() const { return 1; }; +int StartLiveData::version() const { return 1; } //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. diff --git a/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt b/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt index 13401374db1e4699ab34141640a4a60ea6f00973..0e2f238894bde22742308c3059194480d88ffa1d 100644 --- a/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt +++ b/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt @@ -23,6 +23,7 @@ set ( SRC_FILES src/ConvertToMDParent.cpp src/CreateMDHistoWorkspace.cpp src/CreateMDWorkspace.cpp + src/CutMD.cpp src/DivideMD.cpp src/EqualToMD.cpp src/EvaluateMDFunction.cpp @@ -107,6 +108,7 @@ set ( INC_FILES inc/MantidMDAlgorithms/ConvertToMDParent.h inc/MantidMDAlgorithms/CreateMDHistoWorkspace.h inc/MantidMDAlgorithms/CreateMDWorkspace.h + inc/MantidMDAlgorithms/CutMD.h inc/MantidMDAlgorithms/DivideMD.h inc/MantidMDAlgorithms/DllConfig.h inc/MantidMDAlgorithms/EqualToMD.h @@ -195,6 +197,7 @@ set ( TEST_FILES ConvertToQ3DdETest.h CreateMDHistoWorkspaceTest.h CreateMDWorkspaceTest.h + CutMDTest.h DivideMDTest.h EqualToMDTest.h EvaluateMDFunctionTest.h @@ -271,9 +274,8 @@ endif () # Add to the 'Framework' group in VS set_property ( TARGET MDAlgorithms PROPERTY FOLDER "MantidFramework" ) -include_directories ( inc ../MDEvents/inc) - -target_link_libraries ( MDAlgorithms ${MANTIDLIBS} MDEvents) +include_directories ( inc ../MDEvents/inc ) +target_link_libraries ( MDAlgorithms ${MANTIDLIBS} MDEvents ) # Add the unit tests directory add_subdirectory ( test ) diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWPDMDToSpectra.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWPDMDToSpectra.h index 453b48e6095125680b48c8d677128a77710d03c4..b2176621470c9e43f527728f7521b7c4c7174148 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWPDMDToSpectra.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWPDMDToSpectra.h @@ -108,8 +108,12 @@ public: /// Summary of algorithms purpose virtual const std::string summary() const { - return "Binning the constant wavelength powder diffracton data stored in " - "MDWorkspaces to single spectrum."; + return "Convert constant wavelength (CW) powder diffraction (PD) data in " + "MDEventWorksapces " + " to a single-spectrum MatrixWorkspace, i.e., binning the " + "diffraction data " + " to single spectrum according to neutron's scattering angle, " + "d-spacing or Q. "; } /// Algorithm's version @@ -134,6 +138,12 @@ private: const std::map<int, double> &map_runwavelength, const double xmin, const double xmax, const double binsize, bool dolinearinterpolation); + /// Find the binning boundary according to detectors' positions + void findXBoundary(API::IMDEventWorkspace_const_sptr dataws, + const std::string &targetunit, + const std::map<int, double> &map_runwavelength, + double &xmin, double &xmax); + /// Bin signals to its 2theta position void binMD(API::IMDEventWorkspace_const_sptr mdws, const char &unitbit, const std::map<int, double> &map_runlambda, diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CutMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CutMD.h new file mode 100644 index 0000000000000000000000000000000000000000..2ad56c17ac8fb378531609d91df78f79a2aaeee7 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CutMD.h @@ -0,0 +1,58 @@ +#ifndef MANTID_MDALGORITHMS_CUTMD_H_ +#define MANTID_MDALGORITHMS_CUTMD_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidAPI/DataProcessorAlgorithm.h" + +namespace Mantid { +namespace MDAlgorithms { + +/** CutMD : Slices multidimensional workspaces. + + @date 2015-03-20 + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + 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://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class DLLExport CutMD : public API::DataProcessorAlgorithm { +public: + CutMD(); + virtual ~CutMD(); + + virtual const std::string name() const { return "CutMD"; } + virtual int version() const { return 1; } + virtual const std::string summary() const { + return "Slices multidimensional workspaces using input projection " + "information and binning limits."; + } + virtual const std::string category() const { return "MDAlgorithms"; } + + virtual void init(); + virtual void exec(); + +private: +}; + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_CUTMD_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h index dbf60ce1b9ddb6a6335cdf12477da31bcd627c8e..1377fd4dc122d97a790ebf4399a69f1a7e4a1903 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h @@ -75,6 +75,8 @@ private: void loadDimensions(); + void loadCoordinateSystem(); + /// Load all the affine matricies void loadAffineMatricies(API::IMDWorkspace_sptr ws); /// Load a given affine matrix @@ -91,6 +93,8 @@ private: /// Each dimension object loaded. std::vector<Mantid::Geometry::IMDDimension_sptr> m_dims; + /// Coordinate system + Kernel::SpecialCoordinateSystem m_coordSystem; /// load only the box structure with empty boxes but do not tload boxes events bool m_BoxStructureAndMethadata; }; diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/CachedExperimentInfo.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/CachedExperimentInfo.h index a4a590186b0c79b7b8e6aa4af5c7f2ad45d74da1..22d7b317caca9200217f48f58c4e69206f283b47 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/CachedExperimentInfo.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/CachedExperimentInfo.h @@ -78,8 +78,8 @@ public: const Kernel::DblMatrix &sampleToDetectorTransform() const; private: - DISABLE_DEFAULT_CONSTRUCT(CachedExperimentInfo); - DISABLE_COPY_AND_ASSIGN(CachedExperimentInfo); + DISABLE_DEFAULT_CONSTRUCT(CachedExperimentInfo) + DISABLE_COPY_AND_ASSIGN(CachedExperimentInfo) /// Cache frequently used values void initCaches(const Geometry::Instrument_const_sptr &instrument, diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModel.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModel.h index a7e03768a32fd3b2000bfb3d5f3bb32032be6434..29a258d31bf3f6ca32fb2e4cd5d7d64d80eefe5e 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModel.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModel.h @@ -107,7 +107,7 @@ protected: double &arlu2, double &arlu3); private: - DISABLE_COPY_AND_ASSIGN(ForegroundModel); + DISABLE_COPY_AND_ASSIGN(ForegroundModel) /// Required by the interface void function(const Mantid::API::FunctionDomain &, diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h index 7a2ce0cf3e3612d6d2dcb743a56b968a8fd4dcc9..5bb9e80788bd51ee5eaf9c963a97c4494df16fff 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h @@ -57,7 +57,7 @@ private: friend struct Kernel::CreateUsingNew<ForegroundModelFactoryImpl>; /// Default constructor ForegroundModelFactoryImpl(); - DISABLE_COPY_AND_ASSIGN(ForegroundModelFactoryImpl); + DISABLE_COPY_AND_ASSIGN(ForegroundModelFactoryImpl) // Do not allow the default create & createUnwrapped to be called using BaseClass::create; diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolution.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolution.h index 5e2184882dc6a25a9c0f356a0262e63c01634799..3be84661565fd8ac0f3fc307d23f19cff6c0de35 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolution.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolution.h @@ -117,7 +117,7 @@ protected: const API::IFunctionMD &getFittingFunction() const; private: - DISABLE_COPY_AND_ASSIGN(MDResolutionConvolution); + DISABLE_COPY_AND_ASSIGN(MDResolutionConvolution) /// Required for function interface void function(const Mantid::API::FunctionDomain &, diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h index 1c3d66d59226403d81849b1d8dc03c3177062214..005d9af1314d58cff2318dc97757c62c9421ac9d 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h @@ -56,7 +56,7 @@ private: friend struct Kernel::CreateUsingNew<MDResolutionConvolutionFactoryImpl>; /// Default constructor. Private for singleton holder MDResolutionConvolutionFactoryImpl(); - DISABLE_COPY_AND_ASSIGN(MDResolutionConvolutionFactoryImpl); + DISABLE_COPY_AND_ASSIGN(MDResolutionConvolutionFactoryImpl) // Do not allow the default create & createUnwrapped to be called using BaseClass::create; diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/Resolution/ModeratorChopperResolution.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/Resolution/ModeratorChopperResolution.h index 27fea7faefbac98040ebadb3886623ba0aa457c7..429d7b56bf1588ed79b7b9cb86553b1f7355a65a 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/Resolution/ModeratorChopperResolution.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/Resolution/ModeratorChopperResolution.h @@ -57,8 +57,8 @@ public: double energyWidth(const double deltaE) const; private: - DISABLE_DEFAULT_CONSTRUCT(ModeratorChopperResolution); - DISABLE_COPY_AND_ASSIGN(ModeratorChopperResolution); + DISABLE_DEFAULT_CONSTRUCT(ModeratorChopperResolution) + DISABLE_COPY_AND_ASSIGN(ModeratorChopperResolution) /// Store required cached variables void initCaches(); diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitResolutionModel.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitResolutionModel.h index 11822cc28d3011687cc3b3a893ac99a98e600ae3..df512cf7df717e31497dedea0884405f14edbdb6 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitResolutionModel.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitResolutionModel.h @@ -77,7 +77,7 @@ public: const size_t eventIndex) const; private: - DISABLE_COPY_AND_ASSIGN(TobyFitResolutionModel); + DISABLE_COPY_AND_ASSIGN(TobyFitResolutionModel) friend class TobyFitYVector; diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitYVector.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitYVector.h index d5dd3631ca876f3b1268deeac7952cde1f0b4512..6993c3e3656b5c0fe61dc6e7d40c21121b48ddb2 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitYVector.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitYVector.h @@ -77,7 +77,7 @@ public: 8, // width-coordinate of point of detection in detector frame DetectorHeightCoord = 9, // height-coordinate of point of detection in detector frame - DetectionTime = 10, // deviation in detection time of neutron + DetectionTime = 10 // deviation in detection time of neutron }; /// Returns the number of parameters, i.e. length of the Y vector diff --git a/Code/Mantid/Framework/MDAlgorithms/src/AndMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/AndMD.cpp index 613414e8bec281fa4562a12d1c5c991d7187961e..4f18cf8d18502c6e8cd7166b66c9c6917d47a298 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/AndMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/AndMD.cpp @@ -22,10 +22,10 @@ AndMD::~AndMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string AndMD::name() const { return "AndMD"; }; +const std::string AndMD::name() const { return "AndMD"; } /// Algorithm's version for identification. @see Algorithm::version -int AndMD::version() const { return 1; }; +int AndMD::version() const { return 1; } //---------------------------------------------------------------------------------------------- /// Run the algorithm with a MDHisotWorkspace as output and operand diff --git a/Code/Mantid/Framework/MDAlgorithms/src/BinMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/BinMD.cpp index ee3fe19deeca6bcdf0c39b82adfd8ef57295f01f..418ef2789c7d9a2313f2aff7063094c83fb46981 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/BinMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/BinMD.cpp @@ -410,11 +410,15 @@ void BinMD::exec() { CALL_MDEVENT_FUNCTION(this->binByIterating, m_inWS); - // Copy the experiment infos to the output + // Copy the + + // Copy the coordinate system & experiment infos to the output IMDEventWorkspace_sptr inEWS = boost::dynamic_pointer_cast<IMDEventWorkspace>(m_inWS); - if (inEWS) + if (inEWS) { + outWS->setCoordinateSystem(inEWS->getSpecialCoordinateSystem()); outWS->copyExperimentInfos(*inEWS); + } outWS->updateSum(); // Save the output diff --git a/Code/Mantid/Framework/MDAlgorithms/src/BinaryOperationMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/BinaryOperationMD.cpp index 5868cf52579e792ea01e6e7908f722d11f05f985..c618b3692d4518e8986f7d6e6e7f32e06f5ed94f 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/BinaryOperationMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/BinaryOperationMD.cpp @@ -32,10 +32,10 @@ BinaryOperationMD::~BinaryOperationMD() {} /// Algorithm's name for identification. @see Algorithm::name const std::string BinaryOperationMD::name() const { return "BinaryOperationMD"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int BinaryOperationMD::version() const { return 1; }; +int BinaryOperationMD::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string BinaryOperationMD::category() const { diff --git a/Code/Mantid/Framework/MDAlgorithms/src/BooleanBinaryOperationMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/BooleanBinaryOperationMD.cpp index 3c000629af7223e921f52970aaac0952b4c18899..26d6ce085794916100f135b842e07bb25c8ae737 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/BooleanBinaryOperationMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/BooleanBinaryOperationMD.cpp @@ -22,10 +22,10 @@ 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; }; +int BooleanBinaryOperationMD::version() const { return 1; } //---------------------------------------------------------------------------------------------- /// diff --git a/Code/Mantid/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp b/Code/Mantid/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp index 82b7e4dabb17cc5a7d7f778719c124e989235cad..9a435bf5db1b499e9be40c1bc8fe4f5d422009d4 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp @@ -52,7 +52,7 @@ const std::string CalculateCoverageDGS::name() const { } /// Algorithm's version for identification. @see Algorithm::version -int CalculateCoverageDGS::version() const { return 1; }; +int CalculateCoverageDGS::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string CalculateCoverageDGS::category() const { @@ -63,7 +63,7 @@ const std::string CalculateCoverageDGS::category() const { const std::string CalculateCoverageDGS::summary() const { return "Calculate the reciprocal space coverage for direct geometry " "spectrometers"; -}; +} /** *Stores the X values from each H,K,L dimension as member variables diff --git a/Code/Mantid/Framework/MDAlgorithms/src/CompareMDWorkspaces.cpp b/Code/Mantid/Framework/MDAlgorithms/src/CompareMDWorkspaces.cpp index e7959d9c9fbbe0affa5b4e65283e15915fc92ee2..28178f447fa3f61fec2290e4a5c8209cda0dbd1c 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/CompareMDWorkspaces.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/CompareMDWorkspaces.cpp @@ -43,10 +43,10 @@ CompareMDWorkspaces::~CompareMDWorkspaces() {} /// Algorithm's name for identification. @see Algorithm::name const std::string CompareMDWorkspaces::name() const { return "CompareMDWorkspaces"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int CompareMDWorkspaces::version() const { return 1; }; +int CompareMDWorkspaces::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string CompareMDWorkspaces::category() const { diff --git a/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp b/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp index 6edfe95bb13237bed211a7ffe0cdc7c696ebd836..590bc5dbc27e8d73de04ae98c6f6e8693fd6df7b 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp @@ -15,6 +15,8 @@ using namespace Mantid::MDAlgorithms; DECLARE_ALGORITHM(ConvertCWPDMDToSpectra) +const double BIGNUMBER = 1.0E100; + //---------------------------------------------------------------------------------------------- /** Constructor */ @@ -53,7 +55,7 @@ void ConvertCWPDMDToSpectra::init() { std::vector<std::string> vecunits; vecunits.push_back("2theta"); vecunits.push_back("dSpacing"); - vecunits.push_back("Momenum Transfer (Q)"); + vecunits.push_back("Momentum Transfer (Q)"); auto unitval = boost::make_shared<ListValidator<std::string> >(vecunits); declareProperty("UnitOutput", "2theta", unitval, "Unit of the output workspace."); @@ -140,16 +142,33 @@ void ConvertCWPDMDToSpectra::exec() { } // bin parameters - if (binParams.size() != 3) - throw std::runtime_error("Binning parameters must have 3 items."); - if (binParams[0] >= binParams[2]) + double xmin, xmax, binsize; + xmin = xmax = binsize = -1; + if (binParams.size() == 1) { + binsize = binParams[0]; + g_log.warning() + << "Only bin size " << binParams[0] + << " is specified. Xmin and Xmax " + " will be calcualted from motor positions and wavelength. " + "More CPU time will be used." + << "\n"; + } else if (binParams.size() == 3) { + xmin = binParams[0]; + binsize = binParams[1]; + xmax = binParams[2]; + if (xmin >= xmax) + throw std::runtime_error( + "Min value of the bin must be smaller than maximum value."); + } else { + // Either 1 or 3 parameters. Throw exception throw std::runtime_error( - "Min value of the bin must be smaller than maximum value."); + "Binning parameters must have either 1 or 3 items."); + } // Rebin API::MatrixWorkspace_sptr outws = reducePowderData( - inputDataWS, inputMonitorWS, outputunit, map_runWavelength, binParams[0], - binParams[2], binParams[1], doLinearInterpolation); + inputDataWS, inputMonitorWS, outputunit, map_runWavelength, xmin, xmax, + binsize, doLinearInterpolation); // Scale scaleMatrixWorkspace(outws, scaleFactor, m_infitesimal); @@ -188,25 +207,46 @@ API::MatrixWorkspace_sptr ConvertCWPDMDToSpectra::reducePowderData( // Get some information int64_t numevents = dataws->getNEvents(); + // check xmin and xmax + double lowerboundary, upperboundary; + if (xmin < 0 || xmax < 0) { + // xmin or xmax cannot be negative (2theta, dspace and q are always + // positive) + findXBoundary(dataws, targetunit, map_runwavelength, lowerboundary, + upperboundary); + } else { + lowerboundary = xmin; + upperboundary = xmax; + } + + g_log.debug() << "Binning from " << lowerboundary << " to " << upperboundary + << "\n"; + // Create bins in 2theta (degree) size_t sizex, sizey; - sizex = static_cast<size_t>((xmax - xmin) / binsize + 0.5); + sizex = static_cast<size_t>((upperboundary - lowerboundary) / binsize + 1); + if (lowerboundary + static_cast<double>(sizex)*binsize < upperboundary) + ++ lowerboundary; + sizey = sizex - 1; g_log.debug() << "Number of events = " << numevents - << "bin size = " << binsize << ", SizeX = " << sizex << ", " - << ", SizeY = " << sizey << "\n"; + << ", bin size = " << binsize << ", SizeX = " << sizex << ", " + << ", SizeY = " << sizey + << ", Delta = " << upperboundary - lowerboundary + << ", Bin size = " << binsize << ", sizex_d = " + << (upperboundary - lowerboundary) / binsize + 2 << "\n"; std::vector<double> vecx(sizex), vecy(sizex - 1, 0), vecm(sizex - 1, 0), vece(sizex - 1, 0); for (size_t i = 0; i < sizex; ++i) { - vecx[i] = xmin + static_cast<double>(i) * binsize; + vecx[i] = lowerboundary + static_cast<double>(i) * binsize; } // Convert unit to unit char bit char unitchar = 't'; // default 2theta if (targetunit.compare("dSpacing") == 0) unitchar = 'd'; - else if (targetunit.compare("Momenum Transfer (Q)") == 0) + else if (targetunit.compare("Momentum Transfer (Q)") == 0) unitchar = 'q'; binMD(dataws, unitchar, map_runwavelength, vecx, vecy); @@ -243,12 +283,7 @@ API::MatrixWorkspace_sptr ConvertCWPDMDToSpectra::reducePowderData( pdws->getAxis(0)->setUnit("MomentumTransfer"); else { // Twotheta - Unit_sptr xUnit = pdws->getAxis(0)->unit(); - if (xUnit) { - g_log.warning("Unable to set unit to an Unit::Empty object."); - } else { - throw std::runtime_error("Unable to get unit from Axis(0)"); - } + pdws->getAxis(0)->setUnit("Degrees"); } MantidVec &dataX = pdws->dataX(0); @@ -270,6 +305,115 @@ API::MatrixWorkspace_sptr ConvertCWPDMDToSpectra::reducePowderData( return pdws; } +//---------------------------------------------------------------------------------------------- +/** Find the binning boundaries for 2theta (det position), d-spacing or Q. + * @brief ConvertCWPDMDToSpectra::findXBoundary + * @param dataws + * @param targetunit + * @param wavelength + * @param xmin :: (output) lower binning boundary + * @param xmax :: (output) upper binning boundary + */ +void ConvertCWPDMDToSpectra::findXBoundary( + API::IMDEventWorkspace_const_sptr dataws, const std::string &targetunit, + const std::map<int, double> &map_runwavelength, double &xmin, + double &xmax) { + // Go through all instruments + uint16_t numruns = dataws->getNumExperimentInfo(); + + xmin = BIGNUMBER; + xmax = -1; + + for (uint16_t irun = 0; irun < numruns; ++irun) { + // Skip the Experiment Information does not have run + if (!dataws->getExperimentInfo(irun)->getInstrument()) { + g_log.warning() << "iRun = " << irun << " of total " << numruns + << " does not have instrument associated" + << "\n"; + continue; + } + + // Get run number + int runnumber = dataws->getExperimentInfo(irun)->getRunNumber(); + g_log.debug() << "Run " << runnumber << ": "; + std::map<int, double>::const_iterator miter = + map_runwavelength.find(runnumber); + double wavelength = -1; + if (miter != map_runwavelength.end()) { + wavelength = miter->second; + g_log.debug() << " wavelength = " << wavelength << "\n"; + } else { + g_log.debug() << " no matched wavelength." + << "\n"; + } + + // Get source and sample position + std::vector<detid_t> vec_detid = + dataws->getExperimentInfo(irun)->getInstrument()->getDetectorIDs(true); + if (vec_detid.size() == 0) { + g_log.information() << "Run " << runnumber << " has no detectors." + << "\n"; + continue; + } + const V3D samplepos = + dataws->getExperimentInfo(irun)->getInstrument()->getSample()->getPos(); + const V3D sourcepos = + dataws->getExperimentInfo(irun)->getInstrument()->getSource()->getPos(); + + // Get all detectors + // std::vector<detid_t> vec_detid = + // dataws->getExperimentInfo(irun)->getInstrument()->getDetectorIDs(true); + std::vector<Geometry::IDetector_const_sptr> vec_det = + dataws->getExperimentInfo(irun)->getInstrument()->getDetectors( + vec_detid); + size_t numdets = vec_det.size(); + g_log.debug() << "Run = " << runnumber + << ": Number of detectors = " << numdets << "\n"; + + // Scan all the detectors to get Xmin and Xmax + for (size_t idet = 0; idet < numdets; ++idet) { + Geometry::IDetector_const_sptr tmpdet = vec_det[idet]; + const V3D detpos = tmpdet->getPos(); + + double R, theta, phi; + detpos.getSpherical(R, theta, phi); + if (R < 0.0001) + g_log.error("Invalid detector position"); + + Kernel::V3D v_det_sample = detpos - samplepos; + Kernel::V3D v_sample_src = samplepos - sourcepos; + double twotheta = + calculate2Theta(v_det_sample, v_sample_src) / M_PI * 180.; + + // convert unit optionally + double outx = -1; + if (targetunit.compare("2theta") == 0) + outx = twotheta; + else { + if (wavelength <= 0) + throw std::runtime_error("Wavelength is not defined!"); + + if (targetunit.compare("dSpacing") == 0) + outx = calculateDspaceFrom2Theta(twotheta, wavelength); + else if (targetunit.compare("Momentum Transfer (Q)") == 0) + outx = calculateQFrom2Theta(twotheta, wavelength); + else + throw std::runtime_error("Unrecognized unit."); + } + + // Compare with xmin and xmax + if (outx < xmin) + xmin = outx; + if (outx > xmax) + xmax = outx; + } + } + + + g_log.debug() << "Find boundary for unit " << targetunit << ": [" << xmin << ", " << xmax << "]" + << "\n"; +} + //---------------------------------------------------------------------------------------------- /** Bin MD Workspace for detector's position at 2theta * @brief ConvertCWPDMDToSpectra::binMD @@ -359,27 +503,84 @@ void ConvertCWPDMDToSpectra::binMD(API::IMDEventWorkspace_const_sptr mdws, } // get signal and assign signal to bin - double signal = mditer->getInnerSignal(iev); - std::vector<double>::const_iterator vfiter = - std::lower_bound(vecx.begin(), vecx.end(), outx); - int xindex = static_cast<int>(vfiter - vecx.begin()); + int xindex; + const double SMALL = 1.0E-5; + if (outx+SMALL < vecx.front()) + { + // Significantly out of left boundary + xindex = -1; + } + else if (fabs(outx - vecx.front()) < SMALL) + { + // Almost on the left boundary + xindex = 0; + } + else if (outx-SMALL > vecx.back()) + { + // Significantly out of right boundary + xindex = static_cast<int>(vecx.size()); + } + else if (fabs(outx-vecx.back()) < SMALL) + { + // Right on the right boundary + xindex = static_cast<int>(vecy.size())-1; + } + else + { + // Other situation + std::vector<double>::const_iterator vfiter = + std::lower_bound(vecx.begin(), vecx.end(), outx); + xindex = static_cast<int>(vfiter - vecx.begin()); + if ( (xindex < static_cast<int>(vecx.size())) && (outx + 1.0E-5 < vecx[xindex]) ) + { + // assume the bin's boundaries are of [...) and consider numerical error + xindex -= 1; + } + else + { + g_log.debug() << "Case for almost same. Event X = " << outx + << ", Boundary = " << vecx[xindex] << "\n"; + } + if (xindex < 0 || xindex >= static_cast<int>(vecy.size())) + { + g_log.warning() << "Case unexpected: Event X = " << outx + << ", Boundary = " << vecx[xindex] << "\n"; + } + } + + // add signal if (xindex < 0) - g_log.warning("xindex < 0"); - if (xindex >= static_cast<int>(vecy.size()) - 1) { - // If the Xmax is set too narrow, then - g_log.information() << "Event is out of user-specified range " - << "xindex = " << xindex << ", " << unitbit << " = " - << outx << " out of [" << vecx.front() << ", " - << vecx.back() << "]. dep pos = " << detpos.X() - << ", " << detpos.Y() << ", " << detpos.Z() - << "; sample pos = " << samplepos.X() << ", " - << samplepos.Y() << ", " << samplepos.Z() << "\n"; + { + // Out of left boundary + int32_t detid = mditer->getInnerDetectorID(iev); + uint16_t runid = mditer->getInnerRunIndex(iev); + g_log.debug() << "Event is out of user-specified range by " << (outx-vecx.front()) + << ", xindex = " << xindex << ", " << unitbit << " = " + << outx << " out of left boundeary [" << vecx.front() << ", " + << vecx.back() << "]. dep pos = " << detpos.X() + << ", " << detpos.Y() << ", " << detpos.Z() + << ", Run = " << runid << ", DetectorID = " << detid << "\n"; continue; } - - if (xindex > 0 && outx < *vfiter) - xindex -= 1; - vecy[xindex] += signal; + else if (xindex >= static_cast<int>(vecy.size())) { + // Out of right boundary + int32_t detid = mditer->getInnerDetectorID(iev); + uint16_t runid = mditer->getInnerRunIndex(iev); + g_log.debug() << "Event is out of user-specified range " + << "xindex = " << xindex << ", " << unitbit << " = " + << outx << " out of [" << vecx.front() << ", " + << vecx.back() << "]. dep pos = " << detpos.X() + << ", " << detpos.Y() << ", " << detpos.Z() + << "; sample pos = " << samplepos.X() << ", " + << samplepos.Y() << ", " << samplepos.Z() + << ", Run = " << runid << ", DetectorID = " << detid << "\n"; + continue; + } + else + { + double signal = mditer->getInnerSignal(iev); + vecy[xindex] += signal; + } } // Advance to next cell diff --git a/Code/Mantid/Framework/MDAlgorithms/src/ConvertToDetectorFaceMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/ConvertToDetectorFaceMD.cpp index 414eb440975ed79dfd397aada8397225551c2170..a2adcd804e4626c7ce472b00e6f9cc571af23bf8 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/ConvertToDetectorFaceMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/ConvertToDetectorFaceMD.cpp @@ -37,10 +37,10 @@ ConvertToDetectorFaceMD::~ConvertToDetectorFaceMD() {} /// Algorithm's name for identification. @see Algorithm::name const std::string ConvertToDetectorFaceMD::name() const { return "ConvertToDetectorFaceMD"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int ConvertToDetectorFaceMD::version() const { return 1; }; +int ConvertToDetectorFaceMD::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string ConvertToDetectorFaceMD::category() const { diff --git a/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMD.cpp index 3f08264ba430a8b365a631a9716e46f1310154a0..36f8b333c09fbc27d83b866f15a182e83a67e969 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMD.cpp @@ -87,8 +87,9 @@ void ConvertToMD::init() { setPropertyGroup("MinRecursionDepth", getBoxSettingsGroupName()); declareProperty( - new PropertyWithValue<bool>("InitialSplitting", 0, Direction::Input), - "This option causes an initial split of 50 for the first four dimensions at level 0."); + new PropertyWithValue<bool>("InitialSplitting", 0, Direction::Input), + "This option causes an initial split of 50 for the first four dimensions " + "at level 0."); } //---------------------------------------------------------------------------------------------- /** Destructor @@ -326,9 +327,13 @@ void ConvertToMD::copyMetaData(API::IMDEventWorkspace_sptr &mdEventWS) const { } } + // The last experiment info should always be the one that refers + // to latest converting workspace. All others should have had this + // information set already uint16_t nexpts = mdEventWS->getNumExperimentInfo(); - for (uint16_t i = 0; i < nexpts; ++i) { - ExperimentInfo_sptr expt = mdEventWS->getExperimentInfo(i); + if (nexpts > 0) { + ExperimentInfo_sptr expt = + mdEventWS->getExperimentInfo(static_cast<uint16_t>(nexpts - 1)); expt->mutableRun().storeHistogramBinBoundaries(binBoundaries); expt->cacheDetectorGroupings(*mapping); } @@ -471,13 +476,10 @@ API::IMDEventWorkspace_sptr ConvertToMD::createNewMDWorkspace( // Check if the user want sto force an initial split or not bool initialSplittingChecked = this->getProperty("InitialSplitting"); - if (!initialSplittingChecked) - { + if (!initialSplittingChecked) { // split boxes; spws->splitBox(); - } - else - { + } else { // Perform initial split with the forced settings performInitialSplitting(spws, bc); } @@ -494,26 +496,27 @@ API::IMDEventWorkspace_sptr ConvertToMD::createNewMDWorkspace( } /** - * Splits the initial box at level 0 into a defined number of subboxes for the the first level. + * Splits the initial box at level 0 into a defined number of subboxes for the + * the first level. * @param spws A pointer to the newly created event workspace. * @param bc A pointer to the box controller. */ -void ConvertToMD::performInitialSplitting(API::IMDEventWorkspace_sptr spws, Mantid::API::BoxController_sptr bc) -{ +void ConvertToMD::performInitialSplitting(API::IMDEventWorkspace_sptr spws, + Mantid::API::BoxController_sptr bc) { const size_t initialSplitSetting = 50; const size_t dimCutoff = 4; - // Record the split settings of the box controller in a buffer and set the new value + // Record the split settings of the box controller in a buffer and set the new + // value std::vector<size_t> splitBuffer; - - for (size_t dim = 0; dim < bc->getNDims(); dim++) - { + + for (size_t dim = 0; dim < bc->getNDims(); dim++) { splitBuffer.push_back(bc->getSplitInto(dim)); - // Replace the box controller setting only for a max of the first three dimensions - if (dim < dimCutoff) - { - bc->setSplitInto(dim, initialSplitSetting); + // Replace the box controller setting only for a max of the first three + // dimensions + if (dim < dimCutoff) { + bc->setSplitInto(dim, initialSplitSetting); } } @@ -521,8 +524,7 @@ void ConvertToMD::performInitialSplitting(API::IMDEventWorkspace_sptr spws, Mant spws->splitBox(); // Revert changes on the box controller - for (size_t dim = 0; dim < bc->getNDims(); ++dim) - { + for (size_t dim = 0; dim < bc->getNDims(); ++dim) { bc->setSplitInto(dim, splitBuffer[dim]); } } diff --git a/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMDMinMaxGlobal.cpp b/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMDMinMaxGlobal.cpp index b4ccc704bb3a78e8db69589e7160ef37d1770a3e..a20bd7ded854596286142d337585f59ef3578238 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMDMinMaxGlobal.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMDMinMaxGlobal.cpp @@ -34,10 +34,10 @@ ConvertToMDMinMaxGlobal::~ConvertToMDMinMaxGlobal() {} /// Algorithm's name for identification. @see Algorithm::name const std::string ConvertToMDMinMaxGlobal::name() const { return "ConvertToMDMinMaxGlobal"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int ConvertToMDMinMaxGlobal::version() const { return 1; }; +int ConvertToMDMinMaxGlobal::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string ConvertToMDMinMaxGlobal::category() const { diff --git a/Code/Mantid/Framework/MDAlgorithms/src/CreateMDHistoWorkspace.cpp b/Code/Mantid/Framework/MDAlgorithms/src/CreateMDHistoWorkspace.cpp index 6684e1cac420e5738452c859a6beeb1f27b0fe61..71f53a68117703c65d067e3de08745376fc66300 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/CreateMDHistoWorkspace.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/CreateMDHistoWorkspace.cpp @@ -32,10 +32,10 @@ CreateMDHistoWorkspace::~CreateMDHistoWorkspace() {} /// Algorithm's name for identification. @see Algorithm::name const std::string CreateMDHistoWorkspace::name() const { return "CreateMDHistoWorkspace"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int CreateMDHistoWorkspace::version() const { return 1; }; +int CreateMDHistoWorkspace::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string CreateMDHistoWorkspace::category() const { diff --git a/Code/Mantid/Framework/MDAlgorithms/src/CutMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/CutMD.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8954f003c7f77163ece08edc3f7e5f891e79227f --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/src/CutMD.cpp @@ -0,0 +1,445 @@ +#include "MantidMDAlgorithms/CutMD.h" +#include "MantidAPI/IMDEventWorkspace.h" +#include "MantidGeometry/Crystal/OrientedLattice.h" +#include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/Matrix.h" +#include "MantidKernel/System.h" + +using namespace Mantid::API; +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + +namespace { + +// Typedef to simplify function signatures +typedef std::pair<double, double> MinMax; + +MinMax getDimensionExtents(IMDEventWorkspace_sptr ws, size_t index) { + if (!ws) + throw std::runtime_error( + "Invalid workspace passed to getDimensionExtents."); + auto dim = ws->getDimension(index); + return std::make_pair(dim->getMinimum(), dim->getMaximum()); +} + +DblMatrix matrixFromProjection(ITableWorkspace_sptr projection) { + if (!projection) { + return DblMatrix(3, 3, true /* makeIdentity */); + } + + const size_t numDims = projection->rowCount(); + DblMatrix ret(3, 3); + for (size_t i = 0; i < numDims; i++) { + const std::string name = + projection->getColumn("name")->cell<std::string>(i); + const std::string valueStr = + projection->getColumn("value")->cell<std::string>(i); + std::vector<std::string> valueStrVec; + boost::split(valueStrVec, valueStr, boost::is_any_of(",")); + + std::vector<double> valueDblVec; + for (auto it = valueStrVec.begin(); it != valueStrVec.end(); ++it) + valueDblVec.push_back(boost::lexical_cast<double>(*it)); + + if (name == "u") + ret.setRow(0, valueDblVec); + else if (name == "v") + ret.setRow(1, valueDblVec); + else if (name == "w") + ret.setRow(2, valueDblVec); + } + return ret; +} + +std::vector<std::string> unitsFromProjection(ITableWorkspace_sptr projection) { + std::vector<std::string> ret(3, "r"); + if (!projection) + return ret; + + const size_t numDims = projection->rowCount(); + for (size_t i = 0; i < numDims; i++) { + const std::string name = + projection->getColumn("name")->cell<std::string>(i); + const std::string unit = + projection->getColumn("type")->cell<std::string>(i); + + if (name == "u") + ret[0] = unit; + else if (name == "v") + ret[1] = unit; + else if (name == "w") + ret[2] = unit; + } + return ret; +} + +DblMatrix scaleProjection(const DblMatrix &inMatrix, + const std::vector<std::string> &inUnits, + const std::vector<std::string> &outUnits, + IMDEventWorkspace_sptr inWS) { + DblMatrix ret(inMatrix); + // Check if we actually need to do anything + if (std::equal(inUnits.begin(), inUnits.end(), outUnits.begin())) + return ret; + + if (inUnits.size() != outUnits.size()) + throw std::runtime_error( + "scaleProjection given different quantity of input and output units"); + + const OrientedLattice &orientedLattice = + inWS->getExperimentInfo(0)->sample().getOrientedLattice(); + + const size_t numDims = inUnits.size(); + for (size_t i = 0; i < numDims; ++i) { + const double dStar = + 2 * M_PI * + orientedLattice.dstar(inMatrix[i][0], inMatrix[i][1], inMatrix[i][2]); + if (inUnits[i] == outUnits[i]) + continue; + else if (inUnits[i] == "a") { + // inv angstroms to rlu + for (size_t j = 0; j < numDims; ++j) + ret[i][j] *= dStar; + } else { + // rlu to inv angstroms + for (size_t j = 0; j < numDims; ++j) + ret[i][j] /= dStar; + } + } + + return ret; +} + +std::vector<MinMax> calculateExtents(const DblMatrix &inMatrix, + const std::vector<MinMax> &limits) { + DblMatrix invMat(inMatrix); + invMat.Invert(); + + // iterate through min/max of each dimension, calculate dot(vert, inv_mat) + // and store min/max value for each dimension + std::vector<double> hRange(2), kRange(2), lRange(2); + + hRange[0] = limits[0].first; + hRange[1] = limits[0].second; + kRange[0] = limits[1].first; + kRange[1] = limits[1].second; + lRange[0] = limits[2].first; + lRange[1] = limits[2].second; + + // Calculate the minimums and maximums of transformed coordinates + // Use maxDbl as a "not-yet-set" placeholder + const double maxDbl = std::numeric_limits<double>::max(); + std::vector<MinMax> extents(3, std::make_pair(maxDbl, maxDbl)); + + for (auto hIt = hRange.begin(); hIt != hRange.end(); ++hIt) { + for (auto kIt = kRange.begin(); kIt != kRange.end(); ++kIt) { + for (auto lIt = lRange.begin(); lIt != lRange.end(); ++lIt) { + V3D origPos(*hIt, *kIt, *lIt); + for (size_t i = 0; i < 3; ++i) { + const V3D other(invMat[i][0], invMat[i][1], invMat[i][2]); + double val = origPos.scalar_prod(other); + // Check if min needs updating + if (extents[i].first == maxDbl || extents[i].first > val) + extents[i].first = val; + // Check if max needs updating + if (extents[i].second == maxDbl || extents[i].second < val) + extents[i].second = val; + } + } + } + } + + return extents; +} + +std::pair<std::vector<MinMax>, std::vector<int>> +calculateSteps(const std::vector<MinMax> &inExtents, + const std::vector<std::vector<double>> &binning) { + std::vector<MinMax> outExtents(inExtents); + std::vector<int> outBins; + + for (size_t i = 0; i < inExtents.size(); ++i) { + const size_t nArgs = binning[i].size(); + int outBin = -1; + + if (nArgs == 0) { + throw std::runtime_error("Binning parameter cannot be empty"); + + } else if (nArgs == 1) { + const double dimRange = inExtents[i].second - inExtents[i].first; + const double stepSize = + binning[i][0] < dimRange ? binning[i][0] : dimRange; + outBin = static_cast<int>(dimRange / stepSize); + outExtents[i].second = inExtents[i].first + outBin * stepSize; + + } else if (nArgs == 2) { + outExtents[i].first = binning[i][0]; + outExtents[i].second = binning[i][1]; + outBin = 1; + + } else if (nArgs == 3) { + const double dimMin = binning[i][0]; + const double dimMax = binning[i][2]; + const double dimRange = dimMax - dimMin; + const double stepSize = + binning[i][1] < dimRange ? binning[i][1] : dimRange; + outBin = static_cast<int>(dimRange / stepSize); + outExtents[i].second = dimMin + outBin * stepSize; + outExtents[i].first = dimMin; + + } else { + throw std::runtime_error("Cannot handle " + + boost::lexical_cast<std::string>(nArgs) + + " bins."); + } + if (outBin < 0) + throw std::runtime_error("output bin calculated to be less than 0"); + outBins.push_back(outBin); + } + return std::make_pair(outExtents, outBins); +} + +std::vector<std::string> labelProjection(const DblMatrix &projection) { + const std::string replacements[] = {"zeta", "eta", "xi"}; + std::vector<std::string> ret(3); + std::vector<std::string> labels(3); + + for (size_t i = 0; i < 3; ++i) { + for (size_t j = 0; j < 3; ++j) { + const double in = projection[i][j]; + if (std::abs(in) == 1) + if (in > 0) + labels[j] = "'" + replacements[i] + "'"; + else + labels[j] = "'-" + replacements[i] + "'"; + else if (in == 0) + labels[j] = "0"; + else { + // We have to be explicit about precision, so lexical cast won't work + std::stringstream s; + s.precision(2); + s.setf(std::ios::fixed, std::ios::floatfield); + s << "'" << in << replacements[i] << "'"; + labels[j] = s.str(); + } + } + ret[i] = "[" + boost::algorithm::join(labels, ", ") + "]"; + } + return ret; +} +} // anonymous namespace + +namespace Mantid { +namespace MDAlgorithms { + +// Register the algorithm into the AlgorithmFactory +DECLARE_ALGORITHM(CutMD) + +//---------------------------------------------------------------------------------------------- +/** Constructor + */ +CutMD::CutMD() {} + +//---------------------------------------------------------------------------------------------- +/** Destructor + */ +CutMD::~CutMD() {} + +//---------------------------------------------------------------------------------------------- + +void CutMD::init() { + declareProperty(new WorkspaceProperty<IMDEventWorkspace>("InputWorkspace", "", + Direction::Input), + "MDWorkspace to slice"); + + declareProperty( + new WorkspaceProperty<ITableWorkspace>("Projection", "", Direction::Input, + PropertyMode::Optional), + "Projection"); + + declareProperty(new ArrayProperty<double>("P1Bin"), "Projection 1 binning."); + declareProperty(new ArrayProperty<double>("P2Bin"), "Projection 2 binning."); + declareProperty(new ArrayProperty<double>("P3Bin"), "Projection 3 binning."); + declareProperty(new ArrayProperty<double>("P4Bin"), "Projection 4 binning."); + declareProperty(new ArrayProperty<double>("P5Bin"), "Projection 5 binning."); + + declareProperty(new WorkspaceProperty<IMDWorkspace>("OutputWorkspace", "", + Direction::Output), + "Output cut workspace"); + declareProperty("NoPix", false, "If False creates a full MDEventWorkspaces " + "as output. True to create an " + "MDHistoWorkspace as output. This is DND " + "only in Horace terminology."); + declareProperty("CheckAxes", true, + "Check that the axis look to be correct, and abort if not."); +} + +void CutMD::exec() { + g_log.warning("CutMD is in the beta stage of development. Its properties and " + "behaviour may change without warning."); + + // Collect input properties + const IMDEventWorkspace_sptr inWS = getProperty("InputWorkspace"); + const size_t numDims = inWS->getNumDims(); + const ITableWorkspace_sptr projection = getProperty("Projection"); + std::vector<std::vector<double>> pbins(5); + pbins[0] = getProperty("P1Bin"); + pbins[1] = getProperty("P2Bin"); + pbins[2] = getProperty("P3Bin"); + pbins[3] = getProperty("P4Bin"); + pbins[4] = getProperty("P5Bin"); + const bool noPix = getProperty("NoPix"); + + // Check Projection format + if (projection) { + auto colNames = projection->getColumnNames(); + if (colNames.size() != 4 || + std::find(colNames.begin(), colNames.end(), "name") == colNames.end() || + std::find(colNames.begin(), colNames.end(), "value") == + colNames.end() || + std::find(colNames.begin(), colNames.end(), "offset") == + colNames.end() || + std::find(colNames.begin(), colNames.end(), "type") == colNames.end()) + throw std::runtime_error( + "Invalid Projection supplied. Please check column names."); + if (projection->rowCount() < 3) + throw std::runtime_error( + "Insufficient rows in projection table. Must be 3 or more."); + } + // Check PBin properties + for (size_t i = 0; i < 5; ++i) { + if (i < numDims && pbins[i].empty()) + throw std::runtime_error( + "P" + boost::lexical_cast<std::string>(i + 1) + + "Bin must be set when processing a workspace with " + + boost::lexical_cast<std::string>(numDims) + " dimensions."); + if (i >= numDims && !pbins[i].empty()) + throw std::runtime_error( + "P" + boost::lexical_cast<std::string>(i + 1) + + "Bin must NOT be set when processing a workspace with " + + boost::lexical_cast<std::string>(numDims) + " dimensions."); + } + + // Get extents in projection + std::vector<MinMax> extentLimits; + extentLimits.push_back(getDimensionExtents(inWS, 0)); + extentLimits.push_back(getDimensionExtents(inWS, 1)); + extentLimits.push_back(getDimensionExtents(inWS, 2)); + + // Scale projection + DblMatrix projectionMatrix = matrixFromProjection(projection); + std::vector<std::string> targetUnits = unitsFromProjection(projection); + std::vector<std::string> originUnits(3); // TODO. This is a hack! + originUnits[0] = "r"; + originUnits[1] = "r"; + originUnits[2] = "r"; + + DblMatrix scaledProjectionMatrix = + scaleProjection(projectionMatrix, originUnits, targetUnits, inWS); + + // Calculate extents for the first 3 dimensions + std::vector<MinMax> scaledExtents = + calculateExtents(scaledProjectionMatrix, extentLimits); + auto stepPair = calculateSteps(scaledExtents, pbins); + std::vector<MinMax> steppedExtents = stepPair.first; + std::vector<int> steppedBins = stepPair.second; + + // Calculate extents for additional dimensions + for (size_t i = 3; i < numDims; ++i) { + const size_t nArgs = pbins[i].size(); + const MinMax extentLimit = getDimensionExtents(inWS, i); + const double dimRange = extentLimit.second - extentLimit.first; + + if (nArgs == 1) { + steppedExtents.push_back(extentLimit); + steppedBins.push_back(static_cast<int>(dimRange / pbins[i][0])); + } else if (nArgs == 2) { + steppedExtents.push_back(std::make_pair(pbins[i][0], pbins[i][1])); + steppedBins.push_back(1); + } else if (nArgs == 3) { + const double dimRange = pbins[i][2] - pbins[i][0]; + const double stepSize = pbins[i][1] < dimRange ? pbins[i][1] : dimRange; + steppedExtents.push_back(std::make_pair(pbins[i][0], pbins[i][2])); + steppedBins.push_back(static_cast<int>(dimRange / stepSize)); + } + + // and double targetUnits' length by appending itself to itself + size_t preSize = targetUnits.size(); + targetUnits.resize(preSize * 2); + for (size_t i = 0; i < preSize; ++i) + targetUnits[preSize + i] = targetUnits[i]; + } + + // Make labels + std::vector<std::string> labels = labelProjection(projectionMatrix); + + // Either run RebinMD or SliceMD + const std::string cutAlgName = noPix ? "BinMD" : "SliceMD"; + IAlgorithm_sptr cutAlg = createChildAlgorithm(cutAlgName, 0.0, 1.0); + cutAlg->initialize(); + cutAlg->setProperty("InputWorkspace", inWS); + cutAlg->setProperty("OutputWorkspace", "sliced"); + cutAlg->setProperty("NormalizeBasisVectors", false); + cutAlg->setProperty("AxisAligned", false); + + for (size_t i = 0; i < numDims; ++i) { + std::string label; + std::string unit; + std::string vecStr; + + if (i < 3) { + // Slicing algorithms accept name as [x, y, z] + label = labels[i]; + unit = targetUnits[i]; + + std::vector<std::string> vec(numDims, "0"); + for (size_t j = 0; j < 3; ++j) + vec[j] = boost::lexical_cast<std::string>(projectionMatrix[i][j]); + vecStr = boost::algorithm::join(vec, ", "); + } else { + // Always orthogonal + auto dim = inWS->getDimension(i); + label = dim->getName(); + unit = dim->getUnits(); + std::vector<std::string> vec(numDims, "0"); + vec[i] = "1"; + vecStr = boost::algorithm::join(vec, ", "); + } + + const std::string value = label + ", " + unit + ", " + vecStr; + cutAlg->setProperty("BasisVector" + boost::lexical_cast<std::string>(i), + value); + } + + // Translate extents into a single vector + std::vector<double> outExtents(steppedExtents.size() * 2); + for (size_t i = 0; i < steppedExtents.size(); ++i) { + outExtents[2 * i] = steppedExtents[i].first; + outExtents[2 * i + 1] = steppedExtents[i].second; + } + + cutAlg->setProperty("OutputExtents", outExtents); + cutAlg->setProperty("OutputBins", steppedBins); + + cutAlg->execute(); + Workspace_sptr sliceWS = cutAlg->getProperty("OutputWorkspace"); + MultipleExperimentInfos_sptr sliceInfo = + boost::dynamic_pointer_cast<MultipleExperimentInfos>(sliceWS); + + if (!sliceInfo) + throw std::runtime_error( + "Could not extract experiment info from child's OutputWorkspace"); + + // Attach projection matrix to output + if (sliceInfo->getNumExperimentInfo() > 0) { + ExperimentInfo_sptr info = sliceInfo->getExperimentInfo(0); + info->mutableRun().addProperty("W_MATRIX", projectionMatrix.getVector(), + true); + } + + // Done! + setProperty("OutputWorkspace", sliceWS); +} + +} // namespace Mantid +} // namespace MDAlgorithms diff --git a/Code/Mantid/Framework/MDAlgorithms/src/DivideMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/DivideMD.cpp index a471bc0c91f1af08b16e3878773813c9405bef36..d5a31cf34ce80ced56d5a8c411926a51b92fd15f 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/DivideMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/DivideMD.cpp @@ -27,10 +27,10 @@ DivideMD::~DivideMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string DivideMD::name() const { return "DivideMD"; }; +const std::string DivideMD::name() const { return "DivideMD"; } /// Algorithm's version for identification. @see Algorithm::version -int DivideMD::version() const { return 1; }; +int DivideMD::version() const { return 1; } //---------------------------------------------------------------------------------------------- diff --git a/Code/Mantid/Framework/MDAlgorithms/src/EqualToMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/EqualToMD.cpp index f53d3f33f7f2200ad6fda5c1ec886682080c8571..32216e09f5f1fa7379c9a731add7ceb8c8481f99 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/EqualToMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/EqualToMD.cpp @@ -22,10 +22,10 @@ EqualToMD::~EqualToMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string EqualToMD::name() const { return "EqualToMD"; }; +const std::string EqualToMD::name() const { return "EqualToMD"; } /// Algorithm's version for identification. @see Algorithm::version -int EqualToMD::version() const { return 1; }; +int EqualToMD::version() const { return 1; } //---------------------------------------------------------------------------------------------- /// Extra properties diff --git a/Code/Mantid/Framework/MDAlgorithms/src/EvaluateMDFunction.cpp b/Code/Mantid/Framework/MDAlgorithms/src/EvaluateMDFunction.cpp index d395663cb7ba0c9a4e7ba66da6f99c2c623059ea..10f64648dac48e419b604e4d4ccf328f30a3c3ad 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/EvaluateMDFunction.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/EvaluateMDFunction.cpp @@ -28,7 +28,7 @@ EvaluateMDFunction::~EvaluateMDFunction() {} //---------------------------------------------------------------------------------------------- /// Algorithm's version for identification. @see Algorithm::version -int EvaluateMDFunction::version() const { return 1; }; +int EvaluateMDFunction::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string EvaluateMDFunction::category() const { @@ -38,7 +38,7 @@ const std::string EvaluateMDFunction::category() const { /// Algorithm's summary for use in the GUI and help. @see Algorithm::summary const std::string EvaluateMDFunction::summary() const { return "Evaluates an MD function on a MD histo workspace."; -}; +} //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. diff --git a/Code/Mantid/Framework/MDAlgorithms/src/ExponentialMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/ExponentialMD.cpp index 50ffffa72ead89f8887883e520bb0b424d6a7b00..7da6298e57aa2d4887cd664a3dbd502def1431d3 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/ExponentialMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/ExponentialMD.cpp @@ -22,10 +22,10 @@ ExponentialMD::~ExponentialMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string ExponentialMD::name() const { return "ExponentialMD"; }; +const std::string ExponentialMD::name() const { return "ExponentialMD"; } /// Algorithm's version for identification. @see Algorithm::version -int ExponentialMD::version() const { return 1; }; +int ExponentialMD::version() const { return 1; } //---------------------------------------------------------------------------------------------- diff --git a/Code/Mantid/Framework/MDAlgorithms/src/GreaterThanMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/GreaterThanMD.cpp index 8818bc87c81e3ed4f93ea6839d06f609ae69e5f6..f98766cfff7d30ea0f189f1b70032d7f23c67c6c 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/GreaterThanMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/GreaterThanMD.cpp @@ -22,10 +22,10 @@ GreaterThanMD::~GreaterThanMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string GreaterThanMD::name() const { return "GreaterThanMD"; }; +const std::string GreaterThanMD::name() const { return "GreaterThanMD"; } /// Algorithm's version for identification. @see Algorithm::version -int GreaterThanMD::version() const { return 1; }; +int GreaterThanMD::version() const { return 1; } //---------------------------------------------------------------------------------------------- /// Run the algorithm with a MDHisotWorkspace as output and operand diff --git a/Code/Mantid/Framework/MDAlgorithms/src/IntegrateFlux.cpp b/Code/Mantid/Framework/MDAlgorithms/src/IntegrateFlux.cpp index 95092d1e84b71a6861640f5a7c625af08da2b0a3..1bb592d391f31166d9f19264859e0dc2902c551d 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/IntegrateFlux.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/IntegrateFlux.cpp @@ -32,7 +32,7 @@ public: const std::string IntegrateFlux::name() const { return "IntegrateFlux"; } /// Algorithm's version for identification. @see Algorithm::version -int IntegrateFlux::version() const { return 1; }; +int IntegrateFlux::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string IntegrateFlux::category() const { return "MDAlgorithms"; } @@ -40,7 +40,7 @@ const std::string IntegrateFlux::category() const { return "MDAlgorithms"; } /// Algorithm's summary for use in the GUI and help. @see Algorithm::summary const std::string IntegrateFlux::summary() const { return "Interates spectra in a matrix workspace at a set of points."; -}; +} //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. diff --git a/Code/Mantid/Framework/MDAlgorithms/src/IntegratePeaksMD2.cpp b/Code/Mantid/Framework/MDAlgorithms/src/IntegratePeaksMD2.cpp index e756c4d49ea192a47f49881edd6efefdee91b9bc..83009e5e60fbf2043f82af27a24678d4e222e03b 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/IntegratePeaksMD2.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/IntegratePeaksMD2.cpp @@ -103,10 +103,12 @@ void IntegratePeaksMD2::init() { "Only warning if all of peak outer radius is not on detector (default).\n" "If false, do not integrate if the outer radius is not on a detector."); - declareProperty("AdaptiveQRadius", false, - "Default is false. If true, all input radii are multiplied " - "by the magnitude of Q at the peak center so each peak has a " - "different integration radius. Q includes the 2*pi factor."); + declareProperty("AdaptiveQBackground", false, + "Default is false. If true, all background values" + "vary on a line so that they are" + "background plus AdaptiveQMultiplier multiplied" + "by the magnitude of Q at the peak center so each peak has a " + "different integration radius. Q includes the 2*pi factor."); declareProperty("Cylinder", false, "Default is sphere. Use next five parameters for cylinder."); @@ -142,6 +144,12 @@ void IntegratePeaksMD2::init() { new FileProperty("ProfilesFile", "", FileProperty::OptionalSave, std::vector<std::string>(1, "profiles")), "Save (Optionally) as Isaw peaks file with profiles included"); + + declareProperty("AdaptiveQMultiplier", 0.0, + "Peak integration radius varies on a line so that it is" + "PeakRadius plus this value multiplied" + "by the magnitude of Q at the peak center so each peak has a " + "different integration radius. Q includes the 2*pi factor."); } //---------------------------------------------------------------------------------------------- @@ -191,7 +199,10 @@ void IntegratePeaksMD2::integrate(typename MDEventWorkspace<MDE, nd>::sptr ws) { Workspace2D_sptr wsProfile2D, wsFit2D, wsDiff2D; size_t numSteps = 0; bool cylinderBool = getProperty("Cylinder"); - bool adaptiveQRadius = getProperty("AdaptiveQRadius"); + bool adaptiveQBackground = getProperty("AdaptiveQBackground"); + double adaptiveQMultiplier = getProperty("AdaptiveQMultiplier"); + double adaptiveQBackgroundMultiplier = 0.0; + if (adaptiveQBackground) adaptiveQBackgroundMultiplier = adaptiveQMultiplier; std::vector<double> PeakRadiusVector(peakWS->getNumberPeaks(), PeakRadius); std::vector<double> BackgroundInnerRadiusVector(peakWS->getNumberPeaks(), BackgroundInnerRadius); @@ -316,8 +327,8 @@ void IntegratePeaksMD2::integrate(typename MDEventWorkspace<MDE, nd>::sptr ws) { double background_total = 0.0; if (!cylinderBool) { // modulus of Q - coord_t lenQpeak = 1.0; - if (adaptiveQRadius) { + coord_t lenQpeak = 0.0; + if (adaptiveQMultiplier > 0.0) { lenQpeak = 0.0; for (size_t d = 0; d < nd; d++) { lenQpeak += center[d] * center[d]; @@ -325,9 +336,9 @@ void IntegratePeaksMD2::integrate(typename MDEventWorkspace<MDE, nd>::sptr ws) { lenQpeak = std::sqrt(lenQpeak); } - PeakRadiusVector[i] = lenQpeak * PeakRadius; - BackgroundInnerRadiusVector[i] = lenQpeak * BackgroundInnerRadius; - BackgroundOuterRadiusVector[i] = lenQpeak * BackgroundOuterRadius; + PeakRadiusVector[i] = adaptiveQMultiplier * lenQpeak + PeakRadius; + BackgroundInnerRadiusVector[i] = adaptiveQBackgroundMultiplier * lenQpeak + BackgroundInnerRadius; + BackgroundOuterRadiusVector[i] = adaptiveQBackgroundMultiplier * lenQpeak + BackgroundOuterRadius; CoordTransformDistance sphere(nd, center, dimensionsUsed); if(Peak* shapeablePeak = dynamic_cast<Peak*>(&p)){ @@ -340,7 +351,7 @@ void IntegratePeaksMD2::integrate(typename MDEventWorkspace<MDE, nd>::sptr ws) { // Perform the integration into whatever box is contained within. ws->getBox()->integrateSphere( sphere, - static_cast<coord_t>(lenQpeak * PeakRadius * lenQpeak * PeakRadius), + static_cast<coord_t>((adaptiveQMultiplier * lenQpeak + PeakRadius) * (adaptiveQMultiplier * lenQpeak + PeakRadius)), signal, errorSquared); // Integrate around the background radius @@ -348,8 +359,8 @@ void IntegratePeaksMD2::integrate(typename MDEventWorkspace<MDE, nd>::sptr ws) { if (BackgroundOuterRadius > PeakRadius) { // Get the total signal inside "BackgroundOuterRadius" ws->getBox()->integrateSphere( - sphere, static_cast<coord_t>(lenQpeak * BackgroundOuterRadius * - lenQpeak * BackgroundOuterRadius), + sphere, static_cast<coord_t>((adaptiveQBackgroundMultiplier * lenQpeak + BackgroundOuterRadius) * + (adaptiveQBackgroundMultiplier * lenQpeak + BackgroundOuterRadius)), bgSignal, bgErrorSquared); // Evaluate the signal inside "BackgroundInnerRadius" @@ -359,8 +370,8 @@ void IntegratePeaksMD2::integrate(typename MDEventWorkspace<MDE, nd>::sptr ws) { // Integrate this 3rd radius, if needed if (BackgroundInnerRadius != PeakRadius) { ws->getBox()->integrateSphere( - sphere, static_cast<coord_t>(lenQpeak * BackgroundInnerRadius * - lenQpeak * BackgroundInnerRadius), + sphere, static_cast<coord_t>((adaptiveQBackgroundMultiplier * lenQpeak + BackgroundInnerRadius) * + (adaptiveQBackgroundMultiplier * lenQpeak + BackgroundInnerRadius)), interiorSignal, interiorErrorSquared); } else { // PeakRadius == BackgroundInnerRadius, so use the previous value diff --git a/Code/Mantid/Framework/MDAlgorithms/src/LessThanMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/LessThanMD.cpp index da8b7db1879f85f2b385b2df8060ebb77ec3e065..ba6e3f654cb3654cb41a5a88ad124210b466af40 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/LessThanMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/LessThanMD.cpp @@ -22,10 +22,10 @@ LessThanMD::~LessThanMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string LessThanMD::name() const { return "LessThanMD"; }; +const std::string LessThanMD::name() const { return "LessThanMD"; } /// Algorithm's version for identification. @see Algorithm::version -int LessThanMD::version() const { return 1; }; +int LessThanMD::version() const { return 1; } //---------------------------------------------------------------------------------------------- /// Run the algorithm with a MDHisotWorkspace as output and operand diff --git a/Code/Mantid/Framework/MDAlgorithms/src/LoadILLAscii.cpp b/Code/Mantid/Framework/MDAlgorithms/src/LoadILLAscii.cpp index ffe7780809d447eac556bd7830af26c2ac0a0d3b..aff2b3ba119c599cda4710ed49aacd27e7034811 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/LoadILLAscii.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/LoadILLAscii.cpp @@ -82,10 +82,10 @@ int LoadILLAscii::confidence(Kernel::FileDescriptor &descriptor) const { //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string LoadILLAscii::name() const { return "LoadILLAscii"; }; +const std::string LoadILLAscii::name() const { return "LoadILLAscii"; } /// Algorithm's version for identification. @see Algorithm::version -int LoadILLAscii::version() const { return 1; }; +int LoadILLAscii::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string LoadILLAscii::category() const { diff --git a/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp index 022116b5941592f0c4cdf2656195155fc1d297d1..7b7d5eafaad185193718a2bc207b66940c027fed 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp @@ -34,13 +34,14 @@ using namespace Mantid::MDEvents; namespace Mantid { namespace MDAlgorithms { -DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadMD); +DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadMD) //---------------------------------------------------------------------------------------------- /** Constructor */ LoadMD::LoadMD() - : m_numDims(0), // uninitialized incorrect value + : m_numDims(0), // uninitialized incorrect value + m_coordSystem(None), m_BoxStructureAndMethadata(true) // this is faster but rarely needed. {} @@ -168,6 +169,8 @@ void LoadMD::exec() { // Now load all the dimension xml this->loadDimensions(); + // Coordinate system + this->loadCoordinateSystem(); if (entryName == "MDEventWorkspace") { // The type of event @@ -233,6 +236,9 @@ void LoadMD::loadHisto() { // Now the ExperimentInfo MDBoxFlatTree::loadExperimentInfos(m_file.get(), m_filename, ws); + // Coordinate system + ws->setCoordinateSystem(m_coordSystem); + // Load the WorkspaceHistory "process" ws->history().loadNexus(m_file.get()); @@ -267,6 +273,30 @@ void LoadMD::loadDimensions() { } } +/** Load the coordinate system **/ +void LoadMD::loadCoordinateSystem() { + // Current version stores the coordinate system + // in its own field. The first version stored it + // as a log value so fallback on that if it can't + // be found. + try { + uint32_t readCoord(0); + m_file->readData("coordinate_system", readCoord); + m_coordSystem = static_cast<SpecialCoordinateSystem>(readCoord); + } catch (::NeXus::Exception &) { + auto pathOnEntry = m_file->getPath(); + try { + m_file->openPath(pathOnEntry + "/experiment0/logs/CoordinateSystem"); + int readCoord(0); + m_file->readData("value", readCoord); + m_coordSystem = static_cast<SpecialCoordinateSystem>(readCoord); + } catch (::NeXus::Exception &) { + } + // return to where we started + m_file->openPath(pathOnEntry); + } +} + //---------------------------------------------------------------------------------------------- /** Do the loading. * @@ -302,6 +332,9 @@ void LoadMD::doLoad(typename MDEventWorkspace<MDE, nd>::sptr ws) { for (size_t d = 0; d < nd; d++) ws->addDimension(m_dims[d]); + // Coordinate system + ws->setCoordinateSystem(m_coordSystem); + // ----------------------------------------- Box Structure // ------------------------------ prog->report("Reading box structure from HDD."); diff --git a/Code/Mantid/Framework/MDAlgorithms/src/LoadSQW.cpp b/Code/Mantid/Framework/MDAlgorithms/src/LoadSQW.cpp index 30682a7f2d1742064f7462e80eb47b52422abb78..5f2e8770c49ce0499d2a89ddc557b1bf360f7091 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/LoadSQW.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/LoadSQW.cpp @@ -43,7 +43,7 @@ template <typename T> T interpretAs(std::vector<char> &Buf, size_t ind = 0) { } } -DECLARE_FILELOADER_ALGORITHM(LoadSQW); +DECLARE_FILELOADER_ALGORITHM(LoadSQW) /// Constructor LoadSQW::LoadSQW() : m_fileName(""), m_fileStream(), diff --git a/Code/Mantid/Framework/MDAlgorithms/src/LogarithmMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/LogarithmMD.cpp index e60b1f162cefe904bf9567fc4be9fb449e3c0f8e..2111d83e333a8a0d67fbf1ad9d1245d0d220b372 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/LogarithmMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/LogarithmMD.cpp @@ -22,10 +22,10 @@ LogarithmMD::~LogarithmMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string LogarithmMD::name() const { return "LogarithmMD"; }; +const std::string LogarithmMD::name() const { return "LogarithmMD"; } /// Algorithm's version for identification. @see Algorithm::version -int LogarithmMD::version() const { return 1; }; +int LogarithmMD::version() const { return 1; } //---------------------------------------------------------------------------------------------- diff --git a/Code/Mantid/Framework/MDAlgorithms/src/MaskMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/MaskMD.cpp index 8a9110bf3397109ae2311f5b0fa2517a6c6a93db..a9f49837d990bb5e67c5bd98502457ec7fea1ae9 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/MaskMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/MaskMD.cpp @@ -41,10 +41,10 @@ MaskMD::~MaskMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string MaskMD::name() const { return "MaskMD"; }; +const std::string MaskMD::name() const { return "MaskMD"; } /// Algorithm's version for identification. @see Algorithm::version -int MaskMD::version() const { return 1; }; +int MaskMD::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string MaskMD::category() const { return "MDAlgorithms"; } diff --git a/Code/Mantid/Framework/MDAlgorithms/src/MergeMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/MergeMD.cpp index c21455165f3175de748eb696049fd3f13a900839..2ab9e50751114cd76478d7ab9febde0d09b43c85 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/MergeMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/MergeMD.cpp @@ -31,10 +31,10 @@ MergeMD::~MergeMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string MergeMD::name() const { return "MergeMD"; }; +const std::string MergeMD::name() const { return "MergeMD"; } /// Algorithm's version for identification. @see Algorithm::version -int MergeMD::version() const { return 1; }; +int MergeMD::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string MergeMD::category() const { return "MDAlgorithms"; } diff --git a/Code/Mantid/Framework/MDAlgorithms/src/MinusMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/MinusMD.cpp index 5b16eb8e592da2f9dc5c940b183a6ad96198c72f..7985cc9b0eb03ff1491202cd5c745b816ac0eea4 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/MinusMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/MinusMD.cpp @@ -27,10 +27,10 @@ MinusMD::~MinusMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string MinusMD::name() const { return "MinusMD"; }; +const std::string MinusMD::name() const { return "MinusMD"; } /// Algorithm's version for identification. @see Algorithm::version -int MinusMD::version() const { return 1; }; +int MinusMD::version() const { return 1; } //---------------------------------------------------------------------------------------------- diff --git a/Code/Mantid/Framework/MDAlgorithms/src/MultiplyMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/MultiplyMD.cpp index 38dd9296568b02e1653a3e08c2dd7311eec1af89..5ba0de5c4512165f66e194b9091242368c2f4bbb 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/MultiplyMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/MultiplyMD.cpp @@ -27,10 +27,10 @@ MultiplyMD::~MultiplyMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string MultiplyMD::name() const { return "MultiplyMD"; }; +const std::string MultiplyMD::name() const { return "MultiplyMD"; } /// Algorithm's version for identification. @see Algorithm::version -int MultiplyMD::version() const { return 1; }; +int MultiplyMD::version() const { return 1; } //---------------------------------------------------------------------------------------------- diff --git a/Code/Mantid/Framework/MDAlgorithms/src/NotMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/NotMD.cpp index fbe2573df7e96cf6f2f3553318d1e46c0d22d9e0..00757fb06ef3831758354d779186022def752783 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/NotMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/NotMD.cpp @@ -22,10 +22,10 @@ NotMD::~NotMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string NotMD::name() const { return "NotMD"; }; +const std::string NotMD::name() const { return "NotMD"; } /// Algorithm's version for identification. @see Algorithm::version -int NotMD::version() const { return 1; }; +int NotMD::version() const { return 1; } //---------------------------------------------------------------------------------------------- diff --git a/Code/Mantid/Framework/MDAlgorithms/src/OrMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/OrMD.cpp index 2dc5f30133e4a1bfc6a0ea27182d0e9a0c014705..1ff0932783ea02630112cd9b865cf9d11269a00c 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/OrMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/OrMD.cpp @@ -22,10 +22,10 @@ OrMD::~OrMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string OrMD::name() const { return "OrMD"; }; +const std::string OrMD::name() const { return "OrMD"; } /// Algorithm's version for identification. @see Algorithm::version -int OrMD::version() const { return 1; }; +int OrMD::version() const { return 1; } //---------------------------------------------------------------------------------------------- /// Run the algorithm with a MDHisotWorkspace as output and operand diff --git a/Code/Mantid/Framework/MDAlgorithms/src/PowerMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/PowerMD.cpp index 90cdcc44f543909d4921b51a2e1368f9e42eeb79..d4e03afa6bcd7f32cd4eeb39bef23e19b86ba83f 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/PowerMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/PowerMD.cpp @@ -22,10 +22,10 @@ PowerMD::~PowerMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string PowerMD::name() const { return "PowerMD"; }; +const std::string PowerMD::name() const { return "PowerMD"; } /// Algorithm's version for identification. @see Algorithm::version -int PowerMD::version() const { return 1; }; +int PowerMD::version() const { return 1; } //---------------------------------------------------------------------------------------------- diff --git a/Code/Mantid/Framework/MDAlgorithms/src/PreprocessDetectorsToMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/PreprocessDetectorsToMD.cpp index d8cec796d70f6358583a04ad56044434e4e51212..f705eaaab279825cb67247d988d8df4a708ac9db 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/PreprocessDetectorsToMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/PreprocessDetectorsToMD.cpp @@ -12,7 +12,7 @@ namespace MDAlgorithms { // Register the algorithm into the AlgorithmFactory DECLARE_ALGORITHM(PreprocessDetectorsToMD) -PreprocessDetectorsToMD::PreprocessDetectorsToMD(){}; +PreprocessDetectorsToMD::PreprocessDetectorsToMD(){} //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. */ void PreprocessDetectorsToMD::init() { diff --git a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/FitResolutionConvolvedModel.cpp b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/FitResolutionConvolvedModel.cpp index dbe2509851495c269337407deaca81965e595799..da845673529edfc948570c4d80e9b8f069538fed 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/FitResolutionConvolvedModel.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/FitResolutionConvolvedModel.cpp @@ -11,7 +11,7 @@ namespace Mantid { namespace MDAlgorithms { // Register the algorithm into the AlgorithmFactory -DECLARE_ALGORITHM(FitResolutionConvolvedModel); +DECLARE_ALGORITHM(FitResolutionConvolvedModel) using Kernel::Direction; using Kernel::ListValidator; diff --git a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/Models/MullerAnsatz.cpp b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/Models/MullerAnsatz.cpp index 2afe41cc2bd27c2f0190d6068de0c77809364626..708ae56914c03ee9ad4938bfa320723d869616d1 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/Models/MullerAnsatz.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/Models/MullerAnsatz.cpp @@ -8,7 +8,7 @@ namespace Mantid { namespace MDAlgorithms { -DECLARE_FOREGROUNDMODEL(MullerAnsatz); +DECLARE_FOREGROUNDMODEL(MullerAnsatz) using Kernel::Math::BoseEinsteinDistribution; diff --git a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/Models/QCoordinate.cpp b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/Models/QCoordinate.cpp index cb3d62350f1796c2e6d54664319eb92c87cdd392..ca3ed919e0adfc35925fd19e0ef7784a792f660a 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/Models/QCoordinate.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/Models/QCoordinate.cpp @@ -4,7 +4,7 @@ namespace Mantid { namespace MDAlgorithms { -DECLARE_FOREGROUNDMODEL(QCoordinate); +DECLARE_FOREGROUNDMODEL(QCoordinate) namespace // anonymous { diff --git a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/Models/Strontium122.cpp b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/Models/Strontium122.cpp index de1d838c4652b2918a56445d6fb1559d54132a8a..d613b2059c84197dbca84c2f6c78568f2de031cc 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/Models/Strontium122.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/Models/Strontium122.cpp @@ -5,7 +5,7 @@ namespace Mantid { namespace MDAlgorithms { -DECLARE_FOREGROUNDMODEL(Strontium122); +DECLARE_FOREGROUNDMODEL(Strontium122) using Kernel::Math::BoseEinsteinDistribution; diff --git a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/Resolution/TobyFitResolutionModel.cpp b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/Resolution/TobyFitResolutionModel.cpp index cabafe77cd995646c07444bad775ff4c91620df6..3ac60433469ce308e37a7b12a96c77ba0420501e 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/Resolution/TobyFitResolutionModel.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/Resolution/TobyFitResolutionModel.cpp @@ -23,7 +23,7 @@ using API::Run; using API::IFunction; DECLARE_MDRESOLUTIONCONVOLUTION(TobyFitResolutionModel, - "TobyFitResolutionModel"); + "TobyFitResolutionModel") namespace // anonymous { diff --git a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/ResolutionConvolvedCrossSection.cpp b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/ResolutionConvolvedCrossSection.cpp index 031e84db52c50d27a4998c6187b7994d97599408..ba9dd517a09566889f4be563555cea5982229c8e 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/ResolutionConvolvedCrossSection.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/ResolutionConvolvedCrossSection.cpp @@ -50,7 +50,7 @@ namespace Mantid { namespace MDAlgorithms { -DECLARE_FUNCTION(ResolutionConvolvedCrossSection); +DECLARE_FUNCTION(ResolutionConvolvedCrossSection) namespace { // Attribute names diff --git a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/SimulateResolutionConvolvedModel.cpp b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/SimulateResolutionConvolvedModel.cpp index f9ec66937c51c87e60150eee2c2bd54ce01fed42..e9cb4227084c3c752c0442c58bc1c398f0b4ff49 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/SimulateResolutionConvolvedModel.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/SimulateResolutionConvolvedModel.cpp @@ -18,7 +18,7 @@ namespace Mantid { namespace MDAlgorithms { // Register the algorithm into the AlgorithmFactory -DECLARE_ALGORITHM(SimulateResolutionConvolvedModel); +DECLARE_ALGORITHM(SimulateResolutionConvolvedModel) using namespace API; using namespace Kernel; @@ -176,6 +176,8 @@ void SimulateResolutionConvolvedModel::createOutputWorkspace() { } // Run information m_outputWS->copyExperimentInfos(*m_inputWS); + // Coordinates + m_outputWS->setCoordinateSystem(m_inputWS->getSpecialCoordinateSystem()); m_outputWS->initialize(); m_outputWS->splitBox(); // Make grid box diff --git a/Code/Mantid/Framework/MDAlgorithms/src/SaveMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/SaveMD.cpp index 8d7503fa945e4b3752e425a083a062d35bd36c15..e515be24ad82fb806d0619d9b4edafc24878a15a 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/SaveMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/SaveMD.cpp @@ -235,6 +235,10 @@ void SaveMD::doSaveHisto(Mantid::MDEvents::MDHistoWorkspace_sptr ws) { // The base entry. Named so as to distinguish from other workspace types. file->makeGroup("MDHistoWorkspace", "NXentry", true); + // Write out the coordinate system + file->writeData("coordinate_system", + static_cast<uint32_t>(ws->getSpecialCoordinateSystem())); + // Save the algorithm history under "process" ws->getHistory().saveNexus(file); diff --git a/Code/Mantid/Framework/MDAlgorithms/src/SaveZODS.cpp b/Code/Mantid/Framework/MDAlgorithms/src/SaveZODS.cpp index 1b7ad75e9a5b78e29ea2d4157a14c8dd61c0b6ea..df0b220d579988d682516f03cf06ccbb30d84e50 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/SaveZODS.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/SaveZODS.cpp @@ -28,10 +28,10 @@ SaveZODS::~SaveZODS() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string SaveZODS::name() const { return "SaveZODS"; }; +const std::string SaveZODS::name() const { return "SaveZODS"; } /// Algorithm's version for identification. @see Algorithm::version -int SaveZODS::version() const { return 1; }; +int SaveZODS::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string SaveZODS::category() const { return "MDAlgorithms"; } diff --git a/Code/Mantid/Framework/MDAlgorithms/src/SetMDUsingMask.cpp b/Code/Mantid/Framework/MDAlgorithms/src/SetMDUsingMask.cpp index bb35f8b10486b00baf42129771c09b3071b0548a..2363f5970a63e89252ae26d1926b909fbc05c725 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/SetMDUsingMask.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/SetMDUsingMask.cpp @@ -27,10 +27,10 @@ SetMDUsingMask::~SetMDUsingMask() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string SetMDUsingMask::name() const { return "SetMDUsingMask"; }; +const std::string SetMDUsingMask::name() const { return "SetMDUsingMask"; } /// Algorithm's version for identification. @see Algorithm::version -int SetMDUsingMask::version() const { return 1; }; +int SetMDUsingMask::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string SetMDUsingMask::category() const { diff --git a/Code/Mantid/Framework/MDAlgorithms/src/SliceMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/SliceMD.cpp index ac2348eadb8fc05f39e4afaa2007c5921ff393e2..3519c4677ecaa8dcb17cd28e9dd6946f8547f368 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/SliceMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/SliceMD.cpp @@ -44,8 +44,8 @@ void SliceMD::init() { // Properties for specifying the slice to perform. this->initSlicingProps(); - declareProperty(new WorkspaceProperty<IMDEventWorkspace>( - "OutputWorkspace", "", Direction::Output), + declareProperty(new WorkspaceProperty<Workspace>("OutputWorkspace", "", + Direction::Output), "Name of the output MDEventWorkspace."); std::vector<std::string> exts; @@ -122,8 +122,10 @@ void SliceMD::slice(typename MDEventWorkspace<MDE, nd>::sptr ws) { // Create the ouput workspace typename MDEventWorkspace<OMDE, ond>::sptr outWS( new MDEventWorkspace<OMDE, ond>()); - for (size_t od = 0; od < m_binDimensions.size(); od++) + for (size_t od = 0; od < m_binDimensions.size(); od++) { outWS->addDimension(m_binDimensions[od]); + } + outWS->setCoordinateSystem(ws->getSpecialCoordinateSystem()); outWS->initialize(); // Copy settings from the original box controller BoxController_sptr bc = ws->getBoxController(); diff --git a/Code/Mantid/Framework/MDAlgorithms/src/ThresholdMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/ThresholdMD.cpp index 217943daffb07a428824cc8a33adcfe79c364755..bb03a8dfb78694e3d6e088580cd4f4c0c975bd5a 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/ThresholdMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/ThresholdMD.cpp @@ -34,10 +34,10 @@ ThresholdMD::~ThresholdMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string ThresholdMD::name() const { return "ThresholdMD"; }; +const std::string ThresholdMD::name() const { return "ThresholdMD"; } /// Algorithm's version for identification. @see Algorithm::version -int ThresholdMD::version() const { return 1; }; +int ThresholdMD::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string ThresholdMD::category() const { return "MDAlgorithms"; } diff --git a/Code/Mantid/Framework/MDAlgorithms/src/TransformMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/TransformMD.cpp index 20cd8862083742074123189c063c3402baf3c63b..896c29c74d763ab9941a7c6961f02e0d2921b9fe 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/TransformMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/TransformMD.cpp @@ -29,10 +29,10 @@ TransformMD::~TransformMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string TransformMD::name() const { return "TransformMD"; }; +const std::string TransformMD::name() const { return "TransformMD"; } /// Algorithm's version for identification. @see Algorithm::version -int TransformMD::version() const { return 1; }; +int TransformMD::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string TransformMD::category() const { return "MDAlgorithms"; } diff --git a/Code/Mantid/Framework/MDAlgorithms/src/UnaryOperationMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/UnaryOperationMD.cpp index 3d6d07f994e7cfe48786956580c2b6967661b350..38862d9c2143761c691a9c815fd1333a13aa805c 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/UnaryOperationMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/UnaryOperationMD.cpp @@ -25,10 +25,10 @@ UnaryOperationMD::~UnaryOperationMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string UnaryOperationMD::name() const { return "UnaryOperationMD"; }; +const std::string UnaryOperationMD::name() const { return "UnaryOperationMD"; } /// Algorithm's version for identification. @see Algorithm::version -int UnaryOperationMD::version() const { return 1; }; +int UnaryOperationMD::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string UnaryOperationMD::category() const { diff --git a/Code/Mantid/Framework/MDAlgorithms/src/XorMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/XorMD.cpp index 2a388274f38b50c3580d3912b7aca9b0902714f1..c960c27df589b49e574333d8b4f7707bf4c19f30 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/XorMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/XorMD.cpp @@ -22,10 +22,10 @@ XorMD::~XorMD() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string XorMD::name() const { return "XorMD"; }; +const std::string XorMD::name() const { return "XorMD"; } /// Algorithm's version for identification. @see Algorithm::version -int XorMD::version() const { return 1; }; +int XorMD::version() const { return 1; } //---------------------------------------------------------------------------------------------- /// Run the algorithm with a MDHisotWorkspace as output and operand diff --git a/Code/Mantid/Framework/MDAlgorithms/test/BinMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/BinMDTest.h index 5200dc777f76e0ea2b4291231ac4e92d968df588..c23b7c04e4c7bb3577691bf7a7d243d2537a08ba 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/BinMDTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/BinMDTest.h @@ -137,8 +137,10 @@ public: TS_ASSERT( alg.isInitialized() ) IMDEventWorkspace_sptr in_ws = MDEventsTestHelper::makeMDEW<3>(10, 0.0, 10.0, numEventsPerBox); - in_ws->addExperimentInfo(ExperimentInfo_sptr(new ExperimentInfo)); + Mantid::Kernel::SpecialCoordinateSystem appliedCoord = Mantid::Kernel::QSample; + in_ws->setCoordinateSystem(appliedCoord); AnalysisDataService::Instance().addOrReplace("BinMDTest_ws", in_ws); + // 1000 boxes with 1 event each TS_ASSERT_EQUALS( in_ws->getNPoints(), 1000*numEventsPerBox); @@ -161,6 +163,7 @@ public: TS_ASSERT(out); if(!out) return; + TS_ASSERT_EQUALS(appliedCoord, out->getSpecialCoordinateSystem()); // Took 6x6x6 bins in the middle of the box TS_ASSERT_EQUALS(out->getNPoints(), expected_numBins); // Every box has a single event summed into it, so 1.0 weight diff --git a/Code/Mantid/Framework/MDAlgorithms/test/CMakeLists.txt b/Code/Mantid/Framework/MDAlgorithms/test/CMakeLists.txt index 791f360df42fb43851ba54cd9409eed32b142fa6..1925dff30ee954097ab795d07c9dd0a98737a677 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/CMakeLists.txt +++ b/Code/Mantid/Framework/MDAlgorithms/test/CMakeLists.txt @@ -1,5 +1,5 @@ if ( CXXTEST_FOUND ) - include_directories ( SYSTEM ${CXXTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR} ${GTEST_INCLUDE_DIR} ) + include_directories ( SYSTEM ${CXXTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR} ${GTEST_INCLUDE_DIR} ${HDF5_INCLUDE_DIRS} ) include_directories( ../../TestHelpers/inc ../../DataHandling/inc ../../CurveFitting/inc) # This variable is used within the cxxtest_add_test macro to build these helper classes into the test executable. @@ -11,10 +11,10 @@ if ( CXXTEST_FOUND ) ../../TestHelpers/src/BinaryOperationMDTestHelper.cpp ) if ( GMOCK_FOUND AND GTEST_FOUND ) cxxtest_add_test ( MDAlgorithmsTest ${TEST_FILES} ${GMOCK_TEST_FILES}) - target_link_libraries( MDAlgorithmsTest MDAlgorithms DataHandling CurveFitting Nexus ${GMOCK_LIBRARIES} ${GTEST_LIBRARIES} ${NEXUS_LIBRARIES} ) + target_link_libraries( MDAlgorithmsTest MDAlgorithms DataHandling CurveFitting Nexus ${GMOCK_LIBRARIES} ${GTEST_LIBRARIES} ${NEXUS_LIBRARIES} ${HDF5_LIBRARIES} ) else () cxxtest_add_test ( MDAlgorithmsTest ${TEST_FILES} ) - target_link_libraries( MDAlgorithmsTest MDAlgorithms Nexus ${NEXUS_LIBRARIES} ) + target_link_libraries( MDAlgorithmsTest MDAlgorithms Nexus ${NEXUS_LIBRARIES} ${HDF5_LIBRARIES} ) endif () add_dependencies ( MDAlgorithmsTest DataHandling Algorithms CurveFitting ) add_dependencies ( FrameworkTests MDAlgorithmsTest ) diff --git a/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h b/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h index a88676e9c523d2751a493dc98dc385a368bdbcf2..990a75d4299a7683e30e786f43fdb01b33a0ad95 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h @@ -73,7 +73,7 @@ public: const Mantid::MantidVec &vecE = outws->readE(0); TS_ASSERT_DELTA(vecX.front(), 0.0, 0.0001); - TS_ASSERT_DELTA(vecX.back(), 120.0 - 0.1, 0.0001); + TS_ASSERT_DELTA(vecX.back(), 120.0, 0.0001); double y1101 = vecY[1101]; double e1101 = vecE[1101]; @@ -135,7 +135,52 @@ public: const Mantid::MantidVec &vecX = outws->readX(0); TS_ASSERT_DELTA(vecX.front(), 0.5, 0.0001); - TS_ASSERT_DELTA(vecX.back(), 4.99, 0.0001); + TS_ASSERT_DELTA(vecX.back(), 5.00, 0.0001); + + // Check statistics + + // Clean + AnalysisDataService::Instance().remove("ReducedData"); + } + + //---------------------------------------------------------------------------------------------- + /** Unit test to reduce/bin the HB2A data with more options + * @brief test_ReduceHB2AData + */ + void test_ReduceHB2ADataAutoBinBoundary() { + // Init + ConvertCWPDMDToSpectra alg; + alg.initialize(); + + // Set properties + TS_ASSERT_THROWS_NOTHING( + alg.setPropertyValue("InputWorkspace", m_dataMD->name())); + TS_ASSERT_THROWS_NOTHING( + alg.setPropertyValue("InputMonitorWorkspace", m_monitorMD->name())); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("UnitOutput", "dSpacing")); + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("BinningParams", "0.01")); + TS_ASSERT_THROWS_NOTHING( + alg.setProperty("LinearInterpolateZeroCounts", true)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("ScaleFactor", 10.0)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("NeutronWaveLength", 2.41)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("OutputWorkspace", "ReducedData")); + + // Execute + TS_ASSERT_THROWS_NOTHING(alg.execute()); + TS_ASSERT(alg.isExecuted()); + + // Get ouput + MatrixWorkspace_sptr outws = boost::dynamic_pointer_cast<MatrixWorkspace>( + AnalysisDataService::Instance().retrieve("ReducedData")); + TS_ASSERT(outws); + + // Check unit and range of X + std::string unit = outws->getAxis(0)->unit()->unitID(); + TS_ASSERT_EQUALS(unit, "dSpacing"); + + const Mantid::MantidVec &vecX = outws->readX(0); + TS_ASSERT_DELTA(vecX.front(), 1.3416, 0.0001); + TS_ASSERT_DELTA(vecX.back(), 23.0216, 0.001); // Check statistics diff --git a/Code/Mantid/Framework/MDAlgorithms/test/CutMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/CutMDTest.h new file mode 100644 index 0000000000000000000000000000000000000000..b93b6c4d0dcfefd3662c8551d25529e689c973ff --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/test/CutMDTest.h @@ -0,0 +1,490 @@ +#ifndef MANTID_MDALGORITHMS_CUTMDTEST_H_ +#define MANTID_MDALGORITHMS_CUTMDTEST_H_ + +#include "MantidMDAlgorithms/CutMD.h" + +#include "MantidAPI/FrameworkManager.h" +#include "MantidAPI/IMDWorkspace.h" +#include "MantidAPI/IMDEventWorkspace.h" +#include "MantidAPI/IMDHistoWorkspace.h" +#include "MantidAPI/TableRow.h" + +#include <cxxtest/TestSuite.h> + +using namespace Mantid::MDAlgorithms; +using namespace Mantid::API; +using namespace Mantid::Kernel; + +namespace { +const std::string sharedWSName = "__CutMDTest_dataWS"; +} + +class CutMDTest : public CxxTest::TestSuite { +private: + IMDWorkspace_sptr m_inWS; + +public: + CutMDTest() { + FrameworkManager::Instance().exec("CreateMDWorkspace", 10, + "OutputWorkspace", sharedWSName.c_str(), + "Dimensions", "3", + "Extents", "-10,10,-10,10,-10,10", + "Names", "A,B,C", + "Units", "U,U,U"); + + FrameworkManager::Instance().exec("SetSpecialCoordinates", 4, + "InputWorkspace", sharedWSName.c_str(), + "SpecialCoordinates", "HKL"); + + FrameworkManager::Instance().exec("SetUB", 14, + "Workspace", sharedWSName.c_str(), + "a", "1", + "b", "1", + "c", "1", + "alpha", "90", + "beta", "90", + "gamma", "90"); + + FrameworkManager::Instance().exec("FakeMDEventData", 4, + "InputWorkspace", sharedWSName.c_str(), + "PeakParams", "10000,0,0,0,1"); + + m_inWS = + AnalysisDataService::Instance().retrieveWS<IMDWorkspace>(sharedWSName); + } + + virtual ~CutMDTest() { AnalysisDataService::Instance().remove(sharedWSName); } + + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static CutMDTest *createSuite() { return new CutMDTest(); } + static void destroySuite(CutMDTest *suite) { delete suite; } + + void test_init() { + CutMD alg; + TS_ASSERT_THROWS_NOTHING(alg.initialize()) + TS_ASSERT(alg.isInitialized()) + } + + void test_exec_throws_if_giving_4th_binning_param_when_workspace_is_3d() { + const std::string wsName = "__CutMDTest_4thbinon3dthrows"; + + FrameworkManager::Instance().exec("CreateMDWorkspace", 10, + "OutputWorkspace", wsName.c_str(), + "Dimensions", "3", + "Extents", "-10,10,-10,10,-10,10", + "Names", "H,K,L", + "Units", "U,U,U"); + + FrameworkManager::Instance().exec("SetSpecialCoordinates", 4, + "InputWorkspace", wsName.c_str(), + "SpecialCoordinates", "HKL"); + + auto algCutMD = FrameworkManager::Instance().createAlgorithm("CutMD"); + algCutMD->initialize(); + algCutMD->setRethrows(true); + algCutMD->setProperty("InputWorkspace", wsName); + algCutMD->setProperty("OutputWorkspace", wsName); + algCutMD->setProperty("P1Bin", "0.1"); + algCutMD->setProperty("P2Bin", "0.1"); + algCutMD->setProperty("P3Bin", "0.1"); + algCutMD->setProperty("P4Bin", "0.1"); + TS_ASSERT_THROWS(algCutMD->execute(), std::runtime_error) + + AnalysisDataService::Instance().remove(wsName); + } + + void test_slice_to_original() { + const std::string wsName = "__CutMDTest_slice_to_original"; + + auto algCutMD = FrameworkManager::Instance().createAlgorithm("CutMD"); + algCutMD->initialize(); + algCutMD->setRethrows(true); + algCutMD->setProperty("InputWorkspace", sharedWSName); + algCutMD->setProperty("OutputWorkspace", wsName); + algCutMD->setProperty("P1Bin", "0.1"); + algCutMD->setProperty("P2Bin", "0.1"); + algCutMD->setProperty("P3Bin", "0.1"); + algCutMD->setProperty("CheckAxes", false); + algCutMD->execute(); + TS_ASSERT(algCutMD->isExecuted()); + + IMDEventWorkspace_sptr outWS = + AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>(wsName); + TS_ASSERT(outWS.get()); + + TS_ASSERT_EQUALS( + outWS->getDimension(0)->getMinimum(), + m_inWS->getDimension(0)->getMinimum()); + TS_ASSERT_EQUALS( + outWS->getDimension(0)->getMaximum(), + m_inWS->getDimension(0)->getMaximum()); + TS_ASSERT_EQUALS( + outWS->getDimension(1)->getMinimum(), + m_inWS->getDimension(1)->getMinimum()); + TS_ASSERT_EQUALS( + outWS->getDimension(1)->getMaximum(), + m_inWS->getDimension(1)->getMaximum()); + TS_ASSERT_EQUALS( + outWS->getDimension(2)->getMinimum(), + m_inWS->getDimension(2)->getMinimum()); + TS_ASSERT_EQUALS( + outWS->getDimension(2)->getMaximum(), + m_inWS->getDimension(2)->getMaximum()); + + TS_ASSERT_EQUALS("['zeta', 0, 0]", outWS->getDimension(0)->getName()); + TS_ASSERT_EQUALS("[0, 'eta', 0]", outWS->getDimension(1)->getName()); + TS_ASSERT_EQUALS("[0, 0, 'xi']", outWS->getDimension(2)->getName()); + + AnalysisDataService::Instance().remove(wsName); + } + + void test_recalculate_extents_with_3_bin_arguments() { + const std::string wsName = "__CutMDTest_recalc_extents_with_3_bin_args"; + + auto algCutMD = FrameworkManager::Instance().createAlgorithm("CutMD"); + algCutMD->initialize(); + algCutMD->setRethrows(true); + algCutMD->setProperty("InputWorkspace", sharedWSName); + algCutMD->setProperty("OutputWorkspace", wsName); + algCutMD->setProperty("P1Bin", "0,0.3,0.8"); + algCutMD->setProperty("P2Bin", "0.1"); + algCutMD->setProperty("P3Bin", "0.1"); + algCutMD->setProperty("CheckAxes", false); + algCutMD->setProperty("NoPix", true); + algCutMD->execute(); + TS_ASSERT(algCutMD->isExecuted()); + + IMDWorkspace_sptr outWS = + AnalysisDataService::Instance().retrieveWS<IMDWorkspace>(wsName); + TS_ASSERT(outWS.get()); + + TS_ASSERT_DELTA(outWS->getDimension(0)->getMinimum(), 0.0, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(0)->getMaximum(), 0.6, 1E-6); + TS_ASSERT_EQUALS(outWS->getDimension(0)->getNBins(), 2); + + AnalysisDataService::Instance().remove(wsName); + } + + void test_truncate_extents() { + const std::string wsName = "__CutMDTest_truncate_extents"; + + auto algCutMD = FrameworkManager::Instance().createAlgorithm("CutMD"); + algCutMD->initialize(); + algCutMD->setRethrows(true); + algCutMD->setProperty("InputWorkspace", sharedWSName); + algCutMD->setProperty("OutputWorkspace", wsName); + algCutMD->setProperty("P1Bin", "0,1.1,1"); + algCutMD->setProperty("P2Bin", "21"); + algCutMD->setProperty("P3Bin", "0.1"); + algCutMD->setProperty("CheckAxes", false); + algCutMD->setProperty("NoPix", true); + algCutMD->execute(); + TS_ASSERT(algCutMD->isExecuted()); + + IMDWorkspace_sptr outWS = + AnalysisDataService::Instance().retrieveWS<IMDWorkspace>(wsName); + TS_ASSERT(outWS.get()); + + TS_ASSERT_EQUALS(outWS->getDimension(0)->getNBins(), 1); + TS_ASSERT_EQUALS(outWS->getDimension(1)->getNBins(), 1); + + AnalysisDataService::Instance().remove(wsName); + } + + void test_wrong_proj_format_columns() { + const std::string wsName = "__CutMDTest_wrong_proj_columns"; + + ITableWorkspace_sptr proj = WorkspaceFactory::Instance().createTable(); + proj->addColumn("str", "name"); + + auto algCutMD = FrameworkManager::Instance().createAlgorithm("CutMD"); + algCutMD->initialize(); + algCutMD->setRethrows(true); + algCutMD->setProperty("InputWorkspace", sharedWSName); + algCutMD->setProperty("OutputWorkspace", wsName); + algCutMD->setProperty("Projection", proj); + algCutMD->setProperty("P1Bin", "0.1"); + algCutMD->setProperty("P2Bin", "0.2"); + algCutMD->setProperty("P3Bin", "0.1"); + algCutMD->setProperty("CheckAxes", false); + TS_ASSERT_THROWS(algCutMD->execute(), std::runtime_error); + } + + void test_wrong_proj_format_rows() { + const std::string wsName = "__CutMDTest_wrong_proj_rows"; + + // Correct columns + ITableWorkspace_sptr proj = WorkspaceFactory::Instance().createTable(); + proj->addColumn("str", "name"); + proj->addColumn("str", "value"); + proj->addColumn("double", "offset"); + proj->addColumn("str", "type"); + // ...but no rows + + auto algCutMD = FrameworkManager::Instance().createAlgorithm("CutMD"); + algCutMD->initialize(); + algCutMD->setRethrows(true); + algCutMD->setProperty("InputWorkspace", sharedWSName); + algCutMD->setProperty("OutputWorkspace", wsName); + algCutMD->setProperty("Projection", proj); + algCutMD->setProperty("P1Bin", "0.1"); + algCutMD->setProperty("P2Bin", "0.2"); + algCutMD->setProperty("P3Bin", "0.1"); + algCutMD->setProperty("CheckAxes", false); + TS_ASSERT_THROWS(algCutMD->execute(), std::runtime_error); + } + + void test_orthogonal_slice_with_scaling() { + const std::string wsName = "__CutMDTest_orthog_slice_with_scaling"; + + FrameworkManager::Instance().exec("CreateMDWorkspace", 10, + "OutputWorkspace", wsName.c_str(), + "Dimensions", "3", + "Extents", "-1,1,-1,1,-1,1", + "Names", "H,K,L", + "Units", "U,U,U"); + + FrameworkManager::Instance().exec("SetUB", 14, + "Workspace", wsName.c_str(), + "a", "1", "b", "1", "c", "1", + "alpha", "90", "beta", "90", "gamma", "90"); + + FrameworkManager::Instance().exec("SetSpecialCoordinates", 4, + "InputWorkspace", wsName.c_str(), + "SpecialCoordinates", "HKL"); + + ITableWorkspace_sptr proj = WorkspaceFactory::Instance().createTable(); + proj->addColumn("str", "name"); + proj->addColumn("str", "value"); + proj->addColumn("double", "offset"); + proj->addColumn("str", "type"); + + TableRow uRow = proj->appendRow(); + TableRow vRow = proj->appendRow(); + TableRow wRow = proj->appendRow(); + uRow << "u" << "1,0,0" << 0.0 << "r"; + vRow << "v" << "0,1,0" << 0.0 << "r"; + wRow << "w" << "0,0,1" << 0.0 << "r"; + + auto algCutMD = FrameworkManager::Instance().createAlgorithm("CutMD"); + algCutMD->initialize(); + algCutMD->setRethrows(true); + algCutMD->setProperty("InputWorkspace", wsName); + algCutMD->setProperty("OutputWorkspace", wsName); + algCutMD->setProperty("Projection", proj); + algCutMD->setProperty("P1Bin", "-0.5,0.5"); + algCutMD->setProperty("P2Bin", "-0.1,0.1"); + algCutMD->setProperty("P3Bin", "-0.3,0.3"); + algCutMD->setProperty("NoPix", true); + algCutMD->execute(); + TS_ASSERT(algCutMD->isExecuted()); + + IMDHistoWorkspace_sptr outWS = + AnalysisDataService::Instance().retrieveWS<IMDHistoWorkspace>(wsName); + TS_ASSERT(outWS.get()); + + TS_ASSERT_DELTA(outWS->getDimension(0)->getMinimum(), -0.5, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(0)->getMaximum(), 0.5, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(1)->getMinimum(), -0.1, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(1)->getMaximum(), 0.1, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(2)->getMinimum(), -0.3, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(2)->getMaximum(), 0.3, 1E-6); + TS_ASSERT_EQUALS("['zeta', 0, 0]", outWS->getDimension(0)->getName()); + TS_ASSERT_EQUALS("[0, 'eta', 0]", outWS->getDimension(1)->getName()); + TS_ASSERT_EQUALS("[0, 0, 'xi']", outWS->getDimension(2)->getName()); + + AnalysisDataService::Instance().remove(wsName); + } + + void test_non_orthogonal_slice() { + const std::string wsName = "__CutMDTest_non_orthog_slice"; + + FrameworkManager::Instance().exec("CreateMDWorkspace", 10, + "OutputWorkspace", wsName.c_str(), + "Dimensions", "3", + "Extents", "-1,1,-1,1,-1,1", + "Names", "H,K,L", + "Units", "U,U,U"); + + FrameworkManager::Instance().exec("SetUB", 14, + "Workspace", wsName.c_str(), + "a", "1", "b", "1", "c", "1", + "alpha", "90", "beta", "90", "gamma", "90"); + + FrameworkManager::Instance().exec("SetSpecialCoordinates", 4, + "InputWorkspace", wsName.c_str(), + "SpecialCoordinates", "HKL"); + + ITableWorkspace_sptr proj = WorkspaceFactory::Instance().createTable(); + proj->addColumn("str", "name"); + proj->addColumn("str", "value"); + proj->addColumn("double", "offset"); + proj->addColumn("str", "type"); + + TableRow uRow = proj->appendRow(); + TableRow vRow = proj->appendRow(); + TableRow wRow = proj->appendRow(); + uRow << "u" << "1,1,0" << 0.0 << "r"; + vRow << "v" << "-1,1,0" << 0.0 << "r"; + wRow << "w" << "0,0,1" << 0.0 << "r"; + + auto algCutMD = FrameworkManager::Instance().createAlgorithm("CutMD"); + algCutMD->initialize(); + algCutMD->setRethrows(true); + algCutMD->setProperty("InputWorkspace", wsName); + algCutMD->setProperty("OutputWorkspace", wsName); + algCutMD->setProperty("Projection", proj); + algCutMD->setProperty("P1Bin", "0.1"); + algCutMD->setProperty("P2Bin", "0.1"); + algCutMD->setProperty("P3Bin", "0.1"); + algCutMD->setProperty("NoPix", true); + algCutMD->execute(); + TS_ASSERT(algCutMD->isExecuted()); + + IMDHistoWorkspace_sptr outWS = + AnalysisDataService::Instance().retrieveWS<IMDHistoWorkspace>(wsName); + TS_ASSERT(outWS.get()); + + TS_ASSERT_EQUALS(outWS->getDimension(0)->getMinimum(), -1); + TS_ASSERT_EQUALS(outWS->getDimension(0)->getMaximum(), 1); + TS_ASSERT_EQUALS(outWS->getDimension(1)->getMinimum(), -1); + TS_ASSERT_EQUALS(outWS->getDimension(1)->getMaximum(), 1); + TS_ASSERT_EQUALS(outWS->getDimension(2)->getMinimum(), -1); + TS_ASSERT_EQUALS(outWS->getDimension(2)->getMaximum(), 1); + TS_ASSERT_EQUALS("['zeta', 'zeta', 0]", outWS->getDimension(0)->getName()); + TS_ASSERT_EQUALS("['-eta', 'eta', 0]", outWS->getDimension(1)->getName()); + TS_ASSERT_EQUALS("[0, 0, 'xi']", outWS->getDimension(2)->getName()); + + AnalysisDataService::Instance().remove(wsName); + } + + void test_orthogonal_slice_with_cropping() { + const std::string wsName = "__CutMDTest_orthog_slice_crop"; + + FrameworkManager::Instance().exec("CreateMDWorkspace", 10, + "OutputWorkspace", wsName.c_str(), + "Dimensions", "3", + "Extents", "-1,1,-1,1,-1,1", + "Names", "H,K,L", + "Units", "U,U,U"); + + FrameworkManager::Instance().exec("SetUB", 14, + "Workspace", wsName.c_str(), + "a", "1", "b", "1", "c", "1", + "alpha", "90", "beta", "90", "gamma", "90"); + + FrameworkManager::Instance().exec("SetSpecialCoordinates", 4, + "InputWorkspace", wsName.c_str(), + "SpecialCoordinates", "HKL"); + + ITableWorkspace_sptr proj = WorkspaceFactory::Instance().createTable(); + proj->addColumn("str", "name"); + proj->addColumn("str", "value"); + proj->addColumn("double", "offset"); + proj->addColumn("str", "type"); + + TableRow uRow = proj->appendRow(); + TableRow vRow = proj->appendRow(); + TableRow wRow = proj->appendRow(); + uRow << "u" << "1,0,0" << 0.0 << "r"; + vRow << "v" << "0,1,0" << 0.0 << "r"; + wRow << "w" << "0,0,1" << 0.0 << "r"; + + auto algCutMD = FrameworkManager::Instance().createAlgorithm("CutMD"); + algCutMD->initialize(); + algCutMD->setRethrows(true); + algCutMD->setProperty("InputWorkspace", wsName); + algCutMD->setProperty("OutputWorkspace", wsName); + algCutMD->setProperty("Projection", proj); + algCutMD->setProperty("P1Bin", "-0.5,0.5"); + algCutMD->setProperty("P2Bin", "-0.1,0.1"); + algCutMD->setProperty("P3Bin", "-0.3,0.3"); + algCutMD->setProperty("NoPix", true); + algCutMD->execute(); + TS_ASSERT(algCutMD->isExecuted()); + + IMDHistoWorkspace_sptr outWS = + AnalysisDataService::Instance().retrieveWS<IMDHistoWorkspace>(wsName); + TS_ASSERT(outWS.get()); + + TS_ASSERT_DELTA(outWS->getDimension(0)->getMinimum(), -0.5, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(0)->getMaximum(), 0.5, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(1)->getMinimum(), -0.1, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(1)->getMaximum(), 0.1, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(2)->getMinimum(), -0.3, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(2)->getMaximum(), 0.3, 1E-6); + TS_ASSERT_EQUALS("['zeta', 0, 0]", outWS->getDimension(0)->getName()); + TS_ASSERT_EQUALS("[0, 'eta', 0]", outWS->getDimension(1)->getName()); + TS_ASSERT_EQUALS("[0, 0, 'xi']", outWS->getDimension(2)->getName()); + + AnalysisDataService::Instance().remove(wsName); + } + + void test_orthogonal_slice_4d() { + const std::string wsName = "__CutMDTest_orthog_slice_4d"; + const std::string wsOutName = "__CutMDTest_orthog_slice_4d_out"; + + FrameworkManager::Instance().exec("CreateMDWorkspace", 10, + "OutputWorkspace", wsName.c_str(), + "Dimensions", "4", + "Extents", "-1,1,-1,1,-1,1,-10,10", + "Names", "H,K,L,E", + "Units", "U,U,U,V"); + + FrameworkManager::Instance().exec("SetUB", 14, + "Workspace", wsName.c_str(), + "a", "1", "b", "1", "c", "1", + "alpha", "90", "beta", "90", "gamma", "90"); + + FrameworkManager::Instance().exec("SetSpecialCoordinates", 4, + "InputWorkspace", wsName.c_str(), + "SpecialCoordinates", "HKL"); + + auto algCutMD = FrameworkManager::Instance().createAlgorithm("CutMD"); + algCutMD->initialize(); + algCutMD->setRethrows(true); + algCutMD->setProperty("InputWorkspace", wsName); + algCutMD->setProperty("OutputWorkspace", wsOutName); + algCutMD->setProperty("P1Bin", "-0.5,0.5"); + algCutMD->setProperty("P2Bin", "-0.1,0.1"); + algCutMD->setProperty("P3Bin", "-0.3,0.3"); + algCutMD->setProperty("P4Bin", "1"); + algCutMD->setProperty("NoPix", true); + algCutMD->execute(); + TS_ASSERT(algCutMD->isExecuted()); + + IMDHistoWorkspace_sptr outWS = + AnalysisDataService::Instance().retrieveWS<IMDHistoWorkspace>(wsOutName); + TS_ASSERT(outWS.get()); + + TS_ASSERT_DELTA(outWS->getDimension(0)->getMinimum(), -0.5, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(0)->getMaximum(), 0.5, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(1)->getMinimum(), -0.1, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(1)->getMaximum(), 0.1, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(2)->getMinimum(), -0.3, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(2)->getMaximum(), 0.3, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(3)->getMinimum(), -10, 1E-6); + TS_ASSERT_DELTA(outWS->getDimension(3)->getMaximum(), 10, 1E-6); + TS_ASSERT_EQUALS(20, outWS->getDimension(3)->getNBins()); + TS_ASSERT_EQUALS("['zeta', 0, 0]", outWS->getDimension(0)->getName()); + TS_ASSERT_EQUALS("[0, 'eta', 0]", outWS->getDimension(1)->getName()); + TS_ASSERT_EQUALS("[0, 0, 'xi']", outWS->getDimension(2)->getName()); + TS_ASSERT_EQUALS("E", outWS->getDimension(3)->getName()); + + // Process again with a different binning + algCutMD->setProperty("P4Bin", "-8,1,8"); + algCutMD->setProperty("InputWorkspace", wsName); + algCutMD->setProperty("OutputWorkspace", wsOutName); + algCutMD->execute(); + TS_ASSERT(algCutMD->isExecuted()); + outWS = + AnalysisDataService::Instance().retrieveWS<IMDHistoWorkspace>(wsOutName); + TS_ASSERT_EQUALS(16, outWS->getDimension(3)->getNBins()); + + AnalysisDataService::Instance().remove(wsName); + AnalysisDataService::Instance().remove(wsOutName); + } +}; + +#endif /* MANTID_MDALGORITHMS_CUTMDTEST_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/test/IntegratePeaksMD2Test.h b/Code/Mantid/Framework/MDAlgorithms/test/IntegratePeaksMD2Test.h index fa6a6d32befc2e784ee4d3cba77346bf73150d86..f83bbdd97a973797691f3b2780156a9f18e2b7d3 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/IntegratePeaksMD2Test.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/IntegratePeaksMD2Test.h @@ -62,7 +62,7 @@ public: /** Run the IntegratePeaksMD2 with the given peak radius integration param */ static void doRun(double PeakRadius, double BackgroundRadius, std::string OutputWorkspace = "IntegratePeaksMD2Test_peaks", - double BackgroundStartRadius = 0.0, bool edge = true, bool cyl = false, std::string fnct = "NoFit") + double BackgroundStartRadius = 0.0, bool edge = true, bool cyl = false, std::string fnct = "NoFit", double adaptive = 0.0) { IntegratePeaksMD2 alg; TS_ASSERT_THROWS_NOTHING( alg.initialize() ) @@ -79,6 +79,8 @@ public: TS_ASSERT_THROWS_NOTHING( alg.setProperty("PercentBackground", 20.0 ) ); TS_ASSERT_THROWS_NOTHING( alg.setProperty("ProfileFunction", fnct ) ); TS_ASSERT_THROWS_NOTHING( alg.setProperty("IntegrationOption", "Sum" ) ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("AdaptiveQMultiplier", adaptive ) ); + if (adaptive > 0.0) TS_ASSERT_THROWS_NOTHING( alg.setProperty("AdaptiveQBackground", true ) ); TS_ASSERT_THROWS_NOTHING( alg.execute() ); TS_ASSERT( alg.isExecuted() ); } @@ -180,6 +182,15 @@ public: // Error is also calculated TS_ASSERT_DELTA( peakWS0->getPeak(0).getSigmaIntensity(), sqrt(2.0), 1e-2);*/ + + // ------------- Adaptive Integration r=MQ+b where b is PeakRadius and m is 0.01 ------------------------ + peakWS0->addPeak( Peak(inst, 15050, 1.0, V3D(2., 3., 4.) ) ); + doRun(0.1,0.0,"IntegratePeaksMD2Test_peaks",0.0,true,false,"NoFit",0.01); + TS_ASSERT_DELTA( peakWS0->getPeak(1).getIntensity(), 29.0, 1e-2); + + // Error is also calculated + TS_ASSERT_DELTA( peakWS0->getPeak(1).getSigmaIntensity(), sqrt(29.0), 1e-2); + // ------------- Integrate with 0.1 radius but IntegrateIfOnEdge false------------------------ doRun(0.1,0.0,"IntegratePeaksMD2Test_peaks",0.0,false); diff --git a/Code/Mantid/Framework/MDAlgorithms/test/LoadMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/LoadMDTest.h index 0fc5b9c92601b36b424147b66f149856aa867f77..179d58265ca6704dfe4c59f8712424d346009bd6 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/LoadMDTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/LoadMDTest.h @@ -17,6 +17,8 @@ #include "MantidAPI/ExperimentInfo.h" #include "MantidMDAlgorithms/LoadMD.h" +#include <hdf5.h> + using namespace Mantid; using namespace Mantid::MDEvents; using namespace Mantid::MDAlgorithms; @@ -531,44 +533,122 @@ public: } /// More of an integration test as it uses both load and save. - void test_save_and_load_special_coordinates() - { - MDEventWorkspace1Lean::sptr ws = MDEventsTestHelper::makeMDEW<1>(10, 0.0, 10.0, 2); - // Set the special coordinate system + void test_save_and_load_special_coordinates_MDEventWorkspace() { + MDEventWorkspace1Lean::sptr mdeventWS = + MDEventsTestHelper::makeMDEW<1>(10, 0.0, 10.0, 2); + const SpecialCoordinateSystem appliedCoordinateSystem = QSample; + mdeventWS->setCoordinateSystem(appliedCoordinateSystem); + + auto loadedWS = testSaveAndLoadWorkspace(mdeventWS, "MDEventWorkspace"); + // Check that the special coordinate system is the same before the save-load + // cycle. + TS_ASSERT_EQUALS(appliedCoordinateSystem, + loadedWS->getSpecialCoordinateSystem()); + } + + // backwards-compatability check for coordinate in log + void test_load_coordinate_system_MDEventWorkspace_from_experiment_info() { + MDEventWorkspace1Lean::sptr mdeventWS = + MDEventsTestHelper::makeMDEW<1>(10, 0.0, 10.0, 2); const SpecialCoordinateSystem appliedCoordinateSystem = QSample; - ws->setCoordinateSystem(appliedCoordinateSystem); + mdeventWS->setCoordinateSystem(appliedCoordinateSystem); + + // Create a log in the first experiment info to simulated an old version of + // the file + auto expt0 = mdeventWS->getExperimentInfo(0); + expt0->mutableRun().addProperty("CoordinateSystem", + static_cast<int>(appliedCoordinateSystem)); + + const bool rmCoordField(true); + auto loadedWS = + testSaveAndLoadWorkspace(mdeventWS, "MDEventWorkspace", rmCoordField); + // Check that the special coordinate system is the same before the save-load + // cycle. + TS_ASSERT_EQUALS(appliedCoordinateSystem, + loadedWS->getSpecialCoordinateSystem()); + } - const std::string inputWSName = "SaveMDSpecialCoordinatesTest"; - const std::string fileName = inputWSName + ".nxs"; - AnalysisDataService::Instance().addOrReplace(inputWSName, ws); + void test_save_and_load_special_coordinates_MDHistoWorkspace() { + auto mdhistoWS = MDEventsTestHelper::makeFakeMDHistoWorkspace( + 2.5, 2, 10, 10.0, 3.5, "", 4.5); + const SpecialCoordinateSystem appliedCoordinateSystem = QSample; + mdhistoWS->setCoordinateSystem(appliedCoordinateSystem); + + auto loadedWS = testSaveAndLoadWorkspace(mdhistoWS, "MDHistoWorkspace"); + // Check that the special coordinate system is the same before the save-load + // cycle. + TS_ASSERT_EQUALS(appliedCoordinateSystem, + loadedWS->getSpecialCoordinateSystem()); + } + // backwards-compatability check for coordinate in log + void test_load_coordinate_system_MDHistoWorkspace_from_experiment_info() { + auto mdhistoWS = MDEventsTestHelper::makeFakeMDHistoWorkspace( + 2.5, 2, 10, 10.0, 3.5, "", 4.5); + const SpecialCoordinateSystem appliedCoordinateSystem = QSample; + mdhistoWS->setCoordinateSystem(appliedCoordinateSystem); + + // Create a log in the first experiment info to simulated an old version of + // the file + auto expt0 = mdhistoWS->getExperimentInfo(0); + expt0->mutableRun().addProperty("CoordinateSystem", + static_cast<int>(appliedCoordinateSystem)); + + const bool rmCoordField(true); + auto loadedWS = + testSaveAndLoadWorkspace(mdhistoWS, "MDHistoWorkspace", rmCoordField); + // Check that the special coordinate system is the same before the save-load + // cycle. + TS_ASSERT_EQUALS(appliedCoordinateSystem, + loadedWS->getSpecialCoordinateSystem()); + } + + Mantid::API::IMDWorkspace_sptr + testSaveAndLoadWorkspace(Mantid::API::IMDWorkspace_sptr inputWS, + const char *rootGroup, + const bool rmCoordField = false) { + const std::string fileName = "SaveMDSpecialCoordinatesTest.nxs"; SaveMD saveAlg; + saveAlg.setChild(true); saveAlg.initialize(); - saveAlg.isInitialized(); - saveAlg.setPropertyValue("InputWorkspace", inputWSName); + saveAlg.setProperty("InputWorkspace", inputWS); saveAlg.setPropertyValue("Filename", fileName); saveAlg.execute(); TS_ASSERT( saveAlg.isExecuted() ); std::string this_fileName = saveAlg.getProperty("Filename"); + if (rmCoordField) { + // Remove the coordinate_system entry so it falls back on the log. NeXus + // can't do this + // so use the HDF5 API directly + auto fid = H5Fopen(fileName.c_str(), H5F_ACC_RDWR, H5P_DEFAULT); + auto gid = H5Gopen(fid, rootGroup, H5P_DEFAULT); + if (gid > 0) { + H5Ldelete(gid, "coordinate_system", H5P_DEFAULT); + H5Gclose(gid); + } else { + TS_FAIL("Cannot open MDEventWorkspace group. Test file has unexpected " + "structure."); + } + H5Fclose(fid); + } + LoadMD loadAlg; + loadAlg.setChild(true); loadAlg.initialize(); loadAlg.isInitialized(); loadAlg.setPropertyValue("Filename", fileName); loadAlg.setProperty("FileBackEnd", false); - loadAlg.setPropertyValue("OutputWorkspace", "reloaded_again"); + loadAlg.setPropertyValue("OutputWorkspace", "_unused_for_child"); loadAlg.execute(); TS_ASSERT( loadAlg.isExecuted() ); - // Check that the special coordinate system is the same before the save-load cycle. - TS_ASSERT_EQUALS(appliedCoordinateSystem, ws->getSpecialCoordinateSystem()); - if (Poco::File(this_fileName).exists()) { Poco::File(this_fileName).remove(); } - AnalysisDataService::Instance().remove(inputWSName); - AnalysisDataService::Instance().remove("OutputWorkspace"); + + return loadAlg.getProperty("OutputWorkspace"); } void test_loadAffine() diff --git a/Code/Mantid/Framework/MDAlgorithms/test/MergeMDFilesTest.h b/Code/Mantid/Framework/MDAlgorithms/test/MergeMDFilesTest.h index 3ecbe17b97b7d4048fb06facfd79cd232f6691f8..e4e4d932672d69ada816168c75b9cfe0d5a8c5d8 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/MergeMDFilesTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/MergeMDFilesTest.h @@ -48,6 +48,7 @@ public: // Create a bunch of input files std::vector<std::vector<std::string> > filenames; + Mantid::Kernel::SpecialCoordinateSystem appliedCoord = Mantid::Kernel::QSample; std::vector<MDEventWorkspace3Lean::sptr> inWorkspaces; // how many events put into each file. long nFileEvents(1000); @@ -55,7 +56,9 @@ public: { std::ostringstream mess; mess << "MergeMDFilesTestInput" << i; - MDEventWorkspace3Lean::sptr ws = MDEventsTestHelper::makeFileBackedMDEW(mess.str(), true,-nFileEvents); + MDEventWorkspace3Lean::sptr ws = + MDEventsTestHelper::makeFileBackedMDEW(mess.str(), true,-nFileEvents, appliedCoord); + inWorkspaces.push_back(ws); filenames.push_back(std::vector<std::string>(1,ws->getBoxController()->getFilename())); } @@ -87,6 +90,7 @@ public: TS_ASSERT(ws); if (!ws) return; + TS_ASSERT_EQUALS(appliedCoord, ws->getSpecialCoordinateSystem()); TS_ASSERT_EQUALS( ws->getNPoints(), 3*nFileEvents); MDBoxBase3Lean * box = ws->getBox(); TS_ASSERT_EQUALS( box->getNumChildren(), 1000); diff --git a/Code/Mantid/Framework/MDAlgorithms/test/SliceMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/SliceMDTest.h index f031322ce1dce76176cfc9d890ae886f4f63d96c..a02607812cd8f5fb7ff57d99bd67a527f2747267 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/SliceMDTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/SliceMDTest.h @@ -137,6 +137,8 @@ public: TS_ASSERT( alg.isInitialized() ) IMDEventWorkspace_sptr in_ws = MDEventsTestHelper::makeAnyMDEW<MDE,nd>(10, 0.0, 10.0, 1); + Mantid::Kernel::SpecialCoordinateSystem appliedCoord = Mantid::Kernel::QSample; + in_ws->setCoordinateSystem(appliedCoord); AnalysisDataService::Instance().addOrReplace("SliceMDTest_ws", in_ws); TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("InputWorkspace", "SliceMDTest_ws") ); @@ -166,6 +168,8 @@ public: TSM_ASSERT_EQUALS("Should default to TakeMaxRecursionDepthFromInput == true", in_ws->getBoxController()->getMaxDepth(), out->getBoxController()->getMaxDepth()); + TS_ASSERT_EQUALS(appliedCoord, out->getSpecialCoordinateSystem()); + // Took this many events out with the slice TS_ASSERT_EQUALS(out->getNPoints(), expectedNumPoints); // Output has this number of dimensions diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformAligned.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformAligned.h index cc57d1f8ca3ee761c69e3d030482fe1356f730ee..5dd40ca97fbfbc1cd362577b33e4f8e0535edbaf 100644 --- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformAligned.h +++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformAligned.h @@ -9,13 +9,13 @@ namespace Mantid { namespace MDEvents { /// Unique type declaration for which dimensions are used in the input workspace -DECLARE_VECTOR_PARAMETER(DimensionsToBinFromParam, size_t); +DECLARE_VECTOR_PARAMETER(DimensionsToBinFromParam, size_t) /// Unique type declaration for the offset of coordinates -DECLARE_VECTOR_PARAMETER(OriginOffsetParam, coord_t); +DECLARE_VECTOR_PARAMETER(OriginOffsetParam, coord_t) /// Unique type declaration for the step size in transformation -DECLARE_VECTOR_PARAMETER(ScalingParam, coord_t); +DECLARE_VECTOR_PARAMETER(ScalingParam, coord_t) /** A restricted version of CoordTransform which transforms from one set of dimensions to another, allowing: diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformDistance.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformDistance.h index 2c332767cc177c85f8aafe5cdc9b96bb02fda16a..4da70fdac7e0f109657aff9ca68104bce711e27f 100644 --- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformDistance.h +++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/CoordTransformDistance.h @@ -12,11 +12,11 @@ namespace Mantid { namespace MDEvents { /// Unique CoordCenterVectorParam type declaration for ndimensional coordinate /// centers -DECLARE_VECTOR_PARAMETER(CoordCenterVectorParam, coord_t); +DECLARE_VECTOR_PARAMETER(CoordCenterVectorParam, coord_t) /// Unique DimensionsUsedVectorParam type declaration for boolean masks over /// dimensions -DECLARE_VECTOR_PARAMETER(DimensionsUsedVectorParam, bool); +DECLARE_VECTOR_PARAMETER(DimensionsUsedVectorParam, bool) /** A non-linear coordinate transform that takes * a point from nd dimensions and converts it to a diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBoxFlatTree.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBoxFlatTree.h index 7ce65edab215476f4ba1e81b99a3e31cdaf5c68f..ef01cbbad77f6eeeabbba82253b6382b6d807734 100644 --- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBoxFlatTree.h +++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBoxFlatTree.h @@ -138,7 +138,7 @@ public: static void loadExperimentInfos( ::NeXus::File *const file, const std::string & filename, - boost::shared_ptr<API::MultipleExperimentInfos> ei, + boost::shared_ptr<API::MultipleExperimentInfos> mei, bool lazy = false); static void saveAffineTransformMatricies(::NeXus::File *const file, diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEventWorkspace.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEventWorkspace.h index 4aaa6769320a38eaf52dcbaa1b2a2c181a99136b..aa134a84b56d0f3e4a649e825d5287402c7c9f72 100644 --- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEventWorkspace.h +++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEventWorkspace.h @@ -32,7 +32,13 @@ namespace MDEvents { * */ TMDE_CLASS class DLLExport MDEventWorkspace : public API::IMDEventWorkspace { + public: + /// Typedef for a shared pointer of this kind of event workspace + typedef boost::shared_ptr<MDEventWorkspace<MDE, nd>> sptr; + /// Typedef to access the MDEventType. + typedef MDE MDEventType; + MDEventWorkspace(); MDEventWorkspace(const MDEventWorkspace<MDE, nd> &other); virtual ~MDEventWorkspace(); @@ -119,9 +125,6 @@ public: size_t addEvents(const std::vector<MDE> &events); - // void addManyEvents(const std::vector<MDE> & events, - // Mantid::Kernel::ProgressBase * prog); - std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> getMinimumExtents(size_t depth = 2); @@ -149,13 +152,10 @@ public: /// Clear masking void clearMDMasking(); - /// Get the special coordinate system. - virtual Mantid::Kernel::SpecialCoordinateSystem - getSpecialCoordinateSystem() const; - - /// Set the special coordinate system. - void setCoordinateSystem( - const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem); + /// Get the coordinate system. + Kernel::SpecialCoordinateSystem getSpecialCoordinateSystem() const; + /// Set the coordinate system. + void setCoordinateSystem(const Kernel::SpecialCoordinateSystem coordSystem); /// make the workspace file backed if it has not been already file backed; virtual void setFileBacked(const std::string &fileName); /// if workspace was file-backed, this should clear file-backed information @@ -167,14 +167,10 @@ protected: MDBoxBase<MDE, nd> *data; /// Box controller in use - Mantid::API::BoxController_sptr m_BoxController; + API::BoxController_sptr m_BoxController; // boost::shared_ptr<BoxCtrlChangesList > m_BoxController; private: -public: - /// Typedef for a shared pointer of this kind of event workspace - typedef boost::shared_ptr<MDEventWorkspace<MDE, nd>> sptr; - /// Typedef to access the MDEventType. - typedef MDE MDEventType; + Kernel::SpecialCoordinateSystem m_coordSystem; }; } // namespace MDEvents diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspace.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspace.h index 1bc89a29dc241b68e26aeccceb723991299da44b..b43bb81ba1b601c6af22dd207f73c7db2e7cd6d8 100644 --- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspace.h +++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspace.h @@ -147,12 +147,11 @@ public: const coord_t *getBinWidths() const { return m_boxLength; } /// Get the special coordinate system. - virtual Mantid::Kernel::SpecialCoordinateSystem - getSpecialCoordinateSystem() const; + virtual Kernel::SpecialCoordinateSystem getSpecialCoordinateSystem() const; /// Set the special coordinate system. - void setCoordinateSystem( - const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem); + void + setCoordinateSystem(const Kernel::SpecialCoordinateSystem coordinateSystem); void setTo(signal_t signal, signal_t errorSquared, signal_t numEvents); @@ -161,7 +160,7 @@ public: coord_t *getVertexesArray(size_t linearIndex, size_t &numVertices) const; - Mantid::Kernel::VMD getCenter(size_t linearIndex) const; + Kernel::VMD getCenter(size_t linearIndex) const; /// Returns the (normalized) signal at a given coordinates signal_t @@ -422,6 +421,8 @@ private: /// the number of events, contributed into the workspace; mutable uint64_t m_nEventsContributed; + Kernel::SpecialCoordinateSystem m_coordSystem; + protected: /// Linear array of masks for each bin bool *m_masks; diff --git a/Code/Mantid/Framework/MDEvents/src/ConvToMDBase.cpp b/Code/Mantid/Framework/MDEvents/src/ConvToMDBase.cpp index 2bb6898f1a077c30956fe253fa3bbd217c275522..34beee6fd332e6437181aeded445836a1df17d7a 100644 --- a/Code/Mantid/Framework/MDEvents/src/ConvToMDBase.cpp +++ b/Code/Mantid/Framework/MDEvents/src/ConvToMDBase.cpp @@ -94,7 +94,7 @@ size_t ConvToMDBase::initialize( m_coordinateSystem = WSD.getCoordinateSystem(); return n_spectra; -}; +} /** empty default constructor */ ConvToMDBase::ConvToMDBase() diff --git a/Code/Mantid/Framework/MDEvents/src/ConvertToReflectometryQ.cpp b/Code/Mantid/Framework/MDEvents/src/ConvertToReflectometryQ.cpp index c8785b26cb211005945eb69367cf4491304ea785..1c5df9e388a81edc7a3cd313dc0245fc6f804bc7 100644 --- a/Code/Mantid/Framework/MDEvents/src/ConvertToReflectometryQ.cpp +++ b/Code/Mantid/Framework/MDEvents/src/ConvertToReflectometryQ.cpp @@ -136,10 +136,10 @@ ConvertToReflectometryQ::~ConvertToReflectometryQ() {} /// Algorithm's name for identification. @see Algorithm::name const std::string ConvertToReflectometryQ::name() const { return "ConvertToReflectometryQ"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int ConvertToReflectometryQ::version() const { return 1; }; +int ConvertToReflectometryQ::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string ConvertToReflectometryQ::category() const { diff --git a/Code/Mantid/Framework/MDEvents/src/FitMD.cpp b/Code/Mantid/Framework/MDEvents/src/FitMD.cpp index e398bee85440879542788b6ddba14790a211b12c..64d2ce71eb3e0d25065e015c49173539874838bb 100644 --- a/Code/Mantid/Framework/MDEvents/src/FitMD.cpp +++ b/Code/Mantid/Framework/MDEvents/src/FitMD.cpp @@ -23,7 +23,7 @@ namespace Mantid { namespace MDEvents { -DECLARE_DOMAINCREATOR(FitMD); +DECLARE_DOMAINCREATOR(FitMD) using namespace API; using namespace Kernel; @@ -211,6 +211,8 @@ boost::shared_ptr<API::Workspace> FitMD::createEventOutputWorkspace( // Run information outputWS->copyExperimentInfos(inputWorkspace); + // Coordinates + outputWS->setCoordinateSystem(inputWorkspace.getSpecialCoordinateSystem()); // Set sensible defaults for splitting behaviour BoxController_sptr bc = outputWS->getBoxController(); bc->setSplitInto(3); diff --git a/Code/Mantid/Framework/MDEvents/src/ImportMDEventWorkspace.cpp b/Code/Mantid/Framework/MDEvents/src/ImportMDEventWorkspace.cpp index 778dae5954c68138cb19041cbd7eda45903ded49..25613ad38949bb3f7b0e8fabcaa5ba495c02e5a3 100644 --- a/Code/Mantid/Framework/MDEvents/src/ImportMDEventWorkspace.cpp +++ b/Code/Mantid/Framework/MDEvents/src/ImportMDEventWorkspace.cpp @@ -81,10 +81,10 @@ ImportMDEventWorkspace::~ImportMDEventWorkspace() {} /// Algorithm's name for identification. @see Algorithm::name const std::string ImportMDEventWorkspace::name() const { return "ImportMDEventWorkspace"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int ImportMDEventWorkspace::version() const { return 1; }; +int ImportMDEventWorkspace::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string ImportMDEventWorkspace::category() const { diff --git a/Code/Mantid/Framework/MDEvents/src/ImportMDHistoWorkspace.cpp b/Code/Mantid/Framework/MDEvents/src/ImportMDHistoWorkspace.cpp index 3773fc1802319885c626268f72c325d790e325e9..134a84b5007e1173d14c4820891e8a06dc6e420a 100644 --- a/Code/Mantid/Framework/MDEvents/src/ImportMDHistoWorkspace.cpp +++ b/Code/Mantid/Framework/MDEvents/src/ImportMDHistoWorkspace.cpp @@ -31,10 +31,10 @@ ImportMDHistoWorkspace::~ImportMDHistoWorkspace() {} /// Algorithm's name for identification. @see Algorithm::name const std::string ImportMDHistoWorkspace::name() const { return "ImportMDHistoWorkspace"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int ImportMDHistoWorkspace::version() const { return 1; }; +int ImportMDHistoWorkspace::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string ImportMDHistoWorkspace::category() const { diff --git a/Code/Mantid/Framework/MDEvents/src/IntegrateEllipsoids.cpp b/Code/Mantid/Framework/MDEvents/src/IntegrateEllipsoids.cpp index ddc312d7ea57429b477793c1c54e811a680247f7..57ede42f6f5f52bc4087bfa13ee87ad0b0ed525f 100644 --- a/Code/Mantid/Framework/MDEvents/src/IntegrateEllipsoids.cpp +++ b/Code/Mantid/Framework/MDEvents/src/IntegrateEllipsoids.cpp @@ -365,9 +365,6 @@ void IntegrateEllipsoids::exec() { const size_t numSpectra = wksp->getNumberHistograms(); Progress prog(this, 0.5, 1.0, numSpectra); - // loop through the eventlists - std::vector<double> buffer(DIMS); - if (eventWS) { // process as EventWorkspace qListFromEventWS(integrator, prog, eventWS, unitConv, qConverter); diff --git a/Code/Mantid/Framework/MDEvents/src/MDBox.cpp b/Code/Mantid/Framework/MDEvents/src/MDBox.cpp index 510d96f65f5f5ac6450c61572c71962945b8615d..6f4964c01fddff83be93bdfb5332fe1b16df1538 100644 --- a/Code/Mantid/Framework/MDEvents/src/MDBox.cpp +++ b/Code/Mantid/Framework/MDEvents/src/MDBox.cpp @@ -296,7 +296,7 @@ TMDE(void MDBox)::getEventsData(std::vector<coord_t> &coordTable, #ifdef MDBOX_TRACK_CENTROID this->calculateCentroid(this->m_centroid); #endif -}; +} /** The method to convert the table of data into vector of events * Used to load events from plain binary file * @param coordTable -- vector of events parameters, which will be converted @@ -305,7 +305,7 @@ TMDE(void MDBox)::getEventsData(std::vector<coord_t> &coordTable, */ TMDE(void MDBox)::setEventsData(const std::vector<coord_t> &coordTable) { MDE::dataToEvents(coordTable, this->data); -}; +} //----------------------------------------------------------------------------------------------- /** Allocate and return a vector with a copy of all events contained diff --git a/Code/Mantid/Framework/MDEvents/src/MDBoxFlatTree.cpp b/Code/Mantid/Framework/MDEvents/src/MDBoxFlatTree.cpp index 04bf88b25efc2eabdc3b6eb03d20b6f62daf4672..52782b30ed61049b7cad6ee81995d96a16a956ae 100644 --- a/Code/Mantid/Framework/MDEvents/src/MDBoxFlatTree.cpp +++ b/Code/Mantid/Framework/MDEvents/src/MDBoxFlatTree.cpp @@ -745,6 +745,9 @@ MDBoxFlatTree::createOrOpenMDWSgroup(const std::string &fileName, int &nDims, * dimensions etc.*/ void MDBoxFlatTree::saveWSGenericInfo(::NeXus::File *const file, API::IMDWorkspace_const_sptr ws) { + // Write out the coordinate system + file->writeData("coordinate_system", + static_cast<uint32_t>(ws->getSpecialCoordinateSystem())); // Save the algorithm history under "process" ws->getHistory().saveNexus(file); diff --git a/Code/Mantid/Framework/MDEvents/src/MDEventWorkspace.cpp b/Code/Mantid/Framework/MDEvents/src/MDEventWorkspace.cpp index a81802c9df25ea59de10adb9d9eb2a74f29aa17d..03e4c2b0d716a5455ab7e7a8de3c619dec258041 100644 --- a/Code/Mantid/Framework/MDEvents/src/MDEventWorkspace.cpp +++ b/Code/Mantid/Framework/MDEvents/src/MDEventWorkspace.cpp @@ -34,7 +34,7 @@ namespace MDEvents { /** Default constructor */ TMDE(MDEventWorkspace)::MDEventWorkspace() - : m_BoxController(new BoxController(nd)) { + : data(NULL), m_BoxController(new BoxController(nd)), m_coordSystem(None) { // First box is at depth 0, and has this default boxController data = new MDBox<MDE, nd>(m_BoxController.get(), 0); } @@ -781,40 +781,21 @@ TMDE(void MDEventWorkspace)::clearMDMasking() { } /** -Set the special coordinate system (if any) to use. -@param coordinateSystem : Special coordinate system to use. +Get the coordinate system (if any) to use. +@return An enumeration specifying the coordinate system if any. */ -TMDE(void MDEventWorkspace)::setCoordinateSystem( - const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem) { - // If there isn't an experiment info, create one. - if (this->getNumExperimentInfo() == 0) { - ExperimentInfo_sptr expInfo = - boost::shared_ptr<ExperimentInfo>(new ExperimentInfo()); - this->addExperimentInfo(expInfo); - } - this->getExperimentInfo(0)->mutableRun().addProperty( - "CoordinateSystem", (int)coordinateSystem, true); +TMDE(Kernel::SpecialCoordinateSystem + MDEventWorkspace)::getSpecialCoordinateSystem() const { + return m_coordSystem; } /** -Get the special coordinate system (if any) to use. -@return Special coordinate system if any. +Set the coordinate system (if any) to use. +@param coordSystem : Coordinate system to use. */ -TMDE(Mantid::Kernel::SpecialCoordinateSystem - MDEventWorkspace)::getSpecialCoordinateSystem() const { - Mantid::Kernel::SpecialCoordinateSystem result = None; - try { - auto nInfos = this->getNumExperimentInfo(); - if (nInfos > 0) { - Property *prop = - this->getExperimentInfo(0)->run().getProperty("CoordinateSystem"); - PropertyWithValue<int> *p = dynamic_cast<PropertyWithValue<int> *>(prop); - int temp = *p; - result = (SpecialCoordinateSystem)temp; - } - } catch (Mantid::Kernel::Exception::NotFoundError &) { - } - return result; +TMDE(void MDEventWorkspace)::setCoordinateSystem( + const Kernel::SpecialCoordinateSystem coordSystem) { + m_coordSystem = coordSystem; } } // namespace MDEvents diff --git a/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspace.cpp b/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspace.cpp index 6bda2b2a2d1f662f7cfb2992f09e821f38a4c853..f83adb37808c86556b6a5e530893a941e3dc5878 100644 --- a/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspace.cpp +++ b/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspace.cpp @@ -31,7 +31,8 @@ MDHistoWorkspace::MDHistoWorkspace(Mantid::Geometry::MDHistoDimension_sptr dimX, Mantid::Geometry::MDHistoDimension_sptr dimZ, Mantid::Geometry::MDHistoDimension_sptr dimT) : IMDHistoWorkspace(), numDimensions(0), - m_nEventsContributed(std::numeric_limits<uint64_t>::quiet_NaN()) { + m_nEventsContributed(std::numeric_limits<uint64_t>::quiet_NaN()), + m_coordSystem(None) { std::vector<Mantid::Geometry::MDHistoDimension_sptr> dimensions; if (dimX) dimensions.push_back(dimX); @@ -51,7 +52,8 @@ MDHistoWorkspace::MDHistoWorkspace(Mantid::Geometry::MDHistoDimension_sptr dimX, MDHistoWorkspace::MDHistoWorkspace( std::vector<Mantid::Geometry::MDHistoDimension_sptr> &dimensions) : IMDHistoWorkspace(), numDimensions(0), m_numEvents(NULL), - m_nEventsContributed(std::numeric_limits<uint64_t>::quiet_NaN()) { + m_nEventsContributed(std::numeric_limits<uint64_t>::quiet_NaN()), + m_coordSystem(None) { this->init(dimensions); } @@ -62,7 +64,8 @@ MDHistoWorkspace::MDHistoWorkspace( MDHistoWorkspace::MDHistoWorkspace( std::vector<Mantid::Geometry::IMDDimension_sptr> &dimensions) : IMDHistoWorkspace(), numDimensions(0), m_numEvents(NULL), - m_nEventsContributed(std::numeric_limits<uint64_t>::quiet_NaN()) { + m_nEventsContributed(std::numeric_limits<uint64_t>::quiet_NaN()), + m_coordSystem(None) { this->init(dimensions); } @@ -1183,39 +1186,20 @@ uint64_t MDHistoWorkspace::sumNContribEvents() const { } /** -Set the special coordinate system (if any) to use. -@param coordinateSystem : Special coordinate system to use. +Get the special coordinate system (if any) to use. */ -void MDHistoWorkspace::setCoordinateSystem( - const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem) { - // If there isn't an experiment info, create one. - if (this->getNumExperimentInfo() == 0) { - ExperimentInfo_sptr expInfo = - boost::shared_ptr<ExperimentInfo>(new ExperimentInfo()); - this->addExperimentInfo(expInfo); - } - this->getExperimentInfo(0)->mutableRun().addProperty( - "CoordinateSystem", (int)coordinateSystem, true); +Kernel::SpecialCoordinateSystem +MDHistoWorkspace::getSpecialCoordinateSystem() const { + return m_coordSystem; } /** -Get the special coordinate system (if any) to use. +Set the special coordinate system (if any) to use. +@param coordinateSystem : Special coordinate system to use. */ -Mantid::Kernel::SpecialCoordinateSystem -MDHistoWorkspace::getSpecialCoordinateSystem() const { - Mantid::Kernel::SpecialCoordinateSystem result = None; - try { - auto nInfos = this->getNumExperimentInfo(); - if (nInfos > 0) { - Property *prop = - this->getExperimentInfo(0)->run().getProperty("CoordinateSystem"); - PropertyWithValue<int> *p = dynamic_cast<PropertyWithValue<int> *>(prop); - int temp = *p; - result = (SpecialCoordinateSystem)temp; - } - } catch (Mantid::Kernel::Exception::NotFoundError &) { - } - return result; +void MDHistoWorkspace::setCoordinateSystem( + const Kernel::SpecialCoordinateSystem coordinateSystem) { + m_coordSystem = coordinateSystem; } /** diff --git a/Code/Mantid/Framework/MDEvents/src/MDTransfModQ.cpp b/Code/Mantid/Framework/MDEvents/src/MDTransfModQ.cpp index c5066f6a2b219290a9def174747e56aa57285399..64150e9fa8a1bed3a780afa511aac02462d61703 100644 --- a/Code/Mantid/Framework/MDEvents/src/MDTransfModQ.cpp +++ b/Code/Mantid/Framework/MDEvents/src/MDTransfModQ.cpp @@ -4,7 +4,7 @@ namespace Mantid { namespace MDEvents { // register the class, whith conversion factory under ModQ name -DECLARE_MD_TRANSFID(MDTransfModQ, |Q|); +DECLARE_MD_TRANSFID(MDTransfModQ, |Q|) /**method calculates the units, the transformation expects the input ws to be in. If the input ws is in different units, diff --git a/Code/Mantid/Framework/MDEvents/src/MDTransfNoQ.cpp b/Code/Mantid/Framework/MDEvents/src/MDTransfNoQ.cpp index ea013bd3239563a815534d0918c55ad4de7a6ddb..f8022527affa48d6e33e2cb3e96bcc7596ceb411 100644 --- a/Code/Mantid/Framework/MDEvents/src/MDTransfNoQ.cpp +++ b/Code/Mantid/Framework/MDEvents/src/MDTransfNoQ.cpp @@ -4,7 +4,7 @@ namespace Mantid { namespace MDEvents { // register the class, whith conversion factory under NoQ name -DECLARE_MD_TRANSFID(MDTransfNoQ, CopyToMD); +DECLARE_MD_TRANSFID(MDTransfNoQ, CopyToMD) /** Method fills-in all additional properties requested by user and not defined *by matrix workspace itselt. @@ -177,7 +177,7 @@ MDTransfNoQ::inputUnitID(Kernel::DeltaEMode::Type mode, return pXAxis->unit()->unitID(); } -MDTransfNoQ::MDTransfNoQ() : m_NMatrixDim(0), m_YAxis(NULL), m_Det(NULL){}; +MDTransfNoQ::MDTransfNoQ() : m_NMatrixDim(0), m_YAxis(NULL), m_Det(NULL){} } // End MDAlgorighms namespace } // End Mantid namespace diff --git a/Code/Mantid/Framework/MDEvents/src/MDTransfQ3D.cpp b/Code/Mantid/Framework/MDEvents/src/MDTransfQ3D.cpp index aacc63c1c0932f63dde313c888bc3ffb82785c2b..4b28ee722568cff8fa139fedfe0e91bd1451ea66 100644 --- a/Code/Mantid/Framework/MDEvents/src/MDTransfQ3D.cpp +++ b/Code/Mantid/Framework/MDEvents/src/MDTransfQ3D.cpp @@ -4,7 +4,7 @@ namespace Mantid { namespace MDEvents { // register the class, whith conversion factory under Q3D name -DECLARE_MD_TRANSFID(MDTransfQ3D, Q3D); +DECLARE_MD_TRANSFID(MDTransfQ3D, Q3D) /** method returns number of matrix dimensions calculated by this class * as function of energy analysis mode */ diff --git a/Code/Mantid/Framework/MDEvents/src/MDWSDescription.cpp b/Code/Mantid/Framework/MDEvents/src/MDWSDescription.cpp index 10b30e0d7135a7ad80b24e48ca81cc478fb4f00f..fe787634d1dcfdf0098af6981ab8edb4310f7b25 100644 --- a/Code/Mantid/Framework/MDEvents/src/MDWSDescription.cpp +++ b/Code/Mantid/Framework/MDEvents/src/MDWSDescription.cpp @@ -128,7 +128,7 @@ Kernel::Matrix<double> MDWSDescription::getGoniometerMatr() const { return m_InWS->run().getGoniometer().getR(); else return Kernel::Matrix<double>(3, 3, true); -}; +} /** the function builds MD event WS description from existing workspace. * Primary used to obtain existing ws parameters @@ -156,16 +156,6 @@ MDWSDescription::buildFromMDWS(const API::IMDEventWorkspace_const_sptr &pWS) { m_DimMax[i] = pDim->getMaximum(); } m_Wtransf = Kernel::DblMatrix(pWS->getWTransf()); - // deal with the case when source MD workspace does not have any experiment - // infos - if (pWS->getNumExperimentInfo() != 0) { - this->addProperty( - "W_MATRIX", - pWS->getExperimentInfo(0) - ->run() - .getPropertyValueAsType<std::vector<double>>("W_MATRIX"), - true); - } } /** When the workspace has been build from existing MDWrokspace, some target *workspace parameters can not be defined, diff --git a/Code/Mantid/Framework/MDEvents/src/UnitsConversionHelper.cpp b/Code/Mantid/Framework/MDEvents/src/UnitsConversionHelper.cpp index 9ef8f0b06ef0029023e017348f6debbffd599f9a..8ae927468775706771aa13666b793b4bebb2188c 100644 --- a/Code/Mantid/Framework/MDEvents/src/UnitsConversionHelper.cpp +++ b/Code/Mantid/Framework/MDEvents/src/UnitsConversionHelper.cpp @@ -366,7 +366,7 @@ UnitsConversionHelper::UnitsConversionHelper() : m_UnitCnvrsn(CnvrtToMD::ConvertNo), m_Factor(1), m_Power(1), m_Emode(-1), // undefined m_L1(1), m_Efix(1), m_TwoTheta(0), m_L2(1), m_pTwoThetas(NULL), - m_pL2s(NULL), m_pEfixedArray(NULL){}; + m_pL2s(NULL), m_pEfixedArray(NULL){} } // endNamespace MDEvents } // endNamespace Mantid diff --git a/Code/Mantid/Framework/MDEvents/src/UserFunctionMD.cpp b/Code/Mantid/Framework/MDEvents/src/UserFunctionMD.cpp index 7b2eb2d1dd07343da6518336da55312d59d2ebbf..bb44a51918550e0c3b2755115afc41bbfa7da265 100644 --- a/Code/Mantid/Framework/MDEvents/src/UserFunctionMD.cpp +++ b/Code/Mantid/Framework/MDEvents/src/UserFunctionMD.cpp @@ -11,7 +11,7 @@ namespace Mantid { namespace MDEvents { // Subscribe the function into the factory. -DECLARE_FUNCTION(UserFunctionMD); +DECLARE_FUNCTION(UserFunctionMD) /// Default constructor UserFunctionMD::UserFunctionMD() { diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/FitFunctions/IFunction1DAdapter.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/FitFunctions/IFunction1DAdapter.h index f8eb459d600f591555f931c0e3d5cbf711b720e8..4dfd15fa59522fa1ea6e053695784ab31a84fb32 100644 --- a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/FitFunctions/IFunction1DAdapter.h +++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/FitFunctions/IFunction1DAdapter.h @@ -62,8 +62,8 @@ public: private: /// The PyObject must be supplied to construct the object - DISABLE_DEFAULT_CONSTRUCT(IFunction1DAdapter); - DISABLE_COPY_AND_ASSIGN(IFunction1DAdapter); + DISABLE_DEFAULT_CONSTRUCT(IFunction1DAdapter) + DISABLE_COPY_AND_ASSIGN(IFunction1DAdapter) /// Flag if the functionDeriv1D method is overridden (avoids multiple checks) bool m_derivOveridden; diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/FitFunctions/IFunctionAdapter.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/FitFunctions/IFunctionAdapter.h index 791e261ac94a171674566958a64aa445ecca14b8..30479217d156ce155cd019e22bcc89b07082a1da 100644 --- a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/FitFunctions/IFunctionAdapter.h +++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/FitFunctions/IFunctionAdapter.h @@ -106,8 +106,8 @@ protected: private: /// The PyObject must be supplied to construct the object - DISABLE_DEFAULT_CONSTRUCT(IFunctionAdapter); - DISABLE_COPY_AND_ASSIGN(IFunctionAdapter); + DISABLE_DEFAULT_CONSTRUCT(IFunctionAdapter) + DISABLE_COPY_AND_ASSIGN(IFunctionAdapter) /// The name of the function std::string m_name; diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/FitFunctions/IPeakFunctionAdapter.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/FitFunctions/IPeakFunctionAdapter.h index 73a5d5a485bc1f7f300403975a0abd726b50176c..a9e32e733de2b29d86df618c6b15306b16d5ce0a 100644 --- a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/FitFunctions/IPeakFunctionAdapter.h +++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/FitFunctions/IPeakFunctionAdapter.h @@ -87,8 +87,8 @@ public: private: /// The PyObject must be supplied to construct the object - DISABLE_DEFAULT_CONSTRUCT(IPeakFunctionAdapter); - DISABLE_COPY_AND_ASSIGN(IPeakFunctionAdapter); + DISABLE_DEFAULT_CONSTRUCT(IPeakFunctionAdapter) + DISABLE_COPY_AND_ASSIGN(IPeakFunctionAdapter) }; } } diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h index 8da49cf8c2fc6d5e36cfabdeb2656e0ad5e0104e..4ff4e6147e7179cdba497844e0f64cc30ebfe276 100644 --- a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h +++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h @@ -123,8 +123,8 @@ protected: private: /// The PyObject must be supplied to construct the object - DISABLE_DEFAULT_CONSTRUCT(AlgorithmAdapter); - DISABLE_COPY_AND_ASSIGN(AlgorithmAdapter); + DISABLE_DEFAULT_CONSTRUCT(AlgorithmAdapter) + DISABLE_COPY_AND_ASSIGN(AlgorithmAdapter) /// Private init for this algorithm virtual void init(); diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/DataProcessorAdapter.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/DataProcessorAdapter.h index f635b0bd465177fc75ed99ff0fbd1fda3897263a..56d0093b0a8e2e7f1ee1ee3c8ff1fe40399a32aa 100644 --- a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/DataProcessorAdapter.h +++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/DataProcessorAdapter.h @@ -100,8 +100,8 @@ public: private: /// The PyObject must be supplied to construct the object - DISABLE_DEFAULT_CONSTRUCT(DataProcessorAdapter); - DISABLE_COPY_AND_ASSIGN(DataProcessorAdapter); + DISABLE_DEFAULT_CONSTRUCT(DataProcessorAdapter) + DISABLE_COPY_AND_ASSIGN(DataProcessorAdapter) }; } } diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/NumpyFunctions.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/NumpyFunctions.h new file mode 100644 index 0000000000000000000000000000000000000000..473189403f991563d30440d500a2c302104226a7 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/NumpyFunctions.h @@ -0,0 +1,56 @@ +#ifndef NUMPY_FUNCTIONS_H +#define NUMPY_FUNCTIONS_H +/* + Copyright © 2011 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + 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://github.com/mantidproject/mantid>. + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +#ifdef __GNUC__ +#pragma GCC system_header +#endif + +#include <boost/python/list.hpp> +#include "MantidKernel/WarningSuppressions.h" +GCC_DIAG_OFF(cast - qual) +// 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/arrayobject.h> +GCC_DIAG_ON(cast - qual) + +/**functions containing numpy macros. We put them in a separate header file to + *suppress the warning + *ISO C++ forbids casting between pointer-to-function and pointer-to-object + */ +namespace Mantid { +namespace PythonInterface { +namespace Converters { +namespace Impl { +/// equivalent to macro PyArray_IterNew +PyObject *func_PyArray_IterNew(PyArrayObject *arr); +/// equivalent to macro PyArray_NewFromDescr +PyArrayObject *func_PyArray_NewFromDescr(int datatype, const int ndims, + Py_intptr_t *dims); +} +} +} +} +#endif // NUMPY_FUNCTIONS_H diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp index 71dd4571e3213c1a41e66e795a667e290ec0f9af..99e7e215f5d7f55b1d030bf42a7d644114cda969 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp @@ -33,9 +33,9 @@ namespace typedef void(*declarePropertyType4)(boost::python::object & self, const std::string &, const boost::python::object &, const int); // Overload types - BOOST_PYTHON_FUNCTION_OVERLOADS(declarePropertyType1_Overload, PythonAlgorithm::declarePyAlgProperty, 2, 3); - BOOST_PYTHON_FUNCTION_OVERLOADS(declarePropertyType2_Overload, PythonAlgorithm::declarePyAlgProperty, 3, 6); - BOOST_PYTHON_FUNCTION_OVERLOADS(declarePropertyType3_Overload, PythonAlgorithm::declarePyAlgProperty, 4, 5); + BOOST_PYTHON_FUNCTION_OVERLOADS(declarePropertyType1_Overload, PythonAlgorithm::declarePyAlgProperty, 2, 3) + BOOST_PYTHON_FUNCTION_OVERLOADS(declarePropertyType2_Overload, PythonAlgorithm::declarePyAlgProperty, 3, 6) + BOOST_PYTHON_FUNCTION_OVERLOADS(declarePropertyType3_Overload, PythonAlgorithm::declarePyAlgProperty, 4, 5) } void export_leaf_classes() diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmFactory.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmFactory.cpp index 12bfc84afbc68a1900b0a1214a4e3ef48a9e81fd..4719f8e959126fdb9aa392704adc0518d41a8b3d 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmFactory.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmFactory.cpp @@ -97,7 +97,7 @@ GCC_DIAG_OFF(cast-qual) FileLoaderRegistry::Instance().unsubscribe(descr.first, descr.second); } - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(existsOverloader, exists, 1, 2); + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(existsOverloader, exists, 1, 2) ///@endcond } diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmManager.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmManager.cpp index d44c0a1f606327a92cf20adb9a64e7392fff9922..4296086b4f68f950c5e8326dd0de2d9bf6a57914 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmManager.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmManager.cpp @@ -59,8 +59,8 @@ namespace ///@cond //------------------------------------------------------------------------------------------------------ /// Define overload generators - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(create_overloads,AlgorithmManagerImpl::create, 1,2); - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(createUnmanaged_overloads,AlgorithmManagerImpl::createUnmanaged, 1,2); + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(create_overloads,AlgorithmManagerImpl::create, 1,2) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(createUnmanaged_overloads,AlgorithmManagerImpl::createUnmanaged, 1,2) ///@endcond } diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp index 0a1e917bd120a1ad8aabd2b97e582f008116c595..4151bcbebf843e22591789803a3f9136041fc14e 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp @@ -27,7 +27,7 @@ namespace //------------------------------- Overload macros --------------------------- // Overloads for operator() function which has 1 optional argument - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Axis_getValue, Axis::getValue, 1, 2); + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Axis_getValue, Axis::getValue, 1, 2) /** * Extract the axis values as a sequence. A numpy array is used if the diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp index 4f784af07eae140aff25064204561875e5cb6ba2..b02c444f40f44c630a6a4e48363a50a87983f78d 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp @@ -11,7 +11,7 @@ using Mantid::PythonInterface::Policies::RemoveConstSharedPtr; using namespace boost::python; /// Overload generator for getInstrumentFilename -BOOST_PYTHON_FUNCTION_OVERLOADS(getInstrumentFilename_Overload, ExperimentInfo::getInstrumentFilename, 1, 2); +BOOST_PYTHON_FUNCTION_OVERLOADS(getInstrumentFilename_Overload, ExperimentInfo::getInstrumentFilename, 1, 2) void export_ExperimentInfo() { diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/FileFinder.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/FileFinder.cpp index 88eb1d1f94cef3923c2473d89c2ca74384c8f7f5..d4bec6851b00d0549be757ae4136600725e18278 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/FileFinder.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/FileFinder.cpp @@ -1,17 +1,22 @@ #include "MantidAPI/FileFinder.h" #include <boost/python/class.hpp> +#include <boost/python/overloads.hpp> #include <boost/python/reference_existing_object.hpp> using Mantid::API::FileFinder; using Mantid::API::FileFinderImpl; using namespace boost::python; +namespace { + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getFullPathOverloader, getFullPath, 1, 2) +} + void export_FileFinder() { class_<FileFinderImpl, boost::noncopyable>("FileFinderImpl", no_init) .def("getFullPath", &FileFinderImpl::getFullPath, - "Return a full path to the given file if it can be found within datasearch.directories paths. " - "An empty string is returned otherwise.") + getFullPathOverloader((arg("path"), arg("ignoreDirs")=false), + "Return a full path to the given file if it can be found within datasearch.directories paths. Directories can be ignored with ignoreDirs=True. An empty string is returned otherwise.")) .def("findRuns", &FileFinderImpl::findRuns, "Find a list of files file given a hint. " "The hint can be a comma separated list of run numbers and can also include ranges of runs, e.g. 123-135 or equivalently 123-35" "If no instrument prefix is given then the current default is used.") diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp index 23ee2542e21ba7603a8aba7d277ed8152f169538..07ef49a108f54e31646f4fd7addfd8a80049b5de 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp @@ -312,6 +312,7 @@ void export_ialgorithm() .def("setLogging", &IAlgorithm::setLogging, "Toggle logging on/off.") .def("setRethrows", &IAlgorithm::setRethrows) .def("initialize", &IAlgorithm::initialize, "Initializes the algorithm") + .def("validateInputs", &IAlgorithm::validateInputs, "Cross-check all inputs and return any errors as a dictionary") .def("execute", &executeWhileReleasingGIL, "Runs the algorithm and returns whether it has been successful") // Special methods .def("__str__", &IAlgorithm::toString) diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp index caa28aea2a08327eefdfff4d5014de8cea77b281..d43ac0538b798e6bf3bf5978e8e9af36a0e3d391 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp @@ -35,10 +35,10 @@ namespace // -- Set property overloads -- // setProperty(index,value,explicit) typedef void(IFunction::*setParameterType1)(size_t,const double & value,bool); - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType1_Overloads, setParameter, 2, 3); + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType1_Overloads, setParameter, 2, 3) // setProperty(index,value,explicit) typedef void(IFunction::*setParameterType2)(const std::string &,const double & value,bool); - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType2_Overloads, setParameter, 2, 3); + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType2_Overloads, setParameter, 2, 3) ///@endcond diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Workspace.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Workspace.cpp index 6ec0dcda804db20c630a039e12d8c73d1ff0e7b1..11dd4f9b8bff6891cb963f523178ba945c98c2b5 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Workspace.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Workspace.cpp @@ -13,7 +13,7 @@ using namespace boost::python; namespace { ///@cond - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Workspace_isDirtyOverloads, Workspace::isDirty, 0, 1); + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Workspace_isDirtyOverloads, Workspace::isDirty, 0, 1) ///@endcond } diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp index 6ff101d8dddd7456ad557193dd45a01f75080b53..e7cc6802b0fa5033923d65d5a65afe00c161053b 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp @@ -34,9 +34,9 @@ namespace } /// Overload generator for create - BOOST_PYTHON_FUNCTION_OVERLOADS(createFromParent_Overload, createFromParentPtr, 2, 5); - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(createTable_Overload, createTable, 0, 1); - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(createPeaks_Overload, createPeaks, 0, 1); + BOOST_PYTHON_FUNCTION_OVERLOADS(createFromParent_Overload, createFromParentPtr, 2, 5) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(createTable_Overload, createTable, 0, 1) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(createPeaks_Overload, createPeaks, 0, 1) } void export_WorkspaceFactory() diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/mantid/geometry/CMakeLists.txt index 0bbe6d970e7a3ba89682aec7b667418a92fd1eef..ece3afcacc2c82c63bc6089d728cadc3fa0e1e56 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/CMakeLists.txt @@ -25,6 +25,7 @@ set ( EXPORT_FILES src/Exports/Goniometer.cpp src/Exports/Object.cpp src/Exports/PeakShape.cpp + src/Exports/Group.cpp src/Exports/PointGroup.cpp src/Exports/PointGroupFactory.cpp src/Exports/SpaceGroup.cpp diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/Component.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/Component.cpp index 406a438bcb3df8e5e49006ceec9a7cb9e7fd840d..02856d5765b992fc759ed31b96ea8768567ed06d 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/Component.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/Component.cpp @@ -9,15 +9,15 @@ using namespace boost::python; namespace { // Default parameter function overloads - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getParameterNames,Component::getParameterNames,0,1); - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_hasParameter,Component::hasParameter,1,2); - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getNumberParameter,Component::getNumberParameter,1,2); - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getBoolParameter,Component::getBoolParameter,1,2); - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getPositionParameter,Component::getPositionParameter,1,2); - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getRotationParameter,Component::getRotationParameter,1,2); - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getStringParameter,Component::getStringParameter,1,2); - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getIntParameter,Component::getIntParameter,1,2); - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getParameterType,Component::getParameterType,1,2); + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getParameterNames,Component::getParameterNames,0,1) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_hasParameter,Component::hasParameter,1,2) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getNumberParameter,Component::getNumberParameter,1,2) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getBoolParameter,Component::getBoolParameter,1,2) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getPositionParameter,Component::getPositionParameter,1,2) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getRotationParameter,Component::getRotationParameter,1,2) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getStringParameter,Component::getStringParameter,1,2) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getIntParameter,Component::getIntParameter,1,2) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Component_getParameterType,Component::getParameterType,1,2) } diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp index 16bcc7cf7b1918846db178a0e7cb3cd26ad64f04..74b37cfebead2690565ab953180431d4bc3ec39c 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp @@ -14,7 +14,7 @@ namespace //<unnamed> { ///@cond // define overloaded functions - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getEulerAngles_overloads, Goniometer::getEulerAngles, 0, 1); + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getEulerAngles_overloads, Goniometer::getEulerAngles, 0, 1) ///@endcond /// Set the U vector via a numpy array diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/Group.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/Group.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5a0cbef5c8d3b3d4e0575c92519cbc7c75358c4a --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/Group.cpp @@ -0,0 +1,20 @@ +#include "MantidGeometry/Crystal/Group.h" + +#include <boost/python/class.hpp> +#include <boost/python/enum.hpp> +#include <boost/python/scope.hpp> + +using Mantid::Geometry::Group; + +using namespace boost::python; + +void export_Group() +{ + enum_<Group::CoordinateSystem>("CoordinateSystem") + .value("Orthogonal", Group::Orthogonal) + .value("Hexagonal", Group::Hexagonal); + + class_<Group, boost::noncopyable>("Group", no_init) + .def("coordinateSystem", &Group::getCoordinateSystem); +} + diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroup.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroup.cpp index 545f5bbd984793b7ab20b2003e72f34d916b2e08..074c9aae7c1f8b678156c9566167a67948345bd1 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroup.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroup.cpp @@ -1,4 +1,4 @@ - +#include "MantidGeometry/Crystal/Group.h" #include "MantidGeometry/Crystal/PointGroup.h" #include "MantidPythonInterface/kernel/Converters/PyObjectToV3D.h" @@ -8,6 +8,7 @@ #include <boost/python/list.hpp> #include <boost/python/register_ptr_to_python.hpp> +using Mantid::Geometry::Group; using Mantid::Geometry::PointGroup; using namespace boost::python; @@ -37,7 +38,6 @@ namespace //<unnamed> { return self.getReflectionFamily(Converters::PyObjectToV3D(hkl)()); } - } void export_PointGroup() @@ -55,7 +55,7 @@ void export_PointGroup() .value("Trigonal", PointGroup::Trigonal) .value("Cubic", PointGroup::Cubic); - class_<PointGroup, boost::noncopyable>("PointGroup", no_init) + class_<PointGroup, boost::noncopyable, bases<Group> >("PointGroup", no_init) .def("getName", &PointGroup::getName) .def("getSymbol", &PointGroup::getSymbol) .def("crystalSystem", &PointGroup::crystalSystem) diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroupFactory.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroupFactory.cpp index 6d36f2418c20274930b72c9914b4e4b28f1160c3..8700da8f509361a5dbe35f4554ef28d002b9b8dc 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroupFactory.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroupFactory.cpp @@ -1,4 +1,5 @@ #include "MantidGeometry/Crystal/PointGroupFactory.h" +#include "MantidGeometry/Crystal/SpaceGroupFactory.h" #include "MantidPythonInterface/kernel/PythonObjectInstantiator.h" #include <boost/python/class.hpp> @@ -6,13 +7,26 @@ using namespace Mantid::Geometry; using namespace boost::python; +namespace { + PointGroup_sptr getPointGroupFromSpaceGroup(PointGroupFactoryImpl & self, const SpaceGroup &group) + { + return self.createPointGroupFromSpaceGroup(group); + } + + PointGroup_sptr getPointGroupFromSpaceGroupSymbol(PointGroupFactoryImpl & self, const std::string &group) + { + return self.createPointGroupFromSpaceGroup(SpaceGroupFactory::Instance().createSpaceGroup(group)); + } +} + void export_PointGroupFactory() { class_<PointGroupFactoryImpl,boost::noncopyable>("PointGroupFactoryImpl", no_init) .def("exists", &PointGroupFactoryImpl::isSubscribed) .def("createPointGroup", &PointGroupFactoryImpl::createPointGroup) - .def("createPointGroupFromSpaceGroupSymbol", &PointGroupFactoryImpl::createPointGroupFromSpaceGroupSymbol) + .def("createPointGroupFromSpaceGroup", &getPointGroupFromSpaceGroup) + .def("createPointGroupFromSpaceGroupSymbol", &getPointGroupFromSpaceGroupSymbol) .def("getAllPointGroupSymbols", &PointGroupFactoryImpl::getAllPointGroupSymbols) .def("getPointGroupSymbols", &PointGroupFactoryImpl::getPointGroupSymbols) .def("Instance", &PointGroupFactory::Instance, return_value_policy<reference_existing_object>(), diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroup.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroup.cpp index 442a4783d4e00265e31b6004a6f26c8afc48c255..2608650efae0afb655e41a3022890f6b1da3ceb5 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroup.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroup.cpp @@ -1,4 +1,5 @@ +#include "MantidGeometry/Crystal/Group.h" #include "MantidGeometry/Crystal/SpaceGroup.h" #include "MantidPythonInterface/kernel/Converters/PyObjectToV3D.h" @@ -8,6 +9,7 @@ #include <boost/python/list.hpp> #include <boost/python/register_ptr_to_python.hpp> +using Mantid::Geometry::Group; using Mantid::Geometry::SpaceGroup; using Mantid::Geometry::SymmetryOperation; @@ -47,7 +49,7 @@ void export_SpaceGroup() { register_ptr_to_python<boost::shared_ptr<SpaceGroup> >(); - class_<SpaceGroup, boost::noncopyable>("SpaceGroup", no_init) + class_<SpaceGroup, boost::noncopyable, bases<Group> >("SpaceGroup", no_init) .def("order", &SpaceGroup::order) .def("getSymmetryOperationStrings", &getSymmetryOperationStrings) .def("number", &SpaceGroup::number) diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroupFactory.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroupFactory.cpp index de61f14cbef451f2255ea67b6051bdb5238acb17..0f906422a0f69a1d79769f36b661ce17fd57242e 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroupFactory.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroupFactory.cpp @@ -33,7 +33,6 @@ namespace SpaceGroup_sptr createSpaceGroup(SpaceGroupFactoryImpl &self, const std::string &symbol) { SpaceGroup_const_sptr spaceGroup = self.createSpaceGroup(symbol); - return boost::const_pointer_cast<SpaceGroup>(spaceGroup); } diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt index 32975fce4226f3b7a7ac09dca016e6070120b638..02058243e4c2a308c227eebf75ec25646685c597 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt @@ -54,6 +54,7 @@ set ( SRC_FILES src/Converters/CloneToNumpy.cpp src/Converters/NDArrayToVector.cpp src/Converters/NDArrayTypeIndex.cpp + src/Converters/NumpyFunctions.cpp src/Converters/PyArrayType.cpp src/Converters/PyObjectToMatrix.cpp src/Converters/PyObjectToV3D.cpp @@ -71,6 +72,7 @@ set ( SRC_FILES set ( INC_FILES ${HEADER_DIR}/kernel/Converters/CArrayToNDArray.h ${HEADER_DIR}/kernel/Converters/MatrixToNDArray.h + ${HEADER_DIR}/kernel/Converters/NumpyFunctions.h ${HEADER_DIR}/kernel/Converters/NDArrayToVector.h ${HEADER_DIR}/kernel/Converters/NDArrayTypeIndex.h ${HEADER_DIR}/kernel/Converters/WrapWithNumpy.h diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/CloneToNumpy.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/CloneToNumpy.cpp index 6213ffb71c9efddf16c8060a5b115367bbce7565..55534dbc1cc8b4409c38d454c38e994a5dbe28c7 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/CloneToNumpy.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/CloneToNumpy.cpp @@ -3,14 +3,7 @@ //----------------------------------------------------------------------------- #include "MantidPythonInterface/kernel/Converters/CloneToNumpy.h" #include "MantidPythonInterface/kernel/Converters/NDArrayTypeIndex.h" -#include "MantidKernel/WarningSuppressions.h" -#include <boost/python/list.hpp> - -GCC_DIAG_OFF(cast-qual) -#define PY_ARRAY_UNIQUE_SYMBOL KERNEL_ARRAY_API -#define NO_IMPORT_ARRAY -#include <numpy/arrayobject.h> -GCC_DIAG_ON(cast-qual) +#include "MantidPythonInterface/kernel/Converters/NumpyFunctions.h" #include <string> @@ -44,13 +37,9 @@ namespace Mantid { namespace PythonInterface { Py_intptr_t dims[1] = { static_cast<int>(cvector.size()) }; int datatype = NDArrayTypeIndex<bool>::typenum; - PyArrayObject *nparray = (PyArrayObject*) - PyArray_NewFromDescr(&PyArray_Type, - PyArray_DescrFromType(datatype), - 1, // rank - dims, // Length in each dimension - NULL, NULL, - 0, NULL); + PyArrayObject *nparray = + func_PyArray_NewFromDescr(datatype, 1, &dims[0]); + for(Py_intptr_t i = 0; i < dims[0]; ++i) { void *itemPtr = PyArray_GETPTR1(nparray, i); @@ -71,13 +60,8 @@ namespace Mantid { namespace PythonInterface PyObject *cloneND(const ElementType * carray, const int ndims, Py_intptr_t *dims) { int datatype = NDArrayTypeIndex<ElementType>::typenum; - PyArrayObject *nparray = (PyArrayObject*) - PyArray_NewFromDescr(&PyArray_Type, - PyArray_DescrFromType(datatype), - ndims, // rank - dims, // Length in each dimension - NULL, NULL, - 0, NULL); + PyArrayObject *nparray = + func_PyArray_NewFromDescr(datatype, ndims, &dims[0]); // Compute total number of elements size_t length(dims[0]); if(ndims > 1) @@ -133,18 +117,18 @@ namespace Mantid { namespace PythonInterface INSTANTIATE_CLONEND(ElementType) ///@cond Doxygen doesn't seem to like this... - INSTANTIATE_CLONE(int); - INSTANTIATE_CLONE(long); - INSTANTIATE_CLONE(long long); - INSTANTIATE_CLONE(unsigned int); - INSTANTIATE_CLONE(unsigned long); - INSTANTIATE_CLONE(unsigned long long); - INSTANTIATE_CLONE(double); - INSTANTIATE_CLONE(float); + INSTANTIATE_CLONE(int) + INSTANTIATE_CLONE(long) + INSTANTIATE_CLONE(long long) + INSTANTIATE_CLONE(unsigned int) + INSTANTIATE_CLONE(unsigned long) + INSTANTIATE_CLONE(unsigned long long) + INSTANTIATE_CLONE(double) + INSTANTIATE_CLONE(float) // Need further 1D specialisation for string INSTANTIATE_CLONE1D(std::string) // Need further ND specialisation for bool - INSTANTIATE_CLONEND(bool); + INSTANTIATE_CLONEND(bool) ///@endcond } } diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp index 8151c09da2f91a52f7326c8128e540da49bf07ce..98324f55d71d656602c8596399e959fdce10ba88 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp @@ -4,11 +4,7 @@ #include "MantidPythonInterface/kernel/Converters/NDArrayToVector.h" #include "MantidPythonInterface/kernel/Converters/NDArrayTypeIndex.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/arrayobject.h> +#include "MantidPythonInterface/kernel/Converters/NumpyFunctions.h" namespace Mantid { @@ -30,16 +26,20 @@ namespace Mantid { // Use the iterator API to iterate through the array // and assign each value to the corresponding vector - PyObject *iter = PyArray_IterNew((PyObject*)arr); + typedef union { + DestElementType* output; + void *input; + } npy_union; + npy_union data; + PyObject *iter = Converters::Impl::func_PyArray_IterNew(arr); npy_intp index(0); do { - DestElementType *data = (DestElementType*)PyArray_ITER_DATA(iter); - cvector[index] = *data; + data.input = PyArray_ITER_DATA(iter); + cvector[index] = *data.output; ++index; PyArray_ITER_NEXT(iter); - } - while(PyArray_ITER_NOTDONE(iter)); + } while (PyArray_ITER_NOTDONE(iter)); } }; @@ -163,15 +163,15 @@ namespace Mantid template DLLExport struct NDArrayToVector<ElementType>; ///@cond Doxygen doesn't seem to like this... - INSTANTIATE_TOVECTOR(int); - INSTANTIATE_TOVECTOR(long); - INSTANTIATE_TOVECTOR(long long); - INSTANTIATE_TOVECTOR(unsigned int); - INSTANTIATE_TOVECTOR(unsigned long); - INSTANTIATE_TOVECTOR(unsigned long long); - INSTANTIATE_TOVECTOR(double); - INSTANTIATE_TOVECTOR(bool); - INSTANTIATE_TOVECTOR(std::string); + INSTANTIATE_TOVECTOR(int) + INSTANTIATE_TOVECTOR(long) + INSTANTIATE_TOVECTOR(long long) + INSTANTIATE_TOVECTOR(unsigned int) + INSTANTIATE_TOVECTOR(unsigned long) + INSTANTIATE_TOVECTOR(unsigned long long) + INSTANTIATE_TOVECTOR(double) + INSTANTIATE_TOVECTOR(bool) + INSTANTIATE_TOVECTOR(std::string) ///@endcond } } diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayTypeIndex.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayTypeIndex.cpp index a1efd28e193cad6e6512bea77ae6157f510806bd..5a7981231fa947acebb8cd983bd8b73b630b7082 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayTypeIndex.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayTypeIndex.cpp @@ -24,15 +24,15 @@ namespace Mantid template DLLExport struct NDArrayTypeIndex<CType>;\ - DEFINE_TYPE_MAPPING(int, NPY_INT); - DEFINE_TYPE_MAPPING(long, NPY_LONG); - DEFINE_TYPE_MAPPING(long long, NPY_LONGLONG); - DEFINE_TYPE_MAPPING(unsigned int, NPY_UINT); - DEFINE_TYPE_MAPPING(unsigned long, NPY_ULONG); - DEFINE_TYPE_MAPPING(unsigned long long, NPY_ULONGLONG); - DEFINE_TYPE_MAPPING(bool, NPY_BOOL); - DEFINE_TYPE_MAPPING(double, NPY_DOUBLE); - DEFINE_TYPE_MAPPING(float, NPY_FLOAT); + DEFINE_TYPE_MAPPING(int, NPY_INT) + DEFINE_TYPE_MAPPING(long, NPY_LONG) + DEFINE_TYPE_MAPPING(long long, NPY_LONGLONG) + DEFINE_TYPE_MAPPING(unsigned int, NPY_UINT) + DEFINE_TYPE_MAPPING(unsigned long, NPY_ULONG) + DEFINE_TYPE_MAPPING(unsigned long long, NPY_ULONGLONG) + DEFINE_TYPE_MAPPING(bool, NPY_BOOL) + DEFINE_TYPE_MAPPING(double, NPY_DOUBLE) + DEFINE_TYPE_MAPPING(float, NPY_FLOAT) } } } diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/NumpyFunctions.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/NumpyFunctions.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5696352a6cacb38cdb90e5ff7b5e0a487572301c --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/NumpyFunctions.cpp @@ -0,0 +1,22 @@ +#include "MantidPythonInterface/kernel/Converters/NumpyFunctions.h" + +namespace Mantid { +namespace PythonInterface { +namespace Converters { +namespace Impl { + +PyObject *func_PyArray_IterNew(PyArrayObject *arr) { + return PyArray_IterNew((PyObject *)arr); +} + +PyArrayObject *func_PyArray_NewFromDescr(int datatype, const int ndims, + Py_intptr_t *dims) { + return (PyArrayObject *)PyArray_NewFromDescr( + &PyArray_Type, PyArray_DescrFromType(datatype), ndims, // rank + dims, // Length in each dimension + NULL, NULL, 0, NULL); +} +} +} +} +} diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/WrapWithNumpy.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/WrapWithNumpy.cpp index d353890b416dd59e13b296e6144bed28f29bbbb4..8b56c8eb7a17f623ded38b8000850ba2781c6c16 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/WrapWithNumpy.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Converters/WrapWithNumpy.cpp @@ -65,14 +65,14 @@ namespace Mantid { namespace PythonInterface template DLLExport PyObject *wrapWithNDArray<ElementType>(const ElementType*, const int ndims, Py_intptr_t *dims, const NumpyWrapMode); ///@cond Doxygen doesn't seem to like this... - INSTANTIATE_WRAPNUMPY(int); - INSTANTIATE_WRAPNUMPY(long); - INSTANTIATE_WRAPNUMPY(long long); - INSTANTIATE_WRAPNUMPY(unsigned int); - INSTANTIATE_WRAPNUMPY(unsigned long); - INSTANTIATE_WRAPNUMPY(unsigned long long); - INSTANTIATE_WRAPNUMPY(double); - INSTANTIATE_WRAPNUMPY(float); + INSTANTIATE_WRAPNUMPY(int) + INSTANTIATE_WRAPNUMPY(long) + INSTANTIATE_WRAPNUMPY(long long) + INSTANTIATE_WRAPNUMPY(unsigned int) + INSTANTIATE_WRAPNUMPY(unsigned long) + INSTANTIATE_WRAPNUMPY(unsigned long long) + INSTANTIATE_WRAPNUMPY(double) + INSTANTIATE_WRAPNUMPY(float) ///@endcond } } diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigService.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigService.cpp index 762f446435d56a3f2bad87ec96e4bccaf5a7481d..45a9d0f8a559794869adc667a6bd9cd94776578f 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigService.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigService.cpp @@ -31,9 +31,9 @@ namespace } /// Overload generator for getInstrument - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getInstrument_Overload, getInstrument, 0, 1); + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getInstrument_Overload, getInstrument, 0, 1) /// Overload generator for getString - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getString_Overload, getString, 1, 2); + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getString_Overload, getString, 1, 2) } void export_ConfigService() diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp index 8fc7a039ebfccf5490771a26128961bec9504395..3bfa9244083a18adb81d5a276d1f037ac23bf52d 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp @@ -94,7 +94,7 @@ namespace } } // Define an overload to handle the default argument - BOOST_PYTHON_FUNCTION_OVERLOADS(getStatisticsOverloads, getStatisticsNumpy, 1, 2); + BOOST_PYTHON_FUNCTION_OVERLOADS(getStatisticsOverloads, getStatisticsNumpy, 1, 2) //============================ Z score ============================================ // Function pointer to real implementation of Zscore functions @@ -132,7 +132,7 @@ namespace return getZScoreNumpyImpl(&getZscore, data, sorted); } // Define an overload to handle the default argument - BOOST_PYTHON_FUNCTION_OVERLOADS(getZscoreOverloads, getZscoreNumpy, 1, 2); + BOOST_PYTHON_FUNCTION_OVERLOADS(getZscoreOverloads, getZscoreNumpy, 1, 2) /** * Proxy for @see Mantid::Kernel::getModifiedZscore so that it can accept numpy arrays, @@ -143,7 +143,7 @@ namespace return getZScoreNumpyImpl(&getModifiedZscore, data, sorted); } // Define an overload to handle the default argument - BOOST_PYTHON_FUNCTION_OVERLOADS(getModifiedZscoreOverloads, getModifiedZscoreNumpy, 1, 2); + BOOST_PYTHON_FUNCTION_OVERLOADS(getModifiedZscoreOverloads, getModifiedZscoreNumpy, 1, 2) //============================ getMoments ============================================ @@ -194,7 +194,7 @@ namespace } // Define an overload to handle the default argument - BOOST_PYTHON_FUNCTION_OVERLOADS(getMomentsAboutOriginOverloads, getMomentsAboutOriginNumpy, 2, 3); + BOOST_PYTHON_FUNCTION_OVERLOADS(getMomentsAboutOriginOverloads, getMomentsAboutOriginNumpy, 2, 3) /** * Proxy for @see Mantid::Kernel::getMomentsAboutMean so that it can accept numpy arrays @@ -207,7 +207,7 @@ namespace } // Define an overload to handle the default argument - BOOST_PYTHON_FUNCTION_OVERLOADS(getMomentsAboutMeanOverloads, getMomentsAboutMeanNumpy, 2, 3); + BOOST_PYTHON_FUNCTION_OVERLOADS(getMomentsAboutMeanOverloads, getMomentsAboutMeanNumpy, 2, 3) ///@endcond } diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/TimeSeriesProperty.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/TimeSeriesProperty.cpp index 0934388431327414d8b523c38c9edb853e63b872..2f9bf530009231a934726719b8dbaad4acd44bf5 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/TimeSeriesProperty.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/TimeSeriesProperty.cpp @@ -38,7 +38,6 @@ namespace .def("getStatistics", &TimeSeriesProperty<TYPE>::getStatistics) \ .def("timeAverageValue", &TimeSeriesProperty<TYPE>::timeAverageValue) \ ; - ; } void export_TimeSeriesProperty_Double() diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Registry/SequenceTypeHandler.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Registry/SequenceTypeHandler.cpp index 067aa64fc4d24d7f9fcbe749edcfad9faf257e14..627bc2d4cd003f5afc9e907616619daf8c69f931 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Registry/SequenceTypeHandler.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Registry/SequenceTypeHandler.cpp @@ -128,15 +128,15 @@ namespace Mantid #define INSTANTIATE(ElementType)\ template DLLExport struct SequenceTypeHandler<std::vector<ElementType> >; - INSTANTIATE(int); - INSTANTIATE(long); - INSTANTIATE(long long); - INSTANTIATE(unsigned int); - INSTANTIATE(unsigned long); - INSTANTIATE(unsigned long long); - INSTANTIATE(double); - INSTANTIATE(std::string); - INSTANTIATE(bool); + INSTANTIATE(int) + INSTANTIATE(long) + INSTANTIATE(long long) + INSTANTIATE(unsigned int) + INSTANTIATE(unsigned long) + INSTANTIATE(unsigned long long) + INSTANTIATE(double) + INSTANTIATE(std::string) + INSTANTIATE(bool) ///@endcond } } diff --git a/Code/Mantid/Framework/PythonInterface/mantid/simpleapi.py b/Code/Mantid/Framework/PythonInterface/mantid/simpleapi.py index 17d7d7463573b81bbad2e4e555b2cfe29d37ed37..1ded6b0bf0352e05f97a0fe0054a9010ac70383b 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/simpleapi.py +++ b/Code/Mantid/Framework/PythonInterface/mantid/simpleapi.py @@ -20,6 +20,7 @@ """ from __future__ import absolute_import +import os, string import mantid.api as _api import mantid.kernel as _kernel @@ -31,7 +32,7 @@ from mantid.api._aliases import * #------------------------ Specialized function calls -------------------------- # List of specialized algorithms -__SPECIALIZED_FUNCTIONS__ = ["Load", "Fit"] +__SPECIALIZED_FUNCTIONS__ = ["Load", "Fit", "CutMD"] # List of specialized algorithms __MDCOORD_FUNCTIONS__ = ["PeakIntensityVsRadius", "CentroidPeaksMD","IntegratePeaksMD"] # The "magic" keyword to enable/disable logging @@ -257,6 +258,125 @@ def FitDialog(*args, **kwargs): #--------------------------------------------------- -------------------------- +def CutMD(*args, **kwargs): + """ + Slices multidimensional workspaces using input projection information and binning limits. + """ + (in_wss,) = _get_mandatory_args('CutMD', ["InputWorkspace"], *args, **kwargs) + + # If the input isn't a list, wrap it in one so we can iterate easily + if isinstance(in_wss, list): + in_list = in_wss + handling_multiple_workspaces = True + else: + in_list = [in_wss] + handling_multiple_workspaces = False + + # Remove from keywords so it is not set twice + if "InputWorkspace" in kwargs: + del kwargs['InputWorkspace'] + + #Make sure we were given some output workspace names + lhs = _kernel.funcreturns.lhs_info() + if lhs[0] == 0 and 'OutputWorkspace' not in kwargs: + raise RuntimeError("Unable to set output workspace name. Please either assign the output of " + "CutMD to a variable or use the OutputWorkspace keyword.") + + #Take what we were given + if "OutputWorkspace" in kwargs: + out_names = kwargs["OutputWorkspace"] + else: + out_names = list(lhs[1]) + + #Ensure the output names we were given are valid + if handling_multiple_workspaces: + if not isinstance(out_names, list): + raise RuntimeError("Multiple OutputWorkspaces must be given as a list when processing multiple InputWorkspaces.") + else: + #We wrap in a list for our convenience. The user musn't pass us one though. + if not isinstance(out_names, list): + out_names = [out_names] + elif len(out_names) != 1: + raise RuntimeError("Only one OutputWorkspace required") + + if len(out_names) != len(in_list): + raise RuntimeError("Different number of input and output workspaces given.") + + # Split PBins up into P1Bin, P2Bin, etc. + if "PBins" in kwargs: + bins = kwargs["PBins"] + del kwargs["PBins"] + if isinstance(bins, tuple) or isinstance(bins, list): + for bin in range(len(bins)): + kwargs["P{0}Bin".format(bin+1)] = bins[bin] + + # Create and execute + algm = _create_algorithm_object('CutMD') + _set_logging_option(algm, kwargs) + + # Now check that all the kwargs we've got are correct + for key in kwargs.keys(): + if key not in algm: + raise RuntimeError("Unknown property: {0}".format(key)) + + # We're now going to build to_process, which is the list of workspaces we want to process. + to_process = list() + for i in range(len(in_list)): + ws = in_list[i] + + if isinstance(ws, _api.Workspace): + #It's a workspace, do nothing to it + to_process.append(ws) + elif isinstance(ws, str): + if ws in mtd: + #It's a name of something in the ads, just take it from the ads + to_process.append(_api.AnalysisDataService[ws]) + else: + #Let's try treating it as a filename + load_alg = AlgorithmManager.create("Load") + load_alg.setLogging(True) + load_alg.setAlwaysStoreInADS(False) + load_alg.setProperty("Filename", ws) + load_alg.setProperty("OutputWorkspace", "__loaded_by_cutmd_{0}".format(i+1)) + load_alg.execute() + if not load_alg.isExecuted(): + raise TypeError("Failed to load " + ws) + wsn = load_alg.getProperty("OutputWorkspace").valueAsStr + to_process.append(_api.AnalysisDataService[wsn]) + else: + raise TypeError("Unexpected type: " + type(ws)) + + #Run the algorithm across the inputs and outputs + for i in range(len(to_process)): + _set_properties(algm, **kwargs) + algm.setProperty('InputWorkspace', to_process[i]) + algm.setProperty('OutputWorkspace', out_names[i]) + algm.execute() + + #Get the workspace objects so we can return them + for i in range(len(out_names)): + out_names[i] = _api.AnalysisDataService[out_names[i]] + + #We should only return a list if we're handling multiple workspaces + if handling_multiple_workspaces: + return out_names + else: + return out_names[0] + +# Have a better load signature for autocomplete +_signature = "\bInputWorkspace" +# Getting the code object for Load +_f = CutMD.func_code +# Creating a new code object nearly identical, but with the two variable names replaced +# by the property list. +_c = _f.__new__(_f.__class__, _f.co_argcount, _f.co_nlocals, _f.co_stacksize, _f.co_flags, _f.co_code, _f.co_consts, _f.co_names,\ + (_signature, "kwargs"), _f.co_filename, _f.co_name, _f.co_firstlineno, _f.co_lnotab, _f.co_freevars) + +# Replace the code object of the wrapper function +CutMD.func_code = _c + +#--------------------------------------------------- -------------------------- + def _get_function_spec(func): """Get the python function signature for the given function object @@ -550,6 +670,7 @@ def _create_algorithm_function(algorithm, version, _algm_object): Note that if the Version parameter is passed, we will create the proper version of the algorithm without failing. """ + _version = version if "Version" in kwargs: _version = kwargs["Version"] diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CylinderPaalmanPingsCorrection.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CylinderPaalmanPingsCorrection.py new file mode 100644 index 0000000000000000000000000000000000000000..9bddc49898f77c8e6f4a8a2631e2b77d878349d4 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CylinderPaalmanPingsCorrection.py @@ -0,0 +1,361 @@ +from mantid.simpleapi import * +from mantid.api import PythonAlgorithm, AlgorithmFactory, PropertyMode, MatrixWorkspaceProperty, \ + WorkspaceGroupProperty, InstrumentValidator, WorkspaceUnitValidator +from mantid.kernel import StringListValidator, StringMandatoryValidator, IntBoundedValidator, \ + FloatBoundedValidator, Direction, logger, CompositeValidator +from mantid import config +import math, os.path, numpy as np + + +class CylinderPaalmanPingsCorrection(PythonAlgorithm): + + _sample_ws_name = None + _sample_chemical_formula = None + _sample_number_density = None + _sample_inner_radius = None + _sample_outer_radius = None + _usecan = False + _can_ws_name = None + _can_chemical_formula = None + _can_number_density = None + _can_outer_radius = None + _step_size = None + _number_wavelengths = 10 + _emode = None + _efixed = 0.0 + _output_ws_name = None + + + def category(self): + return "Workflow\\MIDAS;PythonAlgorithms;CorrectionFunctions\\AbsorptionCorrections" + + + def summary(self): + return "Calculates absorption corrections for a cylindrical or annular sample using Paalman & Pings format." + + + def PyInit(self): + ws_validator = CompositeValidator([WorkspaceUnitValidator('Wavelength'), InstrumentValidator()]) + + self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '', + direction=Direction.Input, + validator=ws_validator), + doc='Name for the input sample workspace') + + self.declareProperty(name='SampleChemicalFormula', defaultValue='', + validator=StringMandatoryValidator(), + doc='Sample chemical formula') + self.declareProperty(name='SampleNumberDensity', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Sample number density in atoms/Angstrom3') + self.declareProperty(name='SampleInnerRadius', defaultValue=0.05, + doc='Sample inner radius') + self.declareProperty(name='SampleOuterRadius', defaultValue=0.1, + doc='Sample outer radius') + + self.declareProperty(MatrixWorkspaceProperty('CanWorkspace', '', + direction=Direction.Input, + optional=PropertyMode.Optional, + validator=ws_validator), + doc="Name for the input container workspace") + + self.declareProperty(name='CanChemicalFormula', defaultValue='', + doc='Container chemical formula') + self.declareProperty(name='CanNumberDensity', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Container number density in atoms/Angstrom3') + self.declareProperty(name='CanOuterRadius', defaultValue=0.15, + doc='Can outer radius') + + self.declareProperty(name='BeamHeight', defaultValue=0.1, + doc='Height of the beam at the sample.') + self.declareProperty(name='BeamWidth', defaultValue=0.1, + doc='Width of the beam at the sample.') + + self.declareProperty(name='StepSize', defaultValue=0.002, + doc='Step size for calculation') + + self.declareProperty(name='Interpolate', defaultValue=True, + doc='Interpolate the correction workspaces to match the sample workspace') + + self.declareProperty(name='Emode', defaultValue='Elastic', + validator=StringListValidator(['Elastic', 'Indirect']), + doc='Emode: Elastic or Indirect') + self.declareProperty(name='Efixed', defaultValue=1.0, + doc='Analyser energy') + + self.declareProperty(WorkspaceGroupProperty('OutputWorkspace', '', + direction=Direction.Output), + doc='The output corrections workspace group') + + + def PyExec(self): + + from IndirectImport import is_supported_f2py_platform, import_f2py + + if is_supported_f2py_platform(): + cylabs = import_f2py("cylabs") + else: + raise RuntimeError('This algorithm is only available on Windows') + + workdir = config['defaultsave.directory'] + self._setup() + self._wave_range() + + # Set sample material from chemical formula + SetSampleMaterial(self._sample_ws_name, ChemicalFormula=self._sample_chemical_formula, + SampleNumberDensity=self._sample_number_density) + sample = mtd[self._sample_ws_name].sample() + sam_material = sample.getMaterial() + # total scattering x-section + sigs = [sam_material.totalScatterXSection()] + # absorption x-section + siga = [sam_material.absorbXSection()] + density = [self._sample_number_density, self._can_number_density, self._can_number_density] + half_width = 0.5*float(self._beam_width) + beam = [self._beam_height, half_width, -half_width, half_width, -half_width, 0.0, self._beam_height, 0.0, self._beam_height] + radii = [self._sample_inner_radius, self._sample_outer_radius, self._can_outer_radius, self._can_outer_radius] + ncan = 0 + + # If using a can, set sample material using chemical formula + if self._use_can: + ncan = 2 + SetSampleMaterial(InputWorkspace=self._can_ws_name, ChemicalFormula=self._can_chemical_formula, + SampleNumberDensity=self._can_number_density) + can_sample = mtd[self._can_ws_name].sample() + can_material = can_sample.getMaterial() + + # total scattering x-section for can + sigs.append(can_material.totalScatterXSection()) + sigs.append(can_material.totalScatterXSection()) + # absorption x-section for can + siga.append(can_material.absorbXSection()) + siga.append(can_material.absorbXSection()) + + else: + # total scattering x-section for can + sigs.append(0.0) + sigs.append(0.0) + # absorption x-section for can + siga.append(0.0) + siga.append(0.0) + + # Holders for the corrected data + data_ass = [] + data_assc = [] + data_acsc = [] + data_acc = [] + + # initially set errors to zero + wrk = workdir + self._can_ws_name + self._get_angles() + number_angles = len(self._angles) + + for angle_idx in range(number_angles): + kill, ass, assc, acsc, acc = cylabs.cylabs(self._step_size, beam, ncan, radii, + density, sigs, siga, self._angles[angle_idx], self._elastic, self._waves, angle_idx, wrk, 0) + + if kill == 0: + logger.information('Angle %d: %f successful' % (angle_idx+1, self._angles[angle_idx])) + + data_ass = np.append(data_ass, ass) + data_assc = np.append(data_assc, assc) + data_acsc = np.append(data_acsc, acsc) + data_acc = np.append(data_acc, acc) + + else: + raise ValueError('Angle ' + str(angle_idx) + ' : ' + str(self._angles[angle_idx]) + ' *** failed : Error code ' + str(kill)) + + sample_logs = {'sample_shape': 'cylinder', 'sample_filename': self._sample_ws_name, + 'sample_inner_radius': self._sample_inner_radius, 'sample_outer_radius': self._sample_outer_radius} + dataX = self._waves * number_angles + + # Create the output workspaces + ass_ws = self._output_ws_name + '_ass' + + CreateWorkspace(OutputWorkspace=ass_ws, DataX=dataX, DataY=data_ass, + NSpec=number_angles, UnitX='Wavelength') + self._add_sample_logs(ass_ws, sample_logs) + workspaces = [ass_ws] + + if self._use_can: + sample_logs['can_filename'] = self._can_ws_name + sample_logs['can_outer_radius'] = self._can_outer_radius + + assc_ws = self._output_ws_name + '_assc' + workspaces.append(assc_ws) + CreateWorkspace(OutputWorkspace=assc_ws, DataX=dataX, DataY=data_assc, + NSpec=number_angles, UnitX='Wavelength') + self._add_sample_logs(assc_ws, sample_logs) + + acsc_ws = self._output_ws_name + '_acsc' + workspaces.append(acsc_ws) + CreateWorkspace(OutputWorkspace=acsc_ws, DataX=dataX, DataY=data_acsc, + NSpec=number_angles, UnitX='Wavelength') + self._add_sample_logs(acsc_ws, sample_logs) + + acc_ws = self._output_ws_name + '_acc' + workspaces.append(acc_ws) + CreateWorkspace(OutputWorkspace=acc_ws, DataX=dataX, DataY=data_acc, + NSpec=number_angles, UnitX='Wavelength') + self._add_sample_logs(acc_ws, sample_logs) + + if self._interpolate: + self._interpolate_corrections(workspaces) + + try: + self. _copy_detector_table(workspaces) + except RuntimeError: + logger.warning('Cannot copy spectra mapping. Check input workspace instrument.') + + GroupWorkspaces(InputWorkspaces=','.join(workspaces), OutputWorkspace=self._output_ws_name) + self.setPropertyValue('OutputWorkspace', self._output_ws_name) + + + def validateInputs(self): + self._setup() + issues = dict() + + # Ensure that a can chemical formula is given when using a can workspace + if self._use_can: + can_chemical_formula = self.getPropertyValue('CanChemicalFormula') + if can_chemical_formula == '': + issues['CanChemicalFormula'] = 'Must provide a chemical foruma when providing a can workspace' + + # Ensure there are enough steps + number_steps = int((self._sample_outer_radius - self._sample_inner_radius) / self._step_size) + if number_steps < 20: + issues['StepSize'] = 'Number of steps (%d) should be >= 20' % number_steps + + return issues + + + def _setup(self): + """ + Get algorithm properties. + """ + + # This is fixed by the Fortran code + self._number_wavelengths = 10 + + self._sample_ws_name = self.getPropertyValue('SampleWorkspace') + + self._sample_chemical_formula = self.getPropertyValue('SampleChemicalFormula') + self._sample_number_density = self.getProperty('SampleNumberDensity').value + self._sample_inner_radius = self.getProperty('SampleInnerRadius').value + self._sample_outer_radius = self.getProperty('SampleOuterRadius').value + + self._can_ws_name = self.getPropertyValue('CanWorkspace') + self._use_can = self._can_ws_name != '' + + self._can_chemical_formula = self.getPropertyValue('CanChemicalFormula') + self._can_number_density = self.getProperty('CanNumberDensity').value + self._can_outer_radius = self.getProperty('CanOuterRadius').value + + self._step_size = self.getProperty('StepSize').value + + self._beam_height = self.getProperty('BeamHeight').value + self._beam_width = self.getProperty('BeamWidth').value + + self._interpolate = self.getProperty('Interpolate').value + + self._emode = self.getPropertyValue('Emode') + self._efixed = self.getProperty('Efixed').value + + self._output_ws_name = self.getPropertyValue('OutputWorkspace') + + + def _get_angles(self): + """ + Populates the list of workspace angles. + """ + + num_hist = mtd[self._sample_ws_name].getNumberHistograms() + source_pos = mtd[self._sample_ws_name].getInstrument().getSource().getPos() + sample_pos = mtd[self._sample_ws_name].getInstrument().getSample().getPos() + beam_pos = sample_pos - source_pos + self._angles = list() + for index in range(0, num_hist): + detector = mtd[self._sample_ws_name].getDetector(index) + two_theta = detector.getTwoTheta(sample_pos, beam_pos) * 180.0 / math.pi # calc angle + self._angles.append(two_theta) + + + def _wave_range(self): + wave_range = '__WaveRange' + ExtractSingleSpectrum(InputWorkspace=self._sample_ws_name, OutputWorkspace=wave_range, WorkspaceIndex=0) + Xin = mtd[wave_range].readX(0) + wave_min = mtd[wave_range].readX(0)[0] + wave_max = mtd[wave_range].readX(0)[len(Xin) - 1] + number_waves = int(self._number_wavelengths) + wave_bin = (wave_max - wave_min) / (number_waves-1) + + self._waves = list() + for idx in range(0, number_waves): + self._waves.append(wave_min + idx * wave_bin) + + if self._emode == 'Elastic': + self._elastic = self._waves[int(number_waves / 2)] + elif self._emode == 'Indirect': + self._elastic = math.sqrt(81.787 / self._efixed) # elastic wavelength + + logger.information('Elastic lambda %f' % self._elastic) + DeleteWorkspace(wave_range) + + + def _interpolate_corrections(self, workspaces): + """ + Performs interpolation on the correction workspaces such that the number of bins + matches that of the input sample workspace. + + @param workspaces List of correction workspaces to interpolate + """ + + for ws in workspaces: + SplineInterpolation(WorkspaceToMatch=self._sample_ws_name, + WorkspaceToInterpolate=ws, + OutputWorkspace=ws, + OutputWorkspaceDeriv='') + + + def _copy_detector_table(self, workspaces): + """ + Copy the detector table from the sample workspaces to the correction workspaces. + + @param workspaces List of correction workspaces + """ + + instrument = mtd[self._sample_ws_name].getInstrument().getName() + + for ws in workspaces: + LoadInstrument(Workspace=ws, + InstrumentName=instrument) + + CopyDetectorMapping(WorkspaceToMatch=self._sample_ws_name, + WorkspaceToRemap=ws, + IndexBySpectrumNumber=True) + + + def _add_sample_logs(self, ws, sample_logs): + """ + Add a dictionary of logs to a workspace. + + The type of the log is inferred by the type of the value passed to the log. + + @param ws - workspace to add logs too. + @param sample_logs - dictionary of logs to append to the workspace. + """ + + for key, value in sample_logs.iteritems(): + if isinstance(value, bool): + log_type = 'String' + elif isinstance(value, (int, long, float)): + log_type = 'Number' + else: + log_type = 'String' + + AddSampleLog(Workspace=ws, LogName=key, LogType=log_type, LogText=str(value)) + + +# Register algorithm with Mantid +AlgorithmFactory.subscribe(CylinderPaalmanPingsCorrection) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LoadDNSLegacy.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LoadDNSLegacy.py new file mode 100644 index 0000000000000000000000000000000000000000..62b8cc71d145baab36164ae0dd180e608fa212be --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LoadDNSLegacy.py @@ -0,0 +1,98 @@ +from mantid.kernel import * +from mantid.api import * +import mantid.simpleapi as api +import numpy as np + +import os, sys + +sys.path.insert(0, os.path.dirname(__file__)) +from dnsdata import DNSdata +sys.path.pop(0) + +class LoadDNSLegacy(PythonAlgorithm): + """ + Load the DNS Legacy data file to the mantid workspace + """ + def category(self): + """ + Returns categore + """ + return 'DataHandling' + + def name(self): + """ + Returns name + """ + return "LoadDNSLegacy" + + def summary(self): + return "Load the DNS Legacy data file to the mantid workspace." + + def PyInit(self): + self.declareProperty(FileProperty("Filename", "", \ + FileAction.Load, ['.d_dat']), \ + "Name of DNS experimental data file.") + self.declareProperty(WorkspaceProperty("OutputWorkspace", \ + "", direction=Direction.Output), \ + doc="Name of the workspace to store the experimental data.") + + return + + + def PyExec(self): + # Input + filename = self.getPropertyValue("Filename") + outws = self.getPropertyValue("OutputWorkspace") + + # load data array from the given file + data_array = np.loadtxt(filename) + ndet = 24 + dataX = np.zeros(ndet) + dataY = data_array[0:ndet, 1:] + dataE = np.sqrt(dataY) + # create workspace + __temporary_workspace__ = api.CreateWorkspace(DataX=dataX, \ + DataY=dataY, DataE=dataE, NSpec=ndet, UnitX="Wavelength") + api.LoadInstrument(__temporary_workspace__, InstrumentName='DNS') + + # load run information + metadata = DNSdata() + metadata.read_legacy(filename) + run = __temporary_workspace__.mutableRun() + run.setStartAndEndTime(DateAndTime(metadata.start_time), \ + DateAndTime(metadata.end_time)) + + # rotate the detector bank to the proper position + api.RotateInstrumentComponent(__temporary_workspace__, \ + "bank0", X=0, Y=1, Z=0, Angle=metadata.deterota) + # add sample log Ei + energy = get_energy(metadata.wavelength) + api.AddSampleLog(__temporary_workspace__, \ + 'Ei', LogText=str(energy), LogType='Number') + # add other sample logs + api.AddSampleLog(__temporary_workspace__, 'deterota', \ + LogText=str(metadata.deterota), LogType='Number') + api.AddSampleLog(__temporary_workspace__, 'huber', \ + LogText=str(metadata.huber), LogType='Number') + api.AddSampleLog(__temporary_workspace__, 'T1', \ + LogText=str(metadata.t1), LogType='Number') + api.AddSampleLog(__temporary_workspace__, 'T2', \ + LogText=str(metadata.t2), LogType='Number') + api.AddSampleLog(__temporary_workspace__, 'Tsp', \ + LogText=str(metadata.tsp), LogType='Number') + + self.setProperty("OutputWorkspace", __temporary_workspace__) + self.log().debug('LoadDNSLegacy: OK') + api.DeleteWorkspace(__temporary_workspace__) + + return + + +def get_energy(wavelength): + """ + Calculates neutron energy in eV from the given wavelength in Angstrom + """ + return 1e-3*81.73 / wavelength**2 + +# Register algorithm with Mantid +AlgorithmFactory.subscribe(LoadDNSLegacy) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/MSDFit.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/MSDFit.py new file mode 100644 index 0000000000000000000000000000000000000000..84df7738b4f721a942d54fcbe6c3f72fe1e96f48 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/MSDFit.py @@ -0,0 +1,199 @@ +from mantid.simpleapi import * +from mantid.api import * +from mantid.kernel import * + + +class MSDFit(DataProcessorAlgorithm): + + def category(self): + return 'Workflow\\MIDAS;PythonAlgorithms' + + + def summary(self): + return 'Fits log(intensity) vs Q-squared to obtain the mean squared displacement.' + + + def PyInit(self): + self.declareProperty(MatrixWorkspaceProperty('InputWorkspace', '', + direction=Direction.Input), + doc='Sample input workspace') + + self.declareProperty(name='XStart', defaultValue=0.0, + doc='Start of fitting range') + self.declareProperty(name='XEnd', defaultValue=0.0, + doc='End of fitting range') + + self.declareProperty(name='SpecMin', defaultValue=0, + doc='Start of spectra range to be fit') + self.declareProperty(name='SpecMax', defaultValue=0, + doc='End of spectra range to be fit') + + self.declareProperty(name='Plot', defaultValue=False, + doc='Plots results after fit') + + self.declareProperty(WorkspaceGroupProperty('OutputWorkspace', '', + direction=Direction.Output), + doc='Output mean squared displacement') + + self.declareProperty(ITableWorkspaceProperty('ParameterWorkspace', '', + direction=Direction.Output, + optional=PropertyMode.Optional), + doc='Output fit parameters table') + + self.declareProperty(WorkspaceGroupProperty('FitWorkspaces', '', + direction=Direction.Output, + optional=PropertyMode.Optional), + doc='Output fitted workspaces') + + + def validateInputs(self): + issues = dict() + tolerance = 1e-10 + + workspace = self.getProperty('InputWorkspace').value + x_data = workspace.readX(0) + + # Validate X axis fitting range + x_min = self.getProperty('XStart').value + x_max = self.getProperty('XEnd').value + + if x_min > x_max: + msg = 'XStart must be less then XEnd' + issues['XStart'] = msg + issues['XEnd'] = msg + + if x_min < x_data[0]: + issues['XStart'] = 'Must be greater than minimum X value in workspace' + + if x_max > x_data[-1]: + issues['XEnd'] = 'Must be less than maximum X value in workspace' + + # Validate specta fitting range + spec_min = self.getProperty('SpecMin').value + spec_max = self.getProperty('SpecMax').value + + if spec_min < 0: + issues['SpecMin'] = 'Minimum spectrum index must be greater than or equal to 0' + + if spec_max > workspace.getNumberHistograms(): + issues['SpecMax'] = 'Maximum spectrum index must be less than number of spectra in workspace' + + if spec_min > spec_max: + msg = 'SpecMin must be less then SpecMax' + issues['SpecMin'] = msg + issues['SpecMax'] = msg + + return issues + + + def PyExec(self): + self._setup() + + # Fit line to each of the spectra + function = 'name=LinearBackground, A0=0, A1=0' + input_params = [self._input_ws + ',i%d' % i for i in xrange( + self._spec_range[0], self._spec_range[1] + 1)] + input_params = ';'.join(input_params) + PlotPeakByLogValue(Input=input_params, OutputWorkspace=self._output_msd_ws, + Function=function, StartX=self._x_range[0], EndX=self._x_range[1], + FitType='Sequential', CreateOutput=True) + + DeleteWorkspace(self._output_msd_ws + '_NormalisedCovarianceMatrices') + DeleteWorkspace(self._output_msd_ws + '_Parameters') + RenameWorkspace(self._output_msd_ws, OutputWorkspace=self._output_param_ws) + + params_table = mtd[self._output_param_ws] + + # MSD value should be positive, but the fit output is negative + msd = params_table.column('A1') + for i, value in enumerate(msd): + params_table.setCell('A1', i, value * -1) + + # Create workspaces for each of the parameters + parameter_ws_group = [] + + # A0 workspace + ws_name = self._output_msd_ws + '_A0' + parameter_ws_group.append(ws_name) + ConvertTableToMatrixWorkspace(self._output_param_ws, OutputWorkspace=ws_name, + ColumnX='axis-1', ColumnY='A0', ColumnE='A0_Err') + xunit = mtd[ws_name].getAxis(0).setUnit('Label') + xunit.setLabel('Temperature', 'K') + + # A1 workspace + ws_name = self._output_msd_ws + '_A1' + parameter_ws_group.append(ws_name) + ConvertTableToMatrixWorkspace(self._output_param_ws, OutputWorkspace=ws_name, + ColumnX='axis-1', ColumnY='A1', ColumnE='A1_Err') + xunit = mtd[ws_name].getAxis(0).setUnit('Label') + xunit.setLabel('Temperature', 'K') + SortXAxis(ws_name, OutputWorkspace=ws_name) + + # Group parameter workspaces + GroupWorkspaces(InputWorkspaces=','.join(parameter_ws_group), + OutputWorkspace=self._output_msd_ws) + + # Rename fit workspace group + original_fit_ws_name = self._output_msd_ws + '_Workspaces' + if original_fit_ws_name != self._output_fit_ws: + RenameWorkspace(InputWorkspace=self._output_msd_ws + '_Workspaces', + OutputWorkspace=self._output_fit_ws) + + # Add sample logs to output workspace + CopyLogs(InputWorkspace=self._input_ws, OutputWorkspace=self._output_msd_ws) + CopyLogs(InputWorkspace=self._output_msd_ws + '_A0', OutputWorkspace=self._output_fit_ws) + + self.setProperty('OutputWorkspace', self._output_msd_ws) + self.setProperty('ParameterWorkspace', self._output_param_ws) + self.setProperty('FitWorkspaces', self._output_fit_ws) + + if self._plot: + self._plot_result() + + + def _setup(self): + """ + Gets algorithm properties. + """ + self._input_ws = self.getPropertyValue('InputWorkspace') + self._output_msd_ws = self.getPropertyValue('OutputWorkspace') + + self._output_param_ws = self.getPropertyValue('ParameterWorkspace') + if self._output_param_ws == '': + self._output_param_ws = self._output_msd_ws + '_Parameters' + + self._output_fit_ws = self.getPropertyValue('FitWorkspaces') + if self._output_fit_ws == '': + self._output_fit_ws = self._output_msd_ws + '_Workspaces' + + self._x_range = [self.getProperty('XStart').value, + self.getProperty('XEnd').value] + + self._spec_range = [self.getProperty('SpecMin').value, + self.getProperty('SpecMax').value] + + self._plot = self.getProperty('Plot').value + + + def _plot_result(self): + """ + Handles plotting result workspaces. + """ + + from IndirectImport import import_mantidplot + mtd_plot = import_mantidplot() + + x_label = '' + ws_run = mtd[self._input_ws].getRun() + if 'vert_axis' in ws_run: + x_label = ws_run.getLogData('vert_axis').value + + result_ws = mtd[self._output_msd_ws + '_A1'] + if len(result_ws.readX(0)) > 1: + msd_plot = mtd_plot.plotSpectrum(result_ws, 0, True) + msd_layer = msd_plot.activeLayer() + msd_layer.setAxisTitle(mtd_plot.Layer.Bottom, x_label) + msd_layer.setAxisTitle(mtd_plot.Layer.Left, '<u2>') + + +AlgorithmFactory.subscribe(MSDFit) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/PoldiCreatePeaksFromFile.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/PoldiCreatePeaksFromFile.py new file mode 100644 index 0000000000000000000000000000000000000000..d68a14bfb2a65c2fcfcb370d2d4a651e66c59eca --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/PoldiCreatePeaksFromFile.py @@ -0,0 +1,217 @@ +# pylint: disable=no-init,invalid-name,too-few-public-methods +from mantid.kernel import * +from mantid.simpleapi import * +from mantid.api import * +from mantid.geometry import * + +from pyparsing import * + +import os + + +class PoldiCompound(object): + """Small helper class to handle the results from PoldiCrystalFileParser.""" + _name = "" + _spacegroup = "" + _atomString = "" + _cellDict = "" + + def __init__(self, name, elements): + self._name = name + + self.assign(elements) + + def assign(self, elements): + for c in elements: + if c[0] == "atoms": + self._atomString = ';'.join(c[1:]) + elif c[0] == "lattice": + cellNames = ['a', 'b', 'c', 'alpha', 'beta', 'gamma'] + self._cellDict = dict(zip(cellNames, c[1:])) + elif c[0] == "spacegroup": + self._spacegroup = c[1] + + def getAtomString(self): + return self._atomString + + def getCellParameters(self): + return self._cellDict + + def getSpaceGroup(self): + return self._spacegroup + + def getName(self): + return self._name + + +def raiseParseErrorException(message): + raise ParseException(message) + + +class PoldiCrystalFileParser(object): + """Small parser for crystal structure files used at POLDI + + This class encapsulates a small parser for crystal structure files that are used at + POLDI. The files contains information about the lattice, the space group and the basis (atoms + in the asymmetric unit). + + The file format is defined as follows: + + Compound_1 { + Lattice: [1 - 6 floats] => a, b, c, alpha, beta, gamma + Spacegroup: [valid space group symbol] + Atoms; { + Element x y z [occupancy [U_eq]] + Element x y z [occupancy [U_eq]] + } + } + + Compound_2 { + ... + } + + The parser returns a list of PoldiCompound objects with the compounds that were found + in the file. These are then processed by PoldiCreatePeaksFromFile to generate arguments + for calling PoldiCreatePeaksFromCell. + """ + elementSymbol = Word(alphas, min=1, max=2).setFailAction( + lambda o, s, loc, token: raiseParseErrorException("Element symbol must be one or two characters.")) + integerNumber = Word(nums) + decimalSeparator = Literal('.') + floatNumber = Combine( + integerNumber + + Optional(decimalSeparator + Optional(integerNumber)) + ) + + whiteSpace = Suppress(White()) + + atomLine = Combine( + elementSymbol + whiteSpace + + delimitedList(floatNumber, delim=White()), + joinString=' ' + ) + + keyValueSeparator = Suppress(Literal(":")) + + groupOpener = Suppress(Literal('{')) + groupCloser = Suppress(Literal('}')) + + atomsGroup = Group(CaselessLiteral("atoms") + keyValueSeparator + + groupOpener + delimitedList(atomLine, delim=lineEnd) + groupCloser) + + unitCell = Group(CaselessLiteral("lattice") + keyValueSeparator + delimitedList( + floatNumber, delim=White())) + + spaceGroup = Group(CaselessLiteral("spacegroup") + keyValueSeparator + Word( + alphanums + "-" + ' ')) + + compoundContent = Each([atomsGroup, unitCell, spaceGroup]).setFailAction( + lambda o, s, loc, token: raiseParseErrorException( + "One of 'Lattice', 'SpaceGroup', 'Atoms' is missing or contains errors.")) + + compoundName = Word(alphanums + '_') + + compound = Group(compoundName + Optional(whiteSpace) + \ + groupOpener + compoundContent + groupCloser) + + comment = Suppress(Literal('#') + restOfLine) + + compounds = Optional(comment) + OneOrMore(compound).ignore(comment) + stringEnd + + def __call__(self, contentString): + parsedContent = None + + if os.path.isfile(contentString): + parsedContent = self._parseFile(contentString) + else: + parsedContent = self._parseString(contentString) + + return [PoldiCompound(x[0], x[1:]) for x in parsedContent] + + def _parseFile(self, filename): + return self.compounds.parseFile(filename) + + def _parseString(self, stringContent): + return self.compounds.parseString(stringContent) + + +class PoldiCreatePeaksFromFile(PythonAlgorithm): + _parser = PoldiCrystalFileParser() + + def category(self): + return "SINQ\\POLDI" + + def name(self): + return "PoldiLoadCrystalData" + + def summary(self): + return ("The algorithm reads a POLDI crystal structure file and creates a WorkspaceGroup that contains tables" + "with the expected reflections.") + + def PyInit(self): + self.declareProperty( + FileProperty(name="InputFile", + defaultValue="", + action=FileAction.Load, + extensions=["dat"]), + doc="A file with POLDI crystal data.") + + self.declareProperty("LatticeSpacingMin", 0.5, + direction=Direction.Input, + doc="Lowest allowed lattice spacing.") + + self.declareProperty("LatticeSpacingMax", 0.0, + direction=Direction.Input, + doc="Largest allowed lattice spacing.") + + self.declareProperty( + WorkspaceProperty(name="OutputWorkspace", + defaultValue="", direction=Direction.Output), + doc="WorkspaceGroup with reflection tables.") + + + def PyExec(self): + crystalFileName = self.getProperty("InputFile").value + try: + # Try parsing the supplied file using PoldiCrystalFileParser + compounds = self._parser(crystalFileName) + + dMin = self.getProperty("LatticeSpacingMin").value + dMax = self.getProperty("LatticeSpacingMax").value + + workspaces = [] + + # Go through found compounds and run "_createPeaksFromCell" for each of them + # If two compounds have the same name, a warning is written to the log. + for compound in compounds: + if compound.getName() in workspaces: + self.log().warning("A compound with the name '" + compound.getName() + \ + "' has already been created. Please check the file '" + crystalFileName + "'") + else: + workspaces.append(self._createPeaksFromCell(compound, dMin, dMax)) + + self.setProperty("OutputWorkspace", GroupWorkspaces(workspaces)) + + # All parse errors are caught here and logged as errors + except ParseException as error: + errorString = "Could not parse input file '" + crystalFileName + "'.\n" + errorString += "The parser reported the following error:\n\t" + str(error) + + self.log().error(errorString) + + + def _createPeaksFromCell(self, compound, dMin, dMax): + if not SpaceGroupFactory.isSubscribedSymbol(compound.getSpaceGroup()): + raise RuntimeError("SpaceGroup '" + compound.getSpaceGroup() + "' is not registered.") + + PoldiCreatePeaksFromCell(SpaceGroup=compound.getSpaceGroup(), + Atoms=compound.getAtomString(), + LatticeSpacingMin=dMin, + LatticeSpacingMax=dMax, + OutputWorkspace=compound.getName(), + **compound.getCellParameters()) + + return compound.getName() + + +AlgorithmFactory.subscribe(PoldiCreatePeaksFromFile) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/Symmetrise.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/Symmetrise.py index 3e5ecae529fc9fee4352b5d6c2646fc931bc0f85..563c56c6ccad12148ef4a99896e8c7f7c4a6ac8d 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/Symmetrise.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/Symmetrise.py @@ -57,9 +57,6 @@ class Symmetrise(PythonAlgorithm): def PyExec(self): - from IndirectCommon import StartTime, EndTime - - StartTime('Symmetrise') self._setup() temp_ws_name = '__symm_temp' @@ -173,8 +170,6 @@ class Symmetrise(PythonAlgorithm): self.setProperty('OutputWorkspace', self._output_workspace) - EndTime('Symmetrise') - def validateInputs(self): """ diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/AddSampleLogMultiple.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/AddSampleLogMultiple.py new file mode 100644 index 0000000000000000000000000000000000000000..d6c099d943327441c319b8f3e6c4a29e7a3010c4 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/AddSampleLogMultiple.py @@ -0,0 +1,87 @@ +#pylint: disable=no-init +from mantid.simpleapi import * +from mantid.kernel import * +from mantid.api import * + + +class AddSampleLogMultiple(PythonAlgorithm): + + def category(self): + return 'DataHandling\\Logs' + + + def summary(self): + return 'Add multiple sample logs to a workspace' + + + def PyInit(self): + self.declareProperty(WorkspaceProperty('Workspace', '', direction=Direction.InOut), + doc='Workspace to add logs to') + + self.declareProperty(StringArrayProperty('LogNames', ''), + doc='Comma separated list of log names') + + self.declareProperty(StringArrayProperty('LogValues', ''), + doc='Comma separated list of log values') + + self.declareProperty('ParseType', True, + doc='Determine the value type by parsing the string') + + + def PyExec(self): + workspace = self.getPropertyValue('Workspace') + log_names = self.getProperty('LogNames').value + log_values = self.getProperty('LogValues').value + parse_type = self.getProperty('ParseType').value + + for idx in range(0, len(log_names)): + # Get the name and value + name = log_names[idx] + value = log_values[idx] + + # Try to get the correct type + value_type = 'String' + if parse_type: + try: + float(value) + value_type = 'Number' + except ValueError: + pass + + # Add the log + alg = AlgorithmManager.create('AddSampleLog') + alg.initialize() + alg.setChild(True) + alg.setLogging(False) + alg.setProperty('Workspace', workspace) + alg.setProperty('LogType', value_type) + alg.setProperty('LogName', name) + alg.setProperty('LogText', value) + alg.execute() + + + def validateInputs(self): + issues = dict() + + log_names = self.getProperty('LogNames').value + log_values = self.getProperty('LogValues').value + + num_names = len(log_names) + num_values = len(log_values) + + # Ensure there is at leats 1 log name + if num_names == 0: + issues['LogNames'] = 'Must have at least one log name' + + # Ensure there is at leats 1 log value + if num_values == 0: + issues['LogValues'] = 'Must have at least one log value' + + if num_names > 0 and num_values > 0 and num_names != num_values: + issues['LogValues'] = 'Number of log values must match number of log names' + + return issues + + +# Register algorithm with Mantid +AlgorithmFactory.subscribe(AddSampleLogMultiple) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ApplyPaalmanPingsCorrection.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ApplyPaalmanPingsCorrection.py new file mode 100644 index 0000000000000000000000000000000000000000..d37d518831a02d8268a2b68529381316ec9b503d --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ApplyPaalmanPingsCorrection.py @@ -0,0 +1,285 @@ +from mantid.simpleapi import * +from mantid.api import PythonAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, WorkspaceGroupProperty, \ + PropertyMode, MatrixWorkspace +from mantid.kernel import Direction, logger + + +class ApplyPaalmanPingsCorrection(PythonAlgorithm): + + _sample_ws_name = None + _corrections_ws_name = None + _use_can = False + _can_ws_name = None + _use_corrections = False + _can_scale_factor = 1.0 + _scale_can = False + _output_ws_name = None + _corrections = None + _scaled_container = None + + + def category(self): + return "Workflow\\MIDAS;PythonAlgorithms" + + + def summary(self): + return "Applies a calculated absorption correction in the Paalman and Pings factor style." + + + def PyInit(self): + self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '', + direction=Direction.Input), + doc='Name for the input Sample workspace.') + + self.declareProperty(WorkspaceGroupProperty('CorrectionsWorkspace', '', + optional=PropertyMode.Optional, direction=Direction.Input), + doc='Name for the input Corrections workspace.') + + self.declareProperty(MatrixWorkspaceProperty('CanWorkspace', '', + optional=PropertyMode.Optional, direction=Direction.Input), + doc='Name for the input Can workspace.') + + self.declareProperty(name='CanScaleFactor', defaultValue=1.0, + doc='Factor to scale the can data') + + self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '', + direction=Direction.Output), + doc='The output corrections workspace.') + + + def PyExec(self): + self._setup() + + if not self._use_corrections: + logger.information('Not using corrections') + if not self._use_can: + logger.information('Not using container') + + # Apply container scale factor if needed + if self._use_can: + if self._scale_can: + # Use temp workspace so we don't modify original data + Scale(InputWorkspace=self._can_ws_name, + OutputWorkspace=self._scaled_container, + Factor=self._can_scale_factor, + Operation='Multiply') + logger.information('Container scaled by %f' % self._can_scale_factor) + else: + CloneWorkspace(InputWorkspace=self._can_ws_name, + OutputWorkspace=self._scaled_container) + + if self._use_corrections: + self._pre_process_corrections() + + if self._use_can: + # Use container factors + self._correct_sample_can() + correction_type = 'sample_and_can_corrections' + else: + # Use sample factor only + self._correct_sample() + correction_type = 'sample_corrections_only' + + else: + # Do simple subtraction + self._subtract() + correction_type = 'can_subtraction' + + # Record the container scale factor + if self._use_can and self._scale_can: + AddSampleLog(Workspace=self._output_ws_name, + LogName='apply_corr_can_scale_factor', + LogType='Number', + LogText=str(self._can_scale_factor)) + + # Record the type of corrections applied + AddSampleLog(Workspace=self._output_ws_name, + LogName='corrections_type', + LogType='String', + LogText=correction_type) + + self.setPropertyValue('OutputWorkspace', self._output_ws_name) + + # Remove temporary workspaces + if self._corrections in mtd: + DeleteWorkspace(self._corrections) + if self._scaled_container in mtd: + DeleteWorkspace(self._scaled_container) + + + def validateInputs(self): + """ + Validate user input. + """ + + self._setup() + issues = dict() + + # Need something to get corrections from + if not (self._use_can or self._use_corrections): + error_msg = 'Must provide either CorrectionsWorkspace or CanWorkspace or both' + issues['CorrectionsWorkspace'] = error_msg + issues['CanWorkspace'] = error_msg + + sample_ws = mtd[self._sample_ws_name] + if isinstance(sample_ws, MatrixWorkspace): + sample_unit_id = sample_ws.getAxis(0).getUnit().unitID() + + # Check sample and container X axis units match + if self._use_can: + can_ws = mtd[self._can_ws_name] + if isinstance(can_ws, MatrixWorkspace): + can_unit_id = can_ws.getAxis(0).getUnit().unitID() + if can_unit_id != sample_unit_id: + issues['CanWorkspace'] = 'X axis unit must match SampleWorkspace' + else: + issues['CanWorkspace'] = 'Must be a MatrixWorkspace' + else: + issues['SampleWorkspace'] = 'Must be a MatrixWorkspace' + + return issues + + + def _setup(self): + """ + Get properties and setup instance variables. + """ + + self._sample_ws_name = self.getPropertyValue('SampleWorkspace') + self._output_ws_name = self.getPropertyValue('OutputWorkspace') + + # Get corrections workspace + self._corrections_ws_name = self.getPropertyValue('CorrectionsWorkspace') + self._use_corrections = self._corrections_ws_name != '' + + # Get container workspace + self._can_ws_name = self.getPropertyValue('CanWorkspace') + self._use_can = self._can_ws_name != '' + + self._can_scale_factor = self.getProperty('CanScaleFactor').value + self._scale_can = self._can_scale_factor != 1.0 + + # This temporary WS is needed because ConvertUnits does not like named WS in a Group + self._corrections = '__converted_corrections' + self._scaled_container = '__scaled_container' + + + def _get_correction_factor_ws_name(self, factor_type): + """ + Gets the full name for a correction factor workspace given the correction type. + + @param factor_type Factory type (ass, acc, acsc, assc) + @return Full name of workspace (None if not found) + """ + + corrections_ws = mtd[self._corrections_ws_name] + + for ws_name in corrections_ws.getNames(): + if factor_type in ws_name: + return ws_name + + return None + + + def _pre_process_corrections(self): + """ + If the sample is not in wavelength then convert the corrections to + whatever units the sample is in. + """ + + instrument = mtd[self._sample_ws_name].getInstrument() + unit_id = mtd[self._sample_ws_name].getAxis(0).getUnit().unitID() + logger.information('x-unit is ' + unit_id) + + factor_types = ['ass'] + if self._use_can: + factor_types.extend(['acc', 'acsc', 'assc']) + + for factor_type in factor_types: + input_name = self._get_correction_factor_ws_name(factor_type) + output_name = self._corrections + '_' + factor_type + + if unit_id != 'Wavelength': + # Configure conversion + if unit_id == 'dSpacing': + emode = 'Elastic' + efixed = 0.0 + elif unit_id == 'DeltaE': + emode = 'Indirect' + efixed = instrument.getNumberParameter('efixed-val')[0] + else: + raise ValueError('Unit %s in sample workspace is not supported' % unit_id) + + # Do conversion + ConvertUnits(InputWorkspace=input_name, + OutputWorkspace=output_name, + Target=unit_id, + EMode=emode, + EFixed=efixed) + + else: + # No need to convert + CloneWorkspace(InputWorkspace=input_name, + OutputWorkspace=output_name) + + # Group the temporary factor workspaces (for easy removal later) + GroupWorkspaces(InputWorkspaces=[self._corrections + '_' + f_type for f_type in factor_types], + OutputWorkspace=self._corrections) + + + def _subtract(self): + """ + Do a simple container subtraction (when no corrections are given). + """ + + logger.information('Using simple container subtraction') + + Minus(LHSWorkspace=self._sample_ws_name, + RHSWorkspace=self._scaled_container, + OutputWorkspace=self._output_ws_name) + + + def _correct_sample(self): + """ + Correct for sample only (when no container is given). + """ + + logger.information('Correcting sample') + + # Ass + Divide(LHSWorkspace=self._sample_ws_name, + RHSWorkspace=self._corrections + '_ass', + OutputWorkspace=self._output_ws_name) + + + def _correct_sample_can(self): + """ + Correct for sample and container. + """ + + logger.information('Correcting sample and container') + corrected_can_ws = '__corrected_can' + + # Acc + Divide(LHSWorkspace=self._scaled_container, + RHSWorkspace=self._corrections + '_acc', + OutputWorkspace=corrected_can_ws) + + # Acsc + Multiply(LHSWorkspace=corrected_can_ws, + RHSWorkspace=self._corrections + '_acsc', + OutputWorkspace=corrected_can_ws) + Minus(LHSWorkspace=self._sample_ws_name, + RHSWorkspace=corrected_can_ws, + OutputWorkspace=self._output_ws_name) + + # Assc + Divide(LHSWorkspace=self._output_ws_name, + RHSWorkspace=self._corrections + '_assc', + OutputWorkspace=self._output_ws_name) + + DeleteWorkspace(corrected_can_ws) + + +# Register algorithm with Mantid +AlgorithmFactory.subscribe(ApplyPaalmanPingsCorrection) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CutMD.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CutMD.py deleted file mode 100644 index 67f6efc025b5731ff14298f1fa3b40b514cc992a..0000000000000000000000000000000000000000 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CutMD.py +++ /dev/null @@ -1,350 +0,0 @@ -#pylint: disable=invalid-name,no-init -from mantid.kernel import * -from mantid.api import * -from mantid.simpleapi import * -import numpy as np -import __builtin__ - -class Projection(object): - u = "u" - v = "v" - w = "w" - -class ProjectionUnit(object): - r = "r" - a = "a" - - -class CutMD(DataProcessorAlgorithm): - - def category(self): - return 'MDAlgorithms' - - def summary(self): - return 'Slices multidimensional workspaces using input projection information and binning limits.' - - def PyInit(self): - self.declareProperty(IMDEventWorkspaceProperty('InputWorkspace', '', direction=Direction.Input), - doc='MDWorkspace to slice') - - self.declareProperty(ITableWorkspaceProperty('Projection', '', direction=Direction.Input, optional = PropertyMode.Optional), doc='Projection') - - self.declareProperty(FloatArrayProperty(name='P1Bin', values=[]), - doc='Projection 1 binning') - - self.declareProperty(FloatArrayProperty(name='P2Bin', values=[]), - doc='Projection 2 binning') - - self.declareProperty(FloatArrayProperty(name='P3Bin', values=[]), - doc='Projection 3 binning') - - self.declareProperty(FloatArrayProperty(name='P4Bin', values=[]), - doc='Projection 4 binning') - - self.declareProperty(IMDWorkspaceProperty('OutputWorkspace', '',\ - direction=Direction.Output), - doc='Output cut workspace') - - self.declareProperty(name="NoPix", defaultValue=False, doc="If False creates a full MDEventWorkspaces as output. True to create an MDHistoWorkspace as output. This is DND only in Horace terminology.") - - self.declareProperty(name="CheckAxes", defaultValue=True, doc="Check that the axis look to be correct, and abort if not.") - - - def __calculate_steps(self, extents, horace_binning ): - # Because the step calculations may involve moving the extents, we re-publish the extents. - out_extents = extents - out_n_bins = list() - for i in range(len(horace_binning)): - - n_arguments = len(horace_binning[i]) - max_extent_index = (i*2) + 1 - min_extent_index = (i*2) - dim_range = extents[ max_extent_index ] - extents[ min_extent_index ] - - if n_arguments == 0: - raise ValueError("binning parameter cannot be empty") - elif n_arguments == 1: - step_size = horace_binning[i][0] - if step_size > dim_range: - step_size = dim_range - n_bins = int( dim_range / step_size) - # Correct the max extent to fit n * step_size - out_extents[max_extent_index] = extents[min_extent_index] + ( n_bins * step_size ) - elif n_arguments == 2: - out_extents[ min_extent_index ] = horace_binning[i][0] - out_extents[ max_extent_index ] = horace_binning[i][1] - n_bins = 1 - elif n_arguments == 3: - dim_min = horace_binning[i][0] - dim_max = horace_binning[i][2] - step_size = horace_binning[i][1] - dim_range = dim_max - dim_min - if step_size > dim_range: - step_size = dim_range - n_bins = int( dim_range / step_size) - # Correct the max extent to fit n * step_size - out_extents[ max_extent_index ] = dim_min + ( n_bins * step_size ) - out_extents[ min_extent_index ] = dim_min - if n_bins < 1: - raise ValueError("Number of bins calculated to be < 1") - out_n_bins.append( n_bins ) - return out_extents, out_n_bins - - def __extents_in_current_projection(self, to_cut, dimension_index): - - dim = to_cut.getDimension(dimension_index) - dim_min = dim.getMinimum() - dim_max = dim.getMaximum() - return (dim_min, dim_max) - - def __calculate_extents(self, u, v, w, limits): - M=np.array([u,v,w]) - Minv=np.linalg.inv(M) - - # unpack limits - Hrange, Krange, Lrange = limits - - # Create a numpy 2D array. Makes finding minimums and maximums for each transformed coordinates over every corner easier. - new_coords = np.empty([8, 3]) - counter = 0 - for h in Hrange: - for k in Krange: - for l in Lrange: - original_corner=np.array([h,k,l]) - new_coords[counter]=np.dot(original_corner, Minv) - counter += 1 - - # Get the min max extents - extents = list() - for i in range(0,3): - # Vertical slice down each corner for each dimension, then determine the max, min and use as extents - extents.append(np.amin(new_coords[:,i])) - extents.append(np.amax(new_coords[:,i])) - - return extents - - def __uvw_from_projection_table(self, projection_table): - if not isinstance(projection_table, ITableWorkspace): - I = np.identity(3) - return (I[0, :], I[1, :], I[2, :]) - (u, v, w) = (None, None, None) - for i in range(projection_table.rowCount()): - name = str(projection_table.cell("name", i)) - value = str(projection_table.cell("value", i)) - if name == "u": - u = np.array(map(float,value.split(","))) - if name == "v": - v = np.array(map(float,value.split(","))) - if name == "w": - w = np.array(map(float,value.split(","))) - - if u is None or v is None or w is None: - raise ValueError("u, v, or w missing from projection table") - - return (u, v, w) - - def __units_from_projection_table(self, projection_table): - if not isinstance(projection_table, ITableWorkspace) or not "type" in projection_table.getColumnNames(): - units = (ProjectionUnit.r, ProjectionUnit.r, ProjectionUnit.r) - else: - #Extract units for each dimension - (u, v, w) = (None, None, None) - for i in range(projection_table.rowCount()): - name = str(projection_table.cell("name", i)) - unit = str(projection_table.cell("type", i)) - if name == "u": - u = unit - if name == "v": - v = unit - if name == "w": - w = unit - if u is None or v is None or w is None: - raise ValueError("u, v, or w missing from projection table") - units = (u, v, w) - return units - - - def __make_labels(self, projection): - - class Mapping: - - def __init__(self, replace): - self.__replace = replace - - def replace(self, entry): - if np.absolute(entry) == 1: - if entry > 0: - return self.__replace - else: - return "-" + self.__replace - elif entry == 0: - return 0 - else: - return "%.2f%s" % ( entry, self.__replace ) - return entry - - crystallographic_names = ['zeta', 'eta', 'xi' ] - labels = list() - for i in range(len(projection)): - cmapping = Mapping(crystallographic_names[i]) - labels.append( [cmapping.replace(x) for x in projection[i] ] ) - - return labels - - def __verify_projection_input(self, projection_table): - if isinstance(projection_table, ITableWorkspace): - column_names = set(projection_table.getColumnNames()) - if column_names != set(["name", "value", "type", "offset"]): - raise ValueError("Projection table schema is wrong! Column names received: " + str(column_names) ) - if projection_table.rowCount() < 2: - raise ValueError("Projection table expects at least 2 rows") - elif projection_table is not None: - print(help(projection_table)) - raise ValueError("Projection should be either an ITableWorkspace or None. It's a: " + str(type(projection_table))) - - def __scale_projection(self, (u, v, w), origin_units, target_units, to_cut): - - if set(origin_units) == set(target_units): - return (u,v,w) # Nothing to do. - - ol = to_cut.getExperimentInfo(0).sample().getOrientedLattice() - - projection_scaled = [u, v, w] - - to_from_pairs = zip(origin_units, target_units) - for i in range(len(to_from_pairs)) : - - proj = projection_scaled[i] - d_star = 2 * np.pi * ol.dstar( float(proj[0]), float(proj[1]), float(proj[2]) ) - - from_unit, to_unit = to_from_pairs[i] - if from_unit == to_unit: - continue - elif from_unit == ProjectionUnit.a: # From inverse Angstroms to rlu - projection_scaled[i] *= d_star - else: # From rlu to inverse Anstroms - projection_scaled[i] /= d_star - return projection_scaled - - - def PyExec(self): - - logger.warning('You are running algorithm %s that is the beta stage of development' % (self.name())) - - to_cut = self.getProperty("InputWorkspace").value - - ndims = to_cut.getNumDims() - - nopix = self.getProperty("NoPix").value - - projection_table = self.getProperty("Projection").value - self.__verify_projection_input(projection_table) - - p1_bins = self.getProperty("P1Bin").value - p2_bins = self.getProperty("P2Bin").value - p3_bins = self.getProperty("P3Bin").value - p4_bins_property = self.getProperty("P4Bin") - p4_bins = p4_bins_property.value - - x_extents = self.__extents_in_current_projection(to_cut, 0) - y_extents = self.__extents_in_current_projection(to_cut, 1) - z_extents = self.__extents_in_current_projection(to_cut, 2) - - projection = self.__uvw_from_projection_table(projection_table) - target_units = self.__units_from_projection_table(projection_table) - origin_units = (ProjectionUnit.r, ProjectionUnit.r, ProjectionUnit.r) # TODO. This is a hack! - - u,v,w = self.__scale_projection(projection, origin_units, target_units, to_cut) - - extents = self.__calculate_extents(u, v, w, ( x_extents, y_extents, z_extents ) ) - extents, bins = self.__calculate_steps( extents, ( p1_bins, p2_bins, p3_bins ) ) - - if not p4_bins_property.isDefault: - if ndims == 4: - n_args = len(p4_bins) - min, max = self.__extents_in_current_projection(to_cut, 3) - d_range = max - min - if n_args == 1: - step_size = p4_bins[0] - nbins = d_range / step_size - elif n_args == 2: - min = p4_bins[0] - max = p4_bins[1] - nbins = 1 - elif n_args == 3: - min = p4_bins[0] - max = p4_bins[2] - step_size = p4_bins[1] - dim_range = max - min - if step_size > dim_range: - step_size = dim_range - nbins = int( dim_range / step_size) - - extents.append(min) - extents.append(max) - bins.append(int(nbins)) - - e_units = to_cut.getDimension(3).getUnits() - - temp = list(target_units) - temp.append(target_units) - target_units = tuple(temp) - else: - raise ValueError("Cannot specify P4Bins unless the workspace is of sufficient dimensions") - - projection_labels = self.__make_labels(projection) - - cut_alg_name = "BinMD" if nopix else "SliceMD" - ''' - Actually perform the binning operation - ''' - cut_alg = self.createChildAlgorithm(name=cut_alg_name, startProgress=0, endProgress=1.0) - cut_alg.initialize() - cut_alg.setProperty("InputWorkspace", to_cut) - cut_alg.setPropertyValue("OutputWorkspace", "sliced") - cut_alg.setProperty("NormalizeBasisVectors", False) - cut_alg.setProperty("AxisAligned", False) - # Now for the basis vectors. - - n_padding = __builtin__.max(0, ndims-3) - - for i in range(0, ndims): - - - if i <= 2: - - label = projection_labels[i] - unit = target_units[i] - vec = list(projection[i]) + ( [0] * n_padding ) - - # These are always orthogonal to the rest. - else: - orthogonal_dimension = to_cut.getDimension(i) - label = orthogonal_dimension.getName() - unit = orthogonal_dimension.getUnits() - vec = [0] * ndims - vec[i] = 1 - - value = "%s, %s, %s" % ( label, unit, ",".join(map(str, vec))) - cut_alg.setPropertyValue("BasisVector{0}".format(i) , value) - - - cut_alg.setProperty("OutputExtents", extents) - cut_alg.setProperty("OutputBins", bins) - - cut_alg.execute() - - slice = cut_alg.getProperty("OutputWorkspace").value - - - # Attach the w-matrix (projection matrix) - if slice.getNumExperimentInfo() > 0: - u, v, w = projection - w_matrix = np.array([u, v, w]).flatten().tolist() - info = slice.getExperimentInfo(0) - info.run().addProperty("W_MATRIX", w_matrix, True) - - self.setProperty("OutputWorkspace", slice) - - -AlgorithmFactory.subscribe(CutMD) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DensityOfStates.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DensityOfStates.py index 8682789f49402327f89c3c10e39d3b903d97bd1c..3722e26c75cdf9525ff876ccc9e2261c239d5b89 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DensityOfStates.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DensityOfStates.py @@ -28,9 +28,15 @@ class DensityOfStates(PythonAlgorithm): _num_ions = None _num_branches = None + + def category(self): + return "Simulation" + + def summary(self): return "Calculates phonon densities of states, Raman and IR spectrum." + def PyInit(self): # Declare properties self.declareProperty(FileProperty('File', '', action=FileAction.Load,\ diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/FlatPlatePaalmanPingsCorrection.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/FlatPlatePaalmanPingsCorrection.py index c89f003cba7a127aba7b6ba1988a81169cc5e7d9..16f1f8d550a2410b3d471ae0d015d2023b5b967d 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/FlatPlatePaalmanPingsCorrection.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/FlatPlatePaalmanPingsCorrection.py @@ -1,9 +1,9 @@ #pylint: disable=no-init,invalid-name from mantid.simpleapi import * from mantid.api import PythonAlgorithm, AlgorithmFactory, PropertyMode, MatrixWorkspaceProperty, \ - WorkspaceGroupProperty + WorkspaceGroupProperty, InstrumentValidator, WorkspaceUnitValidator from mantid.kernel import StringListValidator, StringMandatoryValidator, IntBoundedValidator, \ - FloatBoundedValidator, Direction, logger + FloatBoundedValidator, Direction, logger, CompositeValidator import math, numpy as np @@ -20,7 +20,6 @@ class FlatPlatePaalmanPingsCorrection(PythonAlgorithm): _can_number_density = None _can_front_thickness = None _can_back_thickness = None - _can_scale = 1.0 _number_wavelengths = 10 _emode = None _efixed = 0.0 @@ -39,8 +38,11 @@ class FlatPlatePaalmanPingsCorrection(PythonAlgorithm): def PyInit(self): + ws_validator = CompositeValidator([WorkspaceUnitValidator('Wavelength'), InstrumentValidator()]) + self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '', - direction=Direction.Input), + direction=Direction.Input, + validator=ws_validator), doc='Name for the input sample workspace') self.declareProperty(name='SampleChemicalFormula', defaultValue='', @@ -57,7 +59,8 @@ class FlatPlatePaalmanPingsCorrection(PythonAlgorithm): self.declareProperty(MatrixWorkspaceProperty('CanWorkspace', '', direction=Direction.Input, - optional=PropertyMode.Optional), + optional=PropertyMode.Optional, + validator=ws_validator), doc="Name for the input container workspace") self.declareProperty(name='CanChemicalFormula', defaultValue='', @@ -73,12 +76,12 @@ class FlatPlatePaalmanPingsCorrection(PythonAlgorithm): validator=FloatBoundedValidator(0.0), doc='Container back thickness in cm') - self.declareProperty(name='CanScaleFactor', defaultValue=1.0, - doc='Scale factor to multiply can data') - self.declareProperty(name='NumberWavelengths', defaultValue=10, validator=IntBoundedValidator(1), doc='Number of wavelengths for calculation') + self.declareProperty(name='Interpolate', defaultValue=True, + doc='Interpolate the correction workspaces to match the sample workspace') + self.declareProperty(name='Emode', defaultValue='Elastic', validator=StringListValidator(['Elastic', 'Indirect']), doc='Emode: Elastic or Indirect') @@ -174,6 +177,14 @@ class FlatPlatePaalmanPingsCorrection(PythonAlgorithm): self._add_sample_logs(acc_ws, sample_logs) AddSampleLog(Workspace=acc_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws_name)) + if self._interpolate: + self._interpolate_corrections(workspaces) + + try: + self. _copy_detector_table(workspaces) + except RuntimeError: + logger.warning('Cannot copy spectra mapping. Check input workspace instrument.') + GroupWorkspaces(InputWorkspaces=','.join(workspaces), OutputWorkspace=self._output_ws_name) self.setPropertyValue('OutputWorkspace', self._output_ws_name) @@ -192,11 +203,13 @@ class FlatPlatePaalmanPingsCorrection(PythonAlgorithm): self._can_number_density = self.getProperty('CanNumberDensity').value self._can_front_thickness = self.getProperty('CanFrontThickness').value self._can_back_thickness = self.getProperty('CanBackThickness').value - self._can_scale = self.getProperty('CanScaleFactor').value self._number_wavelengths = self.getProperty('NumberWavelengths').value + self._interpolate = self.getProperty('Interpolate').value + self._emode = self.getPropertyValue('Emode') self._efixed = self.getProperty('Efixed').value + self._output_ws_name = self.getPropertyValue('OutputWorkspace') @@ -234,6 +247,39 @@ class FlatPlatePaalmanPingsCorrection(PythonAlgorithm): DeleteWorkspace(wave_range) + def _interpolate_corrections(self, workspaces): + """ + Performs interpolation on the correction workspaces such that the number of bins + matches that of the input sample workspace. + + @param workspaces List of correction workspaces to interpolate + """ + + for ws in workspaces: + SplineInterpolation(WorkspaceToMatch=self._sample_ws_name, + WorkspaceToInterpolate=ws, + OutputWorkspace=ws, + OutputWorkspaceDeriv='') + + + def _copy_detector_table(self, workspaces): + """ + Copy the detector table from the sample workspaces to the correction workspaces. + + @param workspaces List of correction workspaces + """ + + instrument = mtd[self._sample_ws_name].getInstrument().getName() + + for ws in workspaces: + LoadInstrument(Workspace=ws, + InstrumentName=instrument) + + CopyDetectorMapping(WorkspaceToMatch=self._sample_ws_name, + WorkspaceToRemap=ws, + IndexBySpectrumNumber=True) + + def _add_sample_logs(self, ws, sample_logs): """ Add a dictionary of logs to a workspace. diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py new file mode 100644 index 0000000000000000000000000000000000000000..3d9a00cb0c2a169811392736af249204e19b8e31 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py @@ -0,0 +1,283 @@ +from mantid.simpleapi import * +from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, PropertyMode, Progress, WorkspaceGroupProperty +from mantid.kernel import StringMandatoryValidator, Direction, logger, IntBoundedValidator, FloatBoundedValidator + + +class IndirectAnnulusAbsorption(DataProcessorAlgorithm): + + def category(self): + return "Workflow\\Inelastic;PythonAlgorithms;CorrectionFunctions\\AbsorptionCorrections;Workflow\\MIDAS" + + + def summary(self): + return "Calculates indirect absorption corrections for an annulus sample shape." + + + def PyInit(self): + # Sample options + self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '', direction=Direction.Input), + doc='Sample workspace.') + + self.declareProperty(name='SampleChemicalFormula', defaultValue='', + validator=StringMandatoryValidator(), + doc='Chemical formula for the sample') + self.declareProperty(name='SampleNumberDensity', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Sample number density') + self.declareProperty(name='SampleInnerRadius', defaultValue=0.2, + validator=FloatBoundedValidator(0.0), + doc='Sample radius') + self.declareProperty(name='SampleOuterRadius', defaultValue=0.25, + validator=FloatBoundedValidator(0.0), + doc='Sample radius') + + # Container options + self.declareProperty(MatrixWorkspaceProperty('CanWorkspace', '', optional=PropertyMode.Optional, + direction=Direction.Input), + doc='Container workspace.') + self.declareProperty(name='UseCanCorrections', defaultValue=False, + doc='Use can corrections in subtraction') + self.declareProperty(name='CanChemicalFormula', defaultValue='', + doc='Chemical formula for the can') + self.declareProperty(name='CanNumberDensity', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Can number density') + self.declareProperty(name='CanInnerRadius', defaultValue=0.19, + validator=FloatBoundedValidator(0.0), + doc='Sample radius') + self.declareProperty(name='CanOuterRadius', defaultValue=0.26, + validator=FloatBoundedValidator(0.0), + doc='Sample radius') + self.declareProperty(name='CanScaleFactor', defaultValue=1.0, + validator=FloatBoundedValidator(0.0), + doc='Scale factor to multiply can data') + + # General options + self.declareProperty(name='Events', defaultValue=5000, + validator=IntBoundedValidator(0), + doc='Number of neutron events') + self.declareProperty(name='Plot', defaultValue=False, + doc='Plot options') + + # Output options + self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '', direction=Direction.Output), + doc='The output corrected workspace.') + + self.declareProperty(WorkspaceGroupProperty('CorrectionsWorkspace', '', direction=Direction.Output, + optional=PropertyMode.Optional), + doc='The corrections workspace for scattering and absorptions in sample.') + + + def PyExec(self): + from IndirectCommon import getEfixed + + self._setup() + + # Set up progress reporting + n_prog_reports = 2 + if self._can_ws_name is not None: + n_prog_reports += 1 + prog = Progress(self, 0.0, 1.0, n_prog_reports) + + efixed = getEfixed(self._sample_ws_name) + + sample_wave_ws = '__sam_wave' + ConvertUnits(InputWorkspace=self._sample_ws_name, OutputWorkspace=sample_wave_ws, + Target='Wavelength', EMode='Indirect', EFixed=efixed) + + sample_thickness = self._sample_outer_radius - self._sample_inner_radius + logger.information('Sample thickness: ' + str(sample_thickness)) + + prog.report('Calculating sample corrections') + AnnularRingAbsorption(InputWorkspace=sample_wave_ws, + OutputWorkspace=self._ass_ws, + SampleHeight=3.0, + SampleThickness=sample_thickness, + CanInnerRadius=self._can_inner_radius, + CanOuterRadius=self._can_outer_radius, + SampleChemicalFormula=self._sample_chemical_formula, + SampleNumberDensity=self._sample_number_density, + NumberOfWavelengthPoints=10, + EventsPerPoint=self._events) + + plot_data = [self._output_ws, self._sample_ws_name] + plot_corr = [self._ass_ws] + group = self._ass_ws + + if self._can_ws_name is not None: + can1_wave_ws = '__can1_wave' + can2_wave_ws = '__can2_wave' + ConvertUnits(InputWorkspace=self._can_ws_name, OutputWorkspace=can1_wave_ws, + Target='Wavelength', EMode='Indirect', EFixed=efixed) + if self._can_scale != 1.0: + logger.information('Scaling can by: ' + str(self._can_scale)) + Scale(InputWorkspace=can1_wave_ws, OutputWorkspace=can1_wave_ws, Factor=self._can_scale, Operation='Multiply') + CloneWorkspace(InputWorkspace=can1_wave_ws, OutputWorkspace=can2_wave_ws) + + can_thickness_1 = self._sample_inner_radius - self._can_inner_radius + can_thickness_2 = self._can_outer_radius - self._sample_outer_radius + logger.information('Can thickness: %f & %f' % (can_thickness_1, can_thickness_2)) + + if self._use_can_corrections: + prog.report('Calculating container corrections') + Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) + + SetSampleMaterial(can1_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_number_density) + AnnularRingAbsorption(InputWorkspace=can1_wave_ws, + OutputWorkspace='__Acc1', + SampleHeight=3.0, + SampleThickness=can_thickness_1, + CanInnerRadius=self._can_inner_radius, + CanOuterRadius=self._sample_outer_radius, + SampleChemicalFormula=self._can_chemical_formula, + SampleNumberDensity=self._can_number_density, + NumberOfWavelengthPoints=10, + EventsPerPoint=self._events) + + SetSampleMaterial(can2_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_number_density) + AnnularRingAbsorption(InputWorkspace=can2_wave_ws, + OutputWorkspace='__Acc2', + SampleHeight=3.0, + SampleThickness=can_thickness_2, + CanInnerRadius=self._sample_inner_radius, + CanOuterRadius=self._can_outer_radius, + SampleChemicalFormula=self._can_chemical_formula, + SampleNumberDensity=self._can_number_density, + NumberOfWavelengthPoints=10, + EventsPerPoint=self._events) + + Multiply(LHSWorkspace='__Acc1', RHSWorkspace='__Acc2', OutputWorkspace=self._acc_ws) + DeleteWorkspace('__Acc1') + DeleteWorkspace('__Acc2') + + Divide(LHSWorkspace=can1_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can1_wave_ws) + Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can1_wave_ws, OutputWorkspace=sample_wave_ws) + plot_corr.append(self._acc_ws) + group += ',' + self._acc_ws + + else: + prog.report('Calculating can scaling') + Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can1_wave_ws, OutputWorkspace=sample_wave_ws) + Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) + + DeleteWorkspace(can1_wave_ws) + DeleteWorkspace(can2_wave_ws) + plot_data.append(self._can_ws_name) + + else: + Divide(LHSWorkspace=sample_wave_ws, + RHSWorkspace=self._ass_ws, + OutputWorkspace=sample_wave_ws) + + ConvertUnits(InputWorkspace=sample_wave_ws, + OutputWorkspace=self._output_ws, + Target='DeltaE', + EMode='Indirect', + EFixed=efixed) + DeleteWorkspace(sample_wave_ws) + + prog.report('Recording sample logs') + sample_log_workspaces = [self._output_ws, self._ass_ws] + sample_logs = [('sample_shape', 'annulus'), + ('sample_filename', self._sample_ws_name), + ('sample_inner', self._sample_inner_radius), + ('sample_outer', self._sample_outer_radius), + ('can_inner', self._can_inner_radius), + ('can_outer', self._can_outer_radius)] + + if self._can_ws_name is not None: + sample_logs.append(('can_filename', self._can_ws_name)) + sample_logs.append(('can_scale', self._can_scale)) + if self._use_can_corrections: + sample_log_workspaces.append(self._acc_ws) + sample_logs.append(('can_thickness_1', can_thickness_1)) + sample_logs.append(('can_thickness_2', can_thickness_2)) + + log_names = [item[0] for item in sample_logs] + log_values = [item[1] for item in sample_logs] + + for ws_name in sample_log_workspaces: + AddSampleLogMultiple(Workspace=ws_name, LogNames=log_names, LogValues=log_values) + + self.setProperty('OutputWorkspace', self._output_ws) + + # Output the Ass workspace if it is wanted, delete if not + if self._abs_ws == '': + DeleteWorkspace(self._ass_ws) + if self._can_ws_name is not None and self._use_can_corrections: + DeleteWorkspace(self._acc_ws) + else: + GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._abs_ws) + self.setProperty('CorrectionsWorkspace', self._abs_ws) + + if self._plot: + from IndirectImport import import_mantidplot + mantid_plot = import_mantidplot() + mantid_plot.plotSpectrum(plot_data, 0) + if self._abs_ws != '': + mantid_plot.plotSpectrum(plot_corr, 0) + + + def _setup(self): + """ + Get algorithm properties. + """ + + self._sample_ws_name = self.getPropertyValue('SampleWorkspace') + self._sample_chemical_formula = self.getPropertyValue('SampleChemicalFormula') + self._sample_number_density = self.getProperty('SampleNumberDensity').value + self._sample_inner_radius = self.getProperty('SampleInnerRadius').value + self._sample_outer_radius = self.getProperty('SampleOuterRadius').value + + self._can_ws_name = self.getPropertyValue('CanWorkspace') + if self._can_ws_name == '': + self._can_ws_name = None + self._use_can_corrections = self.getProperty('UseCanCorrections').value + self._can_chemical_formula = self.getPropertyValue('CanChemicalFormula') + self._can_number_density = self.getProperty('CanNumberDensity').value + self._can_inner_radius = self.getProperty('CanInnerRadius').value + self._can_outer_radius = self.getProperty('CanOuterRadius').value + self._can_scale = self.getProperty('CanScaleFactor').value + + self._events = self.getProperty('Events').value + self._plot = self.getProperty('Plot').value + self._output_ws = self.getPropertyValue('OutputWorkspace') + + self._abs_ws = self.getPropertyValue('CorrectionsWorkspace') + if self._abs_ws == '': + self._ass_ws = '__ass' + self._acc_ws = '__acc' + else: + self._ass_ws = self._abs_ws + '_ass' + self._acc_ws = self._abs_ws + '_acc' + + + def validateInputs(self): + """ + Validate algorithm options. + """ + + self._setup() + issues = dict() + + if self._use_can_corrections and self._can_chemical_formula == '': + issues['CanChemicalFormula'] = 'Must be set to use can corrections' + + if self._use_can_corrections and self._can_ws_name is None: + issues['UseCanCorrections'] = 'Must specify a can workspace to use can corections' + + # Geometry validation: can inner < sample inner < sample outer < can outer + if self._sample_inner_radius < self._can_inner_radius: + issues['SampleInnerRadius'] = 'Must be greater than CanInnerRadius' + + if self._sample_outer_radius < self._sample_inner_radius: + issues['SampleOuterRadius'] = 'Must be greater than SampleInnerRadius' + + if self._can_outer_radius < self._sample_outer_radius: + issues['CanOuterRadius'] = 'Must be greater than SampleOuterRadius' + + return issues + + +# Register algorithm with Mantid +AlgorithmFactory.subscribe(IndirectAnnulusAbsorption) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CreateCalibrationWorkspace.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCalibration.py similarity index 95% rename from Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CreateCalibrationWorkspace.py rename to Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCalibration.py index e3754e3433b851786fcb3c7d438dee8b740d3d44..316d12877b0f512c79da826ec4437c7e67c8c642 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CreateCalibrationWorkspace.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCalibration.py @@ -6,7 +6,7 @@ from mantid.simpleapi import * import os.path -class CreateCalibrationWorkspace(DataProcessorAlgorithm): +class IndirectCalibration(DataProcessorAlgorithm): _input_files = None _out_ws = None @@ -16,12 +16,15 @@ class CreateCalibrationWorkspace(DataProcessorAlgorithm): _intensity_scale = None _plot = None + def category(self): return 'Workflow\\Inelastic;PythonAlgorithms;Inelastic' + def summary(self): return 'Creates a calibration workspace from a White-Beam Vanadium run.' + def PyInit(self): self.declareProperty(StringArrayProperty(name='InputFiles'), doc='Comma separated list of input files') @@ -47,6 +50,7 @@ class CreateCalibrationWorkspace(DataProcessorAlgorithm): self.declareProperty(name='Plot', defaultValue=False, doc='Plot the calibration data') + def validateInputs(self): """ Validates input ranges. @@ -59,6 +63,7 @@ class CreateCalibrationWorkspace(DataProcessorAlgorithm): return issues + def _validate_range(self, property_name): """ Validates a range property. @@ -76,12 +81,11 @@ class CreateCalibrationWorkspace(DataProcessorAlgorithm): return None + def PyExec(self): from mantid import logger - from IndirectCommon import StartTime, EndTime self._setup() - StartTime('CreateCalibrationWorkspace') runs = [] for in_file in self._input_files: @@ -122,7 +126,6 @@ class CreateCalibrationWorkspace(DataProcessorAlgorithm): self.setProperty('OutputWorkspace', self._out_ws) self._post_process() - EndTime('CreateCalibrationWorkspace') def _setup(self): """ @@ -142,6 +145,7 @@ class CreateCalibrationWorkspace(DataProcessorAlgorithm): self._plot = self.getProperty('Plot').value + def _post_process(self): """ Handles adding logs and plotting. @@ -159,5 +163,6 @@ class CreateCalibrationWorkspace(DataProcessorAlgorithm): from mantidplot import plotBin plotBin(mtd[self._out_ws], 0) + # Register algorithm with Mantid -AlgorithmFactory.subscribe(CreateCalibrationWorkspace) +AlgorithmFactory.subscribe(IndirectCalibration) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py new file mode 100644 index 0000000000000000000000000000000000000000..c413199a8992d57da7448efda74f8bbfb64de575 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py @@ -0,0 +1,258 @@ +from mantid.simpleapi import * +from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, WorkspaceGroupProperty, PropertyMode, Progress +from mantid.kernel import StringMandatoryValidator, Direction, logger, FloatBoundedValidator, IntBoundedValidator + + +class IndirectCylinderAbsorption(DataProcessorAlgorithm): + + _sample_ws_name = None + _sample_chemical_formula = None + _sample_number_density = None + _sample_radius = None + _can_ws_name = None + _use_can_corrections = None + _can_chemical_formula = None + _can_number_density = None + _can_radius = None + _can_scale = None + _events = None + _plot = None + _output_ws = None + _abs_ws = None + _ass_ws = None + _acc_ws = None + + + def category(self): + return "Workflow\\Inelastic;PythonAlgorithms;CorrectionFunctions\\AbsorptionCorrections;Workflow\\MIDAS" + + + def summary(self): + return "Calculates indirect absorption corrections for a cylinder sample shape." + + + def PyInit(self): + # Sample options + self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '', direction=Direction.Input), + doc='Sample workspace.') + self.declareProperty(name='SampleChemicalFormula', defaultValue='', validator=StringMandatoryValidator(), + doc='Sample chemical formula') + self.declareProperty(name='SampleNumberDensity', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Sample number density') + self.declareProperty(name='SampleRadius', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Sample radius') + + # Container options + self.declareProperty(MatrixWorkspaceProperty('CanWorkspace', '', optional=PropertyMode.Optional, + direction=Direction.Input), + doc='Container workspace.') + self.declareProperty(name='UseCanCorrections', defaultValue=False, + doc='Use can corrections in subtraction') + self.declareProperty(name='CanChemicalFormula', defaultValue='', + doc='Can chemical formula') + self.declareProperty(name='CanNumberDensity', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Can number density') + self.declareProperty(name='CanRadius', defaultValue=0.2, + validator=FloatBoundedValidator(0.0), + doc='Can radius') + self.declareProperty(name='CanScaleFactor', defaultValue=1.0, + validator=FloatBoundedValidator(0.0), + doc='Scale factor to multiply can data') + + # General options + self.declareProperty(name='Events', defaultValue=5000, + validator=IntBoundedValidator(0), + doc='Number of neutron events') + self.declareProperty(name='Plot', defaultValue=False, + doc='Plot options') + + # Output options + self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '', direction=Direction.Output), + doc='The output corrected workspace.') + + self.declareProperty(WorkspaceGroupProperty('CorrectionsWorkspace', '', direction=Direction.Output, + optional=PropertyMode.Optional), + doc='The corrections workspace for scattering and absorptions in sample.') + + + def PyExec(self): + from IndirectCommon import getEfixed + + self._setup() + + # Set up progress reporting + n_prog_reports = 2 + if self._can_ws_name is not None: + n_prog_reports += 1 + prog = Progress(self, 0.0, 1.0, n_prog_reports) + + efixed = getEfixed(self._sample_ws_name) + + sample_wave_ws = '__sam_wave' + ConvertUnits(InputWorkspace=self._sample_ws_name, OutputWorkspace=sample_wave_ws, + Target='Wavelength', EMode='Indirect', EFixed=efixed) + + SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_number_density) + + prog.report('Calculating sample corrections') + CylinderAbsorption(InputWorkspace=sample_wave_ws, + OutputWorkspace=self._ass_ws, + SampleNumberDensity=self._sample_number_density, + NumberOfWavelengthPoints=10, + CylinderSampleHeight=3.0, + CylinderSampleRadius=self._sample_radius, + NumberOfSlices=1, + NumberOfAnnuli=10) + + plot_data = [self._output_ws, self._sample_ws_name] + plot_corr = [self._ass_ws] + group = self._ass_ws + + if self._can_ws_name is not None: + can_wave_ws = '__can_wave' + ConvertUnits(InputWorkspace=self._can_ws_name, OutputWorkspace=can_wave_ws, + Target='Wavelength', EMode='Indirect', EFixed=efixed) + if self._can_scale != 1.0: + logger.information('Scaling can by: ' + str(self._can_scale)) + Scale(InputWorkspace=can_wave_ws, OutputWorkspace=can_wave_ws, Factor=self._can_scale, Operation='Multiply') + + can_thickness = self._can_radius - self._sample_radius + logger.information('Can thickness: ' + str(can_thickness)) + + if self._use_can_corrections: + # Doing can corrections + prog.report('Calculating can corrections') + Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) + + SetSampleMaterial(can_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_number_density) + AnnularRingAbsorption(InputWorkspace=can_wave_ws, + OutputWorkspace=self._acc_ws, + SampleHeight=3.0, + SampleThickness=can_thickness, + CanInnerRadius=0.9*self._sample_radius, + CanOuterRadius=1.1*self._can_radius, + SampleChemicalFormula=self._can_chemical_formula, + SampleNumberDensity=self._can_number_density, + NumberOfWavelengthPoints=10, + EventsPerPoint=self._events) + + Divide(LHSWorkspace=can_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can_wave_ws) + Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) + plot_corr.append(self._acc_ws) + group += ',' + self._acc_ws + + else: + # Doing simple can subtraction + prog.report('Calculating can scaling') + Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) + Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) + + DeleteWorkspace(can_wave_ws) + plot_data.append(self._can_ws_name) + + else: + Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) + + ConvertUnits(InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws, + Target='DeltaE', EMode='Indirect', EFixed=efixed) + DeleteWorkspace(sample_wave_ws) + + # Record sample logs + prog.report('Recording sample logs') + sample_log_workspaces = [self._output_ws, self._ass_ws] + sample_logs = [('sample_shape', 'cylinder'), + ('sample_filename', self._sample_ws_name), + ('sample_radius', self._sample_radius)] + + if self._can_ws_name is not None: + sample_logs.append(('can_filename', self._can_ws_name)) + sample_logs.append(('can_scale', self._can_scale)) + if self._use_can_corrections: + sample_log_workspaces.append(self._acc_ws) + sample_logs.append(('can_thickness', can_thickness)) + + log_names = [item[0] for item in sample_logs] + log_values = [item[1] for item in sample_logs] + + for ws_name in sample_log_workspaces: + AddSampleLogMultiple(Workspace=ws_name, LogNames=log_names, LogValues=log_values) + + self.setProperty('OutputWorkspace', self._output_ws) + + # Output the Abs group workspace if it is wanted, delete if not + if self._abs_ws == '': + DeleteWorkspace(self._ass_ws) + if self._can_ws_name is not None and self._use_can_corrections: + DeleteWorkspace(self._acc_ws) + + else: + GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._abs_ws) + self.setProperty('CorrectionsWorkspace', self._abs_ws) + + if self._plot: + from IndirectImport import import_mantidplot + mantid_plot = import_mantidplot() + mantid_plot.plotSpectrum(plot_data, 0) + if self._abs_ws != '': + mantid_plot.plotSpectrum(plot_corr, 0) + + + def _setup(self): + """ + Get algorithm properties. + """ + + self._sample_ws_name = self.getPropertyValue('SampleWorkspace') + self._sample_chemical_formula = self.getPropertyValue('SampleChemicalFormula') + self._sample_number_density = self.getProperty('SampleNumberDensity').value + self._sample_radius = self.getProperty('SampleRadius').value + + self._can_ws_name = self.getPropertyValue('CanWorkspace') + if self._can_ws_name == '': + self._can_ws_name = None + + self._use_can_corrections = self.getProperty('UseCanCorrections').value + self._can_chemical_formula = self.getPropertyValue('CanChemicalFormula') + self._can_number_density = self.getProperty('CanNumberDensity').value + self._can_radius = self.getProperty('CanRadius').value + self._can_scale = self.getProperty('CanScaleFactor').value + + self._events = self.getPropertyValue('Events') + self._plot = self.getProperty('Plot').value + + self._output_ws = self.getPropertyValue('OutputWorkspace') + + self._abs_ws = self.getPropertyValue('CorrectionsWorkspace') + if self._abs_ws == '': + self._ass_ws = '__ass' + self._acc_ws = '__acc' + else: + self._ass_ws = self._abs_ws + '_ass' + self._acc_ws = self._abs_ws + '_acc' + + + def validateInputs(self): + """ + Validate algorithm options. + """ + + self._setup() + issues = dict() + + if self._sample_radius > self._can_radius: + issues['CanRadius'] = 'Must be greater than SampleRadius' + + if self._use_can_corrections and self._can_chemical_formula == '': + issues['CanChemicalFormula'] = 'Must be set to use can corrections' + + if self._use_can_corrections and self._can_ws_name is None: + issues['UseCanCorrections'] = 'Must specify a can workspace to use can corections' + + return issues + + +# Register algorithm with Mantid +AlgorithmFactory.subscribe(IndirectCylinderAbsorption) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py new file mode 100644 index 0000000000000000000000000000000000000000..4651084b326a647d8b49c97c2de61c46865b40cb --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py @@ -0,0 +1,266 @@ +from mantid.simpleapi import * +from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, PropertyMode, Progress, WorkspaceGroupProperty +from mantid.kernel import StringMandatoryValidator, Direction, logger, FloatBoundedValidator + + +class IndirectFlatPlateAbsorption(DataProcessorAlgorithm): + + _sample_ws = None + _sample_chemical_formula = None + _sample_number_density = None + _sample_height = None + _sample_width = None + _sample_thickness = None + _can_ws_name = None + _use_can_corrections = None + _can_chemical_formula = None + _can_number_density = None + _can_front_thickness = None + _can_back_thickness = None + _can_scale = None + _element_size = None + _plot = None + _output_ws = None + _abs_ws = None + _ass_ws = None + _acc_ws = None + + + def category(self): + return "Workflow\\Inelastic;PythonAlgorithms;CorrectionFunctions\\AbsorptionCorrections;Workflow\\MIDAS" + + + def summary(self): + return "Calculates indirect absorption corrections for a flat sample shape." + + + def PyInit(self): + # Sample + self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '', direction=Direction.Input), + doc='Sample workspace') + self.declareProperty(name='SampleChemicalFormula', defaultValue='', + validator=StringMandatoryValidator(), + doc='Chemical formula for the sample') + self.declareProperty(name='SampleNumberDensity', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Sample number density') + self.declareProperty(name='SampleHeight', defaultValue=1.0, + validator=FloatBoundedValidator(0.0), + doc='Sample height') + self.declareProperty(name='SampleWidth', defaultValue=1.0, + validator=FloatBoundedValidator(0.0), + doc='Sample width') + self.declareProperty(name='SampleThickness', defaultValue=0.5, + validator=FloatBoundedValidator(0.0), + doc='Sample thickness') + + # Container + self.declareProperty(MatrixWorkspaceProperty('CanWorkspace', '', optional=PropertyMode.Optional, + direction=Direction.Input), + doc='Container workspace') + self.declareProperty(name='UseCanCorrections', defaultValue=False, + doc='Use can corrections in subtraction') + self.declareProperty(name='CanChemicalFormula', defaultValue='', + doc='Chemical formula for the Container') + self.declareProperty(name='CanNumberDensity', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Container number density') + self.declareProperty(name='CanFrontThickness', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Can front thickness') + self.declareProperty(name='CanBackThickness', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Can back thickness') + self.declareProperty(name='CanScaleFactor', defaultValue=1.0, + validator=FloatBoundedValidator(0.0), + doc='Scale factor to multiply can data') + + # General + self.declareProperty(name='ElementSize', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Element size in mm') + self.declareProperty(name='Plot', defaultValue=False, + doc='Plot options') + + # Output + self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '', direction=Direction.Output), + doc='The output corrected workspace') + + self.declareProperty(WorkspaceGroupProperty('CorrectionsWorkspace', '', direction=Direction.Output, + optional=PropertyMode.Optional), + doc='The workspace group to save correction factors') + + + def PyExec(self): + from IndirectCommon import getEfixed + + self._setup() + + # Set up progress reporting + n_prog_reports = 2 + if self._can_ws_name is not None: + n_prog_reports += 1 + prog = Progress(self, 0.0, 1.0, n_prog_reports) + + efixed = getEfixed(self._sample_ws) + + sample_wave_ws = '__sam_wave' + ConvertUnits(InputWorkspace=self._sample_ws, OutputWorkspace=sample_wave_ws, + Target='Wavelength', EMode='Indirect', EFixed=efixed) + + SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_number_density) + + prog.report('Calculating sample corrections') + FlatPlateAbsorption(InputWorkspace=sample_wave_ws, + OutputWorkspace=self._ass_ws, + SampleHeight=self._sample_height, + SampleWidth=self._sample_width, + SampleThickness=self._sample_thickness, + ElementSize=self._element_size, + EMode='Indirect', + EFixed=efixed, + NumberOfWavelengthPoints=10) + + plot_data = [self._output_ws, self._sample_ws] + plot_corr = [self._ass_ws] + group = self._ass_ws + + if self._can_ws_name is not None: + can_wave_ws = '__can_wave' + ConvertUnits(InputWorkspace=self._can_ws_name, OutputWorkspace=can_wave_ws, + Target='Wavelength', EMode='Indirect', EFixed=efixed) + if self._can_scale != 1.0: + logger.information('Scaling can by: ' + str(self._can_scale)) + Scale(InputWorkspace=can_wave_ws, OutputWorkspace=can_wave_ws, Factor=self._can_scale, Operation='Multiply') + + if self._use_can_corrections: + prog.report('Calculating container corrections') + Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) + + SetSampleMaterial(can_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_number_density) + FlatPlateAbsorption(InputWorkspace=can_wave_ws, + OutputWorkspace=self._acc_ws, + SampleHeight=self._sample_height, + SampleWidth=self._sample_width, + SampleThickness=self._can_front_thickness + self._can_back_thickness, + ElementSize=self._element_size, + EMode='Indirect', + EFixed=efixed, + NumberOfWavelengthPoints=10) + + Divide(LHSWorkspace=can_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can_wave_ws) + Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) + plot_corr.append(self._acc_ws) + group += ',' + self._acc_ws + + else: + prog.report('Calculating container scaling') + Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) + Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) + + DeleteWorkspace(can_wave_ws) + plot_data.append(self._can_ws_name) + + else: + Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) + + ConvertUnits(InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws, + Target='DeltaE', EMode='Indirect', EFixed=efixed) + DeleteWorkspace(sample_wave_ws) + + prog.report('Recording samle logs') + sample_log_workspaces = [self._output_ws, self._ass_ws] + sample_logs = [('sample_shape', 'flatplate'), + ('sample_filename', self._sample_ws), + ('sample_height', self._sample_height), + ('sample_width', self._sample_width), + ('sample_thickness', self._sample_thickness), + ('element_size', self._element_size)] + + if self._can_ws_name is not None: + sample_logs.append(('can_filename', self._can_ws_name)) + sample_logs.append(('can_scale', self._can_scale)) + if self._use_can_corrections: + sample_log_workspaces.append(self._acc_ws) + sample_logs.append(('can_front_thickness', self. _can_front_thickness)) + sample_logs.append(('can_back_thickness', self. _can_back_thickness)) + + log_names = [item[0] for item in sample_logs] + log_values = [item[1] for item in sample_logs] + + for ws_name in sample_log_workspaces: + AddSampleLogMultiple(Workspace=ws_name, LogNames=log_names, LogValues=log_values) + + self.setProperty('OutputWorkspace', self._output_ws) + + # Output the Ass workspace if it is wanted, delete if not + if self._abs_ws == '': + DeleteWorkspace(self._ass_ws) + if self._can_ws_name is not None and self._use_can_corrections: + DeleteWorkspace(self._acc_ws) + else: + GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._abs_ws) + self.setProperty('CorrectionsWorkspace', self._abs_ws) + + if self._plot: + from IndirectImport import import_mantidplot + mantid_plot = import_mantidplot() + mantid_plot.plotSpectrum(plot_data, 0) + if self._abs_ws != '': + mantid_plot.plotSpectrum(plot_corr, 0) + + + def _setup(self): + """ + Get algorithm properties. + """ + + self._sample_ws = self.getPropertyValue('SampleWorkspace') + self._sample_chemical_formula = self.getPropertyValue('SampleChemicalFormula') + self._sample_number_density = self.getProperty('SampleNumberDensity').value + self._sample_height = self.getProperty('SampleHeight').value + self._sample_width = self.getProperty('SampleWidth').value + self._sample_thickness = self.getProperty('SampleThickness').value + + self._can_ws_name = self.getPropertyValue('CanWorkspace') + if self._can_ws_name == '': + self._can_ws_name = None + self._use_can_corrections = self.getProperty('UseCanCorrections').value + self._can_chemical_formula = self.getPropertyValue('CanChemicalFormula') + self._can_number_density = self.getProperty('CanNumberDensity').value + self._can_front_thickness = self.getProperty('CanFrontThickness').value + self._can_back_thickness = self.getProperty('CanBackThickness').value + self._can_scale = self.getProperty('CanScaleFactor').value + + self._element_size = self.getProperty('ElementSize').value + self._plot = self.getProperty('Plot').value + self._output_ws = self.getPropertyValue('OutputWorkspace') + + self._abs_ws = self.getPropertyValue('CorrectionsWorkspace') + if self._abs_ws == '': + self._ass_ws = '__ass' + self._acc_ws = '__acc' + else: + self._ass_ws = self._abs_ws + '_ass' + self._acc_ws = self._abs_ws + '_acc' + + + def validateInputs(self): + """ + Validate algorithm options. + """ + + self._setup() + issues = dict() + + if self._use_can_corrections and self._can_chemical_formula == '': + issues['CanChemicalFormula'] = 'Must be set to use can corrections' + + if self._use_can_corrections and self._can_ws_name is None: + issues['UseCanCorrections'] = 'Must specify a can workspace to use can corections' + + return issues + + +# Register algorithm with Mantid +AlgorithmFactory.subscribe(IndirectFlatPlateAbsorption) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectResolution.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectResolution.py index 868ad8f8cd9b761ab92dbe1ff0bd18c7bed178a1..1e3ccff2bcb72750d5385da98525dce03f355f14 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectResolution.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectResolution.py @@ -61,9 +61,8 @@ class IndirectResolution(DataProcessorAlgorithm): def PyExec(self): - from IndirectCommon import StartTime, EndTime, getWSprefix + from IndirectCommon import getWSprefix - StartTime('IndirectResolution') self._setup() InelasticIndirectReduction(Instrument=self._instrument, @@ -92,8 +91,6 @@ class IndirectResolution(DataProcessorAlgorithm): self._post_process() self.setProperty('OutputWorkspace', self._out_ws) - EndTime('IndirectResolution') - def _setup(self): """ diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectTransmissionMonitor.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectTransmissionMonitor.py index 7ae4d22ef312c22a67952ee2731a5e6083f69723..6905c0669ab210e1407ce393e75e2970aef83cb0 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectTransmissionMonitor.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectTransmissionMonitor.py @@ -16,12 +16,15 @@ class IndirectTransmissionMonitor(PythonAlgorithm): _plot = None _save = None + def category(self): return "Workflow\\Inelastic;PythonAlgorithms;Inelastic" + def summary(self): return "Calculates the sample transmission using the raw data files of the sample and its background or container." + def PyInit(self): self.declareProperty(WorkspaceProperty('SampleWorkspace', '', direction=Direction.Input), doc='Sample workspace') @@ -32,15 +35,14 @@ class IndirectTransmissionMonitor(PythonAlgorithm): self.declareProperty(WorkspaceProperty('OutputWorkspace', '', direction=Direction.Output), doc='Output workspace group') - self.declareProperty(name='Plot', defaultValue=False, doc='Plot result workspace') - self.declareProperty(name='Save', defaultValue=False, doc='Save result workspace to nexus file in the default save directory') + self.declareProperty(name='Plot', defaultValue=False, + doc='Plot result workspace') + self.declareProperty(name='Save', defaultValue=False, + doc='Save result workspace to nexus file in the default save directory') def PyExec(self): - from IndirectCommon import StartTime, EndTime self._setup() - StartTime('IndirectTransmissionMonitor') - ws_basename = str(self._sample_ws_in) self._trans_mon(ws_basename, 'Sam', self._sample_ws_in) @@ -53,7 +55,9 @@ class IndirectTransmissionMonitor(PythonAlgorithm): # Divide sample and can workspaces Divide(LHSWorkspace=sam_ws, RHSWorkspace=can_ws, OutputWorkspace=trans_ws) + trans = numpy.average(mtd[trans_ws].readY(0)) + logger.information('Average Transmission: ' + str(trans)) AddSampleLog(Workspace=trans_ws, LogName='can_workspace', LogType='String', LogText=self._can_ws_in) @@ -63,8 +67,6 @@ class IndirectTransmissionMonitor(PythonAlgorithm): self.setProperty('OutputWorkspace', self._out_ws) - logger.information('Transmission : ' + str(trans)) - # Save the tranmissin workspace group to a nexus file if self._save: workdir = config['defaultsave.directory'] @@ -77,7 +79,6 @@ class IndirectTransmissionMonitor(PythonAlgorithm): mtd_plot = import_mantidplot() mtd_plot.plotSpectrum(self._out_ws, 0) - EndTime('IndirectTransmissionMonitor') def _setup(self): """ @@ -90,6 +91,7 @@ class IndirectTransmissionMonitor(PythonAlgorithm): self._plot = self.getProperty("Plot").value self._save = self.getProperty("Save").value + def _get_spectra_index(self, input_ws): """ Gets the index of the two monitors and first detector for the current instrument configurtion. @@ -123,6 +125,7 @@ class IndirectTransmissionMonitor(PythonAlgorithm): return monitor_1_idx, monitor_2_idx, detector_1_idx + def _get_detector_spectrum_index(self, workspace, detector_id): """ Returns the spectrum index for a given detector ID in a workspace. @@ -137,6 +140,7 @@ class IndirectTransmissionMonitor(PythonAlgorithm): return None + def _unwrap_mon(self, input_ws): out_ws = '_unwrap_mon_out' @@ -152,13 +156,17 @@ class IndirectTransmissionMonitor(PythonAlgorithm): return out_ws + def _trans_mon(self, ws_basename, file_type, input_ws): monitor_1_idx, monitor_2_idx, detector_1_idx = self._get_spectra_index(input_ws) - CropWorkspace(InputWorkspace=input_ws, OutputWorkspace='__m1', StartWorkspaceIndex=monitor_1_idx, EndWorkspaceIndex=monitor_1_idx) + CropWorkspace(InputWorkspace=input_ws, OutputWorkspace='__m1', + StartWorkspaceIndex=monitor_1_idx, EndWorkspaceIndex=monitor_1_idx) if monitor_2_idx is not None: - CropWorkspace(InputWorkspace=input_ws, OutputWorkspace='__m2', StartWorkspaceIndex=monitor_2_idx, EndWorkspaceIndex=monitor_2_idx) - CropWorkspace(InputWorkspace=input_ws, OutputWorkspace='__det', StartWorkspaceIndex=detector_1_idx, EndWorkspaceIndex=detector_1_idx) + CropWorkspace(InputWorkspace=input_ws, OutputWorkspace='__m2', + StartWorkspaceIndex=monitor_2_idx, EndWorkspaceIndex=monitor_2_idx) + CropWorkspace(InputWorkspace=input_ws, OutputWorkspace='__det', + StartWorkspaceIndex=detector_1_idx, EndWorkspaceIndex=detector_1_idx) # Check for single or multiple time regimes mon_tcb_start = mtd['__m1'].readX(0)[0] diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/InelasticIndirectReduction.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/InelasticIndirectReduction.py index aee835a8773649cedb5f47404fe10da87841ed6c..39070394a695e4f5815bd9135966038d838d16d4 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/InelasticIndirectReduction.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/InelasticIndirectReduction.py @@ -77,13 +77,10 @@ class InelasticIndirectReduction(DataProcessorAlgorithm): def PyExec(self): from mantid import config, logger - from IndirectCommon import StartTime, EndTime import inelastic_indirect_reducer self._setup() - StartTime('InelasticIndirectReduction') - # Setup reducer reducer = inelastic_indirect_reducer.IndirectReducer() @@ -157,8 +154,6 @@ class InelasticIndirectReduction(DataProcessorAlgorithm): if self._plot_type != 'none': self._plot() - EndTime('InelasticIndirectReduction') - def validateInputs(self): """ diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/JumpFit.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/JumpFit.py index 376e9820f6357906b9c9fdab577dc28a6ba76eee..df2c197149b28563320eba9725bd19cf33931a29 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/JumpFit.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/JumpFit.py @@ -15,6 +15,7 @@ class JumpFit(PythonAlgorithm): _plot = None _save = None + def category(self): return 'Workflow\\Inelastic;PythonAlgorithms;Inelastic' @@ -49,12 +50,9 @@ class JumpFit(PythonAlgorithm): from mantid.simpleapi import ExtractSingleSpectrum, Fit, CopyLogs, AddSampleLog, \ DeleteWorkspace from mantid import logger, mtd - from IndirectCommon import StartTime, EndTime self._setup() - StartTime('Jump fit : ' + self._jump_function + ' ; ') - # Select the width we wish to fit spectrum_ws = "__" + self._in_ws ExtractSingleSpectrum(InputWorkspace=self._in_ws, OutputWorkspace=spectrum_ws, @@ -110,7 +108,13 @@ class JumpFit(PythonAlgorithm): # Run fit function if self._out_name is "": + # Find the last underscore ws_suffix_index = self._in_ws.rfind('_') + + if ws_suffix_index == -1: + # Use the entire string if underscore not found + ws_suffix_index = len(self._in_ws) + self._out_name = self._in_ws[:ws_suffix_index] + '_' + self._jump_function + '_fit' Fit(Function=function, InputWorkspace=spectrum_ws, CreateOutput=True, Output=self._out_name, @@ -132,8 +136,6 @@ class JumpFit(PythonAlgorithm): DeleteWorkspace(Workspace=spectrum_ws) - EndTime('Jump fit : ' + self._jump_function + ' ; ') - def _setup(self): self._in_ws = self.getPropertyValue('InputWorkspace') diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MSGDiffractionReduction.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MSGDiffractionReduction.py index 73e8140748acaa31165604c67f7784010f430bcc..ca4277dad752be530a67fd6c9b9c0b604bce23d4 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MSGDiffractionReduction.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MSGDiffractionReduction.py @@ -77,11 +77,8 @@ class MSGDiffractionReduction(PythonAlgorithm): def PyExec(self): - from IndirectCommon import StartTime, EndTime from IndirectDiffractionReduction import MSGDiffractionReducer - StartTime('MSGDiffractionReduction') - input_files = self.getProperty('InputFiles').value sum_files = self.getProperty('SumFiles').value individual_grouping = self.getProperty('IndividualGrouping').value @@ -119,7 +116,5 @@ class MSGDiffractionReduction(PythonAlgorithm): GroupWorkspaces(InputWorkspaces=result_ws_list, OutputWorkspace=output_ws_group) self.setProperty('OutputWorkspace', output_ws_group) - EndTime('MSGDiffractionReduction') - AlgorithmFactory.subscribe(MSGDiffractionReduction) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MolDyn.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MolDyn.py index 046ed36d28f7cade57014b2c9134983f4850ae7a..d13ec85c84824c95415b1be4d8735e2362789b6f 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MolDyn.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MolDyn.py @@ -73,7 +73,7 @@ class MolDyn(PythonAlgorithm): _mtd_plot = None def category(self): - return 'Workflow\\Inelastic;PythonAlgorithms;Inelastic' + return 'Workflow\\Inelastic;PythonAlgorithms;Inelastic;Simulation' def summary(self): return 'Imports nMOLDYN simulations from CDL and ASCII files.' diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/Fury.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TransformToIqt.py similarity index 87% rename from Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/Fury.py rename to Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TransformToIqt.py index ab8aff547bafaa64f74b506e7e0a53a778fd6715..ab2d4a4c5129930c1eb751de12641d099251eecf 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/Fury.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TransformToIqt.py @@ -7,7 +7,7 @@ import math import os -class Fury(PythonAlgorithm): +class TransformToIqt(PythonAlgorithm): _sample = None _resolution = None @@ -21,29 +21,35 @@ class Fury(PythonAlgorithm): _save = None _dry_run = None + def category(self): - return "Workflow\\MIDAS;PythonAlgorithms" + return "Workflow\\Inelastic;PythonAlgorithms" + + + def summary(self): + return 'Transforms an inelastic reduction to I(Q, t)' + def PyInit(self): - self.declareProperty(MatrixWorkspaceProperty('Sample', '',\ + self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '',\ optional=PropertyMode.Mandatory, direction=Direction.Input), - doc="Name for the Sample workspace.") + doc="Name for the sample workspace.") - self.declareProperty(MatrixWorkspaceProperty('Resolution', '',\ + self.declareProperty(MatrixWorkspaceProperty('ResolutionWorkspace', '',\ optional=PropertyMode.Mandatory, direction=Direction.Input), - doc="Name for the Resolution workspace.") + doc="Name for the resolution workspace.") self.declareProperty(name='EnergyMin', defaultValue=-0.5, doc='Minimum energy for fit. Default=-0.5') self.declareProperty(name='EnergyMax', defaultValue=0.5, doc='Maximum energy for fit. Default=0.5') - self.declareProperty(name='NumBins', defaultValue=1, + self.declareProperty(name='BinReductionFactor', defaultValue=10.0, doc='Decrease total number of spectrum points by this ratio through merging of ' 'intensities from neighbouring bins. Default=1') self.declareProperty(MatrixWorkspaceProperty('ParameterWorkspace', '',\ direction=Direction.Output, optional=PropertyMode.Optional), - doc='Table workspace for saving Fury properties') + doc='Table workspace for saving TransformToIqt properties') self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '',\ direction=Direction.Output, optional=PropertyMode.Optional), @@ -76,7 +82,7 @@ class Fury(PythonAlgorithm): if self._plot: self._plot_output() else: - logger.information('Dry run, will not run Fury') + logger.information('Dry run, will not run TransformToIqt') self.setProperty('ParameterWorkspace', self._parameter_table) self.setProperty('OutputWorkspace', self._output_workspace) @@ -88,16 +94,16 @@ class Fury(PythonAlgorithm): """ from IndirectCommon import getWSprefix - self._sample = self.getPropertyValue('Sample') - self._resolution = self.getPropertyValue('Resolution') + self._sample = self.getPropertyValue('SampleWorkspace') + self._resolution = self.getPropertyValue('ResolutionWorkspace') self._e_min = self.getProperty('EnergyMin').value self._e_max = self.getProperty('EnergyMax').value - self._number_points_per_bin = self.getProperty('NumBins').value + self._number_points_per_bin = self.getProperty('BinReductionFactor').value self._parameter_table = self.getPropertyValue('ParameterWorkspace') if self._parameter_table == '': - self._parameter_table = getWSprefix(self._sample) + 'FuryParameters' + self._parameter_table = getWSprefix(self._sample) + 'TransformToIqtParameters' self._output_workspace = self.getPropertyValue('OutputWorkspace') if self._output_workspace == '': @@ -128,13 +134,13 @@ class Fury(PythonAlgorithm): def _calculate_parameters(self): """ - Calculates the Fury parameters and saves in a table workspace. + Calculates the TransformToIqt parameters and saves in a table workspace. """ - CropWorkspace(InputWorkspace=self._sample, OutputWorkspace='__Fury_sample_cropped', + CropWorkspace(InputWorkspace=self._sample, OutputWorkspace='__TransformToIqt_sample_cropped', Xmin=self._e_min, Xmax=self._e_max) - x_data = mtd['__Fury_sample_cropped'].readX(0) + x_data = mtd['__TransformToIqt_sample_cropped'].readX(0) number_input_points = len(x_data) - 1 - num_bins = number_input_points / self._number_points_per_bin + num_bins = int(number_input_points / self._number_points_per_bin) self._e_width = (abs(self._e_min) + abs(self._e_max)) / num_bins try: @@ -167,7 +173,7 @@ class Fury(PythonAlgorithm): param_table = CreateEmptyTableWorkspace(OutputWorkspace=self._parameter_table) param_table.addColumn('int', 'SampleInputBins') - param_table.addColumn('int', 'NumberBins') + param_table.addColumn('float', 'BinReductionFactor') param_table.addColumn('int', 'SampleOutputBins') param_table.addColumn('float', 'EnergyMin') param_table.addColumn('float', 'EnergyMax') @@ -179,7 +185,7 @@ class Fury(PythonAlgorithm): self._e_min, self._e_max, self._e_width, resolution, resolution_bins]) - DeleteWorkspace('__Fury_sample_cropped') + DeleteWorkspace('__TransformToIqt_sample_cropped') self.setProperty('ParameterWorkspace', param_table) @@ -212,7 +218,7 @@ class Fury(PythonAlgorithm): def _fury(self): """ - Run Fury. + Run TransformToIqt. """ from IndirectCommon import CheckHistZero, CheckHistSame, CheckAnalysers @@ -261,4 +267,4 @@ class Fury(PythonAlgorithm): # Register algorithm with Mantid -AlgorithmFactory.subscribe(Fury) +AlgorithmFactory.subscribe(TransformToIqt) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/dnsdata.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/dnsdata.py new file mode 100644 index 0000000000000000000000000000000000000000..97f14ac5e68d1f33ac83c597dc64808f1980f0f3 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/dnsdata.py @@ -0,0 +1,213 @@ +import sys, re +import datetime + +class DNSdata: + """ + class which describes the DNS data structure + will be used for data read-in and write-out routines + """ + def __init__(self): + self.title = "" + self.experiment_number = "" + self.run_number = "" + self.start_time = "" + self.end_time = "" + self.duration = None + self.deterota = 0 + self.wavelength = None # Angstrom + self.ndet = 24 + self.sample_name = "" + self.userid = "" + self.user_name = "" + self.sample_description = "" + self.coil_status = "" + self.befilter_status = "" + self.notes = "" + self.monochromator_angle = None # degree + self.monochromator_position = None + self.huber = None + self.cradle_lower = None + self.cradle_upper = None + self.slit_i_upper_blade_position = None + self.slit_i_lower_blade_position = None + self.slit_i_left_blade_position = None + self.slit_i_right_blade_position = None + self.slit_f_upper_blade_position = None + self.slit_f_lower_blade_position = None + self.detector_position_vertical = None + self.polarizer_translation = None + self.polarizer_rotation = None + self.flipper_precession_current = None + self.flipper_z_compensation_current = None + self.a_coil_current = None + self.b_coil_current = None + self.c_coil_current = None + self.z_coil_current = None + self.t1 = None # T1 + self.t2 = None # T2 + self.tsp = None # T_setpoint + self.tof_channel_number = None + self.tof_channel_width = None + self.tof_delay_time = None + self.tof_elastic_channel = None + self.chopper_rotation_speed = None + self.chopper_slits = None + self.monitor_counts = None + + + def read_legacy(self, filename): + """ + reads the DNS legacy ascii file into the DNS data object + """ + with open(filename, 'r') as fhandler: + # read file content and split it into blocks + splitsymbol = \ + '#--------------------------------------------------------------------------' + unparsed = fhandler.read() + blocks = unparsed.split(splitsymbol) + + # parse each block + # parse block 0 (header) + res = parse_header(blocks[0]) + #if not res: raise Exception "wrong file format" else + try: + self.run_number = res['file'] + self.experiment_number = res['exp'] + self.sample_name = res['sample'] + self.userid = res['userid'] + except: + raise ValueError("The file %s does not contain valid DNS data format." % filename) + # parse block 1 (general information) + b1splitted = map(str.strip, blocks[1].split('#')) + b1rest = [el for el in b1splitted] + r_user = re.compile("User:\s*(?P<name>.*?$)") + r_sample = re.compile("Sample:\s*(?P<sample>.*?$)") + r_coil = re.compile("^(?P<coil>.*?)\s*xyz-coil.*") + r_filter = re.compile("^(?P<filter>.*?)\s*Be-filter.*") + for line in b1splitted: + res = r_user.match(line) + if res: + self.user_name = res.group("name") + b1rest.remove(line) + res = r_sample.match(line) + if res: + self.sample_description = res.group("sample") + b1rest.remove(line) + res = r_coil.match(line) + if res: + self.coil_status = res.group("coil") + b1rest.remove(line) + res = r_filter.match(line) + if res: + self.befilter_status = res.group("filter") + b1rest.remove(line) + # the rest unparsed lines go to notes for the moment + # [TODO]: parse more information about the sample + self.notes = ' '.join(b1rest) + + # parse block 2 (wavelength and mochromator angle) + # for the moment, only theta and lambda are needed + b2splitted = map(str.strip, blocks[2].split('#')) + # assume that theta and lambda are always on the fixed positions + # assume theta is give in degree, lambda in nm + line = b2splitted[2].split() + self.monochromator_angle = float(line[2]) + self.wavelength = float(line[3])*10.0 + + # parse block 3 (motors position) + b3splitted = map(str.strip, blocks[3].split('#')) + self.monochromator_position = float(b3splitted[2].split()[1]) + # DeteRota, angle of rotation of detector bank + self.deterota = float(b3splitted[3].split()[1]) + # Huber default units degree + self.huber = float(b3splitted[5].split()[1]) + self.cradle_lower = float(b3splitted[6].split()[1]) + self.cradle_upper = float(b3splitted[7].split()[1]) + # Slit_i, convert mm to meter + self.slit_i_upper_blade_position = \ + 0.001*float(b3splitted[9].split()[2]) + self.slit_i_lower_blade_position = \ + 0.001*float(b3splitted[10].split()[1]) + self.slit_i_left_blade_position = \ + 0.001*float(b3splitted[11].split()[2]) + self.slit_i_right_blade_position = \ + 0.001*float(b3splitted[12].split()[1]) + # Slit_f + self.slit_f_upper_blade_position = \ + 0.001*float(b3splitted[14].split()[1]) + self.slit_f_lower_blade_position = \ + 0.001*float(b3splitted[15].split()[1]) + # Detector_position vertical + self.detector_position_vertical = \ + 0.001*float(b3splitted[16].split()[1]) + # Polarizer + self.polarizer_translation = \ + 0.001*float(b3splitted[19].split()[1]) + self.polarizer_rotation = float(b3splitted[20].split()[1]) + + # parse block 4 (B-fields), only currents in A are taken + b4splitted = map(str.strip, blocks[4].split('#')) + self.flipper_precession_current = float(b4splitted[2].split()[1]) + self.flipper_z_compensation_current = float(b4splitted[3].split()[1]) + self.a_coil_current = float(b4splitted[4].split()[1]) + self.b_coil_current = float(b4splitted[5].split()[1]) + self.c_coil_current = float(b4splitted[6].split()[1]) + self.z_coil_current = float(b4splitted[7].split()[1]) + + + # parse block 5 (Temperatures) + # assume: T1=cold_head_temperature, T2=sample_temperature + b5splitted = map(str.strip, blocks[5].split('#')) + self.t1 = float(b5splitted[2].split()[1]) + self.t2 = float(b5splitted[3].split()[1]) + self.tsp = float(b5splitted[4].split()[1]) + + # parse block 6 (TOF parameters) + b6splitted = map(str.strip, blocks[6].split('#')) + self.tof_channel_number = int(b6splitted[2].split()[2]) + self.tof_channel_width = float(b6splitted[3].split()[3]) + self.tof_delay_time = float(b6splitted[4].split()[2]) + self.tof_elastic_channel = int(b6splitted[6].split()[3]) + # chopper rotation speed + self.chopper_rotation_speed = float(b6splitted[7].split()[2]) + # chopper number of slits + self.chopper_slits = int(b6splitted[5].split()[2]) + + # parse block 7 (Time and monitor) + # assume everything to be at the fixed positions + b7splitted = map(str.strip, blocks[7].split('#')) + # duration + line = b7splitted[2].split() + self.duration = float(line[1]) # assume seconds [TODO]: check + # monitor data + line = b7splitted[3].split() + self.monitor_counts = int(line[1]) + # start_time and end_time + outfmt = "%Y-%m-%dT%H:%M:%S" + sinfmt = "start at %a %b %d %H:%M:%S %Y" + einfmt = "stopped at %a %b %d %H:%M:%S %Y" + self.start_time = datetime.datetime.strptime(b7splitted[5], sinfmt).strftime(outfmt) + self.end_time = datetime.datetime.strptime(b7splitted[6], einfmt).strftime(outfmt) + +def parse_header(h): + """ + parses the header string and returns the parsed dictionary + """ + d = {} + regexp = re.compile("(\w+)=(\w+)") + result = regexp.finditer(h) + for r in result: + d[r.groups()[0]] = r.groups()[1] + return d + + +if __name__ == '__main__': + fname = sys.argv[1] + dns_data = DNSdata() + dns_data.read_legacy(fname) + print dns_data.__dict__ + + + + + diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/SimpleAPITest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/SimpleAPITest.py index 54f19d234c8f282a46e35ef3ccfc0a5946638756..f2bfb1f7a92b9c495c216ef9febdc821e3d550e0 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/SimpleAPITest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/SimpleAPITest.py @@ -4,36 +4,6 @@ from mantid.api import (AlgorithmFactory, AlgorithmProxy, IAlgorithm, IEventWork import mantid.simpleapi as simpleapi import numpy -import os -import sys - -#====================================================================================================================== -# Helper class for test -class TemporaryPythonAlgorithm(object): - """ - Dumps the given code to a file in the Python algorithm directory - an removes the file in the del method - """ - def __init__(self, name, code): - from mantid import config - - plugin_dirs = config['python.plugins.directories'].split(";") - if len(plugin_dirs) == 0: - raise RuntimeError("No Python algorithm directories defined") - - self._pyfile = os.path.join(plugin_dirs[0], name + ".py") - alg_file = open(self._pyfile, "w") - alg_file.write(code) - alg_file.close() - - def __del__(self): - try: - os.remove(self._pyfile) - pycfile = self._pyfile.replace(".py",".pyc") - os.remove(pycfile) - except OSError: - pass - #====================================================================================================================== class SimpleAPITest(unittest.TestCase): @@ -218,42 +188,34 @@ FullBinsOnly(Input) *boolean* Omit the final bin if it's width is smaller self.assertTrue('raw' in mtd) def test_python_alg_can_use_other_python_alg_through_simple_api(self): - """ - Runs a test in a separate process as it requires a reload of the - whole mantid module - """ - src = """ -from mantid.api import PythonAlgorithm, AlgorithmFactory -import mantid.simpleapi as api -from mantid.simpleapi import * - -class %(name)s(PythonAlgorithm): + class SimpleAPIPythonAlgorithm1(PythonAlgorithm): + def PyInit(self): + pass + def PyExec(self): + from mantid.simpleapi import SimpleAPIPythonAlgorithm2 + SimpleAPIPythonAlgorithm2() + class SimpleAPIPythonAlgorithm2(PythonAlgorithm): + def PyInit(self): + pass + def PyExec(self): + pass - def PyInit(self): - pass - def PyExec(self): - %(execline1)s - %(execline2)s - -AlgorithmFactory.subscribe(%(name)s) -""" - name1 = "SimpleAPIPythonAlgorithm1" - name2 = "SimpleAPIPythonAlgorithm2" - src1 = src % {"name":name1,"execline1":name2+"()","execline2":"api."+name2+"()"} - src2 = src % {"name":name2,"execline1":"pass","execline2":"pass"} - a = TemporaryPythonAlgorithm(name1,src1) - b = TemporaryPythonAlgorithm(name2,src2) - import subprocess - # Try to use algorithm 1 to run algorithm 2 - cmd = sys.executable + ' -c "from mantid.simpleapi import %(name)s;%(name)s()"' % {'name':name1} + AlgorithmFactory.subscribe(SimpleAPIPythonAlgorithm1) + AlgorithmFactory.subscribe(SimpleAPIPythonAlgorithm2) + # --------------------------------------------------------- + alg1 = SimpleAPIPythonAlgorithm1() + alg1.initialize() + # Puts function in simpleapi globals + simpleapi_alg1_func = simpleapi._create_algorithm_function("SimpleAPIPythonAlgorithm1", 1, alg1) + alg2 = SimpleAPIPythonAlgorithm1() + alg2.initialize() + # Puts function in simpleapi globals + simpleapi._create_algorithm_function("SimpleAPIPythonAlgorithm2", 1, alg2) try: - subprocess.check_call(cmd,shell=True) - except subprocess.CalledProcessError, exc: - self.fail("Error occurred running one Python algorithm from another: %s" % str(exc)) - - # Ensure the files are removed promptly - del a,b - + simpleapi_alg1_func() + except RuntimeError, exc: + self.fail("Running algorithm 2 from 1 failed: " + str(exc)) + def test_optional_workspaces_are_ignored_if_not_present_in_output_even_if_given_as_input(self): # Test algorithm from mantid.api import AlgorithmManager,PropertyMode,PythonAlgorithm,MatrixWorkspaceProperty,WorkspaceFactory @@ -321,5 +283,23 @@ AlgorithmFactory.subscribe(%(name)s) self.assertEquals(alg.version(), version) self.assertTrue(isinstance(alg, expected_class)) + def test_validate_inputs_with_errors_stops_algorithm(self): + class ValidateInputsTest(PythonAlgorithm): + def PyInit(self): + self.declareProperty("Prop1", 1.0) + self.declareProperty("Prop2", 2.0) + def validateInputs(self): + return {"Prop1":"Value is less than Prop2"} + def PyExec(self): + pass + AlgorithmFactory.subscribe(ValidateInputsTest) + # --------------------------------------------------------- + alg_obj = ValidateInputsTest() + alg_obj.initialize() + + simpleapi_func = simpleapi._create_algorithm_function("ValidateInputsTest", 1, alg_obj) + # call + self.assertRaises(RuntimeError, simpleapi_func, Prop1=2.5, Prop2=3.5) + if __name__ == '__main__': unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CMakeLists.txt index 0c6113c925d996ce744e70a2fafbfb75f7c9abf3..57b1f1b8c6bf6608895199784738317b1bf253a6 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CMakeLists.txt @@ -10,7 +10,6 @@ set ( TEST_PY_FILES AnalysisDataServiceTest.py AxisTest.py CatalogManagerTest.py - CutMDTest.py DataProcessorAlgorithmTest.py DeprecatedAlgorithmCheckerTest.py ExperimentInfoTest.py diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CutMDTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CutMDTest.py deleted file mode 100644 index 9d2589b121185109da04c40f679576621d1eeef6..0000000000000000000000000000000000000000 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CutMDTest.py +++ /dev/null @@ -1,237 +0,0 @@ -import unittest -import testhelpers -import numpy as np -from mantid.simpleapi import * -from mantid.api import IMDHistoWorkspace, IMDEventWorkspace - - -class CutMDTest(unittest.TestCase): - - - def setUp(self): - # Create a workspace - data_ws = CreateMDWorkspace(Dimensions=3, Extents=[-10,10,-10,10,-10,10], Names="A,B,C", Units="U,U,U") - # Mark the workspace as being in HKL - SetSpecialCoordinates(InputWorkspace=data_ws, SpecialCoordinates='HKL') - # Set the UB - SetUB(Workspace=data_ws, a = 1, b = 1, c = 1, alpha =90, beta=90, gamma = 90) - # Add some data to the workspace - FakeMDEventData(InputWorkspace=data_ws, PeakParams=[10000,0,0,0,1]) - self.__in_md = data_ws - - def tearDown(self): - DeleteWorkspace(self.__in_md ) - - def test_exec_throws_if_giving_4th_binning_parameter_when_workspace_is_3D(self): - test_md = CreateMDWorkspace(Dimensions=3, Extents=[-10,10,-10,10,-10,10], Names="H,K,L", Units="U,U,U") - # Explicitly set the coordinate system to lab Q. - SetSpecialCoordinates(InputWorkspace=test_md, SpecialCoordinates='HKL') - self.assertRaises(RuntimeError, CutMD, InputWorkspace=test_md, OutputWorkspace="out_ws", P1Bin=[0.1], P2Bin=[0.1], P3Bin=[0.1], P4Bin=[0.1]) - - def test_slice_to_original(self): - out_md = CutMD(self.__in_md, P1Bin=[0.1], P2Bin=[0.1], P3Bin=[0.1], CheckAxes=False) - self.assertTrue(isinstance(out_md, IMDEventWorkspace), "Should default to producing an IMDEventWorkspace.") - # No rotation. Basis vectors should have been left the same, so no extent changes. - self.assertEquals(self.__in_md.getDimension(0).getMinimum(), out_md.getDimension(0).getMinimum()) - self.assertEquals(self.__in_md.getDimension(0).getMaximum(), out_md.getDimension(0).getMaximum()) - self.assertEquals(self.__in_md.getDimension(1).getMinimum(), out_md.getDimension(1).getMinimum()) - self.assertEquals(self.__in_md.getDimension(1).getMaximum(), out_md.getDimension(1).getMaximum()) - self.assertEquals(self.__in_md.getDimension(2).getMinimum(), out_md.getDimension(2).getMinimum()) - self.assertEquals(self.__in_md.getDimension(2).getMaximum(), out_md.getDimension(2).getMaximum()) - self.assertEquals("['zeta', 0, 0]", out_md.getDimension(0).getName() ) - self.assertEquals("[0, 'eta', 0]", out_md.getDimension(1).getName() ) - self.assertEquals("[0, 0, 'xi']", out_md.getDimension(2).getName() ) - self.assertTrue(isinstance(out_md, IMDEventWorkspace), "nopix defaults to True. Should get an IMDEventWorkspace") - - def test_recalculate_extents_with_3_bin_arguments(self): - out_md = CutMD(self.__in_md, P1Bin=[0, 0.3, 0.8], P2Bin=[0.1], P3Bin=[0.1], CheckAxes=False, NoPix=True) - dim = out_md.getDimension(0) - self.assertAlmostEqual(0, dim.getMinimum(), 6, "Wrong minimum") - self.assertEqual(2, dim.getNBins(), "Wrong calculated number of bins") - self.assertAlmostEqual(0.6, dim.getMaximum(), 6, "Wrong calculated maximum") - - def test_truncate_extents(self): - out_md = CutMD(self.__in_md, P1Bin=[0, 1.1, 1], P2Bin=[21], P3Bin=[0.1], CheckAxes=False, NoPix=True) - - self.assertEqual(1, out_md.getDimension(0).getNBins(), "Step is beyond range. Should just be integrated") - self.assertEqual(1, out_md.getDimension(1).getNBins(), "Step is beyond range. Should just be integrated") - - def test_wrong_projection_workspace_format_wrong_column_numbers(self): - projection = CreateEmptyTableWorkspace() - projection.addColumn("str", "name") - # missing other columns - self.assertRaises(RuntimeError, CutMD, InputWorkspace=self.__in_md, Projection=projection, OutputWorkspace="out_ws", P1Bin=[0.1], P2Bin=[0.1], P3Bin=[0.1], CheckAxes=False) - - def test_wrong_table_workspace_format_wrong_row_numbers(self): - projection = CreateEmptyTableWorkspace() - # Correct number of columns, and names - projection.addColumn("str", "name") - projection.addColumn("str", "value") - projection.addColumn("double", "offset") - projection.addColumn("str", "type") - # Incorrect number of rows i.e. zero in this case as none added. - self.assertRaises(RuntimeError, CutMD, InputWorkspace=self.__in_md, Projection=projection, OutputWorkspace="out_ws", P1Bin=[0.1], P2Bin=[0.1], P3Bin=[0.1], CheckAxes=False) - - def test_orthogonal_slice_with_scaling(self): - # We create a fake workspace and check to see that the extents get scaled with the new coordinate system when sliced - to_cut = CreateMDWorkspace(Dimensions=3, Extents=[-1,1,-1,1,-1,1], Names='H,K,L', Units='U,U,U') - # Set the UB - SetUB(Workspace=to_cut, a = 1, b = 1, c = 1, alpha =90, beta=90, gamma = 90) - - SetSpecialCoordinates(InputWorkspace=to_cut, SpecialCoordinates='HKL') - - scale_x = 2.0 - scale_y = 2.0 - - projection = CreateEmptyTableWorkspace() - # Correct number of columns, and names - projection.addColumn("str", "name") - projection.addColumn("str", "value") - projection.addColumn("double", "offset") - projection.addColumn("str", "type") - - projection.addRow(["u", "%s,0,0" % scale_x, 0, "r"]) - projection.addRow(["v", "0,%s,0" % scale_y, 0, "r"]) - - u = map(float,projection.cell(0,1).split(",")) - v = map(float,projection.cell(1,1).split(",")) - scale_z = np.cross(v,u)[-1] - projection.addRow(["w", "0,0,%s" % scale_z, 0, "r"]) - - out_md = CutMD(to_cut, Projection=projection, P1Bin=[0.1], P2Bin=[0.1], P3Bin=[0.1]) - - ''' - Here we check that the corners in HKL end up in the expected positions when transformed into the new scaled basis - provided by the W transform (projection table) - ''' - self.assertEquals(-(1/scale_x), out_md.getDimension(0).getMinimum()) - self.assertEquals((1/scale_x), out_md.getDimension(0).getMaximum()) - self.assertEquals(-(1/scale_y), out_md.getDimension(1).getMinimum()) - self.assertEquals((1/scale_y), out_md.getDimension(1).getMaximum()) - self.assertEquals((1/scale_z), out_md.getDimension(2).getMinimum()) - self.assertEquals(-(1/scale_z), out_md.getDimension(2).getMaximum()) - self.assertEquals("['2.00zeta', 0, 0]", out_md.getDimension(0).getName() ) - self.assertEquals("[0, '2.00eta', 0]", out_md.getDimension(1).getName() ) - self.assertEquals("[0, 0, '-4.00xi']", out_md.getDimension(2).getName() ) - - - def test_non_orthogonal_slice(self): - # We create a fake workspace and check to see that the extents get transformed to the new coordinate system. - to_cut = CreateMDWorkspace(Dimensions=3, Extents=[-1,1,-1,1,-1,1], Names='H,K,L', Units='U,U,U') - # Set the UB - SetUB(Workspace=to_cut, a = 1, b = 1, c = 1, alpha =90, beta=90, gamma = 90) - SetSpecialCoordinates(InputWorkspace=to_cut, SpecialCoordinates='HKL') - - projection = CreateEmptyTableWorkspace() - # Correct number of columns, and names - projection.addColumn("str", "name") - projection.addColumn("str", "value") - projection.addColumn("double", "offset") - projection.addColumn("str", "type") - - projection.addRow(["u", "1,1,0", 0.0, "r"]) - projection.addRow(["v","-1,1,0", 0.0, "r"]) - projection.addRow(["w", "0,0,1", 0.0, "r"]) - - out_md = CutMD(to_cut, Projection=projection, P1Bin=[0.1], P2Bin=[0.1], P3Bin=[0.1], NoPix=True) - - ''' - Here we check that the corners in HKL end up in the expected positions when transformed into the new scaled basis - provided by the W transform (projection table) - ''' - self.assertEquals(-1, out_md.getDimension(0).getMinimum()) - self.assertEquals(1, out_md.getDimension(0).getMaximum()) - self.assertEquals(-1, out_md.getDimension(1).getMinimum()) - self.assertEquals(1, out_md.getDimension(1).getMaximum()) - self.assertEquals(-1, out_md.getDimension(2).getMinimum()) - self.assertEquals(1, out_md.getDimension(2).getMaximum()) - self.assertEquals("['zeta', 'zeta', 0]", out_md.getDimension(0).getName() ) - self.assertEquals("['-eta', 'eta', 0]", out_md.getDimension(1).getName() ) - self.assertEquals("[0, 0, 'xi']", out_md.getDimension(2).getName() ) - - self.assertTrue(isinstance(out_md, IMDHistoWorkspace), "Expect that the output was an IMDHistoWorkspace given the NoPix flag.") - - run = out_md.getExperimentInfo(0).run() - w_matrix = run.getLogData("W_MATRIX").value - w_matrix = list(w_matrix) - self.assertEquals([1,1,0,-1,1,0,0,0,1], w_matrix, "W-matrix should have been set, but should be an identity matrix") - - def test_orthogonal_slice_with_cropping(self): - # We create a fake workspace and check to see that using bin inputs for cropping works - to_cut = CreateMDWorkspace(Dimensions=3, Extents=[-1,1,-1,1,-1,1], Names='H,K,L', Units='U,U,U') - # Set the UB - SetUB(Workspace=to_cut, a = 1, b = 1, c = 1, alpha =90, beta=90, gamma = 90) - SetSpecialCoordinates(InputWorkspace=to_cut, SpecialCoordinates='HKL') - - projection = CreateEmptyTableWorkspace() - # Correct number of columns, and names - projection.addColumn("str", "name") - projection.addColumn("str", "value") - projection.addColumn("double", "offset") - projection.addColumn("str", "type") - - projection.addRow(["u", "1,0,0", 0, "r"]) - projection.addRow(["v", "0,1,0", 0, "r"]) - projection.addRow(["w", "0,0,1", 0, "r"]) - - ''' - Specify the cropping boundaries as part of the bin inputs. - ''' - out_md = CutMD(to_cut, Projection=projection, P1Bin=[-0.5,0.5], P2Bin=[-0.1,0.1], P3Bin=[-0.3,0.3], NoPix=True) - - ''' - Here we check that the corners in HKL end up in the expected positions when transformed into the new scaled basis - provided by the W transform (projection table) - ''' - self.assertAlmostEqual(-0.5, out_md.getDimension(0).getMinimum(), 6) - self.assertAlmostEqual(0.5, out_md.getDimension(0).getMaximum(), 6) - self.assertAlmostEqual(-0.1, out_md.getDimension(1).getMinimum(), 6) - self.assertAlmostEqual(0.1, out_md.getDimension(1).getMaximum(), 6) - self.assertAlmostEqual(-0.3, out_md.getDimension(2).getMinimum(), 6) - self.assertAlmostEqual(0.3, out_md.getDimension(2).getMaximum(), 6) - self.assertEquals("['zeta', 0, 0]", out_md.getDimension(0).getName() ) - self.assertEquals("[0, 'eta', 0]", out_md.getDimension(1).getName() ) - self.assertEquals("[0, 0, 'xi']", out_md.getDimension(2).getName() ) - - self.assertTrue(isinstance(out_md, IMDHistoWorkspace), "Expect that the output was an IMDHistoWorkspace given the NoPix flag.") - - def test_orthogonal_slice_4D(self): - # We create a fake 4-D workspace and check to see that using bin inputs for cropping works - to_cut = CreateMDWorkspace(Dimensions=4, Extents=[-1,1,-1,1,-1,1,-10,10], Names='H,K,L,E', Units='U,U,U,V') - # Set the UB - SetUB(Workspace=to_cut, a = 1, b = 1, c = 1, alpha =90, beta=90, gamma = 90) - SetSpecialCoordinates(InputWorkspace=to_cut, SpecialCoordinates='HKL') - - ''' - Process the 4D workspace - ''' - out_md = CutMD(to_cut, P1Bin=[-0.5,0.5], P2Bin=[-0.1,0.1], P3Bin=[-0.3,0.3], P4Bin=[1], NoPix=True) - - - self.assertAlmostEqual(-0.5, out_md.getDimension(0).getMinimum(), 6) - self.assertAlmostEqual(0.5, out_md.getDimension(0).getMaximum(), 6) - self.assertAlmostEqual(-0.1, out_md.getDimension(1).getMinimum(), 6) - self.assertAlmostEqual(0.1, out_md.getDimension(1).getMaximum(), 6) - self.assertAlmostEqual(-0.3, out_md.getDimension(2).getMinimum(), 6) - self.assertAlmostEqual(0.3, out_md.getDimension(2).getMaximum(), 6) - self.assertAlmostEqual(-10, out_md.getDimension(3).getMinimum(), 6) - self.assertAlmostEqual(10, out_md.getDimension(3).getMaximum(), 6) - self.assertEqual(20, out_md.getDimension(3).getNBins()) - - self.assertEquals("['zeta', 0, 0]", out_md.getDimension(0).getName() ) - self.assertEquals("[0, 'eta', 0]", out_md.getDimension(1).getName() ) - self.assertEquals("[0, 0, 'xi']", out_md.getDimension(2).getName() ) - self.assertEquals("E", out_md.getDimension(3).getName() ) - - self.assertTrue(isinstance(out_md, IMDHistoWorkspace), "Expect that the output was an IMDHistoWorkspace given the NoPix flag.") - - ''' - Process the 4D workspace again, this time with different binning - ''' - out_md = CutMD(to_cut, P1Bin=[-0.5,0.5], P2Bin=[-0.1,0.1], P3Bin=[-0.3,0.3], P4Bin=[-8,1,8], NoPix=True) - self.assertEqual(16, out_md.getDimension(3).getNBins()) - self.assertTrue(isinstance(out_md, IMDHistoWorkspace), "Expect that the output was an IMDHistoWorkspace given the NoPix flag.") - - -if __name__ == '__main__': - unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/AddSampleLogMultipleTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/AddSampleLogMultipleTest.py new file mode 100644 index 0000000000000000000000000000000000000000..8dda9002746d6dbda8878e86e9abecc2d45e1793 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/AddSampleLogMultipleTest.py @@ -0,0 +1,122 @@ +import unittest +from mantid.simpleapi import * +from mantid.api import * + + +class AddSampleLogMultipleTest(unittest.TestCase): + + def setUp(self): + """ + Crates a small sample workspace to test with. + """ + CreateSampleWorkspace(OutputWorkspace='__AddSampleLogMultiple_test', + NumBanks=1, + BankPixelWidth=1, + XMax=10, + BinWidth=1) + self._workspace = mtd['__AddSampleLogMultiple_test'] + + + def tearDown(self): + """ + Removes sample workspaces. + """ + DeleteWorkspace(self._workspace) + + + def _validate_sample_logs(self, names, values, types): + """ + Validates sample logs set on workspace. + + @param names List of sample log names + @param values List of sample log values + @param types List of sample log types + """ + logs = self._workspace.getSampleDetails().getLogData() + matched_logs = list() + + for log in logs: + if log.name in names: + matched_logs.append(log.name) + idx = names.index(log.name) + + self.assertEqual(log.value, values[idx]) + self.assertEqual(log.type, types[idx]) + + self.assertEqual(matched_logs, names) + + + def test_strings(self): + """ + Tests adding multiple strings. + """ + names = ['a', 'b', 'c'] + values = ['one', 'two', 'three'] + types = ['string', 'string', 'string'] + + AddSampleLogMultiple(Workspace=self._workspace, + LogNames=names, + LogValues=values) + + self._validate_sample_logs(names, values, types) + + + def test_strings_and_numbers(self): + """ + Tests adding multiple strings and numbers. + """ + names = ['a', 'b', 'c', 'd', 'e', 'f'] + values = ['one', 'two', 'three', 4, 5.5, 6e2] + types = ['string', 'string', 'string', 'number', 'number', 'number'] + + AddSampleLogMultiple(Workspace=self._workspace, + LogNames=names, + LogValues=values) + + self._validate_sample_logs(names, values, types) + + + def test_validation_no_names(self): + """ + Test validation for no log names. + """ + names = [] + values = ['one', 'two', 'three'] + + self.assertRaises(RuntimeError, + AddSampleLogMultiple, + Workspace=self._workspace, + LogNames=names, + LogValues=values) + + + def test_validation_no_values(self): + """ + Test validation for no log values. + """ + names = ['a', 'b', 'c'] + values = [] + + self.assertRaises(RuntimeError, + AddSampleLogMultiple, + Workspace=self._workspace, + LogNames=names, + LogValues=values) + + + def test_validation_differing_counts(self): + """ + Test validation for differing numbers of log names and log values. + """ + names = ['a', 'b', 'c'] + values = ['one', 'two'] + + self.assertRaises(RuntimeError, + AddSampleLogMultiple, + Workspace=self._workspace, + LogNames=names, + LogValues=values) + + +if __name__ == '__main__': + unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/ApplyPaalmanPingsCorrectionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/ApplyPaalmanPingsCorrectionTest.py new file mode 100644 index 0000000000000000000000000000000000000000..581f3c7e413c935893d8e79bcba6f42cb0f58a52 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/ApplyPaalmanPingsCorrectionTest.py @@ -0,0 +1,118 @@ +import unittest +from mantid.kernel import * +from mantid.api import * +from mantid.simpleapi import Load, ConvertUnits, SplineInterpolation, ApplyPaalmanPingsCorrection, DeleteWorkspace + + +class ApplyPaalmanPingsCorrectionTest(unittest.TestCase): + + def setUp(self): + """ + Create sample workspaces. + """ + + # Load the sample and can + sample_ws = Load('irs26176_graphite002_red.nxs') + can_ws = Load('irs26173_graphite002_red.nxs') + + # Convert sample and can to wavelength + sample_ws = ConvertUnits(InputWorkspace=sample_ws, + Target='Wavelength', + EMode='Indirect', + EFixed=1.845) + can_ws = ConvertUnits(InputWorkspace=can_ws, + Target='Wavelength', + EMode='Indirect', + EFixed=1.845) + + self._sample_ws = sample_ws + self._can_ws = can_ws + + # Load the corrections workspace + corrections = Load('irs26176_graphite002_cyl_Abs.nxs') + + # Interpolate each of the correction factor workspaces + # Required to use corrections from the old indirect calculate + # corrections routines + for factor_ws in corrections: + SplineInterpolation(WorkspaceToMatch=sample_ws, + WorkspaceToInterpolate=factor_ws, + OutputWorkspace=factor_ws, + OutputWorkspaceDeriv='') + + self._corrections_ws = corrections + + + def tearDown(self): + """ + Remove workspaces from ADS. + """ + + DeleteWorkspace(self._sample_ws) + DeleteWorkspace(self._can_ws) + DeleteWorkspace(self._corrections_ws) + + + def _verify_workspace(self, ws, correction_type): + """ + Do validation on a correction workspace. + + @param ws Workspace to validate + @param correction_type Type of correction that should hav ebeen applied + """ + + # X axis should be in wavelength + x_unit = ws.getAxis(0).getUnit().unitID() + self.assertEquals(x_unit, 'Wavelength') + + # Sample logs should contain correction type + logs = ws.getSampleDetails() + self.assertTrue('corrections_type' in logs) + + # Ensure value from sample log is correct + if 'corrections_type' in logs: + log_correction_type = logs['corrections_type'].value + self.assertEqual(log_correction_type, correction_type) + + + def test_can_subtraction(self): + corr = ApplyPaalmanPingsCorrection(SampleWorkspace=self._sample_ws, + CanWorkspace=self._can_ws) + + self._verify_workspace(corr, 'can_subtraction') + + + def test_can_subtraction_with_can_scale(self): + corr = ApplyPaalmanPingsCorrection(SampleWorkspace=self._sample_ws, + CanWorkspace=self._can_ws, + CanScaleFactor=0.9) + + self._verify_workspace(corr, 'can_subtraction') + + + def test_sample_corrections_only(self): + corr = ApplyPaalmanPingsCorrection(SampleWorkspace=self._sample_ws, + CorrectionsWorkspace=self._corrections_ws) + + self._verify_workspace(corr, 'sample_corrections_only') + + + def test_sample_and_can_corrections(self): + corr = ApplyPaalmanPingsCorrection(SampleWorkspace=self._sample_ws, + CorrectionsWorkspace=self._corrections_ws, + CanWorkspace=self._can_ws) + + self._verify_workspace(corr, 'sample_and_can_corrections') + + + def test_sample_and_can_corrections_with_can_scale(self): + corr = ApplyPaalmanPingsCorrection(SampleWorkspace=self._sample_ws, + CorrectionsWorkspace=self._corrections_ws, + CanWorkspace=self._can_ws, + CanScaleFactor=0.9) + + self._verify_workspace(corr, 'sample_and_can_corrections') + + +if __name__=="__main__": + unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt index bc814404ca605fb4f612f4d2acc5d62a53d98b4c..77b67b9edc8f9142c083ae3d3004f4ffe577537f 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt @@ -3,13 +3,16 @@ ## set ( TEST_PY_FILES + AddSampleLogMultipleTest.py + ApplyPaalmanPingsCorrectionTest.py CalculateSampleTransmissionTest.py CheckForSampleLogsTest.py ConjoinSpectraTest.py CorrectLogTimesTest.py CreateLeBailFitInputTest.py - CreateCalibrationWorkspaceTest.py + IndirectCalibrationTest.py CreateWorkspaceTest.py + CylinderPaalmanPingsCorrectionTest.py DakotaChiSquaredTest.py DensityOfStatesTest.py DSFinterpTest.py @@ -17,10 +20,14 @@ set ( TEST_PY_FILES FindReflectometryLinesTest.py FlatPlatePaalmanPingsCorrectionTest.py GetEiT0atSNSTest.py + IndirectAnnulusAbsorptionTest.py + IndirectCylinderAbsorptionTest.py + IndirectFlatPlateAbsorptionTest.py IndirectILLReductionTest.py InelasticIndirectReductionTest.py IndirectTransmissionTest.py IndirectTransmissionMonitorTest.py + LoadDNSLegacyTest.py LoadFullprofFileTest.py LoadLiveDataTest.py LoadLogPropertyTableTest.py @@ -31,6 +38,7 @@ set ( TEST_PY_FILES MeanTest.py MergeCalFilesTest.py MolDynTest.py + MSDFitTest.py PDDetermineCharacterizationsTest.py RetrieveRunInfoTest.py SANSWideAngleCorrectionTest.py @@ -47,10 +55,12 @@ set ( TEST_PY_FILES UpdatePeakParameterTableValueTest.py SANSSubtractTest.py TimeSliceTest.py + TransformToIqtTest.py ExportSampleLogsToCSVFileTest.py ExportExperimentLogTest.py PoldiMergeTest.py VesuvioResolutionTest.py + PoldiCreatePeaksFromFileTest.py ) check_tests_valid ( ${CMAKE_CURRENT_SOURCE_DIR} ${TEST_PY_FILES} ) diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CylinderPaalmanPingsCorrectionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CylinderPaalmanPingsCorrectionTest.py new file mode 100644 index 0000000000000000000000000000000000000000..27955836344d640a0a31f0eab286adac148a61ab --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CylinderPaalmanPingsCorrectionTest.py @@ -0,0 +1,193 @@ +import unittest +from mantid.kernel import * +from mantid.api import * +from mantid.simpleapi import CreateSampleWorkspace, Scale, DeleteWorkspace, CylinderPaalmanPingsCorrection, CreateSimulationWorkspace +from IndirectImport import is_supported_f2py_platform + + +class CylinderPaalmanPingsCorrectionTest(unittest.TestCase): + + def setUp(self): + """ + Create sample workspaces. + """ + + # Create some test data + sample = CreateSampleWorkspace(NumBanks=1, + BankPixelWidth=1, + XUnit='Wavelength', + XMin=6.8, + XMax=7.9, + BinWidth=0.1) + self._sample_ws = sample + + can = Scale(InputWorkspace=sample, Factor=1.2) + self._can_ws = can + + self._corrections_ws_name = 'corrections' + + + def tearDown(self): + """ + Remove workspaces from ADS. + """ + + DeleteWorkspace(self._sample_ws) + DeleteWorkspace(self._can_ws) + + if self._corrections_ws_name in mtd: + DeleteWorkspace(self._corrections_ws_name) + + + def _verify_workspace(self, ws_name): + """ + Do validation on a correction workspace. + + @param ws_name Name of workspace to validate + """ + + corrections_ws = mtd[self._corrections_ws_name] + + # Check it is in the corrections workspace group + self.assertTrue(corrections_ws.contains(ws_name)) + + test_ws = mtd[ws_name] + + # Check workspace is in wavelength + self.assertEqual(test_ws.getAxis(0).getUnit().unitID(), + 'Wavelength') + + # Check it has the same number of spectra as the sample + self.assertEqual(test_ws.getNumberHistograms(), + self._sample_ws.getNumberHistograms()) + + # Check it has X binning matching sample workspace + self.assertEqual(test_ws.blocksize(), self._sample_ws.blocksize()) + + + def _verify_workspaces_for_can(self): + """ + Do validation on the additional correction factors for sample and can. + """ + + ass_ws_name = self._corrections_ws_name + '_ass' + assc_ws_name = self._corrections_ws_name + '_assc' + acsc_ws_name = self._corrections_ws_name + '_acsc' + acc_ws_name = self._corrections_ws_name + '_acc' + + workspaces = [ass_ws_name, assc_ws_name, acsc_ws_name, acc_ws_name] + + for workspace in workspaces: + self._verify_workspace(workspace) + + + def test_sampleOnly(self): + """ + Test simple run with sample workspace only. + """ + + # Just pass if we can't actually run the algorithm + if not is_supported_f2py_platform(): + return + + CylinderPaalmanPingsCorrection(OutputWorkspace=self._corrections_ws_name, + SampleWorkspace=self._sample_ws, + SampleChemicalFormula='H2-O', + SampleInnerRadius=0.05, + SampleOuterRadius=0.1, + Emode='Indirect', + Efixed=1.845) + + ass_ws_name = self._corrections_ws_name + '_ass' + self. _verify_workspace(ass_ws_name) + + + def test_sampleAndCan(self): + """ + Test simple run with sample and can workspace. + """ + + # Just pass if we can't actually run the algorithm + if not is_supported_f2py_platform(): + return + + CylinderPaalmanPingsCorrection(OutputWorkspace=self._corrections_ws_name, + SampleWorkspace=self._sample_ws, + SampleChemicalFormula='H2-O', + SampleInnerRadius=0.05, + SampleOuterRadius=0.1, + CanWorkspace=self._can_ws, + CanChemicalFormula='V', + CanOuterRadius=0.15, + BeamHeight=0.1, + BeamWidth=0.1, + Emode='Indirect', + Efixed=1.845) + + self._verify_workspaces_for_can() + + + def test_sampleAndCanDefaults(self): + """ + Test simple run with sample and can workspace using the default values. + """ + + # Just pass if we can't actually run the algorithm + if not is_supported_f2py_platform(): + return + + CylinderPaalmanPingsCorrection(OutputWorkspace=self._corrections_ws_name, + SampleWorkspace=self._sample_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=self._can_ws, + CanChemicalFormula='V') + + self._verify_workspaces_for_can() + + + def test_InterpolateDisabled(self): + """ + Tests that a workspace with a bin count equal to NumberWavelengths is created + when interpolation is disabled. + """ + + # Just pass if we can't actually run the algorithm + if not is_supported_f2py_platform(): + return + + CylinderPaalmanPingsCorrection(OutputWorkspace=self._corrections_ws_name, + SampleWorkspace=self._sample_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=self._can_ws, + CanChemicalFormula='V', + Interpolate=False) + + corrections_ws = mtd[self._corrections_ws_name] + + # Check each correction workspace has X binning matching NumberWavelengths + for workspace in corrections_ws: + self.assertEqual(workspace.blocksize(), 10) + + + def test_validationNoCanFormula(self): + """ + Tests validation for no chemical formula for can when a can WS is provided. + """ + + self.assertRaises(RuntimeError, + CylinderPaalmanPingsCorrection, + OutputWorkspace=self._corrections_ws_name, + SampleWorkspace=self._sample_ws, + SampleChemicalFormula='H2-O', + SampleInnerRadius=0.05, + SampleOuterRadius=0.1, + CanWorkspace=self._can_ws, + CanOuterRadius=0.15, + BeamHeight=0.1, + BeamWidth=0.1, + Emode='Indirect', + Efixed=1.845) + + +if __name__=="__main__": + unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/FlatPlatePaalmanPingsCorrectionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/FlatPlatePaalmanPingsCorrectionTest.py index a397c69d3458d038fe6e2cc5caf9d53afd088ff4..13732907fdfc99f888071f0d58b0414d6ffbcf83 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/FlatPlatePaalmanPingsCorrectionTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/FlatPlatePaalmanPingsCorrectionTest.py @@ -1,7 +1,7 @@ import unittest from mantid.kernel import * from mantid.api import * -from mantid.simpleapi import CreateSampleWorkspace, Scale, DeleteWorkspace, FlatPlatePaalmanPingsCorrection +from mantid.simpleapi import CreateSampleWorkspace, Scale, DeleteWorkspace, FlatPlatePaalmanPingsCorrection, CreateSimulationWorkspace class FlatPlatePaalmanPingsCorrectionTest(unittest.TestCase): @@ -11,12 +11,13 @@ class FlatPlatePaalmanPingsCorrectionTest(unittest.TestCase): Create sample workspaces. """ - sample = CreateSampleWorkspace(NumBanks=5, - BankPixelWidth=2, - XUnit='Wavelength', - XMin=6.8, - XMax=7.9, - BinWidth=0.1) + # Create some test data + sample = CreateSampleWorkspace(NumBanks=1, + BankPixelWidth=1, + XUnit='Wavelength', + XMin=6.8, + XMax=7.9, + BinWidth=0.1) self._sample_ws = sample can = Scale(InputWorkspace=sample, Factor=1.2) @@ -59,8 +60,8 @@ class FlatPlatePaalmanPingsCorrectionTest(unittest.TestCase): self.assertEqual(test_ws.getNumberHistograms(), self._sample_ws.getNumberHistograms()) - # Check it has X binning matching NumWavelengths - self.assertEqual(test_ws.blocksize(), 10) + # Check it has X binning matching sample workspace + self.assertEqual(test_ws.blocksize(), self._sample_ws.blocksize()) def _verify_workspaces_for_can(self): @@ -132,6 +133,27 @@ class FlatPlatePaalmanPingsCorrectionTest(unittest.TestCase): self._verify_workspaces_for_can() + def test_InterpolateDisabled(self): + """ + Tests that a workspace with a bin count equal to NumberWavelengths is created + when interpolation is disabled. + """ + + FlatPlatePaalmanPingsCorrection(OutputWorkspace=self._corrections_ws_name, + SampleWorkspace=self._sample_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=self._can_ws, + CanChemicalFormula='V', + NumberWavelengths=20, + Interpolate=False) + + corrections_ws = mtd[self._corrections_ws_name] + + # Check each correction workspace has X binning matching NumberWavelengths + for workspace in corrections_ws: + self.assertEqual(workspace.blocksize(), 20) + + def test_validationNoCanFormula(self): """ Tests validation for no chemical formula for can when a can WS is provided. diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectAnnulusAbsorptionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectAnnulusAbsorptionTest.py new file mode 100644 index 0000000000000000000000000000000000000000..c03efb8664f6fb7fe5e5e58d0da154664859a1c7 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectAnnulusAbsorptionTest.py @@ -0,0 +1,105 @@ +import unittest +from mantid.simpleapi import * +from mantid.api import * + + +class IndirectAnnulusAbsorptionTest(unittest.TestCase): + + def setUp(self): + """ + Loads the reduced container and sample files. + """ + + can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs') + red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs') + + self._can_ws = can_ws + self._red_ws = red_ws + + + def _test_workspaces(self, corrected, factor_group): + """ + Checks the units of the Ass and corrected workspaces. + + @param corrected Corrected workspace + @param factor_group WorkspaceGroup containing factors + """ + + # Test units of corrected workspace + corrected_x_unit = corrected.getAxis(0).getUnit().unitID() + self.assertEqual(corrected_x_unit, 'DeltaE') + + # Test units of factor workspaces + for ws in factor_group: + x_unit = ws.getAxis(0).getUnit().unitID() + self.assertEquals(x_unit, 'Wavelength') + + y_unit = ws.YUnitLabel() + self.assertEqual(y_unit, 'Attenuation factor') + + + def test_sample_corrections_only(self): + """ + Tests corrections for the sample only. + """ + + corrected, fact = IndirectAnnulusAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + Events=200, + UseCanCorrections=False) + + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) + + + def test_sample_and_can_subtraction(self): + """ + Tests corrections for the sample and simple container subtraction. + """ + + corrected, fact = IndirectAnnulusAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=self._can_ws, + Events=200, + UseCanCorrections=False) + + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) + + + def test_sample_and_can_subtraction_with_scale(self): + """ + Tests corrections for the sample and simple container subtraction + with can scale. + """ + + corrected, fact = IndirectAnnulusAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=self._can_ws, + CanScaleFactor=0.8, + Events=200, + UseCanCorrections=False) + + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) + + + def test_sample_and_can_corrections(self): + """ + Tests corrections for the sample and container. + """ + + corrected, fact = IndirectAnnulusAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=self._can_ws, + CanChemicalFormula='V', + CanScaleFactor=0.8, + Events=200, + UseCanCorrections=True) + + self.assertEqual(fact.size(), 2) + self._test_workspaces(corrected, fact) + + +if __name__ == '__main__': + unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CreateCalibrationWorkspaceTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectCalibrationTest.py similarity index 69% rename from Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CreateCalibrationWorkspaceTest.py rename to Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectCalibrationTest.py index ced70c8a2ab1ff7cf108b981170c34155a4c12ae..5c9e235384f8deec6e73b35acece65ea53b60b7f 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CreateCalibrationWorkspaceTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectCalibrationTest.py @@ -1,12 +1,12 @@ import unittest import mantid -from mantid.simpleapi import CreateCalibrationWorkspace +from mantid.simpleapi import IndirectCalibration -class CreateCalibrationWorkspaceTest(unittest.TestCase): +class IndirectCalibrationTest(unittest.TestCase): def test_simple(self): - cal_ws = CreateCalibrationWorkspace(InputFiles='IRS38633.raw', + cal_ws = IndirectCalibration(InputFiles='IRS38633.raw', DetectorRange=[3,53], PeakRange=[62000,65000], BackgroundRange=[59000,61000]) diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectCylinderAbsorptionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectCylinderAbsorptionTest.py new file mode 100644 index 0000000000000000000000000000000000000000..cf422a7a7553bcb6b2b24f542ebda132d0b81102 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectCylinderAbsorptionTest.py @@ -0,0 +1,103 @@ +import unittest +from mantid.simpleapi import * +from mantid.api import * + + +class IndirectCylinderAbsorptionTest(unittest.TestCase): + + def setUp(self): + """ + Loads the reduced container and sample files. + """ + + can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs') + red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs') + + self._can_ws = can_ws + self._red_ws = red_ws + + + def _test_workspaces(self, corrected, factor_group): + """ + Checks the units of the Ass and corrected workspaces. + + @param corrected Corrected workspace + @param factor_group WorkspaceGroup containing factors + """ + + # Test units of corrected workspace + corrected_x_unit = corrected.getAxis(0).getUnit().unitID() + self.assertEqual(corrected_x_unit, 'DeltaE') + + # Test units of factor workspaces + for ws in factor_group: + x_unit = ws.getAxis(0).getUnit().unitID() + self.assertEquals(x_unit, 'Wavelength') + + y_unit = ws.YUnitLabel() + self.assertEqual(y_unit, 'Attenuation factor') + + + def test_sample_corrections_only(self): + """ + Tests corrections for the sample only. + """ + + corrected, fact = IndirectCylinderAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + Events=500) + + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) + + + def test_sample_and_can_subtraction(self): + """ + Tests corrections for the sample and simple container subtraction. + """ + + corrected, fact = IndirectCylinderAbsorption(SampleWorkspace=self._red_ws, + CanWorkspace=self._can_ws, + SampleChemicalFormula='H2-O', + UseCanCorrections=False, + Events=500) + + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) + + + def test_sample_and_can_subtraction_with_scale(self): + """ + Tests corrections for the sample and simple container subtraction + with can scale. + """ + + corrected, fact = IndirectCylinderAbsorption(SampleWorkspace=self._red_ws, + CanWorkspace=self._can_ws, + CanScaleFactor=0.8, + SampleChemicalFormula='H2-O', + UseCanCorrections=False, + Events=500) + + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) + + + def test_sample_and_can_corrections(self): + """ + Tests corrections for the sample and container. + """ + + corrected, fact = IndirectCylinderAbsorption(SampleWorkspace=self._red_ws, + CanWorkspace=self._can_ws, + SampleChemicalFormula='H2-O', + CanChemicalFormula='V', + UseCanCorrections=True, + Events=500) + + self.assertEqual(fact.size(), 2) + self._test_workspaces(corrected, fact) + + +if __name__ == '__main__': + unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectFlatPlateAbsorptionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectFlatPlateAbsorptionTest.py new file mode 100644 index 0000000000000000000000000000000000000000..48a9dcc6c0621d335b9a1f93b6ac79b626a82754 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectFlatPlateAbsorptionTest.py @@ -0,0 +1,103 @@ +import unittest +from mantid.simpleapi import * +from mantid.api import * + + +class IndirectFlatPlateAbsorptionTest(unittest.TestCase): + + def setUp(self): + """ + Loads the reduced container and sample files. + """ + + can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs') + red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs') + + self._can_ws = can_ws + self._red_ws = red_ws + + + def _test_workspaces(self, corrected, factor_group): + """ + Checks the units of the Ass and corrected workspaces. + + @param corrected Corrected workspace + @param factor_group WorkspaceGroup containing factors + """ + + # Test units of corrected workspace + corrected_x_unit = corrected.getAxis(0).getUnit().unitID() + self.assertEqual(corrected_x_unit, 'DeltaE') + + # Test units of factor workspaces + for ws in factor_group: + x_unit = ws.getAxis(0).getUnit().unitID() + self.assertEquals(x_unit, 'Wavelength') + + y_unit = ws.YUnitLabel() + self.assertEqual(y_unit, 'Attenuation factor') + + + def test_sample_corrections_only(self): + """ + Tests corrections for the sample only. + """ + + corrected, fact = IndirectFlatPlateAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + ElementSize=1) + + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) + + + def test_sample_and_can_subtraction(self): + """ + Tests corrections for the sample and simple container subtraction. + """ + + corrected, fact = IndirectFlatPlateAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=self._can_ws, + ElementSize=1, + UseCanCorrections=False) + + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) + + + def test_sample_and_can_subtraction_with_scale(self): + """ + Tests corrections for the sample and simple container subtraction + with can scale. + """ + + corrected, fact = IndirectFlatPlateAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=self._can_ws, + CanScaleFactor=0.8, + ElementSize=1, + UseCanCorrections=False) + + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) + + + def test_sample_and_can_correction(self): + """ + Tests corrections for the sample and container. + """ + + corrected, fact = IndirectFlatPlateAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=self._can_ws, + CanChemicalFormula='V', + ElementSize=1, + UseCanCorrections=True) + + self.assertEqual(fact.size(), 2) + self._test_workspaces(corrected, fact) + + +if __name__ == '__main__': + unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/InelasticIndirectReductionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/InelasticIndirectReductionTest.py index 576a0bbf5e5c922f1310071f189b006c377124f8..ef51954f33eb75801cbdd116de8c1f1f37c8e997 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/InelasticIndirectReductionTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/InelasticIndirectReductionTest.py @@ -11,8 +11,7 @@ class InelasticIndirectReductionTest(unittest.TestCase): Instrument='IRIS', Analyser='graphite', Reflection='002', - DetectorRange=[3, 53], - SaveFormats=['nxs']) + DetectorRange=[3, 53]) reduction_workspace = mtd['IndirectReductions'].getItem(0) self.assertEquals(reduction_workspace.getName(), 'irs26176_graphite002_red') diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/LoadDNSLegacyTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/LoadDNSLegacyTest.py new file mode 100644 index 0000000000000000000000000000000000000000..bf8977363dcbcd8fb2e2e425c124506a69166619 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/LoadDNSLegacyTest.py @@ -0,0 +1,40 @@ +from mantid.kernel import * +import mantid.simpleapi as api +import unittest +from testhelpers import run_algorithm +from mantid.api import AnalysisDataService +from math import pi + + +class LoadDNSLegacyTest(unittest.TestCase): + + def test_LoadValidData(self): + outputWorkspaceName = "LoadDNSLegacyTest_Test1" + filename = "dn134011vana.d_dat" + alg_test = run_algorithm("LoadDNSLegacy", Filename = filename, \ + OutputWorkspace = outputWorkspaceName) + + self.assertTrue(alg_test.isExecuted()) + + #Verify some values + ws = AnalysisDataService.retrieve(outputWorkspaceName) + # dimensions + self.assertEqual(24, ws.getNumberHistograms()) + self.assertEqual(2, ws.getNumDims()) + # data array + self.assertEqual(31461, ws.readY(1)) + self.assertEqual(13340, ws.readY(23)) + # sample logs + logs = ws.getRun().getLogData() + self.assertEqual('deterota', logs[4].name) + self.assertEqual(-8.54, logs[4].value) + # check whether detector bank is rotated + samplePos = ws.getInstrument().getSample().getPos() + beamDirection = V3D(0,0,1) + det = ws.getDetector(1) + self.assertAlmostEqual(8.54, det.getTwoTheta(samplePos, beamDirection)*180/pi) + run_algorithm("DeleteWorkspace", Workspace = outputWorkspaceName) + return + +if __name__ == '__main__': + unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/MSDFitTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/MSDFitTest.py new file mode 100644 index 0000000000000000000000000000000000000000..d34b9936dbf6ac32446c0ffc4cfca645622f7edc --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/MSDFitTest.py @@ -0,0 +1,135 @@ +import unittest +from mantid.simpleapi import * +from mantid.api import * + +class MSDFitTest(unittest.TestCase): + + def setUp(self): + """ + Creates a sample workspace for testing. + """ + + sample = CreateSampleWorkspace(Function='User Defined', + UserDefinedFunction='name=ExpDecay,Height=1,Lifetime=6', + NumBanks=5, BankPixelWidth=1, XUnit='QSquared', XMin=0.0, + XMax=5.0, BinWidth=0.1) + self._ws = sample + + + def _validate_workspaces(self, msd_ws, param_ws, fit_ws): + """ + Validates the various workspaces produced by MSDFit. + + @param msd_ws The MSD workspace + @param param_ws The fit parameter table workspace + @param fit_ws The fit workspace group + """ + + # First validate workspace types + self.assertTrue(isinstance(msd_ws, WorkspaceGroup), 'MSD workspace should be a WorkspaceGroup') + self.assertTrue(isinstance(param_ws, ITableWorkspace), 'Fit parameter workspace should be a TableWorkspace') + self.assertTrue(isinstance(fit_ws, WorkspaceGroup), 'Fit workspace should be a WorkspaceGroup') + + # Validate number of items in groups + self.assertEqual(msd_ws.getNumberOfEntries(), 2) + self.assertEqual(fit_ws.getNumberOfEntries(), 5) + + # Validate MSD property workspaces + self.assertEqual(msd_ws[0].name(), 'msd_A0') + self.assertEqual(msd_ws[1].name(), 'msd_A1') + self.assertEqual(len(msd_ws[0].readX(0)), 5) + self.assertEqual(len(msd_ws[1].readX(0)), 5) + + + def test_basic_run(self): + """ + Tests a basic run providing the MSD workspace as output. + """ + + MSDFit(InputWorkspace=self._ws, + XStart=0.0, XEnd=5.0, + SpecMin=0, SpecMax=4, + OutputWorkspace='msd') + + self.assertTrue(mtd.doesExist('msd_Parameters'), 'Should have a parameter WS with the default name') + self.assertTrue(mtd.doesExist('msd_Workspaces'), 'Should have a fit WS with the default name') + self._validate_workspaces(mtd['msd'], mtd['msd_Parameters'], mtd['msd_Workspaces']) + + + def test_basic_run_given_names(self): + """ + Tests a basic run providing names of all output workspaces. + """ + + msd, param, fit = MSDFit(InputWorkspace=self._ws, + XStart=0.0, XEnd=5.0, + SpecMin=0, SpecMax=4) + + self._validate_workspaces(msd, param, fit) + + + def test_fail_spec_min(self): + """ + Tests validation for SpecMin >= 0. + """ + + with self.assertRaises(RuntimeError): + msd, param, fit = MSDFit(InputWorkspace=self._ws, + XStart=0.0, XEnd=5.0, + SpecMin=-1, SpecMax=0) + + + def test_fail_spec_min(self): + """ + Tests validation for SpecMin >= num histograms. + """ + + self.assertRaises(RuntimeError, + MSDFit, + InputWorkspace=self._ws, + XStart=0.0, XEnd=5.0, + SpecMin=0, SpecMax=20, + OutputWorkspace='msd') + + + def test_fail_spec_range(self): + """ + Test svalidation for SpecMax >= SpecMin. + """ + + self.assertRaises(RuntimeError, + MSDFit, + InputWorkspace=self._ws, + XStart=0.0, XEnd=5.0, + SpecMin=1, SpecMax=0, + OutputWorkspace='msd') + + + def test_fail_x_range(self): + """ + Tests validation for XStart < XEnd. + """ + + self.assertRaises(RuntimeError, + MSDFit, + InputWorkspace=self._ws, + XStart=10.0, XEnd=5.0, + SpecMin=0, SpecMax=0, + OutputWorkspace='msd') + + + def test_fail_x_range_ws(self): + """ + Tests validation for X range in workspace range + """ + + self.assertRaises(RuntimeError, + MSDFit, + InputWorkspace=self._ws, + XStart=0.0, XEnd=20.0, + SpecMin=0, SpecMax=0, + OutputWorkspace='msd') + + +if __name__ == '__main__': + unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/PoldiCreatePeaksFromFileTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/PoldiCreatePeaksFromFileTest.py new file mode 100644 index 0000000000000000000000000000000000000000..0e994d3f140e0746368a030d1676474d967ff8ac --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/PoldiCreatePeaksFromFileTest.py @@ -0,0 +1,173 @@ +# pylint: disable=no-init,invalid-name,too-many-public-methods +import unittest +from testhelpers import assertRaisesNothing +from testhelpers.tempfile_wrapper import TemporaryFileHelper + +from mantid.kernel import * +from mantid.api import * +from mantid.simpleapi import * + +class PoldiCreatePeaksFromFileTest(unittest.TestCase): + testname = None + + def __init__(self, *args): + unittest.TestCase.__init__(self, *args) + + def test_Init(self): + assertRaisesNothing(self, AlgorithmManager.create, ("PoldiCreatePeaksFromFile")) + + def test_FileOneCompoundOneAtom(self): + fileHelper = TemporaryFileHelper("""Silicon { + Lattice: 5.43 5.43 5.43 90.0 90.0 90.0 + Spacegroup: F d -3 m + Atoms: { + Si 0 0 0 1.0 0.05 + } + }""") + ws = PoldiCreatePeaksFromFile(fileHelper.getName(), 0.7, 10.0) + + # Check output GroupWorkspace + self.assertEquals(ws.getNumberOfEntries(), 1) + self.assertTrue(ws.contains("Silicon")) + + # Check that the ouput is identical to what's expected + ws_expected = PoldiCreatePeaksFromCell("F d -3 m", "Si 0 0 0 1.0 0.05", a=5.43, LatticeSpacingMin=0.7) + si_ws = AnalysisDataService.retrieve("Silicon") + self._tablesAreEqual(si_ws, ws_expected) + + # Clean up + self._cleanWorkspaces([ws, ws_expected]) + + def test_FileOneCompoundTwoAtoms(self): + # It's the same structure and the same reflections, just the structure factors are different + fileHelper = TemporaryFileHelper("""SiliconCarbon { + Lattice: 5.43 5.43 5.43 90.0 90.0 90.0 + Spacegroup: F d -3 m + Atoms: { + Si 0 0 0 0.9 0.05 + C 0 0 0 0.1 0.05 + } + # Comment + }""") + ws = PoldiCreatePeaksFromFile(fileHelper.getName(), 0.7, 10.0) + + self.assertEquals(ws.getNumberOfEntries(), 1) + self.assertTrue(ws.contains("SiliconCarbon")) + + ws_expected = PoldiCreatePeaksFromCell("F d -3 m", "Si 0 0 0 0.9 0.05; C 0 0 0 0.1 0.05", a=5.43, + LatticeSpacingMin=0.7) + si_ws = AnalysisDataService.retrieve("SiliconCarbon") + self._tablesAreEqual(si_ws, ws_expected) + + # Clean up + self._cleanWorkspaces([ws, ws_expected]) + + def test_FileTwoCompounds(self): + # It's the same structure and the same reflections, just the structure factors are different + fileHelper = TemporaryFileHelper("""SiliconCarbon { + Lattice: 5.43 5.43 5.43 90.0 90.0 90.0 + Spacegroup: F d -3 m + Atoms: { + Si 0 0 0 0.9 0.05 + C 0 0 0 0.1 0.05 + } + } + Silicon { + Lattice: 5.43 5.43 5.43 90.0 90.0 90.0 + Spacegroup: F d -3 m + Atoms: { + Si 0 0 0 1.0 0.05 + } + }""") + ws = PoldiCreatePeaksFromFile(fileHelper.getName(), 0.7, 10.0) + + self.assertEquals(ws.getNumberOfEntries(), 2) + self.assertTrue(ws.contains("SiliconCarbon")) + self.assertTrue(ws.contains("Silicon")) + + self._cleanWorkspaces([ws]) + + def test_FileFaultyLatticeStrings(self): + fhLatticeMissing = TemporaryFileHelper("""Silicon { + Spacegroup: F d -3 m + Atoms: { + Si 0 0 0 1.0 0.05 + } + }""") + + fhNoLattice = TemporaryFileHelper("""Silicon { + Lattice: + Spacegroup: F d -3 m + Atoms: { + Si 0 0 0 1.0 0.05 + } + }""") + + fhInvalidLattice = TemporaryFileHelper("""Silicon { + Lattice: invalid + Spacegroup: F d -3 m + Atoms: { + Si 0 0 0 1.0 0.05 + } + }""") + + self.assertRaises(RuntimeError, PoldiCreatePeaksFromFile, *(fhLatticeMissing.getName(), 0.7, 10.0, 'ws')) + self.assertRaises(RuntimeError, PoldiCreatePeaksFromFile, *(fhNoLattice.getName(), 0.7, 10.0, 'ws')) + self.assertRaises(RuntimeError, PoldiCreatePeaksFromFile, *(fhInvalidLattice.getName(), 0.7, 10.0, 'ws')) + + + def test_FileFaultySpaceGroupStrings(self): + fhSgMissing = TemporaryFileHelper("""Silicon { + Lattice: 5.43 5.43 5.43 90.0 90.0 90.0 + Atoms: { + Si 0 0 0 1.0 0.05 + } + }""") + + fhSgInvalid = TemporaryFileHelper("""Silicon { + Lattice: 5.43 5.43 5.43 90.0 90.0 90.0 + Spacegroup: invalid + Atoms: { + Si 0 0 0 1.0 0.05 + } + }""") + + self.assertRaises(RuntimeError, PoldiCreatePeaksFromFile, *(fhSgMissing.getName(), 0.7, 10.0, 'ws')) + self.assertRaises(RuntimeError, PoldiCreatePeaksFromFile, *(fhSgInvalid.getName(), 0.7, 10.0, 'ws')) + + def test_FileFaultyAtomStrings(self): + fhAtomsMissing = TemporaryFileHelper("""Silicon { + Lattice: 5.43 5.43 5.43 90.0 90.0 90.0 + Spacegroup: F d -3 m + }""") + + fhAtomsNoBraces = TemporaryFileHelper("""Silicon { + Lattice: 5.43 5.43 5.43 90.0 90.0 90.0 + Spacegroup: invalid + Atoms: + Sis 0 0 0 1.0 0.05 + }""") + fhAtomsEmpty = TemporaryFileHelper("""Silicon { + Lattice: 5.43 5.43 5.43 90.0 90.0 90.0 + Spacegroup: invalid + Atoms: { } + }""") + + self.assertRaises(RuntimeError, PoldiCreatePeaksFromFile, *(fhAtomsMissing.getName(), 0.7, 10.0, 'ws')) + self.assertRaises(RuntimeError, PoldiCreatePeaksFromFile, *(fhAtomsNoBraces.getName(), 0.7, 10.0, 'ws')) + self.assertRaises(RuntimeError, PoldiCreatePeaksFromFile, *(fhAtomsEmpty.getName(), 0.7, 10.0, 'ws')) + + + def _tablesAreEqual(self, lhs, rhs): + self.assertEquals(lhs.rowCount(), rhs.rowCount(), msg="Row count of tables is different") + + for r in range(lhs.rowCount()): + self.assertEquals(lhs.row(r), rhs.row(r), "Row " + str(r) + " of tables differ.") + + def _cleanWorkspaces(self, wsList): + for ws in wsList: + DeleteWorkspace(ws) + + +if __name__ == '__main__': + unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/TransformToIqtTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/TransformToIqtTest.py new file mode 100644 index 0000000000000000000000000000000000000000..ac64daa184372cf0ff5cdb01be99549a8036cff2 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/TransformToIqtTest.py @@ -0,0 +1,60 @@ +import unittest +from mantid.simpleapi import * +from mantid.api import * + + +class TransformToIqtTest(unittest.TestCase): + + + def setUp(self): + """ + Generate reference result param table. + """ + + CreateEmptyTableWorkspace(OutputWorkspace='__TransformToIqtTest_param') + self._param_table = mtd['__TransformToIqtTest_param'] + + self._param_table.addColumn('int', 'SampleInputBins') + self._param_table.addColumn('float', 'BinReductionFactor') + self._param_table.addColumn('int', 'SampleOutputBins') + self._param_table.addColumn('float', 'EnergyMin') + self._param_table.addColumn('float', 'EnergyMax') + self._param_table.addColumn('float', 'EnergyWidth') + self._param_table.addColumn('float', 'Resolution') + self._param_table.addColumn('int', 'ResolutionBins') + + self._param_table.addRow([1725, 10.0, 172, -0.5, 0.5, 0.00581395, 0.0175, 6]) + + + def test_with_can_reduction(self): + """ + Tests running using the container reduction as a resolution. + """ + + sample = Load('irs26176_graphite002_red') + can = Load('irs26173_graphite002_red') + + params, iqt = TransformToIqt(SampleWorkspace=sample, + ResolutionWorkspace=can, + BinReductionFactor=10) + + self.assertEqual(CheckWorkspacesMatch(params, self._param_table), "Success!") + + + def test_with_resolution_reduction(self): + """ + Tests running using the instrument resolution workspace. + """ + + sample = Load('irs26176_graphite002_red') + resolution = Load('irs26173_graphite002_res') + + params, iqt = TransformToIqt(SampleWorkspace=sample, + ResolutionWorkspace=resolution, + BinReductionFactor=10) + + self.assertEqual(CheckWorkspacesMatch(params, self._param_table), "Success!") + + +if __name__ == '__main__': + unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/testhelpers/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/test/testhelpers/CMakeLists.txt index 8c15b65d9ee05111c20374bcfb153a78f187dbdc..8db79e4b0cec9c095b59655d80d158bc0074fb36 100644 --- a/Code/Mantid/Framework/PythonInterface/test/testhelpers/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/test/testhelpers/CMakeLists.txt @@ -5,6 +5,7 @@ set ( PY_FILES __init__.py algorithm_decorator.py + tempfile_wrapper.py ) # Copy python files to output directory diff --git a/Code/Mantid/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp b/Code/Mantid/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp index 032de062643f6cf9582bb27f4bae6a365375a7d7..0ae46ae1427422bbed19e4acaa778ab12322118a 100644 --- a/Code/Mantid/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp +++ b/Code/Mantid/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp @@ -16,11 +16,11 @@ using namespace WorkspaceCreationHelper; using namespace Mantid::MDEvents::MDEventsTestHelper; -BOOST_PYTHON_FUNCTION_OVERLOADS(create2DWorkspaceWithFullInstrument_overloads, create2DWorkspaceWithFullInstrument, 2, 4); +BOOST_PYTHON_FUNCTION_OVERLOADS(create2DWorkspaceWithFullInstrument_overloads, create2DWorkspaceWithFullInstrument, 2, 4) -BOOST_PYTHON_FUNCTION_OVERLOADS(makeFakeMDHistoWorkspace_overloads, makeFakeMDHistoWorkspace, 2, 7); +BOOST_PYTHON_FUNCTION_OVERLOADS(makeFakeMDHistoWorkspace_overloads, makeFakeMDHistoWorkspace, 2, 7) -BOOST_PYTHON_FUNCTION_OVERLOADS(create2DWorkspaceWithRectangularInstrument_overloads, create2DWorkspaceWithRectangularInstrument, 3, 3); +BOOST_PYTHON_FUNCTION_OVERLOADS(create2DWorkspaceWithRectangularInstrument_overloads, create2DWorkspaceWithRectangularInstrument, 3, 3) namespace { diff --git a/Code/Mantid/Framework/PythonInterface/test/testhelpers/tempfile_wrapper.py b/Code/Mantid/Framework/PythonInterface/test/testhelpers/tempfile_wrapper.py new file mode 100644 index 0000000000000000000000000000000000000000..b28413a026e0463066b80b6e46548049205d9651 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/testhelpers/tempfile_wrapper.py @@ -0,0 +1,46 @@ +from tempfile import NamedTemporaryFile +import os + + +class TemporaryFileHelper(object): + """Helper class for temporary files in unit tests + + This class is a small helper for using temporary files for unit test. On instantiation, a temporary file will be + created (using NamedTemporaryFile from the tempfile module). If the string argument to the constructor is not empty, + its content will be written to that file. The getName()-method provides the name of the temporary file, which can + for example be passed to an algorithm that expects a FileProperty. On destruction of the TemporaryFileHelper object, + the temporary file is removed automatically using os.unlink(). + + Usage: + emptyFileHelper = TemporaryFileHelper() + fh = open(emptyFileHelper.getName(), 'r+') + fh.write("Something or other\n") + fh.close() + + filledFileHelper = TemporaryFileHelper("Something or other\n") + other = open(filledFileHelper.getName(), 'r') + for line in other: + print line + other.close() + + del emptyFileHelper + del filledFileHelper + """ + tempFile = None + + def __init__(self, fileContent=""): + self.tempFile = NamedTemporaryFile('r+', delete=False) + + if fileContent: + self._setFileContent(fileContent) + + def __del__(self): + os.unlink(self.tempFile.name) + + def getName(self): + return self.tempFile.name + + def _setFileContent(self, content): + fileHandle = open(self.getName(), 'r+') + fileHandle.write(content) + fileHandle.close() diff --git a/Code/Mantid/Framework/RemoteAlgorithms/CMakeLists.txt b/Code/Mantid/Framework/RemoteAlgorithms/CMakeLists.txt index af01be7b0c7b9dae196a1217fb55e74e57d58e84..32c83a098f58e4bfb7f63cfa5544feb6b76d6e56 100644 --- a/Code/Mantid/Framework/RemoteAlgorithms/CMakeLists.txt +++ b/Code/Mantid/Framework/RemoteAlgorithms/CMakeLists.txt @@ -5,12 +5,12 @@ set( SRC_FILES src/QueryAllRemoteJobs.cpp src/QueryRemoteFile.cpp src/QueryRemoteJob.cpp + src/SCARFTomoReconstruction.cpp src/SimpleJSON.cpp src/StartRemoteTransaction.cpp src/StopRemoteTransaction.cpp src/SubmitRemoteJob.cpp src/UploadRemoteFile.cpp - src/SCARFTomoReconstruction.cpp ) set( INC_FILES @@ -20,16 +20,27 @@ set( INC_FILES inc/MantidRemoteAlgorithms/QueryAllRemoteJobs.h inc/MantidRemoteAlgorithms/QueryRemoteJob.h inc/MantidRemoteAlgorithms/QueryRemoteFile.h + inc/MantidRemoteAlgorithms/SCARFTomoReconstruction.h inc/MantidRemoteAlgorithms/SimpleJSON.h inc/MantidRemoteAlgorithms/StartRemoteTransaction.h inc/MantidRemoteAlgorithms/StopRemoteTransaction.h inc/MantidRemoteAlgorithms/SubmitRemoteJob.h inc/MantidRemoteAlgorithms/UploadRemoteFile.h - inc/MantidRemoteAlgorithms/SCARFTomoReconstruction.h ) set ( TEST_FILES + AbortRemoteJobTest.h + AuthenticateTest.h + DownloadRemoteFileTest.h + QueryAllRemoteJobsTest.h + QueryRemoteJobTest.h + QueryRemoteFileTest.h SCARFTomoReconstructionTest.h + SimpleJSONTest.h + StartRemoteTransactionTest.h + StopRemoteTransactionTest.h + SubmitRemoteJobTest.h + UploadRemoteFileTest.h ) #set ( TEST_PY_FILES diff --git a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/AbortRemoteJob.h b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/AbortRemoteJob.h index 2b8a777ee48634d17342eb9ba2ce25de8ef68c69..d8590dfa9d1d2dfbd7848b0c0340050a0650f947 100644 --- a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/AbortRemoteJob.h +++ b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/AbortRemoteJob.h @@ -6,7 +6,7 @@ namespace Mantid { namespace RemoteAlgorithms { -class AbortRemoteJob : public Mantid::API::Algorithm { +class DLLExport AbortRemoteJob : public Mantid::API::Algorithm { public: /// (Empty) Constructor AbortRemoteJob() : Mantid::API::Algorithm() {} diff --git a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/Authenticate.h b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/Authenticate.h index 9afa7aa492655294ad148d30fdb0bad0bfc95085..8b662b902bd97b1b671c5c2109855779ee2b5cb0 100644 --- a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/Authenticate.h +++ b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/Authenticate.h @@ -46,7 +46,7 @@ namespace RemoteAlgorithms { Code Documentation is available at: <http://doxygen.mantidproject.org> */ -class Authenticate : public Mantid::API::Algorithm { +class DLLExport Authenticate : public Mantid::API::Algorithm { public: /// (Empty) Constructor Authenticate() : Mantid::API::Algorithm() {} diff --git a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/DownloadRemoteFile.h b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/DownloadRemoteFile.h index 876e2e1c7c032dfd355b67fbc6c3d83e59cd7396..02a8f2c1dae4c266aa64ee055609afacd1cf2b24 100644 --- a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/DownloadRemoteFile.h +++ b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/DownloadRemoteFile.h @@ -6,7 +6,7 @@ namespace Mantid { namespace RemoteAlgorithms { -class DownloadRemoteFile : public Mantid::API::Algorithm { +class DLLExport DownloadRemoteFile : public Mantid::API::Algorithm { public: /// (Empty) Constructor DownloadRemoteFile() : Mantid::API::Algorithm() {} diff --git a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryAllRemoteJobs.h b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryAllRemoteJobs.h index 7e54faee47a7417d6058edb501196c28de21c9c8..49a153b41525c9a7b36be2b1f4684064f3c1d064 100644 --- a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryAllRemoteJobs.h +++ b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryAllRemoteJobs.h @@ -6,7 +6,7 @@ namespace Mantid { namespace RemoteAlgorithms { -class QueryAllRemoteJobs : public Mantid::API::Algorithm { +class DLLExport QueryAllRemoteJobs : public Mantid::API::Algorithm { public: /// (Empty) Constructor QueryAllRemoteJobs() : Mantid::API::Algorithm() {} diff --git a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryRemoteFile.h b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryRemoteFile.h index a54f0f4e81dddef4ab97ef867e0290c75514d55e..2a07da2a6370e9bc3d1578f468718f1123325b5f 100644 --- a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryRemoteFile.h +++ b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryRemoteFile.h @@ -6,7 +6,7 @@ namespace Mantid { namespace RemoteAlgorithms { -class QueryRemoteFile : public Mantid::API::Algorithm { +class DLLExport QueryRemoteFile : public Mantid::API::Algorithm { public: /// (Empty) Constructor QueryRemoteFile() : Mantid::API::Algorithm() {} diff --git a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryRemoteJob.h b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryRemoteJob.h index c38214c83b0cb38c152ceac2dd658770ce36f176..7f6f41bbcfb8038a132e5309fa642ba1f7624bd7 100644 --- a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryRemoteJob.h +++ b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryRemoteJob.h @@ -6,7 +6,7 @@ namespace Mantid { namespace RemoteAlgorithms { -class QueryRemoteJob : public Mantid::API::Algorithm { +class DLLExport QueryRemoteJob : public Mantid::API::Algorithm { public: /// (Empty) Constructor QueryRemoteJob() : Mantid::API::Algorithm() {} diff --git a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SimpleJSON.h b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SimpleJSON.h index 293b7b7ce26abfe32cabdeea86f4c8768ddac0ff..55626211717f486c6c616b09a318be824afbf23b 100644 --- a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SimpleJSON.h +++ b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SimpleJSON.h @@ -20,6 +20,8 @@ #include <istream> #include <ostream> +#include "MantidKernel/System.h" + class JSONValue; typedef std::map<std::string, JSONValue> JSONObject; typedef std::vector<JSONValue> JSONArray; @@ -29,18 +31,18 @@ typedef std::vector<JSONValue> JSONArray; // This is the "public" initialization function. Since JSONObject // is just a typedef, there's no way to make it a constructor. -void initFromStream(JSONObject &obj, std::istream &istr); +void DLLExport initFromStream(JSONObject &obj, std::istream &istr); // A "public" function for formatted output. It's sort of assumed // that ostr will actually be std::cout or std::cerr, but it can // be any output stream. This function mostly exists for debugging // purposes. -void prettyPrint(const JSONObject &obj, std::ostream &ostr, - unsigned indentLevel); +void DLLExport prettyPrint(const JSONObject &obj, std::ostream &ostr, + unsigned indentLevel); class JSONException; -class JSONValue { +class DLLExport JSONValue { public: enum VALUE_TYPE { NULLTYPE, BOOL, NUMBER, STRING, ARRAY, OBJECT }; @@ -90,7 +92,7 @@ private: }; }; -class JSONException : public std::exception { +class DLLExport JSONException : public std::exception { public: JSONException(const std::string &msg) : m_msg(msg) {} const std::string &getMsg() const { return m_msg; } @@ -103,17 +105,17 @@ private: std::string m_msg; }; -class JSONCopyException : public JSONException { +class DLLExport JSONCopyException : public JSONException { public: JSONCopyException(const std::string &msg) : JSONException(msg) {} }; -class JSONAssignmentException : public JSONException { +class DLLExport JSONAssignmentException : public JSONException { public: JSONAssignmentException(const std::string &msg) : JSONException(msg) {} }; -class JSONParseException : public JSONException { +class DLLExport JSONParseException : public JSONException { public: JSONParseException(const std::string &msg) : JSONException(msg) {} }; diff --git a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/StartRemoteTransaction.h b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/StartRemoteTransaction.h index 96f924ec53b57f672d208d81e637955e22005d69..19ea02ec2d3fb2c1166e269209246320790832d5 100644 --- a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/StartRemoteTransaction.h +++ b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/StartRemoteTransaction.h @@ -6,7 +6,7 @@ namespace Mantid { namespace RemoteAlgorithms { -class StartRemoteTransaction : public Mantid::API::Algorithm { +class DLLExport StartRemoteTransaction : public Mantid::API::Algorithm { public: /// (Empty) Constructor StartRemoteTransaction() : Mantid::API::Algorithm() {} diff --git a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/StopRemoteTransaction.h b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/StopRemoteTransaction.h index 7763f24da5bf03889981082e1e3995caadd0254d..faf0224d11e4419ebfa2d56dd00a91a14a819e9b 100644 --- a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/StopRemoteTransaction.h +++ b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/StopRemoteTransaction.h @@ -6,7 +6,7 @@ namespace Mantid { namespace RemoteAlgorithms { -class StopRemoteTransaction : public Mantid::API::Algorithm { +class DLLExport StopRemoteTransaction : public Mantid::API::Algorithm { public: /// (Empty) Constructor StopRemoteTransaction() : Mantid::API::Algorithm() {} diff --git a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SubmitRemoteJob.h b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SubmitRemoteJob.h index 106ea96d6c3251cba423543177b94d9cf7756dde..5f1be99a5ac3e5a63bffe5c9005bace1115af78b 100644 --- a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SubmitRemoteJob.h +++ b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SubmitRemoteJob.h @@ -54,7 +54,7 @@ namespace RemoteAlgorithms { Code Documentation is available at: <http://doxygen.mantidproject.org> */ -class SubmitRemoteJob : public Mantid::API::Algorithm { +class DLLExport SubmitRemoteJob : public Mantid::API::Algorithm { public: /// (Empty) Constructor SubmitRemoteJob() : Mantid::API::Algorithm() {} diff --git a/Code/Mantid/Framework/RemoteAlgorithms/test/AbortRemoteJobTest.h b/Code/Mantid/Framework/RemoteAlgorithms/test/AbortRemoteJobTest.h new file mode 100644 index 0000000000000000000000000000000000000000..331770bbf3d5cfde0fd8839db1d28835947ac259 --- /dev/null +++ b/Code/Mantid/Framework/RemoteAlgorithms/test/AbortRemoteJobTest.h @@ -0,0 +1,126 @@ +#ifndef MANTID_REMOTEALGORITHMS_ABORTREMOTEJOBTEST_H_ +#define MANTID_REMOTEALGORITHMS_ABORTREMOTEJOBTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/FacilityInfo.h" +#include "MantidRemoteAlgorithms/AbortRemoteJob.h" + +using namespace Mantid::RemoteAlgorithms; + +class AbortRemoteJobTest : 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 AbortRemoteJobTest *createSuite() { return new AbortRemoteJobTest(); } + static void destroySuite(AbortRemoteJobTest *suite) { delete suite; } + + void test_algorithm() { + testAlg = Mantid::API::AlgorithmManager::Instance().create( + "AbortRemoteJob" /*, 1*/); + TS_ASSERT(testAlg); + TS_ASSERT_EQUALS(testAlg->name(), "AbortRemoteJob"); + TS_ASSERT_EQUALS(testAlg->version(), 1); + } + + void test_castAlgorithm() { + // can create + boost::shared_ptr<AbortRemoteJob> a; + TS_ASSERT(a = boost::make_shared<AbortRemoteJob>()); + // can cast to inherited interfaces and base classes + + TS_ASSERT( + dynamic_cast<Mantid::RemoteAlgorithms::AbortRemoteJob *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::Algorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::PropertyManagerOwner *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::IAlgorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::IPropertyManager *>(a.get())); + } + + void test_init() { + if (!testAlg->isInitialized()) + TS_ASSERT_THROWS_NOTHING(testAlg->initialize()); + + TS_ASSERT(testAlg->isInitialized()); + + AbortRemoteJob auth; + TS_ASSERT_THROWS_NOTHING(auth.initialize()); + } + + // TODO: when we have a RemoteJobManager capable of creating + // algorithms for different types of compute resources (example: + // Fermi@SNS and SCARF@STFC), create different algorithms for them + void test_propertiesMissing() { + AbortRemoteJob alg1; + TS_ASSERT_THROWS_NOTHING(alg1.initialize()); + // id missing + TS_ASSERT_THROWS(alg1.setPropertyValue("ComputeResource", "missing!"), + std::invalid_argument); + + TS_ASSERT_THROWS(alg1.execute(), std::runtime_error); + TS_ASSERT(!alg1.isExecuted()); + + AbortRemoteJob alg3; + TS_ASSERT_THROWS_NOTHING(alg3.initialize()); + // compute resource missing + TS_ASSERT_THROWS_NOTHING(alg1.setPropertyValue("JobID", "john_missing")); + + TS_ASSERT_THROWS(alg3.execute(), std::runtime_error); + TS_ASSERT(!alg3.isExecuted()); + } + + void test_wrongProperty() { + AbortRemoteJob ab; + TS_ASSERT_THROWS_NOTHING(ab.initialize();) + TS_ASSERT_THROWS(ab.setPropertyValue("ComputeRes", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(ab.setPropertyValue("username", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(ab.setPropertyValue("sername", "anything"), + std::runtime_error); + } + + void test_wrongResource() { + AbortRemoteJob ab; + TS_ASSERT_THROWS_NOTHING(ab.initialize()); + // the compute resource given does not exist: + TS_ASSERT_THROWS(ab.setPropertyValue("ComputeResource", "missing c r!"), + std::invalid_argument); + } + + void test_propertiesOK() { + testFacilities.push_back(std::make_pair("SNS", "Fermi")); + testFacilities.push_back(std::make_pair("ISIS", "SCARF@STFC")); + + const Mantid::Kernel::FacilityInfo &prevFac = + Mantid::Kernel::ConfigService::Instance().getFacility(); + for (size_t fi = 0; fi < testFacilities.size(); fi++) { + const std::string facName = testFacilities[fi].first; + const std::string compName = testFacilities[fi].second; + + Mantid::Kernel::ConfigService::Instance().setFacility(facName); + AbortRemoteJob ab; + TS_ASSERT_THROWS_NOTHING(ab.initialize()); + TS_ASSERT_THROWS_NOTHING( + ab.setPropertyValue("ComputeResource", compName)); + TS_ASSERT_THROWS_NOTHING(ab.setPropertyValue("JobID", "000001")); + // TODO: this will run the algorithm and do a remote + // connection. uncomment only when/if we have a mock up for this + // TS_ASSERT_THROWS(ab.execute(), std::exception); + TS_ASSERT(!ab.isExecuted()); + } + Mantid::Kernel::ConfigService::Instance().setFacility(prevFac.name()); + } + + // TODO: void test_runOK() - with a mock when we can add it. + // ideally, with different compute resources to check the remote job + // manager factory, etc. + +private: + Mantid::API::IAlgorithm_sptr testAlg; + std::vector<std::pair<std::string, std::string>> testFacilities; +}; + +#endif // MANTID_REMOTEALGORITHMS_ABORTREMOTEJOBTEST_H_ diff --git a/Code/Mantid/Framework/RemoteAlgorithms/test/AuthenticateTest.h b/Code/Mantid/Framework/RemoteAlgorithms/test/AuthenticateTest.h new file mode 100644 index 0000000000000000000000000000000000000000..dc848cc4d5bdd6483697b8274e69af413de8444d --- /dev/null +++ b/Code/Mantid/Framework/RemoteAlgorithms/test/AuthenticateTest.h @@ -0,0 +1,131 @@ +#ifndef MANTID_REMOTEALGORITHMS_AUTHENTICATETEST_H_ +#define MANTID_REMOTEALGORITHMS_AUTHENTICATETEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/FacilityInfo.h" +#include "MantidRemoteAlgorithms/Authenticate.h" + +using namespace Mantid::RemoteAlgorithms; + +class AuthenticateTest : 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 AuthenticateTest *createSuite() { return new AuthenticateTest(); } + static void destroySuite(AuthenticateTest *suite) { delete suite; } + + void test_algorithm() { + testAlg = Mantid::API::AlgorithmManager::Instance().create( + "Authenticate" /*, 1*/); + TS_ASSERT(testAlg); + TS_ASSERT_EQUALS(testAlg->name(), "Authenticate"); + TS_ASSERT_EQUALS(testAlg->version(), 1); + } + + void test_castAlgorithm() { + // can create + boost::shared_ptr<Authenticate> a; + TS_ASSERT(a = boost::make_shared<Authenticate>()); + // can cast to inherited interfaces and base classes + + TS_ASSERT(dynamic_cast<Mantid::RemoteAlgorithms::Authenticate *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::Algorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::PropertyManagerOwner *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::IAlgorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::IPropertyManager *>(a.get())); + } + + void test_init() { + if (!testAlg->isInitialized()) + TS_ASSERT_THROWS_NOTHING(testAlg->initialize()); + + TS_ASSERT(testAlg->isInitialized()); + + Authenticate auth; + TS_ASSERT_THROWS_NOTHING(auth.initialize()); + } + + // TODO: when we have a RemoteJobManager capable of creating + // algorithms for different types of compute resources (example: + // Fermi@SNS and SCARF@STFC), create different algorithms for them + void test_propertiesMissing() { + Authenticate alg1; + TS_ASSERT_THROWS_NOTHING(alg1.initialize()); + // password missing + TS_ASSERT_THROWS_NOTHING(alg1.setPropertyValue("UserName", "john_missing")); + TS_ASSERT_THROWS(alg1.setPropertyValue("ComputeResource", "missing!"), + std::invalid_argument); + + TS_ASSERT_THROWS(alg1.execute(), std::runtime_error); + TS_ASSERT(!alg1.isExecuted()); + + Authenticate alg2; + TS_ASSERT_THROWS_NOTHING(alg2.initialize()); + // username missing + TS_ASSERT_THROWS_NOTHING(alg2.setPropertyValue("Password", "LogIn")); + TS_ASSERT_THROWS(alg2.setPropertyValue("ComputeResource", "missing!"), + std::invalid_argument); + + TS_ASSERT_THROWS(alg2.execute(), std::runtime_error); + TS_ASSERT(!alg2.isExecuted()); + + Authenticate alg3; + TS_ASSERT_THROWS_NOTHING(alg3.initialize()); + // compute resource missing + TS_ASSERT_THROWS_NOTHING(alg3.setPropertyValue("UserName", "john_missing")); + TS_ASSERT_THROWS_NOTHING(alg3.setPropertyValue("Password", "LogIn")); + + TS_ASSERT_THROWS(alg3.execute(), std::runtime_error); + TS_ASSERT(!alg3.isExecuted()); + } + + void test_wrongProperty() { + Authenticate auth; + TS_ASSERT_THROWS_NOTHING(auth.initialize()); + TS_ASSERT_THROWS(auth.setPropertyValue("usernam", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(auth.setPropertyValue("sername", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(auth.setPropertyValue("Passwo", "anything"), + std::runtime_error); + } + + void test_propertiesOK() { + testFacilities.push_back(std::make_pair("SNS", "Fermi")); + testFacilities.push_back(std::make_pair("ISIS", "SCARF@STFC")); + + const Mantid::Kernel::FacilityInfo &prevFac = + Mantid::Kernel::ConfigService::Instance().getFacility(); + for (size_t fi = 0; fi < testFacilities.size(); fi++) { + const std::string facName = testFacilities[fi].first; + const std::string compName = testFacilities[fi].second; + + Mantid::Kernel::ConfigService::Instance().setFacility(facName); + Authenticate auth; + TS_ASSERT_THROWS_NOTHING(auth.initialize()); + TS_ASSERT_THROWS_NOTHING( + auth.setPropertyValue("ComputeResource", compName)); + TS_ASSERT_THROWS_NOTHING( + auth.setPropertyValue("UserName", "john_missing")); + TS_ASSERT_THROWS_NOTHING(auth.setPropertyValue("Password", "LogIn")); + // TODO: this would run the algorithm and do a remote + // connection. uncomment only when/if we have a mock up for this + // TS_ASSERT_THROWS(auth.execute(), std::exception); + TS_ASSERT(!auth.isExecuted()); + } + Mantid::Kernel::ConfigService::Instance().setFacility(prevFac.name()); + } + + // TODO: void test_runOK() - with a mock when we can add it. + // ideally, with different compute resources to check the remote job + // manager factory, etc. + +private: + Mantid::API::IAlgorithm_sptr testAlg; + std::vector<std::pair<std::string, std::string>> testFacilities; +}; + +#endif // MANTID_REMOTEALGORITHMS_AUTHENTICATETEST_H_ diff --git a/Code/Mantid/Framework/RemoteAlgorithms/test/DownloadRemoteFileTest.h b/Code/Mantid/Framework/RemoteAlgorithms/test/DownloadRemoteFileTest.h new file mode 100644 index 0000000000000000000000000000000000000000..2431b4d9ae3d5c61fa2b488eb93f6ade67d961e1 --- /dev/null +++ b/Code/Mantid/Framework/RemoteAlgorithms/test/DownloadRemoteFileTest.h @@ -0,0 +1,137 @@ +#ifndef MANTID_REMOTEALGORITHMS_DOWNLOADREMOTEFILETEST_H_ +#define MANTID_REMOTEALGORITHMS_DOWNLOADREMOTEFILETEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/FacilityInfo.h" +#include "MantidRemoteAlgorithms/DownloadRemoteFile.h" + +using namespace Mantid::RemoteAlgorithms; + +class DownloadRemoteFileTest : 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 DownloadRemoteFileTest *createSuite() { + return new DownloadRemoteFileTest(); + } + static void destroySuite(DownloadRemoteFileTest *suite) { delete suite; } + + void test_algorithm() { + testAlg = Mantid::API::AlgorithmManager::Instance().create( + "DownloadRemoteFile" /*, 1*/); + TS_ASSERT(testAlg); + TS_ASSERT_EQUALS(testAlg->name(), "DownloadRemoteFile"); + TS_ASSERT_EQUALS(testAlg->version(), 1); + } + + void test_castAlgorithm() { + // can create + boost::shared_ptr<DownloadRemoteFile> a; + TS_ASSERT(a = boost::make_shared<DownloadRemoteFile>()); + + // can cast to inherited interfaces and base classes + TS_ASSERT( + dynamic_cast<Mantid::RemoteAlgorithms::DownloadRemoteFile *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::Algorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::PropertyManagerOwner *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::IAlgorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::IPropertyManager *>(a.get())); + } + + void test_init() { + if (!testAlg->isInitialized()) + TS_ASSERT_THROWS_NOTHING(testAlg->initialize()); + + TS_ASSERT(testAlg->isInitialized()); + + DownloadRemoteFile dl; + TS_ASSERT_THROWS_NOTHING(dl.initialize()); + } + + // TODO: when we have a RemoteJobManager capable of creating + // algorithms for different types of compute resources (example: + // Fermi@SNS and SCARF@STFC), create different algorithms for them + void test_propertiesMissing() { + DownloadRemoteFile alg1; + TS_ASSERT_THROWS_NOTHING(alg1.initialize()); + // Transaction id missing + TS_ASSERT_THROWS(alg1.setPropertyValue("ComputeResource", "missing!"), + std::invalid_argument); + TS_ASSERT_THROWS_NOTHING( + alg1.setPropertyValue("RemoteFileName", "file name")); + + TS_ASSERT_THROWS(alg1.execute(), std::runtime_error); + TS_ASSERT(!alg1.isExecuted()); + + DownloadRemoteFile alg2; + TS_ASSERT_THROWS_NOTHING(alg2.initialize()); + // file name missing + TS_ASSERT_THROWS(alg2.setPropertyValue("ComputeResource", "missing!"), + std::invalid_argument); + TS_ASSERT_THROWS_NOTHING(alg2.setPropertyValue("TransactionID", "id001")); + + TS_ASSERT_THROWS(alg2.execute(), std::runtime_error); + TS_ASSERT(!alg2.isExecuted()); + + DownloadRemoteFile alg3; + TS_ASSERT_THROWS_NOTHING(alg3.initialize()); + // compute resource missing + TS_ASSERT_THROWS_NOTHING( + alg3.setPropertyValue("RemoteFileName", "file name")); + TS_ASSERT_THROWS_NOTHING(alg3.setPropertyValue("TransactionID", "id001")); + + TS_ASSERT_THROWS(alg3.execute(), std::runtime_error); + TS_ASSERT(!alg3.isExecuted()); + } + + void test_wrongProperty() { + DownloadRemoteFile dl; + TS_ASSERT_THROWS_NOTHING(dl.initialize();) + TS_ASSERT_THROWS(dl.setPropertyValue("Compute", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(dl.setPropertyValue("TransID", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(dl.setPropertyValue("FileName", "anything"), + std::runtime_error); + } + + void test_propertiesOK() { + testFacilities.push_back(std::make_pair("SNS", "Fermi")); + testFacilities.push_back(std::make_pair("ISIS", "SCARF@STFC")); + + const Mantid::Kernel::FacilityInfo &prevFac = + Mantid::Kernel::ConfigService::Instance().getFacility(); + for (size_t fi = 0; fi < testFacilities.size(); fi++) { + const std::string facName = testFacilities[fi].first; + const std::string compName = testFacilities[fi].second; + + Mantid::Kernel::ConfigService::Instance().setFacility(facName); + DownloadRemoteFile dl; + TS_ASSERT_THROWS_NOTHING(dl.initialize()); + TS_ASSERT_THROWS_NOTHING( + dl.setPropertyValue("ComputeResource", compName)); + TS_ASSERT_THROWS_NOTHING( + dl.setPropertyValue("TransactionID", "anything")); + TS_ASSERT_THROWS_NOTHING( + dl.setPropertyValue("RemoteFileName", "anything")); + // TODO: this would run the algorithm and do a remote + // connection. uncomment only when/if we have a mock up for this + // TS_ASSERT_THROWS(dl.execute(), std::exception); + TS_ASSERT(!dl.isExecuted()); + } + Mantid::Kernel::ConfigService::Instance().setFacility(prevFac.name()); + } + + // TODO: void test_runOK() - with a mock when we can add it. + // ideally, with different compute resources to check the remote job + // manager factory, etc. + +private: + Mantid::API::IAlgorithm_sptr testAlg; + std::vector<std::pair<std::string, std::string>> testFacilities; +}; + +#endif // MANTID_REMOTEALGORITHMS_DOWNLOADREMOTEFILETEST_H_ diff --git a/Code/Mantid/Framework/RemoteAlgorithms/test/QueryAllRemoteJobsTest.h b/Code/Mantid/Framework/RemoteAlgorithms/test/QueryAllRemoteJobsTest.h new file mode 100644 index 0000000000000000000000000000000000000000..1ab456f1d45e980bb63d91161e4f5a1f6b391dae --- /dev/null +++ b/Code/Mantid/Framework/RemoteAlgorithms/test/QueryAllRemoteJobsTest.h @@ -0,0 +1,110 @@ +#ifndef MANTID_REMOTEALGORITHMS_QUERYALLREMOTEJOBSTEST_H_ +#define MANTID_REMOTEALGORITHMS_QUERYALLREMOTEJOBSTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/FacilityInfo.h" +#include "MantidRemoteAlgorithms/QueryAllRemoteJobs.h" + +using namespace Mantid::RemoteAlgorithms; + +class QueryAllRemoteJobsTest : 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 QueryAllRemoteJobsTest *createSuite() { + return new QueryAllRemoteJobsTest(); + } + static void destroySuite(QueryAllRemoteJobsTest *suite) { delete suite; } + + void test_algorithm() { + testAlg = Mantid::API::AlgorithmManager::Instance().create( + "QueryAllRemoteJobs" /*, 1*/); + TS_ASSERT(testAlg); + TS_ASSERT_EQUALS(testAlg->name(), "QueryAllRemoteJobs"); + TS_ASSERT_EQUALS(testAlg->version(), 1); + } + + void test_castAlgorithm() { + // can create + boost::shared_ptr<QueryAllRemoteJobs> a; + TS_ASSERT(a = boost::make_shared<QueryAllRemoteJobs>()); + + // can cast to inherited interfaces and base classes + TS_ASSERT( + dynamic_cast<Mantid::RemoteAlgorithms::QueryAllRemoteJobs *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::Algorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::PropertyManagerOwner *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::IAlgorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::IPropertyManager *>(a.get())); + } + + void test_init() { + if (!testAlg->isInitialized()) + TS_ASSERT_THROWS_NOTHING(testAlg->initialize()); + + TS_ASSERT(testAlg->isInitialized()); + + QueryAllRemoteJobs qar; + TS_ASSERT_THROWS_NOTHING(qar.initialize()); + } + + // TODO: when we have a RemoteJobManager capable of creating + // algorithms for different types of compute resources (example: + // Fermi@SNS and SCARF@STFC), create different algorithms for them + void test_propertiesMissing() { + QueryAllRemoteJobs qar; + TS_ASSERT_THROWS_NOTHING(qar.initialize()); + // compute resource missing + TS_ASSERT_THROWS_NOTHING(qar.setPropertyValue("JobID", "john_missing")); + + TS_ASSERT_THROWS(qar.execute(), std::runtime_error); + TS_ASSERT(!qar.isExecuted()); + } + + void test_wrongProperty() { + QueryAllRemoteJobs qar; + TS_ASSERT_THROWS_NOTHING(qar.initialize();) + TS_ASSERT_THROWS(qar.setPropertyValue("ComputeRes", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(qar.setPropertyValue("TransactionID", "whatever"), + std::runtime_error); + TS_ASSERT_THROWS(qar.setPropertyValue("ID", "whichever"), + std::runtime_error); + } + + void test_propertiesOK() { + testFacilities.push_back(std::make_pair("SNS", "Fermi")); + testFacilities.push_back(std::make_pair("ISIS", "SCARF@STFC")); + + const Mantid::Kernel::FacilityInfo &prevFac = + Mantid::Kernel::ConfigService::Instance().getFacility(); + for (size_t fi = 0; fi < testFacilities.size(); fi++) { + const std::string facName = testFacilities[fi].first; + const std::string compName = testFacilities[fi].second; + + Mantid::Kernel::ConfigService::Instance().setFacility(facName); + QueryAllRemoteJobs qar; + TS_ASSERT_THROWS_NOTHING(qar.initialize()); + TS_ASSERT_THROWS_NOTHING( + qar.setPropertyValue("ComputeResource", compName)); + // TODO: this would run the algorithm and do a remote + // connection. uncomment only when/if we have a mock up for this + // TS_ASSERT_THROWS(qar.execute(), std::exception); + TS_ASSERT(!qar.isExecuted()); + } + Mantid::Kernel::ConfigService::Instance().setFacility(prevFac.name()); + } + + // TODO: void test_runOK() - with a mock when we can add it. + // ideally, with different compute resources to check the remote job + // manager factory, etc. + +private: + Mantid::API::IAlgorithm_sptr testAlg; + std::vector<std::pair<std::string, std::string>> testFacilities; +}; + +#endif // MANTID_REMOTEALGORITHMS_QUERYALLREMOTEJOBSTEST_H_ diff --git a/Code/Mantid/Framework/RemoteAlgorithms/test/QueryRemoteFileTest.h b/Code/Mantid/Framework/RemoteAlgorithms/test/QueryRemoteFileTest.h new file mode 100644 index 0000000000000000000000000000000000000000..1635644164e8a3f59673f5156b7f9e32cfc1daaf --- /dev/null +++ b/Code/Mantid/Framework/RemoteAlgorithms/test/QueryRemoteFileTest.h @@ -0,0 +1,122 @@ +#ifndef MANTID_REMOTEALGORITHMS_QUERYREMOTEFILETEST_H_ +#define MANTID_REMOTEALGORITHMS_QUERYREMOTEFILETEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/FacilityInfo.h" +#include "MantidRemoteAlgorithms/QueryRemoteFile.h" + +using namespace Mantid::RemoteAlgorithms; + +class QueryRemoteFileTest : 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 QueryRemoteFileTest *createSuite() { + return new QueryRemoteFileTest(); + } + static void destroySuite(QueryRemoteFileTest *suite) { delete suite; } + + void test_algorithm() { + testAlg = Mantid::API::AlgorithmManager::Instance().create( + "QueryRemoteFile" /*, 1*/); + TS_ASSERT(testAlg); + TS_ASSERT_EQUALS(testAlg->name(), "QueryRemoteFile"); + TS_ASSERT_EQUALS(testAlg->version(), 1); + } + + void test_castAlgorithm() { + // can create + boost::shared_ptr<QueryRemoteFile> a; + TS_ASSERT(a = boost::make_shared<QueryRemoteFile>()); + + // can cast to inherited interfaces and base classes + TS_ASSERT( + dynamic_cast<Mantid::RemoteAlgorithms::QueryRemoteFile *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::Algorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::PropertyManagerOwner *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::IAlgorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::IPropertyManager *>(a.get())); + } + + void test_init() { + if (!testAlg->isInitialized()) + TS_ASSERT_THROWS_NOTHING(testAlg->initialize()); + + TS_ASSERT(testAlg->isInitialized()); + + QueryRemoteFile qrf; + TS_ASSERT_THROWS_NOTHING(qrf.initialize()); + } + + // TODO: when we have a RemoteJobManager capable of creating + // algorithms for different types of compute resources (example: + // Fermi@SNS and SCARF@STFC), create different algorithms for them + void test_propertiesMissing() { + QueryRemoteFile alg1; + TS_ASSERT_THROWS_NOTHING(alg1.initialize()); + // Transaction id missing + TS_ASSERT_THROWS(alg1.setPropertyValue("ComputeResource", "missing!"), + std::invalid_argument); + + TS_ASSERT_THROWS(alg1.execute(), std::runtime_error); + TS_ASSERT(!alg1.isExecuted()); + + QueryRemoteFile alg2; + TS_ASSERT_THROWS_NOTHING(alg2.initialize()); + // compute resource missing + TS_ASSERT_THROWS_NOTHING( + alg2.setPropertyValue("TransactionID", "trans0001")); + + TS_ASSERT_THROWS(alg2.execute(), std::runtime_error); + TS_ASSERT(!alg2.isExecuted()); + } + + void test_wrongProperty() { + QueryRemoteFile qrf; + TS_ASSERT_THROWS_NOTHING(qrf.initialize();) + TS_ASSERT_THROWS(qrf.setPropertyValue("Compute", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(qrf.setPropertyValue("TransID", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(qrf.setPropertyValue("ComputeResourc", "anything"), + std::runtime_error); + } + + void test_propertiesOK() { + testFacilities.push_back(std::make_pair("SNS", "Fermi")); + testFacilities.push_back(std::make_pair("ISIS", "SCARF@STFC")); + + const Mantid::Kernel::FacilityInfo &prevFac = + Mantid::Kernel::ConfigService::Instance().getFacility(); + for (size_t fi = 0; fi < testFacilities.size(); fi++) { + const std::string facName = testFacilities[fi].first; + const std::string compName = testFacilities[fi].second; + + Mantid::Kernel::ConfigService::Instance().setFacility(facName); + QueryRemoteFile qrf; + TS_ASSERT_THROWS_NOTHING(qrf.initialize()); + TS_ASSERT_THROWS_NOTHING( + qrf.setPropertyValue("ComputeResource", compName)); + TS_ASSERT_THROWS_NOTHING( + qrf.setPropertyValue("TransactionID", "anything001")); + // TODO: this would run the algorithm and do a remote + // connection. uncomment only when/if we have a mock up for this + // TS_ASSERT_THROWS(qrf.execute(), std::exception); + TS_ASSERT(!qrf.isExecuted()); + } + Mantid::Kernel::ConfigService::Instance().setFacility(prevFac.name()); + } + + // TODO: void test_runOK() - with a mock when we can add it. + // ideally, with different compute resources to check the remote job + // manager factory, etc. + +private: + Mantid::API::IAlgorithm_sptr testAlg; + std::vector<std::pair<std::string, std::string>> testFacilities; +}; + +#endif // MANTID_REMOTEALGORITHMS_QUERYREMOTEFILETEST_H_ diff --git a/Code/Mantid/Framework/RemoteAlgorithms/test/QueryRemoteJobTest.h b/Code/Mantid/Framework/RemoteAlgorithms/test/QueryRemoteJobTest.h new file mode 100644 index 0000000000000000000000000000000000000000..cdd9350bf9f5dbe6e501c15601be310e8fce84e4 --- /dev/null +++ b/Code/Mantid/Framework/RemoteAlgorithms/test/QueryRemoteJobTest.h @@ -0,0 +1,118 @@ +#ifndef MANTID_REMOTEALGORITHMS_QUERYREMOTEJOBTEST_H_ +#define MANTID_REMOTEALGORITHMS_QUERYREMOTEJOBTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/FacilityInfo.h" +#include "MantidRemoteAlgorithms/QueryRemoteJob.h" + +using namespace Mantid::RemoteAlgorithms; + +class QueryRemoteJobTest : 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 QueryRemoteJobTest *createSuite() { return new QueryRemoteJobTest(); } + static void destroySuite(QueryRemoteJobTest *suite) { delete suite; } + + void test_algorithm() { + testAlg = Mantid::API::AlgorithmManager::Instance().create( + "QueryRemoteJob" /*, 1*/); + TS_ASSERT(testAlg); + TS_ASSERT_EQUALS(testAlg->name(), "QueryRemoteJob"); + TS_ASSERT_EQUALS(testAlg->version(), 1); + } + + void test_castAlgorithm() { + // can create + boost::shared_ptr<QueryRemoteJob> a; + TS_ASSERT(a = boost::make_shared<QueryRemoteJob>()); + + // can cast to inherited interfaces and base classes + TS_ASSERT( + dynamic_cast<Mantid::RemoteAlgorithms::QueryRemoteJob *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::Algorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::PropertyManagerOwner *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::IAlgorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::IPropertyManager *>(a.get())); + } + + void test_init() { + if (!testAlg->isInitialized()) + TS_ASSERT_THROWS_NOTHING(testAlg->initialize()); + + TS_ASSERT(testAlg->isInitialized()); + + QueryRemoteJob qr; + TS_ASSERT_THROWS_NOTHING(qr.initialize()); + } + + // TODO: when we have a RemoteJobManager capable of creating + // algorithms for different types of compute resources (example: + // Fermi@SNS and SCARF@STFC), create different algorithms for them + void test_propertiesMissing() { + QueryRemoteJob alg1; + TS_ASSERT_THROWS_NOTHING(alg1.initialize()); + // id missing + TS_ASSERT_THROWS(alg1.setPropertyValue("ComputeResource", "missing!"), + std::invalid_argument); + + TS_ASSERT_THROWS(alg1.execute(), std::runtime_error); + TS_ASSERT(!alg1.isExecuted()); + + QueryRemoteJob alg2; + TS_ASSERT_THROWS_NOTHING(alg2.initialize()); + // compute resource missing + TS_ASSERT_THROWS_NOTHING(alg2.setPropertyValue("JobID", "missing001")); + + TS_ASSERT_THROWS(alg2.execute(), std::runtime_error); + TS_ASSERT(!alg2.isExecuted()); + } + + void test_wrongProperty() { + QueryRemoteJob qr; + TS_ASSERT_THROWS_NOTHING(qr.initialize();) + TS_ASSERT_THROWS(qr.setPropertyValue("job", "whatever"), + std::runtime_error); + TS_ASSERT_THROWS(qr.setPropertyValue("id", "whichever"), + std::runtime_error); + TS_ASSERT_THROWS(qr.setPropertyValue("ComputeRes", "anything"), + std::runtime_error); + } + + void test_propertiesOK() { + testFacilities.push_back(std::make_pair("SNS", "Fermi")); + testFacilities.push_back(std::make_pair("ISIS", "SCARF@STFC")); + + const Mantid::Kernel::FacilityInfo &prevFac = + Mantid::Kernel::ConfigService::Instance().getFacility(); + for (size_t fi = 0; fi < testFacilities.size(); fi++) { + const std::string facName = testFacilities[fi].first; + const std::string compName = testFacilities[fi].second; + + Mantid::Kernel::ConfigService::Instance().setFacility(facName); + QueryRemoteJob qr; + TS_ASSERT_THROWS_NOTHING(qr.initialize()); + TS_ASSERT_THROWS_NOTHING( + qr.setPropertyValue("ComputeResource", compName)); + TS_ASSERT_THROWS_NOTHING(qr.setPropertyValue("JobID", "000001")); + // TODO: this would run the algorithm and do a remote + // connection. uncomment only when/if we have a mock up for this + // TS_ASSERT_THROWS(qr.execute(), std::exception); + TS_ASSERT(!qr.isExecuted()); + } + Mantid::Kernel::ConfigService::Instance().setFacility(prevFac.name()); + } + + // TODO: void test_runOK() - with a mock when we can add it. + // ideally, with different compute resources to check the remote job + // manager factory, etc. + +private: + Mantid::API::IAlgorithm_sptr testAlg; + std::vector<std::pair<std::string, std::string>> testFacilities; +}; + +#endif // MANTID_REMOTEALGORITHMS_QUERYREMOTEJOBTEST_H_ diff --git a/Code/Mantid/Framework/RemoteAlgorithms/test/SimpleJSONTest.h b/Code/Mantid/Framework/RemoteAlgorithms/test/SimpleJSONTest.h new file mode 100644 index 0000000000000000000000000000000000000000..1beb82a43b914372993775fa98c03bcbb18d76b1 --- /dev/null +++ b/Code/Mantid/Framework/RemoteAlgorithms/test/SimpleJSONTest.h @@ -0,0 +1,231 @@ +#ifndef MANTID_REMOTEALGORITHMS_SIMPLEJSONTEST_H_ +#define MANTID_REMOTEALGORITHMS_SIMPLEJSONTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidRemoteAlgorithms/SimpleJSON.h" + +class SimpleJSONTest : 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 SimpleJSONTest *createSuite() { return new SimpleJSONTest(); } + static void destroySuite(SimpleJSONTest *suite) { delete suite; } + + void test_JSONValue() { + bool b = true; + TS_ASSERT_THROWS_NOTHING(JSONValue vBool(b)); + + double d = 0.1; + TS_ASSERT_THROWS_NOTHING(JSONValue vDbl(d)); + + JSONValue vBool(b); + bool getBool = false; + TS_ASSERT_EQUALS(true, vBool.getValue(getBool)); + + JSONValue vDbl(d); + TS_ASSERT_THROWS_NOTHING(vBool = vDbl); + TS_ASSERT_EQUALS(false, vBool.getValue(getBool)); + TS_ASSERT_EQUALS(true, getBool); + TS_ASSERT_THROWS_NOTHING(vDbl = 0.0); + TS_ASSERT_THROWS_NOTHING(vBool = vDbl); + TS_ASSERT_EQUALS(false, vBool.getValue(getBool)); + TS_ASSERT_EQUALS(true, getBool); + + TS_ASSERT_THROWS_NOTHING(JSONValue str1("")); + TS_ASSERT_THROWS_NOTHING(JSONValue str2("str")); + + JSONValue str1("s1"); + JSONValue str2("s2"); + TS_ASSERT_THROWS_NOTHING(str1 = str2); + + JSONValue vs; + std::ostringstream out; + TS_ASSERT_THROWS_NOTHING(vs.prettyPrint(out, 1)); + } + + void test_JSONArray() { + std::string str = "json failure here"; + std::istringstream input(str); + std::string res; + + JSONArray ja; + TS_ASSERT_THROWS_NOTHING(ja.push_back(str)); + TS_ASSERT_THROWS_NOTHING(ja.push_back(str)); + JSONValue jv(ja); + + JSONValue vBool(true); + TS_ASSERT_THROWS_NOTHING(vBool = ja); + } + + void test_JSONObjectWrongStrings() { + std::string str = "json failure here"; + std::istringstream input(str); + std::string res; + + str = ""; + JSONObject jo; + TS_ASSERT_THROWS(initFromStream(jo, input), JSONParseException); + TS_ASSERT_THROWS_NOTHING(jo["no_param"].getValue(res)); + TS_ASSERT_EQUALS(false, jo["no_param"].getValue(res)); + TS_ASSERT_EQUALS(res, ""); + TS_ASSERT_EQUALS(false, jo["another_no_param"].getValue(res)); + TS_ASSERT_EQUALS(res, ""); + + TS_ASSERT_THROWS(initFromStream(jo, input), JSONParseException); + TS_ASSERT_THROWS_NOTHING(jo["doesnt_exist"].getValue(res)); + TS_ASSERT_EQUALS(false, jo["doesnt_exist"].getValue(res)); + TS_ASSERT_EQUALS(res, ""); + + str = "{ mistake: }"; + TS_ASSERT_THROWS(initFromStream(jo, input), JSONParseException); + TS_ASSERT_THROWS_NOTHING(jo["no no"].getValue(res)); + TS_ASSERT_EQUALS(false, jo["it's not here"].getValue(res)); + TS_ASSERT_EQUALS(res, ""); + + str = "{ "; + TS_ASSERT_THROWS(initFromStream(jo, input), JSONParseException); + TS_ASSERT_THROWS_NOTHING(jo["no no"].getValue(res)); + TS_ASSERT_EQUALS(false, jo["it's not here"].getValue(res)); + TS_ASSERT_EQUALS(res, ""); + } + + void test_JSONObjectWrongSeparator() { + const std::string wrongSep = ","; + const std::string jsonStr = "{\"" + errName + "\":\"" + errVal + wrongSep + + "\"" + errName + "\":\"" + errVal + "\"}"; + std::istringstream input(jsonStr); + std::string res; + + JSONObject o; + TS_ASSERT_THROWS(initFromStream(o, input), JSONParseException); + TS_ASSERT_THROWS_NOTHING(o["Err_Msg"].getValue(res)); + TS_ASSERT_EQUALS(false, o["Err_Msg"].getValue(res)); + TS_ASSERT_EQUALS(res, ""); + } + + void test_JSONObjectCorrectStrings() { + const std::string name1 = "var1"; + const std::string val1 = "value1"; + const std::string name2 = "variable2"; + const std::string val2 = "[0,1,2,3]"; + const std::string sep = ","; + std::string jsonStr = "{\"" + name1 + "\": \"" + val1 + "\"" + sep + " \"" + + name2 + "\": \"" + val2 + "\"}"; + std::istringstream input(jsonStr); + + JSONObject jo; + std::string res; + TS_ASSERT_THROWS_NOTHING(initFromStream(jo, input)); + TS_ASSERT_THROWS_NOTHING(jo[name1].getValue(res)); + TS_ASSERT_EQUALS(false, jo["missing var"].getValue(res)); + TS_ASSERT_EQUALS(res, val1); + TS_ASSERT_EQUALS(false, jo["got ya"].getValue(res)); + TS_ASSERT_THROWS_NOTHING(jo[name2].getValue(res)); + TS_ASSERT_EQUALS(res, val2); + } + + void test_JSONObjectExampleServerResponseSimple() { + const std::string jsonStr = "{\"" + errName + "\":\"" + errVal + "\"}"; + std::istringstream input(jsonStr); + std::string res; + + JSONObject o; + TS_ASSERT_THROWS_NOTHING(initFromStream(o, input)); + TS_ASSERT_THROWS_NOTHING(o["doesnt_exist"].getValue(res)); + TS_ASSERT_EQUALS(false, o["doesnt_exist"].getValue(res)); + TS_ASSERT_THROWS_NOTHING(o[""].getValue(res)); + TS_ASSERT_EQUALS(false, o[""].getValue(res)); + TS_ASSERT_EQUALS(true, o[errName].getValue(res)); + TS_ASSERT_EQUALS(res, errVal); + } + + void test_JSONObjectExampleServerResponseLonger() { + + const std::string longerJsonStr = + "{\"v1\": \"[1, a, 3]\",\"" + errName + "\":\"" + errVal + "\"}"; + std::istringstream inputLong(longerJsonStr); + std::string res; + + JSONObject ol; + TS_ASSERT_THROWS_NOTHING(initFromStream(ol, inputLong)); + TS_ASSERT_THROWS_NOTHING(ol["doesnt exist"].getValue(res)); + TS_ASSERT_EQUALS(false, ol["doesnt exist"].getValue(res)); + TS_ASSERT_THROWS_NOTHING(ol[""].getValue(res)); + TS_ASSERT_EQUALS(false, ol[""].getValue(res)); + TS_ASSERT_EQUALS(true, ol[errName].getValue(res)); + TS_ASSERT_EQUALS(res, errVal); + + const std::string l2JsonStr = "{\"v1\": \"[1, a, 3]\",\"" + errName + + "\":\"" + errVal + "\", \"" + versName + + "\": \"" + versVal + "\" }" + "\"}"; + std::istringstream inputL2(l2JsonStr); + + TS_ASSERT_THROWS_NOTHING(initFromStream(ol, inputL2)); + TS_ASSERT_THROWS_NOTHING(ol["doesnt exist"].getValue(res)); + TS_ASSERT_EQUALS(false, ol["doesnt exist"].getValue(res)); + TS_ASSERT_THROWS_NOTHING(ol[""].getValue(res)); + TS_ASSERT_EQUALS(false, ol[""].getValue(res)); + TS_ASSERT_EQUALS(true, ol[errName].getValue(res)); + TS_ASSERT_EQUALS(res, errVal); + TS_ASSERT_EQUALS(true, ol[versName].getValue(res)); + TS_ASSERT_EQUALS(res, versVal); + + const std::string l3JsonStr = "{ \"" + impName + "\": \"" + impVal + + "\", \"v1\": \"[1, a, longer str, a4]\",\"" + + errName + "\":\"" + errVal + "\", \"" + + versName + "\": \"" + versVal + "\" }" + "\"}"; + std::istringstream inputL3(l3JsonStr); + + TS_ASSERT_THROWS_NOTHING(initFromStream(ol, inputL3)); + TS_ASSERT_THROWS_NOTHING(ol["doesnt exist"].getValue(res)); + TS_ASSERT_EQUALS(false, ol["doesnt exist"].getValue(res)); + TS_ASSERT_THROWS_NOTHING(ol[""].getValue(res)); + TS_ASSERT_EQUALS(false, ol[""].getValue(res)); + TS_ASSERT_EQUALS(true, ol[errName].getValue(res)); + TS_ASSERT_EQUALS(res, errVal); + TS_ASSERT_EQUALS(true, ol[versName].getValue(res)); + TS_ASSERT_EQUALS(res, versVal); + TS_ASSERT_EQUALS(true, ol[impName].getValue(res)); + TS_ASSERT_EQUALS(res, impVal); + } + + void test_prettyPrint() { + std::ostringstream out; + + std::string str = "json failure here"; + std::istringstream istr(str); + JSONObject jo; + TS_ASSERT_THROWS(initFromStream(jo, istr), JSONParseException); + TS_ASSERT_THROWS_NOTHING(prettyPrint(jo, out, 0)); + + std::string strOK = "{ \"key1\": \"val1\"}"; + std::istringstream istrOK(strOK); + JSONObject j2; + TS_ASSERT_THROWS_NOTHING(initFromStream(j2, istrOK)); + TS_ASSERT_THROWS_NOTHING(prettyPrint(j2, out, 2)); + } + +private: + // these are example parameters used for the mantid web service + // (remote job submission API: + // http://www.mantidproject.org/Remote_Job_Submission_API) + static const std::string errName; + static const std::string errVal; + static const std::string versName; + static const std::string versVal; + static const std::string impName; + static const std::string impVal; +}; + +const std::string SimpleJSONTest::errName = "Err_Msg"; +const std::string SimpleJSONTest::errVal = "fake msg"; +const std::string SimpleJSONTest::versName = "API_Version"; +const std::string SimpleJSONTest::versVal = "1"; +const std::string SimpleJSONTest::impName = + "Implementation_Specific_Post_Variables"; +const std::string SimpleJSONTest::impVal = "example_POST_var1"; + +#endif // MANTID_REMOTEALGORITHMS_SIMPLEJSONTEST_H_ diff --git a/Code/Mantid/Framework/RemoteAlgorithms/test/StartRemoteTransactionTest.h b/Code/Mantid/Framework/RemoteAlgorithms/test/StartRemoteTransactionTest.h new file mode 100644 index 0000000000000000000000000000000000000000..aa6086d8431302942c6713bdee0cb8d46df00d55 --- /dev/null +++ b/Code/Mantid/Framework/RemoteAlgorithms/test/StartRemoteTransactionTest.h @@ -0,0 +1,122 @@ +#ifndef MANTID_REMOTEALGORITHMS_STARTREMOTETRANSACTIONTEST_H_ +#define MANTID_REMOTEALGORITHMS_STARTREMOTETRANSACTIONTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/FacilityInfo.h" +#include "MantidRemoteAlgorithms/StartRemoteTransaction.h" + +using namespace Mantid::RemoteAlgorithms; + +class StartRemoteTransactionTest : 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 StartRemoteTransactionTest *createSuite() { + return new StartRemoteTransactionTest(); + } + static void destroySuite(StartRemoteTransactionTest *suite) { delete suite; } + + void test_algorithm() { + testAlg = Mantid::API::AlgorithmManager::Instance().create( + "StartRemoteTransaction" /*, 1*/); + TS_ASSERT(testAlg); + TS_ASSERT_EQUALS(testAlg->name(), "StartRemoteTransaction"); + TS_ASSERT_EQUALS(testAlg->version(), 1); + } + + void test_castAlgorithm() { + // can create + boost::shared_ptr<StartRemoteTransaction> a; + TS_ASSERT(a = boost::make_shared<StartRemoteTransaction>()); + + // can cast to inherited interfaces and base classes + TS_ASSERT(dynamic_cast<Mantid::RemoteAlgorithms::StartRemoteTransaction *>( + a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::Algorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::PropertyManagerOwner *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::IAlgorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::IPropertyManager *>(a.get())); + } + + void test_init() { + if (!testAlg->isInitialized()) + TS_ASSERT_THROWS_NOTHING(testAlg->initialize()); + + TS_ASSERT(testAlg->isInitialized()); + + StartRemoteTransaction start; + TS_ASSERT_THROWS_NOTHING(start.initialize()); + } + + // TODO: when we have a RemoteJobManager capable of creating + // algorithms for different types of compute resources (example: + // Fermi@SNS and SCARF@STFC), create different algorithms for them + void test_propertiesMissing() { + StartRemoteTransaction alg1; + TS_ASSERT_THROWS_NOTHING(alg1.initialize()); + // id missing + TS_ASSERT_THROWS(alg1.setPropertyValue("ComputeResource", "missing!"), + std::invalid_argument); + + TS_ASSERT_THROWS(alg1.execute(), std::runtime_error); + TS_ASSERT(!alg1.isExecuted()); + + StartRemoteTransaction alg2; + TS_ASSERT_THROWS_NOTHING(alg2.initialize()); + // compute resource missing + TS_ASSERT_THROWS_NOTHING( + alg2.setPropertyValue("TransactionID", "john_missing")); + + TS_ASSERT_THROWS(alg2.execute(), std::runtime_error); + TS_ASSERT(!alg2.isExecuted()); + } + + void test_wrongProperty() { + StartRemoteTransaction start; + TS_ASSERT_THROWS_NOTHING(start.initialize();) + TS_ASSERT_THROWS(start.setPropertyValue("Compute", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(start.setPropertyValue("Transaction", "whatever"), + std::runtime_error); + TS_ASSERT_THROWS(start.setPropertyValue("ID", "whichever"), + std::runtime_error); + } + + void test_propertiesOK() { + testFacilities.push_back(std::make_pair("SNS", "Fermi")); + testFacilities.push_back(std::make_pair("ISIS", "SCARF@STFC")); + + const Mantid::Kernel::FacilityInfo &prevFac = + Mantid::Kernel::ConfigService::Instance().getFacility(); + for (size_t fi = 0; fi < testFacilities.size(); fi++) { + const std::string facName = testFacilities[fi].first; + const std::string compName = testFacilities[fi].second; + + Mantid::Kernel::ConfigService::Instance().setFacility(facName); + StartRemoteTransaction start; + TS_ASSERT_THROWS_NOTHING(start.initialize()); + TS_ASSERT_THROWS_NOTHING( + start.setPropertyValue("ComputeResource", compName)); + TS_ASSERT_THROWS_NOTHING( + start.setPropertyValue("TransactionID", "000001")); + // TODO: this would run the algorithm and do a remote + // connection. uncomment only when/if we have a mock up for this + // TS_ASSERT_THROWS(start.execute(), std::exception); + TS_ASSERT(!start.isExecuted()); + } + Mantid::Kernel::ConfigService::Instance().setFacility(prevFac.name()); + } + + // TODO: void test_runOK() - with a mock when we can add it. + // ideally, with different compute resources to check the remote job + // manager factory, etc. + +private: + Mantid::API::IAlgorithm_sptr testAlg; + std::vector<std::pair<std::string, std::string>> testFacilities; +}; + +#endif // MANTID_REMOTEALGORITHMS_STARTREMOTETRANSACTIONTEST_H_ diff --git a/Code/Mantid/Framework/RemoteAlgorithms/test/StopRemoteTransactionTest.h b/Code/Mantid/Framework/RemoteAlgorithms/test/StopRemoteTransactionTest.h new file mode 100644 index 0000000000000000000000000000000000000000..52555a72e3f6b005ad75c907bf0618bb3491d47e --- /dev/null +++ b/Code/Mantid/Framework/RemoteAlgorithms/test/StopRemoteTransactionTest.h @@ -0,0 +1,124 @@ +#ifndef MANTID_REMOTEALGORITHMS_STOPREMOTETRANSACTIONTEST_H_ +#define MANTID_REMOTEALGORITHMS_STOPREMOTETRANSACTIONTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/FacilityInfo.h" +#include "MantidRemoteAlgorithms/StopRemoteTransaction.h" + +using namespace Mantid::RemoteAlgorithms; + +class StopRemoteTransactionTest : 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 StopRemoteTransactionTest *createSuite() { + return new StopRemoteTransactionTest(); + } + static void destroySuite(StopRemoteTransactionTest *suite) { delete suite; } + + void test_algorithm() { + testAlg = Mantid::API::AlgorithmManager::Instance().create( + "StopRemoteTransaction" /*, 1*/); + TS_ASSERT(testAlg); + TS_ASSERT_EQUALS(testAlg->name(), "StopRemoteTransaction"); + TS_ASSERT_EQUALS(testAlg->version(), 1); + } + + void test_castAlgorithm() { + // can create + boost::shared_ptr<StopRemoteTransaction> a; + TS_ASSERT(a = boost::make_shared<StopRemoteTransaction>()); + + // can cast to inherited interfaces and base classes + TS_ASSERT(dynamic_cast<Mantid::RemoteAlgorithms::StopRemoteTransaction *>( + a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::Algorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::PropertyManagerOwner *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::IAlgorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::IPropertyManager *>(a.get())); + } + + void test_init() { + if (!testAlg->isInitialized()) + TS_ASSERT_THROWS_NOTHING(testAlg->initialize()); + + TS_ASSERT(testAlg->isInitialized()); + + StopRemoteTransaction stop; + TS_ASSERT_THROWS_NOTHING(stop.initialize()); + } + + // TODO: when we have a RemoteJobManager capable of creating + // algorithms for different types of compute resources (example: + // Fermi@SNS and SCARF@STFC), create different algorithms for them + void test_propertiesMissing() { + StopRemoteTransaction alg1; + TS_ASSERT_THROWS_NOTHING(alg1.initialize()); + // transaction id missing + TS_ASSERT_THROWS(alg1.setPropertyValue("ComputeResource", "missing!"), + std::invalid_argument); + + TS_ASSERT_THROWS(alg1.execute(), std::runtime_error); + TS_ASSERT(!alg1.isExecuted()); + + StopRemoteTransaction alg2; + TS_ASSERT_THROWS_NOTHING(alg2.initialize()); + // compute resource missing + TS_ASSERT_THROWS_NOTHING( + alg2.setPropertyValue("TransactionID", "john_missing")); + + TS_ASSERT_THROWS(alg2.execute(), std::runtime_error); + TS_ASSERT(!alg2.isExecuted()); + } + + void test_wrongProperty() { + StopRemoteTransaction stop; + TS_ASSERT_THROWS_NOTHING(stop.initialize();) + TS_ASSERT_THROWS(stop.setPropertyValue("Compute", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(stop.setPropertyValue("Transaction", "whatever"), + std::runtime_error); + TS_ASSERT_THROWS(stop.setPropertyValue("JobID", "whichever"), + std::runtime_error); + TS_ASSERT_THROWS(stop.setPropertyValue("ID", "whichever"), + std::runtime_error); + } + + void test_propertiesOK() { + testFacilities.push_back(std::make_pair("SNS", "Fermi")); + testFacilities.push_back(std::make_pair("ISIS", "SCARF@STFC")); + + const Mantid::Kernel::FacilityInfo &prevFac = + Mantid::Kernel::ConfigService::Instance().getFacility(); + for (size_t fi = 0; fi < testFacilities.size(); fi++) { + const std::string facName = testFacilities[fi].first; + const std::string compName = testFacilities[fi].second; + + Mantid::Kernel::ConfigService::Instance().setFacility(facName); + StopRemoteTransaction stop; + TS_ASSERT_THROWS_NOTHING(stop.initialize()); + TS_ASSERT_THROWS_NOTHING( + stop.setPropertyValue("ComputeResource", compName)); + TS_ASSERT_THROWS_NOTHING( + stop.setPropertyValue("TransactionID", "000001")); + // TODO: this would run the algorithm and do a remote + // connection. uncomment only when/if we have a mock up for this + // TS_ASSERT_THROWS(stop.execute(), std::exception); + TS_ASSERT(!stop.isExecuted()); + } + Mantid::Kernel::ConfigService::Instance().setFacility(prevFac.name()); + } + + // TODO: void test_runOK() - with a mock when we can add it. + // ideally, with different compute resources to check the remote job + // manager factory, etc. + +private: + Mantid::API::IAlgorithm_sptr testAlg; + std::vector<std::pair<std::string, std::string>> testFacilities; +}; + +#endif // MANTID_REMOTEALGORITHMS_STOPREMOTETRANSACTIONTEST_H_ diff --git a/Code/Mantid/Framework/RemoteAlgorithms/test/SubmitRemoteJobTest.h b/Code/Mantid/Framework/RemoteAlgorithms/test/SubmitRemoteJobTest.h new file mode 100644 index 0000000000000000000000000000000000000000..9af2b6cae2c7be0a3c718f2e371583a3b54b9b76 --- /dev/null +++ b/Code/Mantid/Framework/RemoteAlgorithms/test/SubmitRemoteJobTest.h @@ -0,0 +1,193 @@ +#ifndef MANTID_REMOTEALGORITHMS_SUBMITREMOTEJOBTEST_H_ +#define MANTID_REMOTEALGORITHMS_SUBMITREMOTEJOBTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/FacilityInfo.h" +#include "MantidRemoteAlgorithms/SubmitRemoteJob.h" + +using namespace Mantid::RemoteAlgorithms; + +class SubmitRemoteJobTest : 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 SubmitRemoteJobTest *createSuite() { + return new SubmitRemoteJobTest(); + } + static void destroySuite(SubmitRemoteJobTest *suite) { delete suite; } + + void test_algorithm() { + testAlg = Mantid::API::AlgorithmManager::Instance().create( + "SubmitRemoteJob" /*, 1*/); + TS_ASSERT(testAlg); + TS_ASSERT_EQUALS(testAlg->name(), "SubmitRemoteJob"); + TS_ASSERT_EQUALS(testAlg->version(), 1); + } + + void test_castAlgorithm() { + // can create + boost::shared_ptr<SubmitRemoteJob> a; + TS_ASSERT(a = boost::make_shared<SubmitRemoteJob>()); + + // can cast to inherited interfaces and base classes + TS_ASSERT( + dynamic_cast<Mantid::RemoteAlgorithms::SubmitRemoteJob *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::Algorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::PropertyManagerOwner *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::IAlgorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::IPropertyManager *>(a.get())); + } + + void test_init() { + if (!testAlg->isInitialized()) + TS_ASSERT_THROWS_NOTHING(testAlg->initialize()); + + TS_ASSERT(testAlg->isInitialized()); + + SubmitRemoteJob s; + TS_ASSERT_THROWS_NOTHING(s.initialize()); + } + + // TODO: when we have a RemoteJobManager capable of creating + // algorithms for different types of compute resources (example: + // Fermi@SNS and SCARF@STFC), create different algorithms for them + void test_propertiesMissing() { + SubmitRemoteJob alg1; + TS_ASSERT_THROWS_NOTHING(alg1.initialize()); + // Transaction id missing + TS_ASSERT_THROWS_NOTHING(alg1.setPropertyValue("NumNodes", "1")); + TS_ASSERT_THROWS_NOTHING(alg1.setPropertyValue("CoresPerNode", "4")); + TS_ASSERT_THROWS_NOTHING(alg1.setPropertyValue("TaskName", "unit test")); + TS_ASSERT_THROWS_NOTHING( + alg1.setPropertyValue("ScriptName", "test script")); + TS_ASSERT_THROWS_NOTHING( + alg1.setPropertyValue("PythonScript", "print 'hello world'")); + TS_ASSERT_THROWS(alg1.setPropertyValue("ComputeResource", "missing!"), + std::invalid_argument); + + TS_ASSERT_THROWS(alg1.execute(), std::runtime_error); + TS_ASSERT(!alg1.isExecuted()); + + SubmitRemoteJob alg2; + TS_ASSERT_THROWS_NOTHING(alg2.initialize()); + // task name name missing + TS_ASSERT_THROWS(alg2.setPropertyValue("ComputeResource", "missing!"), + std::invalid_argument); + TS_ASSERT_THROWS_NOTHING(alg2.setPropertyValue("TransactionID", "id001")); + TS_ASSERT_THROWS_NOTHING( + alg2.setPropertyValue("ScriptName", "test script")); + TS_ASSERT_THROWS_NOTHING( + alg2.setPropertyValue("PythonScript", "print 'hello world'")); + + TS_ASSERT_THROWS(alg2.execute(), std::runtime_error); + TS_ASSERT(!alg2.isExecuted()); + + SubmitRemoteJob alg3; + TS_ASSERT_THROWS_NOTHING(alg3.initialize()); + // script name name missing + TS_ASSERT_THROWS_NOTHING(alg3.setPropertyValue("TaskName", "unit test")); + TS_ASSERT_THROWS_NOTHING(alg3.setPropertyValue("TransactionID", "id001")); + TS_ASSERT_THROWS_NOTHING( + alg3.setPropertyValue("PythonScript", "print 'hello world'")); + TS_ASSERT_THROWS(alg3.setPropertyValue("ComputeResource", "missing!"), + std::invalid_argument); + + TS_ASSERT_THROWS(alg3.execute(), std::runtime_error); + TS_ASSERT(!alg3.isExecuted()); + + SubmitRemoteJob alg4; + TS_ASSERT_THROWS_NOTHING(alg4.initialize()); + // compute resource missing + TS_ASSERT_THROWS_NOTHING(alg4.setPropertyValue("TransactionID", "id001")); + TS_ASSERT_THROWS_NOTHING(alg4.setPropertyValue("TaskName", "unit test")); + TS_ASSERT_THROWS_NOTHING( + alg4.setPropertyValue("ScriptName", "test script")); + TS_ASSERT_THROWS_NOTHING( + alg4.setPropertyValue("PythonScript", "print 'hello world'")); + + TS_ASSERT_THROWS(alg4.execute(), std::runtime_error); + TS_ASSERT(!alg4.isExecuted()); + + SubmitRemoteJob alg5; + TS_ASSERT_THROWS_NOTHING(alg5.initialize()); + // py script missing + TS_ASSERT_THROWS_NOTHING(alg5.setPropertyValue("TransactionID", "id001")); + TS_ASSERT_THROWS_NOTHING(alg5.setPropertyValue("TaskName", "unit test")); + TS_ASSERT_THROWS_NOTHING( + alg5.setPropertyValue("ScriptName", "test script")); + TS_ASSERT_THROWS(alg5.setPropertyValue("ComputeResource", "missing!"), + std::invalid_argument); + + TS_ASSERT_THROWS(alg5.execute(), std::runtime_error); + TS_ASSERT(!alg5.isExecuted()); + } + + void test_wrongProperty() { + SubmitRemoteJob s; + TS_ASSERT_THROWS_NOTHING(s.initialize();) + TS_ASSERT_THROWS(s.setPropertyValue("Compute", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(s.setPropertyValue("NumNodes", "anything"), + std::invalid_argument); + TS_ASSERT_THROWS(s.setPropertyValue("NumNodes", "-3"), + std::invalid_argument); + TS_ASSERT_THROWS(s.setPropertyValue("CoresPerNode", "anything"), + std::invalid_argument); + TS_ASSERT_THROWS(s.setPropertyValue("Task", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(s.setPropertyValue("Name", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(s.setPropertyValue("Transaction", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(s.setPropertyValue("ID", "anything"), std::runtime_error); + TS_ASSERT_THROWS(s.setPropertyValue("ScriptName", ""), + std::invalid_argument); + TS_ASSERT_THROWS(s.setPropertyValue("Scrip", "any name"), + std::runtime_error); + TS_ASSERT_THROWS(s.setPropertyValue("PythonScript", ""), + std::invalid_argument); + } + + void test_propertiesOK() { + testFacilities.push_back(std::make_pair("SNS", "Fermi")); + testFacilities.push_back(std::make_pair("ISIS", "SCARF@STFC")); + + const Mantid::Kernel::FacilityInfo &prevFac = + Mantid::Kernel::ConfigService::Instance().getFacility(); + for (size_t fi = 0; fi < testFacilities.size(); fi++) { + const std::string facName = testFacilities[fi].first; + const std::string compName = testFacilities[fi].second; + + Mantid::Kernel::ConfigService::Instance().setFacility(facName); + + SubmitRemoteJob s; + TS_ASSERT_THROWS_NOTHING(s.initialize()); + TS_ASSERT_THROWS_NOTHING(s.setPropertyValue("ComputeResource", compName)); + TS_ASSERT_THROWS_NOTHING(s.setPropertyValue("NumNodes", "1")); + TS_ASSERT_THROWS_NOTHING(s.setPropertyValue("CoresPerNode", "4")); + TS_ASSERT_THROWS_NOTHING(s.setPropertyValue("TaskName", "unit test")); + TS_ASSERT_THROWS_NOTHING(s.setPropertyValue("TransactionID", "tr001")); + TS_ASSERT_THROWS_NOTHING(s.setPropertyValue("ScriptName", "test script")); + TS_ASSERT_THROWS_NOTHING( + s.setPropertyValue("PythonScript", "print 'hello world'")); + // TODO: this would run the algorithm and do a remote + // connection. uncomment only when/if we have a mock up for this + // TS_ASSERT_THROWS(s.execute(), std::exception); + TS_ASSERT(!s.isExecuted()); + } + Mantid::Kernel::ConfigService::Instance().setFacility(prevFac.name()); + } + + // TODO: void test_runOK() - with a mock when we can add it. + // ideally, with different compute resources to check the remote job + // manager factory, etc. + +private: + Mantid::API::IAlgorithm_sptr testAlg; + std::vector<std::pair<std::string, std::string>> testFacilities; +}; + +#endif // MANTID_REMOTEALGORITHMS_SUBMITREMOTEJOBTEST_H_ diff --git a/Code/Mantid/Framework/RemoteAlgorithms/test/UploadRemoteFileTest.h b/Code/Mantid/Framework/RemoteAlgorithms/test/UploadRemoteFileTest.h new file mode 100644 index 0000000000000000000000000000000000000000..9aae4d4257dd1d79a0718fd5d9771d572a7c143c --- /dev/null +++ b/Code/Mantid/Framework/RemoteAlgorithms/test/UploadRemoteFileTest.h @@ -0,0 +1,160 @@ +#ifndef MANTID_REMOTEALGORITHMS_UPLOADREMOTEFILETEST_H_ +#define MANTID_REMOTEALGORITHMS_UPLOADREMOTEFILETEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/FacilityInfo.h" +#include "MantidRemoteAlgorithms/UploadRemoteFile.h" + +using namespace Mantid::RemoteAlgorithms; + +class UploadRemoteFileTest : 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 UploadRemoteFileTest *createSuite() { + return new UploadRemoteFileTest(); + } + static void destroySuite(UploadRemoteFileTest *suite) { delete suite; } + + void test_algorithm() { + testAlg = Mantid::API::AlgorithmManager::Instance().create( + "UploadRemoteFile" /*, 1*/); + TS_ASSERT(testAlg); + TS_ASSERT_EQUALS(testAlg->name(), "UploadRemoteFile"); + TS_ASSERT_EQUALS(testAlg->version(), 1); + } + + void test_castAlgorithm() { + // can create + boost::shared_ptr<UploadRemoteFile> a; + TS_ASSERT(a = boost::make_shared<UploadRemoteFile>()); + + // can cast to inherited interfaces and base classes + TS_ASSERT( + dynamic_cast<Mantid::RemoteAlgorithms::UploadRemoteFile *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::Algorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::PropertyManagerOwner *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::API::IAlgorithm *>(a.get())); + TS_ASSERT(dynamic_cast<Mantid::Kernel::IPropertyManager *>(a.get())); + } + + void test_init() { + if (!testAlg->isInitialized()) + TS_ASSERT_THROWS_NOTHING(testAlg->initialize()); + + TS_ASSERT(testAlg->isInitialized()); + + UploadRemoteFile ul; + TS_ASSERT_THROWS_NOTHING(ul.initialize()); + } + + // TODO: when we have a RemoteJobManager capable of creating + // algorithms for different types of compute resources (example: + // Fermi@SNS and SCARF@STFC), create different algorithms for them + void test_propertiesMissing() { + UploadRemoteFile alg1; + TS_ASSERT_THROWS_NOTHING(alg1.initialize()); + // Transaction id missing + TS_ASSERT_THROWS_NOTHING( + alg1.setPropertyValue("RemoteFileName", "file name")); + TS_ASSERT_THROWS_NOTHING( + alg1.setPropertyValue("LocalFileName", "local file name")); + TS_ASSERT_THROWS(alg1.setPropertyValue("ComputeResource", "missing!"), + std::invalid_argument); + + TS_ASSERT_THROWS(alg1.execute(), std::runtime_error); + TS_ASSERT(!alg1.isExecuted()); + + UploadRemoteFile alg2; + TS_ASSERT_THROWS_NOTHING(alg2.initialize()); + // remote file name missing + TS_ASSERT_THROWS_NOTHING(alg2.setPropertyValue("TransactionID", "id001")); + TS_ASSERT_THROWS_NOTHING( + alg2.setPropertyValue("LocalFileName", "local file name")); + TS_ASSERT_THROWS(alg2.setPropertyValue("ComputeResource", "missing!"), + std::invalid_argument); + + TS_ASSERT_THROWS(alg2.execute(), std::runtime_error); + TS_ASSERT(!alg2.isExecuted()); + + UploadRemoteFile alg3; + TS_ASSERT_THROWS_NOTHING(alg3.initialize()); + // local file name missing + TS_ASSERT_THROWS_NOTHING(alg3.setPropertyValue("TransactionID", "id001")); + TS_ASSERT_THROWS_NOTHING( + alg3.setPropertyValue("RemoteFileName", "remote file name")); + TS_ASSERT_THROWS(alg3.setPropertyValue("ComputeResource", "missing!"), + std::invalid_argument); + + TS_ASSERT_THROWS(alg3.execute(), std::runtime_error); + TS_ASSERT(!alg3.isExecuted()); + + UploadRemoteFile alg4; + TS_ASSERT_THROWS_NOTHING(alg4.initialize()); + // compute resource missing + TS_ASSERT_THROWS_NOTHING( + alg4.setPropertyValue("RemoteFileName", "file name")); + TS_ASSERT_THROWS_NOTHING(alg4.setPropertyValue("TransactionID", "id001")); + + TS_ASSERT_THROWS(alg4.execute(), std::runtime_error); + TS_ASSERT(!alg4.isExecuted()); + } + + void test_wrongProperty() { + UploadRemoteFile ul; + TS_ASSERT_THROWS_NOTHING(ul.initialize();) + TS_ASSERT_THROWS(ul.setPropertyValue("Compute", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(ul.setPropertyValue("TransID", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(ul.setPropertyValue("RemoteFile", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(ul.setPropertyValue("FileName", "anything"), + std::runtime_error); + TS_ASSERT_THROWS(ul.setPropertyValue("LocalFile", "anything"), + std::runtime_error); + } + + void test_propertiesOK() { + testFacilities.push_back(std::make_pair("SNS", "Fermi")); + testFacilities.push_back(std::make_pair("ISIS", "SCARF@STFC")); + + const Mantid::Kernel::FacilityInfo &prevFac = + Mantid::Kernel::ConfigService::Instance().getFacility(); + for (size_t fi = 0; fi < testFacilities.size(); fi++) { + const std::string facName = testFacilities[fi].first; + const std::string compName = testFacilities[fi].second; + + Mantid::Kernel::ConfigService::Instance().setFacility(facName); + + UploadRemoteFile ul; + TS_ASSERT_THROWS_NOTHING(ul.initialize()); + TS_ASSERT_THROWS_NOTHING( + ul.setPropertyValue("ComputeResource", compName)); + TS_ASSERT_THROWS_NOTHING( + ul.setPropertyValue("TransactionID", "anything001")); + TS_ASSERT_THROWS_NOTHING( + ul.setPropertyValue("RemoteFileName", "any name")); + TS_ASSERT_THROWS_NOTHING( + ul.setPropertyValue("LocalFileName", "any local path")); + // TODO: this would run the algorithm and do a remote + // connection. uncomment only when/if we have a mock up for this + // TS_ASSERT_THROWS(ul.execute(), std::exception); + TS_ASSERT(!ul.isExecuted()); + } + Mantid::Kernel::ConfigService::Instance().setFacility(prevFac.name()); + } + + // TODO: void test_runOK() - with a mock when we can add it. + // ideally, with different compute resources to check the remote job + // manager factory, etc. + +private: + Mantid::API::IAlgorithm_sptr testAlg; + std::vector<std::pair<std::string, std::string>> testFacilities; +}; + +#endif // MANTID_REMOTEALGORITHMS_UPLOADREMOTEFILETEST_H_ diff --git a/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiCreatePeaksFromCell.h b/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiCreatePeaksFromCell.h index 69f1a90db99018ff6e65201e5d55d9a28aa041e5..b622976ee7e2e3c5f6f2c0689cfe79a0a21b7a39 100644 --- a/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiCreatePeaksFromCell.h +++ b/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiCreatePeaksFromCell.h @@ -71,7 +71,9 @@ protected: Geometry::UnitCell getUnitCellFromProperties() const; Geometry::UnitCell getConstrainedUnitCell( const Geometry::UnitCell &unitCell, - const Geometry::PointGroup::CrystalSystem &crystalSystem) const; + const Geometry::PointGroup::CrystalSystem &crystalSystem, + const Geometry::Group::CoordinateSystem &coordinateSystem = + Geometry::Group::Orthogonal) const; private: void init(); diff --git a/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h b/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h index dc2d381822e324b24fffd5f45d4f864a9865e578..165df2ca7c0bb74e5922db6f39b58832342b1ed5 100644 --- a/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h +++ b/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h @@ -5,6 +5,10 @@ #include "MantidSINQ/DllConfig.h" #include "MantidAPI/Algorithm.h" #include "MantidAPI/IFunction.h" +#include "MantidAPI/IPeakFunction.h" + +#include "MantidKernel/Matrix.h" + #include "MantidDataObjects/TableWorkspace.h" #include "MantidSINQ/PoldiUtilities/PoldiPeakCollection.h" #include "MantidSINQ/PoldiUtilities/PoldiTimeTransformer.h" @@ -58,6 +62,10 @@ public: virtual const std::string summary() const; + boost::shared_ptr<Kernel::DblMatrix> getLocalCovarianceMatrix( + const boost::shared_ptr<const Kernel::DblMatrix> &covarianceMatrix, + size_t parameterOffset, size_t nParams) const; + protected: PoldiPeakCollection_sptr getPeakCollection(const DataObjects::TableWorkspace_sptr &peakTable) const; @@ -72,7 +80,7 @@ protected: PoldiPeakCollection_sptr &to) const; PoldiPeakCollection_sptr - getPeakCollectionFromFunction(const API::IFunction_sptr &fitFunction) const; + getPeakCollectionFromFunction(const API::IFunction_sptr &fitFunction); Poldi2DFunction_sptr getFunctionFromPeakCollection( const PoldiPeakCollection_sptr &peakCollection) const; void addBackgroundTerms(Poldi2DFunction_sptr poldi2DFunction) const; diff --git a/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiPeakSearch.h b/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiPeakSearch.h index 7c28a976d88818788c3b7ec56c3c6f99e0c67fa1..fd87762b5bc5c04c21746fb3551e7f57641b9a0d 100644 --- a/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiPeakSearch.h +++ b/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiPeakSearch.h @@ -4,6 +4,7 @@ #include "MantidSINQ/DllConfig.h" #include "MantidKernel/System.h" +#include "MantidKernel/Unit.h" #include "MantidKernel/V2D.h" #include "MantidAPI/Algorithm.h" @@ -93,11 +94,15 @@ protected: double minimumPeakHeightFromBackground(UncertainValue backgroundWithSigma) const; + + double getTransformedCenter(double value, + const Kernel::Unit_sptr &unit) const; std::vector<PoldiPeak_sptr> getPeaks(const MantidVec::const_iterator &baseListStart, const MantidVec::const_iterator &baseListEnd, std::list<MantidVec::const_iterator> peakPositions, - const MantidVec &xData) const; + const MantidVec &xData, const Kernel::Unit_sptr &unit) const; + double getFWHMEstimate(const MantidVec::const_iterator &baseListStart, const MantidVec::const_iterator &baseListEnd, MantidVec::const_iterator peakPosition, diff --git a/Code/Mantid/Framework/SINQ/src/PoldiCreatePeaksFromCell.cpp b/Code/Mantid/Framework/SINQ/src/PoldiCreatePeaksFromCell.cpp index 331f92a53ea69633cbe5ed451bd1fdefeb6cc31f..487f670ac7a22e5a2f56e9631d4e66306690b888 100644 --- a/Code/Mantid/Framework/SINQ/src/PoldiCreatePeaksFromCell.cpp +++ b/Code/Mantid/Framework/SINQ/src/PoldiCreatePeaksFromCell.cpp @@ -78,8 +78,8 @@ SpaceGroup_const_sptr PoldiCreatePeaksFromCell::getSpaceGroup( CompositeBraggScatterer_sptr PoldiCreatePeaksFromCell::getScatterers( const std::string &scattererString) const { boost::char_separator<char> atomSep(";"); - boost::tokenizer<boost::char_separator<char>> tokens(scattererString, - atomSep); + boost::tokenizer<boost::char_separator<char> > tokens(scattererString, + atomSep); std::vector<BraggScatterer_sptr> scatterers; @@ -104,7 +104,7 @@ BraggScatterer_sptr PoldiCreatePeaksFromCell::getScatterer( getCleanScattererTokens(tokens); std::vector<std::string> properties = boost::assign::list_of("Element")("Position")("Occupancy")("U") - .convert_to_container<std::vector<std::string>>(); + .convert_to_container<std::vector<std::string> >(); std::string initString; for (size_t i = 0; i < cleanScattererTokens.size(); ++i) { @@ -183,12 +183,12 @@ UnitCell PoldiCreatePeaksFromCell::getUnitCellFromProperties() const { } /** Returns a new UnitCell-object with crystal system constraints taken into - *account + * account * * This method constructs a new UnitCell-object based on the values of the - *supplied cell, + * supplied cell, * but takes into account the constraints of the crystal system. For - *monoclinic, a unique b-axis is assumed. + * monoclinic, a unique b-axis is assumed. * * It's useful for "cleaning" user input. * @@ -197,8 +197,8 @@ UnitCell PoldiCreatePeaksFromCell::getUnitCellFromProperties() const { * @return UnitCell-object with applied constraints */ UnitCell PoldiCreatePeaksFromCell::getConstrainedUnitCell( - const UnitCell &unitCell, - const PointGroup::CrystalSystem &crystalSystem) const { + const UnitCell &unitCell, const PointGroup::CrystalSystem &crystalSystem, + const Group::CoordinateSystem &coordinateSystem) const { switch (crystalSystem) { case PointGroup::Cubic: return UnitCell(unitCell.a(), unitCell.a(), unitCell.a()); @@ -209,12 +209,15 @@ UnitCell PoldiCreatePeaksFromCell::getConstrainedUnitCell( case PointGroup::Monoclinic: return UnitCell(unitCell.a(), unitCell.b(), unitCell.c(), 90.0, unitCell.beta(), 90.0); + case PointGroup::Trigonal: + if (coordinateSystem == Group::Orthogonal) { + return UnitCell(unitCell.a(), unitCell.a(), unitCell.a(), + unitCell.alpha(), unitCell.alpha(), unitCell.alpha()); + } + // fall through to hexagonal. case PointGroup::Hexagonal: return UnitCell(unitCell.a(), unitCell.a(), unitCell.c(), 90.0, 90.0, 120.0); - case PointGroup::Trigonal: - return UnitCell(unitCell.a(), unitCell.a(), unitCell.a(), unitCell.alpha(), - unitCell.alpha(), unitCell.alpha()); default: return UnitCell(unitCell); } @@ -233,8 +236,8 @@ void PoldiCreatePeaksFromCell::init() { declareProperty("Atoms", "", "Atoms in the asymmetric unit. Format: \n" "Element x y z Occupancy U; ... "); - boost::shared_ptr<BoundedValidator<double>> latticeParameterEdgeValidator = - boost::make_shared<BoundedValidator<double>>(0.0, 0.0); + boost::shared_ptr<BoundedValidator<double> > latticeParameterEdgeValidator = + boost::make_shared<BoundedValidator<double> >(0.0, 0.0); latticeParameterEdgeValidator->clearUpper(); declareProperty("a", 1.0, latticeParameterEdgeValidator, "Lattice parameter a"); @@ -243,8 +246,8 @@ void PoldiCreatePeaksFromCell::init() { declareProperty("c", 1.0, latticeParameterEdgeValidator->clone(), "Lattice parameter c"); - boost::shared_ptr<BoundedValidator<double>> latticeParameterAngleValidator = - boost::make_shared<BoundedValidator<double>>(0.0, 180.0); + boost::shared_ptr<BoundedValidator<double> > latticeParameterAngleValidator = + boost::make_shared<BoundedValidator<double> >(0.0, 180.0); declareProperty("alpha", 90.0, latticeParameterAngleValidator, "Lattice parameter alpha"); declareProperty("beta", 90.0, latticeParameterAngleValidator->clone(), @@ -252,8 +255,8 @@ void PoldiCreatePeaksFromCell::init() { declareProperty("gamma", 90.0, latticeParameterAngleValidator->clone(), "Lattice parameter gamma"); - boost::shared_ptr<BoundedValidator<double>> dValidator = - boost::make_shared<BoundedValidator<double>>(0.01, 0.0); + boost::shared_ptr<BoundedValidator<double> > dValidator = + boost::make_shared<BoundedValidator<double> >(0.01, 0.0); dValidator->clearUpper(); declareProperty("LatticeSpacingMin", 0.5, dValidator, @@ -272,10 +275,14 @@ void PoldiCreatePeaksFromCell::exec() { // Get all user input regarding the unit cell SpaceGroup_const_sptr spaceGroup = getSpaceGroup(getProperty("SpaceGroup")); PointGroup_sptr pointGroup = - PointGroupFactory::Instance().createPointGroupFromSpaceGroupSymbol( - spaceGroup->hmSymbol()); + PointGroupFactory::Instance().createPointGroupFromSpaceGroup(spaceGroup); UnitCell unitCell = getConstrainedUnitCell(getUnitCellFromProperties(), - pointGroup->crystalSystem()); + pointGroup->crystalSystem(), + pointGroup->getCoordinateSystem()); + + g_log.information() << "Constrained unit cell is: " << unitCellToStr(unitCell) + << std::endl; + CompositeBraggScatterer_sptr scatterers = getScatterers(getProperty("Atoms")); // Create a CrystalStructure-object for use with PoldiPeakCollection diff --git a/Code/Mantid/Framework/SINQ/src/PoldiFitPeaks2D.cpp b/Code/Mantid/Framework/SINQ/src/PoldiFitPeaks2D.cpp index 735094834f0288d4e726c83a446d37d785719773..ce552fe18c6fa3c9f00dc5b70fd85ea99ce4f156 100644 --- a/Code/Mantid/Framework/SINQ/src/PoldiFitPeaks2D.cpp +++ b/Code/Mantid/Framework/SINQ/src/PoldiFitPeaks2D.cpp @@ -50,9 +50,7 @@ const std::string PoldiFitPeaks2D::name() const { return "PoldiFitPeaks2D"; } int PoldiFitPeaks2D::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category -const std::string PoldiFitPeaks2D::category() const { - return "SINQ\\Poldi"; -} +const std::string PoldiFitPeaks2D::category() const { return "SINQ\\Poldi"; } /// Very short algorithm summary. @see Algorith::summary const std::string PoldiFitPeaks2D::summary() const { @@ -102,6 +100,37 @@ void PoldiFitPeaks2D::init() { "Table workspace with fitted peaks."); } +/** + * Extracts the covariance matrix for the supplied function + * + * This method extracts the covariance matrix for a sub-function from + * the global covariance matrix. If no matrix is given, a zero-matrix is + * returned. + * + * @param covarianceMatrix :: Global covariance matrix. + * @param parameterOffset :: Offset for the parameters of profileFunction. + * @param nParams :: Number of parameters of the local function. + * @return + */ +boost::shared_ptr<DblMatrix> PoldiFitPeaks2D::getLocalCovarianceMatrix( + const boost::shared_ptr<const Kernel::DblMatrix> &covarianceMatrix, + size_t parameterOffset, size_t nParams) const { + if (covarianceMatrix) { + boost::shared_ptr<Kernel::DblMatrix> localCov = + boost::make_shared<Kernel::DblMatrix>(nParams, nParams, false); + for (size_t j = 0; j < nParams; ++j) { + for (size_t k = 0; k < nParams; ++k) { + (*localCov)[j][k] = + (*covarianceMatrix)[parameterOffset + j][parameterOffset + k]; + } + } + + return localCov; + } + + return boost::make_shared<Kernel::DblMatrix>(nParams, nParams, false); +} + /** * Construct a PoldiPeakCollection from a Poldi2DFunction * @@ -114,7 +143,7 @@ void PoldiFitPeaks2D::init() { * @return PoldiPeakCollection containing peaks with normalized intensities */ PoldiPeakCollection_sptr PoldiFitPeaks2D::getPeakCollectionFromFunction( - const IFunction_sptr &fitFunction) const { + const IFunction_sptr &fitFunction) { Poldi2DFunction_sptr poldi2DFunction = boost::dynamic_pointer_cast<Poldi2DFunction>(fitFunction); @@ -126,6 +155,11 @@ PoldiPeakCollection_sptr PoldiFitPeaks2D::getPeakCollectionFromFunction( PoldiPeakCollection_sptr normalizedPeaks = boost::make_shared<PoldiPeakCollection>(PoldiPeakCollection::Integral); + boost::shared_ptr<const Kernel::DblMatrix> covarianceMatrix = + poldi2DFunction->getCovarianceMatrix(); + + size_t offset = 0; + for (size_t i = 0; i < poldi2DFunction->nFunctions(); ++i) { boost::shared_ptr<PoldiSpectrumDomainFunction> peakFunction = boost::dynamic_pointer_cast<PoldiSpectrumDomainFunction>( @@ -136,36 +170,35 @@ PoldiPeakCollection_sptr PoldiFitPeaks2D::getPeakCollectionFromFunction( boost::dynamic_pointer_cast<IPeakFunction>( peakFunction->getProfileFunction()); + // Get local covariance matrix + size_t nLocalParams = profileFunction->nParams(); + boost::shared_ptr<Kernel::DblMatrix> localCov = + getLocalCovarianceMatrix(covarianceMatrix, offset, nLocalParams); + profileFunction->setCovarianceMatrix(localCov); + + // Increment offset for next function + offset += nLocalParams; + + IAlgorithm_sptr errorAlg = createChildAlgorithm("EstimatePeakErrors"); + errorAlg->setProperty( + "Function", boost::dynamic_pointer_cast<IFunction>(profileFunction)); + errorAlg->setPropertyValue("OutputWorkspace", "Errors"); + errorAlg->execute(); + double centre = profileFunction->centre(); double height = profileFunction->height(); + double fwhmValue = profileFunction->fwhm(); - size_t dIndex = 0; - size_t iIndex = 0; - size_t fIndex = 0; - - for (size_t j = 0; j < profileFunction->nParams(); ++j) { - if (profileFunction->getParameter(j) == centre) { - dIndex = j; - } else if (profileFunction->getParameter(j) == height) { - iIndex = j; - } else { - fIndex = j; - } - } - - // size_t dIndex = peakFunction->parameterIndex("Centre"); - UncertainValue d(peakFunction->getParameter(dIndex), - peakFunction->getError(dIndex)); + ITableWorkspace_sptr errorTable = + errorAlg->getProperty("OutputWorkspace"); - // size_t iIndex = peakFunction->parameterIndex("Area"); - UncertainValue intensity(peakFunction->getParameter(iIndex), - peakFunction->getError(iIndex)); + double centreError = errorTable->cell<double>(0, 2); + double heightError = errorTable->cell<double>(1, 2); + double fwhmError = errorTable->cell<double>(2, 2); - // size_t fIndex = peakFunction->parameterIndex("Sigma"); - double fwhmValue = profileFunction->fwhm(); - UncertainValue fwhm(fwhmValue, fwhmValue / - peakFunction->getParameter(fIndex) * - peakFunction->getError(fIndex)); + UncertainValue d(centre, centreError); + UncertainValue intensity(height, heightError); + UncertainValue fwhm(fwhmValue, fwhmError); PoldiPeak_sptr peak = PoldiPeak::create(MillerIndices(), d, intensity, UncertainValue(1.0)); diff --git a/Code/Mantid/Framework/SINQ/src/PoldiIndexKnownCompounds.cpp b/Code/Mantid/Framework/SINQ/src/PoldiIndexKnownCompounds.cpp index ee0bf9f4dd06b6e5444244bb6654d64cbf85350c..80eb0093d7374230935d6101b4f85b16292379c7 100644 --- a/Code/Mantid/Framework/SINQ/src/PoldiIndexKnownCompounds.cpp +++ b/Code/Mantid/Framework/SINQ/src/PoldiIndexKnownCompounds.cpp @@ -201,19 +201,25 @@ std::vector<Workspace_sptr> PoldiIndexKnownCompounds::getWorkspaces( std::vector<Workspace_sptr> workspaces; for (auto it = workspaceNames.begin(); it != workspaceNames.end(); ++it) { - Workspace_sptr currentWorkspace = - AnalysisDataService::Instance().retrieveWS<Workspace>(*it); - - WorkspaceGroup_sptr groupTest = - boost::dynamic_pointer_cast<WorkspaceGroup>(currentWorkspace); - if (groupTest) { - std::vector<Workspace_sptr> workspacesNextLevel = - getWorkspaces(groupTest->getNames()); - - workspaces.insert(workspaces.end(), workspacesNextLevel.begin(), - workspacesNextLevel.end()); - } else { - workspaces.insert(workspaces.end(), currentWorkspace); + try { + Workspace_sptr currentWorkspace = + AnalysisDataService::Instance().retrieveWS<Workspace>(*it); + + WorkspaceGroup_sptr groupTest = + boost::dynamic_pointer_cast<WorkspaceGroup>(currentWorkspace); + if (groupTest) { + std::vector<Workspace_sptr> workspacesNextLevel = + getWorkspaces(groupTest->getNames()); + + workspaces.insert(workspaces.end(), workspacesNextLevel.begin(), + workspacesNextLevel.end()); + } else { + workspaces.insert(workspaces.end(), currentWorkspace); + } + } + catch (Kernel::Exception::NotFoundError) { + Workspace_sptr invalid; + workspaces.insert(workspaces.end(), invalid); } } @@ -719,8 +725,8 @@ void PoldiIndexKnownCompounds::assignPeakIndex(const IndexCandidatePair &candidate) { candidate.observed->setHKL(candidate.candidate->hkl()); - m_indexedPeaks[candidate.candidateCollectionIndex]->addPeak( - candidate.observed); + m_indexedPeaks[candidate.candidateCollectionIndex] + ->addPeak(candidate.observed); } PoldiPeakCollection_sptr diff --git a/Code/Mantid/Framework/SINQ/src/PoldiPeakSearch.cpp b/Code/Mantid/Framework/SINQ/src/PoldiPeakSearch.cpp index 5c202387a0e5dd1efa97f3d9001a20df0efc91f2..384743a5834001d2a7d9368c82e3e26f5b1268c5 100644 --- a/Code/Mantid/Framework/SINQ/src/PoldiPeakSearch.cpp +++ b/Code/Mantid/Framework/SINQ/src/PoldiPeakSearch.cpp @@ -3,6 +3,8 @@ #include "MantidAPI/WorkspaceProperty.h" #include "MantidAPI/WorkspaceFactory.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/UnitFactory.h" +#include "MantidKernel/UnitConversion.h" #include "MantidKernel/V2D.h" #include "MantidDataObjects/Workspace2D.h" @@ -197,6 +199,26 @@ PoldiPeakSearch::mapPeakPositionsToCorrelationData( return transformedIndices; } +/// Converts the value-parameter to d-spacing. Assumes unit to be Q if empty. +double PoldiPeakSearch::getTransformedCenter(double value, + const Unit_sptr &unit) const { + if (boost::dynamic_pointer_cast<Units::dSpacing>(unit)) { + return value; + } + + // This is required to preserve default behavior which assumes Q. + Unit_sptr transformUnit = unit; + + if (!unit || boost::dynamic_pointer_cast<Units::Empty>(unit)) { + transformUnit = UnitFactory::Instance().create("MomentumTransfer"); + } + + // Transform value to d-spacing. + Unit_sptr dUnit = UnitFactory::Instance().create("dSpacing"); + return UnitConversion::run((*transformUnit), (*dUnit), value, 0, 0, 0, + DeltaEMode::Elastic, 0.0); +} + /** Creates PoldiPeak-objects from peak position iterators * * In this method, PoldiPeak objects are created from the raw peak position @@ -214,7 +236,7 @@ std::vector<PoldiPeak_sptr> PoldiPeakSearch::getPeaks(const MantidVec::const_iterator &baseListStart, const MantidVec::const_iterator &baseListEnd, std::list<MantidVec::const_iterator> peakPositions, - const MantidVec &xData) const { + const MantidVec &xData, const Unit_sptr &unit) const { std::vector<PoldiPeak_sptr> peakData; peakData.reserve(peakPositions.size()); @@ -223,11 +245,14 @@ PoldiPeakSearch::getPeaks(const MantidVec::const_iterator &baseListStart, peak != peakPositions.end(); ++peak) { size_t index = std::distance(baseListStart, *peak); - PoldiPeak_sptr newPeak = - PoldiPeak::create(UncertainValue(xData[index]), UncertainValue(**peak)); + double xDataD = getTransformedCenter(xData[index], unit); + double fwhmEstimate = getFWHMEstimate(baseListStart, baseListEnd, *peak, xData); - newPeak->setFwhm(UncertainValue(fwhmEstimate)); + UncertainValue fwhm(fwhmEstimate / xData[index]); + + PoldiPeak_sptr newPeak = PoldiPeak::create( + MillerIndices(), UncertainValue(xDataD), UncertainValue(**peak), fwhm); peakData.push_back(newPeak); } @@ -536,6 +561,19 @@ void PoldiPeakSearch::exec() { MantidVec correlatedCounts = correlationWorkspace->readY(0); g_log.information() << " Auto-correlation data read." << std::endl; + Unit_sptr xUnit = correlationWorkspace->getAxis(0)->unit(); + + if (xUnit->caption() == "") { + g_log.information() + << " Workspace does not have unit, defaulting to MomentumTransfer." + << std::endl; + + xUnit = UnitFactory::Instance().create("MomentumTransfer"); + } else { + g_log.information() << " Unit of workspace is " << xUnit->caption() << "." + << std::endl; + } + setMinimumDistance(getProperty("MinimumPeakSeparation")); setMinimumPeakHeight(getProperty("MinimumPeakHeight")); setMaximumPeakNumber(getProperty("MaximumPeakNumber")); @@ -576,7 +614,7 @@ void PoldiPeakSearch::exec() { */ std::vector<PoldiPeak_sptr> peakCoordinates = getPeaks(correlatedCounts.begin(), correlatedCounts.end(), - peakPositionsCorrelation, correlationQValues); + peakPositionsCorrelation, correlationQValues, xUnit); g_log.information() << " Extracted peak positions in Q and intensity guesses." << std::endl; diff --git a/Code/Mantid/Framework/SINQ/test/PoldiCreatePeaksFromCellTest.h b/Code/Mantid/Framework/SINQ/test/PoldiCreatePeaksFromCellTest.h index 3ab73521b241cefdb2446f9dd573e72a2b1e93a7..5bb7cd606b7635195dd720862562e1243c3b5277 100644 --- a/Code/Mantid/Framework/SINQ/test/PoldiCreatePeaksFromCellTest.h +++ b/Code/Mantid/Framework/SINQ/test/PoldiCreatePeaksFromCellTest.h @@ -10,198 +10,191 @@ using Mantid::Poldi::PoldiCreatePeaksFromCell; using namespace Mantid::API; using namespace Mantid::Geometry; -class PoldiCreatePeaksFromCellTest : public CxxTest::TestSuite -{ +class PoldiCreatePeaksFromCellTest : 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 PoldiCreatePeaksFromCellTest *createSuite() { return new PoldiCreatePeaksFromCellTest(); } - static void destroySuite( PoldiCreatePeaksFromCellTest *suite ) { delete suite; } + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static PoldiCreatePeaksFromCellTest *createSuite() { + return new PoldiCreatePeaksFromCellTest(); + } + static void destroySuite(PoldiCreatePeaksFromCellTest *suite) { + delete suite; + } + + void test_Init() { + PoldiCreatePeaksFromCell alg; + TS_ASSERT_THROWS_NOTHING(alg.initialize()) + TS_ASSERT(alg.isInitialized()) + } + + void test_exec() { + /* This test checks that the outcome of the algorithm + * is correct. + */ + std::string outWSName("PoldiCreatePeaksFromCellTest_OutputWS"); + + PoldiCreatePeaksFromCell alg; + TS_ASSERT_THROWS_NOTHING(alg.initialize()) + TS_ASSERT(alg.isInitialized()) + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("SpaceGroup", "P m -3 m")); + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue( + "Atoms", "Cl 0 0 0 1.0 0.005; Cs 0.5 0.5 0.5 1.0 0.005");) + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("a", "4.126")); + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("LatticeSpacingMin", "0.55")); + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("LatticeSpacingMax", "4.0")); + TS_ASSERT_THROWS_NOTHING( + alg.setPropertyValue("OutputWorkspace", outWSName)); + TS_ASSERT_THROWS_NOTHING(alg.execute();); + TS_ASSERT(alg.isExecuted()); + + // Retrieve the workspace from data service. + Workspace_sptr ws; + TS_ASSERT_THROWS_NOTHING( + ws = AnalysisDataService::Instance().retrieveWS<Workspace>(outWSName)); + TS_ASSERT(ws); + + ITableWorkspace_sptr tableWs = + boost::dynamic_pointer_cast<ITableWorkspace>(ws); + + TS_ASSERT(tableWs); + // There should be 68 unique reflections for this cell and d-range. + TS_ASSERT_EQUALS(tableWs->rowCount(), 68); + + if (ws) { + AnalysisDataService::Instance().remove(outWSName); + } + } + void testValidateInput() { + PoldiCreatePeaksFromCell alg; + alg.initialize(); - void test_Init() - { - PoldiCreatePeaksFromCell alg; - TS_ASSERT_THROWS_NOTHING( alg.initialize() ) - TS_ASSERT( alg.isInitialized() ) - } + alg.setPropertyValue("LatticeSpacingMin", "1.0"); + alg.setPropertyValue("LatticeSpacingMax", "2.0"); - void test_exec() - { - /* This test checks that the outcome of the algorithm - * is correct. - */ - std::string outWSName("PoldiCreatePeaksFromCellTest_OutputWS"); - - PoldiCreatePeaksFromCell alg; - TS_ASSERT_THROWS_NOTHING( alg.initialize() ) - TS_ASSERT( alg.isInitialized() ) - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("SpaceGroup", "P m -3 m") ); - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Atoms", "Cl 0 0 0 1.0 0.005; Cs 0.5 0.5 0.5 1.0 0.005");) - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("a", "4.126")); - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("LatticeSpacingMin", "0.55")); - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("LatticeSpacingMax", "4.0")); - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) ); - TS_ASSERT_THROWS_NOTHING( alg.execute(); ); - TS_ASSERT( alg.isExecuted() ); - - // Retrieve the workspace from data service. - Workspace_sptr ws; - TS_ASSERT_THROWS_NOTHING( ws = AnalysisDataService::Instance().retrieveWS<Workspace>(outWSName) ); - TS_ASSERT(ws); - - ITableWorkspace_sptr tableWs = boost::dynamic_pointer_cast<ITableWorkspace>(ws); - - TS_ASSERT(tableWs); - // There should be 68 unique reflections for this cell and d-range. - TS_ASSERT_EQUALS(tableWs->rowCount(), 68); - - if (ws) { - AnalysisDataService::Instance().remove(outWSName); - } - } + // dMax is larger than dMin + std::map<std::string, std::string> errorMap = alg.validateInputs(); + TS_ASSERT_EQUALS(errorMap.size(), 0); - void testValidateInput() - { - PoldiCreatePeaksFromCell alg; - alg.initialize(); + alg.setPropertyValue("LatticeSpacingMax", "0.5"); + // now it's smaller - not allowed + errorMap = alg.validateInputs(); + TS_ASSERT_EQUALS(errorMap.size(), 1); - alg.setPropertyValue("LatticeSpacingMin", "1.0"); - alg.setPropertyValue("LatticeSpacingMax", "2.0"); + errorMap.clear(); - // dMax is larger than dMin - std::map<std::string, std::string> errorMap = alg.validateInputs(); - TS_ASSERT_EQUALS(errorMap.size(), 0); + alg.setPropertyValue("LatticeSpacingMax", "-0.5"); + errorMap = alg.validateInputs(); + TS_ASSERT_EQUALS(errorMap.size(), 1) + } - alg.setPropertyValue("LatticeSpacingMax", "0.5"); - // now it's smaller - not allowed - errorMap = alg.validateInputs(); - TS_ASSERT_EQUALS(errorMap.size(), 1); + void testGetLargestDValue() { + // Maximum d-value is 30.0 + UnitCell cell(10.0, 20.0, 30.0); + TestablePoldiCreatePeaksFromCell alg; - errorMap.clear(); + TS_ASSERT_EQUALS(alg.getLargestDValue(cell), 30.0); + } - alg.setPropertyValue("LatticeSpacingMax", "-0.5"); - errorMap = alg.validateInputs(); - TS_ASSERT_EQUALS(errorMap.size(), 1) - } + void testGetDMaxValue() { + // Maximum d-value is 30.0 + UnitCell cell(10.0, 20.0, 30.0); - void testGetLargestDValue() - { - // Maximum d-value is 30.0 - UnitCell cell(10.0, 20.0, 30.0); - TestablePoldiCreatePeaksFromCell alg; + TestablePoldiCreatePeaksFromCell alg; + alg.initialize(); - TS_ASSERT_EQUALS(alg.getLargestDValue(cell), 30.0); - } + // dMax has default value - largest d-value + 1.0 is supposed to be returned + TS_ASSERT_EQUALS(alg.getDMaxValue(cell), 31.0); - void testGetDMaxValue() - { - // Maximum d-value is 30.0 - UnitCell cell(10.0, 20.0, 30.0); + // dMax has been set to a different value + alg.setPropertyValue("LatticeSpacingMax", "2.0"); + TS_ASSERT_EQUALS(alg.getDMaxValue(cell), 2.0); - TestablePoldiCreatePeaksFromCell alg; - alg.initialize(); + alg.setPropertyValue("LatticeSpacingMax", "100.0"); + TS_ASSERT_EQUALS(alg.getDMaxValue(cell), 100.0); + } - // dMax has default value - largest d-value + 1.0 is supposed to be returned - TS_ASSERT_EQUALS(alg.getDMaxValue(cell), 31.0); + void testGetUnitCellFromProperties() { + TestablePoldiCreatePeaksFromCell alg; + alg.initialize(); - // dMax has been set to a different value - alg.setPropertyValue("LatticeSpacingMax", "2.0"); - TS_ASSERT_EQUALS(alg.getDMaxValue(cell), 2.0); + alg.setPropertyValue("a", "3.0"); + alg.setPropertyValue("b", "4.0"); + alg.setPropertyValue("c", "5.0"); - alg.setPropertyValue("LatticeSpacingMax", "100.0"); - TS_ASSERT_EQUALS(alg.getDMaxValue(cell), 100.0); - } + alg.setPropertyValue("alpha", "90.0"); + alg.setPropertyValue("beta", "91.0"); + alg.setPropertyValue("gamma", "92.0"); - void testGetUnitCellFromProperties() - { - TestablePoldiCreatePeaksFromCell alg; - alg.initialize(); + UnitCell unitCell = alg.getUnitCellFromProperties(); - alg.setPropertyValue("a", "3.0"); - alg.setPropertyValue("b", "4.0"); - alg.setPropertyValue("c", "5.0"); + TS_ASSERT_EQUALS(unitCell.a(), 3.0); + TS_ASSERT_EQUALS(unitCell.b(), 4.0); + TS_ASSERT_EQUALS(unitCell.c(), 5.0); + TS_ASSERT_EQUALS(unitCell.alpha(), 90.0); + TS_ASSERT_EQUALS(unitCell.beta(), 91.0); + TS_ASSERT_EQUALS(unitCell.gamma(), 92.0); + } - alg.setPropertyValue("alpha", "90.0"); - alg.setPropertyValue("beta", "91.0"); - alg.setPropertyValue("gamma", "92.0"); + void testGetConstrainedUnitCell() { + TestablePoldiCreatePeaksFromCell alg; - UnitCell unitCell = alg.getUnitCellFromProperties(); + UnitCell rawCell(2.0, 3.0, 4.0, 91.0, 92.0, 93.0); - TS_ASSERT_EQUALS(unitCell.a(), 3.0); - TS_ASSERT_EQUALS(unitCell.b(), 4.0); - TS_ASSERT_EQUALS(unitCell.c(), 5.0); - TS_ASSERT_EQUALS(unitCell.alpha(), 90.0); - TS_ASSERT_EQUALS(unitCell.beta(), 91.0); - TS_ASSERT_EQUALS(unitCell.gamma(), 92.0); - } + checkUnitCellParameters( + alg.getConstrainedUnitCell(rawCell, PointGroup::Cubic), 2.0, 2.0, 2.0, + 90.0, 90.0, 90.0, "Cubic"); - void testGetConstrainedUnitCell() - { - TestablePoldiCreatePeaksFromCell alg; - - UnitCell rawCell(2.0, 3.0, 4.0, 91.0, 92.0, 93.0); - - checkUnitCellParameters( - alg.getConstrainedUnitCell(rawCell, PointGroup::Cubic), - 2.0, 2.0, 2.0, 90.0, 90.0, 90.0, "Cubic" - ); - - checkUnitCellParameters( - alg.getConstrainedUnitCell(rawCell, PointGroup::Tetragonal), - 2.0, 2.0, 4.0, 90.0, 90.0, 90.0, "Tetragonal" - ); - - checkUnitCellParameters( - alg.getConstrainedUnitCell(rawCell, PointGroup::Orthorhombic), - 2.0, 3.0, 4.0, 90.0, 90.0, 90.0, "Orthorhombic" - ); - - checkUnitCellParameters( - alg.getConstrainedUnitCell(rawCell, PointGroup::Monoclinic), - 2.0, 3.0, 4.0, 90.0, 92.0, 90.0, "Monoclinic" - ); - - checkUnitCellParameters( - alg.getConstrainedUnitCell(rawCell, PointGroup::Triclinic), - 2.0, 3.0, 4.0, 91.0, 92.0, 93.0, "Triclinic" - ); - - checkUnitCellParameters( - alg.getConstrainedUnitCell(rawCell, PointGroup::Hexagonal), - 2.0, 2.0, 4.0, 90.0, 90.0, 120.0, "Hexagonal" - ); - - checkUnitCellParameters( - alg.getConstrainedUnitCell(rawCell, PointGroup::Trigonal), - 2.0, 2.0, 2.0, 91.0, 91.0, 91.0, "Trigonal" - ); - } + checkUnitCellParameters( + alg.getConstrainedUnitCell(rawCell, PointGroup::Tetragonal), 2.0, 2.0, + 4.0, 90.0, 90.0, 90.0, "Tetragonal"); -private: - void checkUnitCellParameters(const UnitCell &cell, double a, double b, double c, double alpha, double beta, double gamma, const std::string &message) - { - TSM_ASSERT_DELTA(message, cell.a(), a, 1e-14); - TSM_ASSERT_DELTA(message, cell.b(), b, 1e-14); - TSM_ASSERT_DELTA(message, cell.c(), c, 1e-14); - - TSM_ASSERT_DELTA(message, cell.alpha(), alpha, 1e-14); - TSM_ASSERT_DELTA(message, cell.beta(), beta, 1e-14); - TSM_ASSERT_DELTA(message, cell.gamma(), gamma, 1e-14); - } + checkUnitCellParameters( + alg.getConstrainedUnitCell(rawCell, PointGroup::Orthorhombic), 2.0, 3.0, + 4.0, 90.0, 90.0, 90.0, "Orthorhombic"); - class TestablePoldiCreatePeaksFromCell : public PoldiCreatePeaksFromCell - { - public: - TestablePoldiCreatePeaksFromCell() : PoldiCreatePeaksFromCell() - { } - ~TestablePoldiCreatePeaksFromCell() { } + checkUnitCellParameters( + alg.getConstrainedUnitCell(rawCell, PointGroup::Monoclinic), 2.0, 3.0, + 4.0, 90.0, 92.0, 90.0, "Monoclinic"); - friend class PoldiCreatePeaksFromCellTest; - }; + checkUnitCellParameters( + alg.getConstrainedUnitCell(rawCell, PointGroup::Triclinic), 2.0, 3.0, + 4.0, 91.0, 92.0, 93.0, "Triclinic"); + checkUnitCellParameters( + alg.getConstrainedUnitCell(rawCell, PointGroup::Hexagonal), 2.0, 2.0, + 4.0, 90.0, 90.0, 120.0, "Hexagonal"); -}; + checkUnitCellParameters( + alg.getConstrainedUnitCell(rawCell, PointGroup::Trigonal), 2.0, 2.0, + 2.0, 91.0, 91.0, 91.0, "Trigonal"); + checkUnitCellParameters(alg.getConstrainedUnitCell(rawCell, + PointGroup::Trigonal, + Group::Hexagonal), + 2.0, 2.0, 4.0, 90.0, 90.0, 120.0, "Trigonal"); + } + +private: + void checkUnitCellParameters(const UnitCell &cell, double a, double b, + double c, double alpha, double beta, + double gamma, const std::string &message) { + TSM_ASSERT_DELTA(message, cell.a(), a, 1e-14); + TSM_ASSERT_DELTA(message, cell.b(), b, 1e-14); + TSM_ASSERT_DELTA(message, cell.c(), c, 1e-14); + + TSM_ASSERT_DELTA(message, cell.alpha(), alpha, 1e-14); + TSM_ASSERT_DELTA(message, cell.beta(), beta, 1e-14); + TSM_ASSERT_DELTA(message, cell.gamma(), gamma, 1e-14); + } + + class TestablePoldiCreatePeaksFromCell : public PoldiCreatePeaksFromCell { + public: + TestablePoldiCreatePeaksFromCell() : PoldiCreatePeaksFromCell() {} + ~TestablePoldiCreatePeaksFromCell() {} + + friend class PoldiCreatePeaksFromCellTest; + }; +}; #endif /* MANTID_SINQ_POLDICREATEPEAKSFROMCELLTEST_H_ */ diff --git a/Code/Mantid/Framework/SINQ/test/PoldiFitPeaks2DTest.h b/Code/Mantid/Framework/SINQ/test/PoldiFitPeaks2DTest.h index 9c18d599c85b0f0833c8ea46ca5a989824390667..1ac7a69edaaf3814ff1e7001da18d7d75adc1249 100644 --- a/Code/Mantid/Framework/SINQ/test/PoldiFitPeaks2DTest.h +++ b/Code/Mantid/Framework/SINQ/test/PoldiFitPeaks2DTest.h @@ -6,6 +6,8 @@ #include "MantidAPI/FrameworkManager.h" #include "MantidAPI/AlgorithmManager.h" +#include "MantidKernel/Matrix.h" + #include "MantidSINQ/PoldiFitPeaks2D.h" #include "MantidSINQ/PoldiUtilities/PoldiSpectrumDomainFunction.h" #include "MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h" @@ -14,6 +16,7 @@ using namespace Mantid::Poldi; using namespace Mantid::API; using namespace Mantid::DataObjects; +using namespace Mantid::Kernel; class PoldiFitPeaks2DTest : public CxxTest::TestSuite { @@ -234,6 +237,18 @@ public: PoldiPeakCollection_sptr peaks = PoldiPeakCollectionHelpers::createPoldiPeakCollectionNormalized(); IFunction_sptr poldi2DFunction = spectrumCalculator.getFunctionFromPeakCollection(peaks); + size_t nParams = poldi2DFunction->nParams(); + + // Make a matrix with diagonal elements = 0.05 and set as covariance matrix + boost::shared_ptr<DblMatrix> matrix = boost::make_shared<DblMatrix>(nParams, nParams, true); + matrix->operator *=(0.05); + poldi2DFunction->setCovarianceMatrix(matrix); + + // Also set errors for old behavior + for(size_t i = 0; i < nParams; ++i) { + poldi2DFunction->setError(i, sqrt(0.05)); + } + PoldiPeakCollection_sptr peaksFromFunction = spectrumCalculator.getPeakCollectionFromFunction(poldi2DFunction); TS_ASSERT_EQUALS(peaksFromFunction->peakCount(), peaks->peakCount()); @@ -241,8 +256,11 @@ public: PoldiPeak_sptr functionPeak = peaksFromFunction->peak(i); PoldiPeak_sptr referencePeak = peaks->peak(i); - TS_ASSERT_EQUALS(functionPeak->d(), referencePeak->d()); - TS_ASSERT_EQUALS(functionPeak->fwhm(), referencePeak->fwhm()); + TS_ASSERT_EQUALS(functionPeak->d().value(), referencePeak->d().value()); + TS_ASSERT_EQUALS(functionPeak->fwhm().value(), referencePeak->fwhm().value()); + TS_ASSERT_DELTA(functionPeak->d().error(), sqrt(0.05), 1e-6); + TS_ASSERT_DELTA(functionPeak->fwhm(PoldiPeak::AbsoluteD).error(), sqrt(0.05) * (2.0 * sqrt(2.0 * log(2.0))), 1e-6); + } } diff --git a/Code/Mantid/Framework/SINQ/test/PoldiPeakSearchTest.h b/Code/Mantid/Framework/SINQ/test/PoldiPeakSearchTest.h index 0674bd4c6375b2b38910c4fc3e967ac9fdf61a6f..17e0deeedab2c741315c454bc42bc3d4dda71f7d 100644 --- a/Code/Mantid/Framework/SINQ/test/PoldiPeakSearchTest.h +++ b/Code/Mantid/Framework/SINQ/test/PoldiPeakSearchTest.h @@ -6,6 +6,7 @@ #include "MantidSINQ/PoldiPeakSearch.h" #include "MantidSINQ/PoldiUtilities/PoldiPeak.h" #include "MantidSINQ/PoldiUtilities/UncertainValue.h" +#include "MantidKernel/UnitFactory.h" using Mantid::Poldi::PoldiPeakSearch; using namespace Mantid::Poldi; @@ -133,7 +134,8 @@ public: maxima.sort(); - std::vector<PoldiPeak_sptr> peaks = poldiPeakSearch.getPeaks(baseData.begin(), baseData.end(), maxima, testXData); + Unit_sptr qUnit = UnitFactory::Instance().create("MomentumTransfer"); + std::vector<PoldiPeak_sptr> peaks = poldiPeakSearch.getPeaks(baseData.begin(), baseData.end(), maxima, testXData, qUnit); TS_ASSERT_EQUALS(peaks.size(), 4); diff --git a/Code/Mantid/Framework/ScriptRepository/inc/MantidScriptRepository/ScriptRepositoryImpl.h b/Code/Mantid/Framework/ScriptRepository/inc/MantidScriptRepository/ScriptRepositoryImpl.h index 64c0750492af73686b09a62ad8d52f4a73ec6a32..89900eeee1bc8c86bf24cc4279c7b31346707ce7 100644 --- a/Code/Mantid/Framework/ScriptRepository/inc/MantidScriptRepository/ScriptRepositoryImpl.h +++ b/Code/Mantid/Framework/ScriptRepository/inc/MantidScriptRepository/ScriptRepositoryImpl.h @@ -171,7 +171,7 @@ private: std::string getParentFolder(const std::string &entry); }; -}; // namespace API -}; // namespace Mantid +} // namespace API +} // namespace Mantid #endif // _MANTIDSCRIPTREPOSITORY_SCRIPTREPOSITORYIMPL_H_ diff --git a/Code/Mantid/Framework/ScriptRepository/src/ScriptRepositoryImpl.cpp b/Code/Mantid/Framework/ScriptRepository/src/ScriptRepositoryImpl.cpp index 1f0f1ea817597f809039d4340ac5d1f7a97e68ee..a3e8d448ce089acc0659ae09e99d0ad10a274887 100644 --- a/Code/Mantid/Framework/ScriptRepository/src/ScriptRepositoryImpl.cpp +++ b/Code/Mantid/Framework/ScriptRepository/src/ScriptRepositoryImpl.cpp @@ -1200,7 +1200,7 @@ void ScriptRepositoryImpl::setIgnorePatterns(const std::string &patterns) { boost::replace_all(newignore, "*", ".*"); ignoreregex = std::string("(").append(newignore).append(")"); } -}; +} /** @todo describe */ diff --git a/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h b/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h index 602776597d710b18448930039d26f8a3cd4e0dd7..f8a69de9bc935c4dbc9c5d2d8eb30a4c3b164dea 100644 --- a/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h +++ b/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h @@ -47,7 +47,8 @@ createDiffractionEventWorkspace(int numEvents, int numPixels = 400, * @return MDEW sptr */ Mantid::MDEvents::MDEventWorkspace3Lean::sptr -makeFileBackedMDEW(std::string wsName, bool fileBacked, long numEvents = 10000); +makeFileBackedMDEW(std::string wsName, bool fileBacked, long numEvents = 10000, + Kernel::SpecialCoordinateSystem coord = Kernel::None); /// Make a fake n-dimensional MDHistoWorkspace Mantid::MDEvents::MDHistoWorkspace_sptr diff --git a/Code/Mantid/Framework/TestHelpers/src/MDEventsTestHelper.cpp b/Code/Mantid/Framework/TestHelpers/src/MDEventsTestHelper.cpp index 22950faaa81aac46ed6da35937b2e1fca03e3b9b..6fa5be11b7fcf19742f7bfd2dfcb6770dc9845be 100644 --- a/Code/Mantid/Framework/TestHelpers/src/MDEventsTestHelper.cpp +++ b/Code/Mantid/Framework/TestHelpers/src/MDEventsTestHelper.cpp @@ -128,11 +128,13 @@ createDiffractionEventWorkspace(int numEvents, int numPixels, int numBins) { * @return MDEW sptr */ MDEventWorkspace3Lean::sptr -makeFileBackedMDEW(std::string wsName, bool fileBacked, long numEvents) { +makeFileBackedMDEW(std::string wsName, bool fileBacked, long numEvents, + Kernel::SpecialCoordinateSystem coord) { // ---------- Make a file-backed MDEventWorkspace ----------------------- std::string snEvents = boost::lexical_cast<std::string>(numEvents); MDEventWorkspace3Lean::sptr ws1 = MDEventsTestHelper::makeMDEW<3>(10, 0.0, 10.0, 0); + ws1->setCoordinateSystem(coord); ws1->getBoxController()->setSplitThreshold(100); Mantid::API::AnalysisDataService::Instance().addOrReplace( wsName, boost::dynamic_pointer_cast<Mantid::API::IMDEventWorkspace>(ws1)); diff --git a/Code/Mantid/Framework/TestHelpers/src/ScopedFileHelper.cpp b/Code/Mantid/Framework/TestHelpers/src/ScopedFileHelper.cpp index e8708decc761fd33dcb5f77262662b8284c64535..243f36ff1373812ac60dfe73e8370baf3ff459b3 100644 --- a/Code/Mantid/Framework/TestHelpers/src/ScopedFileHelper.cpp +++ b/Code/Mantid/Framework/TestHelpers/src/ScopedFileHelper.cpp @@ -41,13 +41,13 @@ ScopedFile &ScopedFile::operator=(const ScopedFile &other) { other.release(); } return *this; -}; +} /// Copy construction. ScopedFile::ScopedFile(const ScopedFile &other) { this->m_filename = other.m_filename; other.release(); -}; +} /** Common method used by all constructors. Creates a file containing the ASCII file diff --git a/Code/Mantid/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp b/Code/Mantid/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp index 11df5295a6c60220911a920e59a2c1d0d462533f..1b5c6875f770090cd9cdbea871d42df51eee2907 100644 --- a/Code/Mantid/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp +++ b/Code/Mantid/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp @@ -81,10 +81,8 @@ Workspace2D_sptr Create1DWorkspaceConstant(int size, double value, double error) { MantidVecPtr x1, y1, e1; x1.access().resize(size, 1); - y1.access().resize(size); - std::fill(y1.access().begin(), y1.access().end(), value); - e1.access().resize(size); - std::fill(y1.access().begin(), y1.access().end(), error); + y1.access().resize(size, value); + e1.access().resize(size, error); Workspace2D_sptr retVal(new Workspace2D); retVal->initialize(1, size, size); retVal->setX(0, x1); diff --git a/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsAbsoluteUnitsReduction.cpp b/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsAbsoluteUnitsReduction.cpp index f8cff1c7562e38cfb885b61f1393a8173b0b50df..7f146efc89ad7d23b531f94bc08b2657bd88657f 100644 --- a/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsAbsoluteUnitsReduction.cpp +++ b/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsAbsoluteUnitsReduction.cpp @@ -30,10 +30,10 @@ DgsAbsoluteUnitsReduction::~DgsAbsoluteUnitsReduction() {} /// Algorithm's name for identification. @see Algorithm::name const std::string DgsAbsoluteUnitsReduction::name() const { return "DgsAbsoluteUnitsReduction"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int DgsAbsoluteUnitsReduction::version() const { return 1; }; +int DgsAbsoluteUnitsReduction::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string DgsAbsoluteUnitsReduction::category() const { diff --git a/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsConvertToEnergyTransfer.cpp b/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsConvertToEnergyTransfer.cpp index 9b5d8f18600fb99474fbdfe947680be892da075d..643c68fa0c224c341f035d3ac669c0a0104e56e9 100644 --- a/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsConvertToEnergyTransfer.cpp +++ b/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsConvertToEnergyTransfer.cpp @@ -42,10 +42,10 @@ DgsConvertToEnergyTransfer::~DgsConvertToEnergyTransfer() {} /// Algorithm's name for identification. @see Algorithm::name const std::string DgsConvertToEnergyTransfer::name() const { return "DgsConvertToEnergyTransfer"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int DgsConvertToEnergyTransfer::version() const { return 1; }; +int DgsConvertToEnergyTransfer::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string DgsConvertToEnergyTransfer::category() const { diff --git a/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsDiagnose.cpp b/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsDiagnose.cpp index bbb21dc2cd5966b8a6b99900dc9b424707823ae7..85be54fcfc2f12d3df4d986d62c863e105129ceb 100644 --- a/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsDiagnose.cpp +++ b/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsDiagnose.cpp @@ -30,10 +30,10 @@ DgsDiagnose::~DgsDiagnose() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string DgsDiagnose::name() const { return "DgsDiagnose"; }; +const std::string DgsDiagnose::name() const { return "DgsDiagnose"; } /// Algorithm's version for identification. @see Algorithm::version -int DgsDiagnose::version() const { return 1; }; +int DgsDiagnose::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string DgsDiagnose::category() const { diff --git a/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsPreprocessData.cpp b/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsPreprocessData.cpp index 56bce546f2d61b35d41df7314cfe0e8c558f7d26..56258b060d0b10e28f0dc52aa4f9db294585e850 100644 --- a/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsPreprocessData.cpp +++ b/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsPreprocessData.cpp @@ -38,10 +38,10 @@ DgsPreprocessData::~DgsPreprocessData() {} /// Algorithm's name for identification. @see Algorithm::name const std::string DgsPreprocessData::name() const { return "DgsPreprocessData"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int DgsPreprocessData::version() const { return 1; }; +int DgsPreprocessData::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string DgsPreprocessData::category() const { diff --git a/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsReduction.cpp b/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsReduction.cpp index 0b8a08209705c234b81399a3c2d047b8e3ae4f0c..f5dc93a0b54af726d6f691f35301b14b0cf34805 100644 --- a/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsReduction.cpp +++ b/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsReduction.cpp @@ -39,10 +39,10 @@ DgsReduction::~DgsReduction() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string DgsReduction::name() const { return "DgsReduction"; }; +const std::string DgsReduction::name() const { return "DgsReduction"; } /// Algorithm's version for identification. @see Algorithm::version -int DgsReduction::version() const { return 1; }; +int DgsReduction::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string DgsReduction::category() const { diff --git a/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsRemap.cpp b/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsRemap.cpp index 5a15d54b2679ffd17b6f31f199312f8becaa16d7..d4008ae2aa53c2bde7d76394a911d1c4debca0f0 100644 --- a/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsRemap.cpp +++ b/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsRemap.cpp @@ -24,10 +24,10 @@ DgsRemap::~DgsRemap() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string DgsRemap::name() const { return "DgsRemap"; }; +const std::string DgsRemap::name() const { return "DgsRemap"; } /// Algorithm's version for identification. @see Algorithm::version -int DgsRemap::version() const { return 1; }; +int DgsRemap::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string DgsRemap::category() const { return "Workflow\\Inelastic"; } diff --git a/Code/Mantid/Framework/WorkflowAlgorithms/src/MuonCalculateAsymmetry.cpp b/Code/Mantid/Framework/WorkflowAlgorithms/src/MuonCalculateAsymmetry.cpp index a508a720150ca85d6747ab2f6393528ea1905dad..a70b9f91146ecf4307042244bc3955785349db15 100644 --- a/Code/Mantid/Framework/WorkflowAlgorithms/src/MuonCalculateAsymmetry.cpp +++ b/Code/Mantid/Framework/WorkflowAlgorithms/src/MuonCalculateAsymmetry.cpp @@ -28,10 +28,10 @@ MuonCalculateAsymmetry::~MuonCalculateAsymmetry() {} /// Algorithm's name for identification. @see Algorithm::name const std::string MuonCalculateAsymmetry::name() const { return "MuonCalculateAsymmetry"; -}; +} /// Algorithm's version for identification. @see Algorithm::version -int MuonCalculateAsymmetry::version() const { return 1; }; +int MuonCalculateAsymmetry::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string MuonCalculateAsymmetry::category() const { diff --git a/Code/Mantid/Framework/WorkflowAlgorithms/src/MuonLoad.cpp b/Code/Mantid/Framework/WorkflowAlgorithms/src/MuonLoad.cpp index 9d2771c1ea439e05c26d11828a179adf837c0311..0690f08d3c2c1650edbc0d70208a5c64bc81ed28 100644 --- a/Code/Mantid/Framework/WorkflowAlgorithms/src/MuonLoad.cpp +++ b/Code/Mantid/Framework/WorkflowAlgorithms/src/MuonLoad.cpp @@ -28,10 +28,10 @@ MuonLoad::~MuonLoad() {} //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name -const std::string MuonLoad::name() const { return "MuonLoad"; }; +const std::string MuonLoad::name() const { return "MuonLoad"; } /// Algorithm's version for identification. @see Algorithm::version -int MuonLoad::version() const { return 1; }; +int MuonLoad::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string MuonLoad::category() const { return "Workflow\\Muon"; } diff --git a/Code/Mantid/Framework/WorkflowAlgorithms/src/StepScan.cpp b/Code/Mantid/Framework/WorkflowAlgorithms/src/StepScan.cpp index 616e1df5844f85a08a05f7f9772e6f911627486e..4541b25d6eae0ecaea86cc41b15ff4131c4a5bb3 100644 --- a/Code/Mantid/Framework/WorkflowAlgorithms/src/StepScan.cpp +++ b/Code/Mantid/Framework/WorkflowAlgorithms/src/StepScan.cpp @@ -19,10 +19,10 @@ StepScan::StepScan() {} StepScan::~StepScan() {} /// Algorithm's name for identification. @see Algorithm::name -const std::string StepScan::name() const { return "StepScan"; }; +const std::string StepScan::name() const { return "StepScan"; } /// Algorithm's version for identification. @see Algorithm::version -int StepScan::version() const { return 1; }; +int StepScan::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string StepScan::category() const { return "Workflow\\Alignment"; } diff --git a/Code/Mantid/MantidPlot/CMakeLists.txt b/Code/Mantid/MantidPlot/CMakeLists.txt index 68daaff89d6fdea488c03b40bf6bba8e2d9fcfac..6314b89a3f66c3453d7097e99b98e615f199154a 100644 --- a/Code/Mantid/MantidPlot/CMakeLists.txt +++ b/Code/Mantid/MantidPlot/CMakeLists.txt @@ -548,7 +548,7 @@ add_custom_command ( OUTPUT ${SIP_SRC} ) # Needed for sip.h header that can end up in a different place to to the main Python include directory -include_directories ( ${SIP_INCLUDE_DIR} ) +include_directories ( SYSTEM ${SIP_INCLUDE_DIR} ) # Needed for sip generated files to find includes in src include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ) diff --git a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp index bff1921b0d3b2081eb73aa813d5898f851058513..e022a8b33290f6d83400ab7328144fd8886ed863 100644 --- a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp +++ b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp @@ -865,7 +865,7 @@ void ApplicationWindow::initGlobalConstants() d_locale.setNumberOptions(QLocale::OmitGroupSeparator); d_decimal_digits = 13; - d_graphing_digits = 3; + d_graphing_digits = 13; d_extended_open_dialog = true; d_extended_export_dialog = true; diff --git a/Code/Mantid/MantidPlot/src/ExpDecayDialog.cpp b/Code/Mantid/MantidPlot/src/ExpDecayDialog.cpp index 98154dc22ff8b7800e14888a1b373fa0ac4b8df8..cd334774930596a9e2ad7d8cbcd8430a8b3a7c98 100644 --- a/Code/Mantid/MantidPlot/src/ExpDecayDialog.cpp +++ b/Code/Mantid/MantidPlot/src/ExpDecayDialog.cpp @@ -158,7 +158,7 @@ void ExpDecayDialog::setGraph(Graph *g) connect (graph, SIGNAL(closedGraph()), this, SLOT(close())); connect (graph, SIGNAL(dataRangeChanged()), this, SLOT(changeDataRange())); -}; +} void ExpDecayDialog::activateCurve(const QString& curveName) { @@ -178,7 +178,7 @@ void ExpDecayDialog::activateCurve(const QString& curveName) if (slopes < 2) boxAmplitude->setText(QString::number(c->maxYValue() - c->minYValue(), 'g', precision)); -}; +} void ExpDecayDialog::changeDataRange() { diff --git a/Code/Mantid/MantidPlot/src/FFTDialog.cpp b/Code/Mantid/MantidPlot/src/FFTDialog.cpp index f83ac4f22c94e60de847057e6f982c4a845bb9f2..e6453e17b295abed8ce016b5b28113ba64a95f78 100644 --- a/Code/Mantid/MantidPlot/src/FFTDialog.cpp +++ b/Code/Mantid/MantidPlot/src/FFTDialog.cpp @@ -186,7 +186,7 @@ void FFTDialog::setGraph(Graph *g) graph = g; boxName->insertStringList (g->analysableCurvesList()); activateCurve(boxName->currentText()); -}; +} void FFTDialog::activateCurve(const QString& curveName) { @@ -202,7 +202,7 @@ void FFTDialog::activateCurve(const QString& curveName) double x1 = d_table->text(1, col).toDouble(); boxSampling->setText(QString::number(x1 - x0)); } -}; +} void FFTDialog::setTable(Table *t) { @@ -233,7 +233,7 @@ void FFTDialog::setTable(Table *t) boxReal->setCurrentItem(t->colIndex(l[0])); boxImaginary->setCurrentItem(t->colIndex(l[1])); } -}; +} void FFTDialog::setMatrix(Matrix *m) { diff --git a/Code/Mantid/MantidPlot/src/FilterDialog.cpp b/Code/Mantid/MantidPlot/src/FilterDialog.cpp index 6f02ae0d0fef6314f841ba1f1c121adde771b645..1e16d247b5955fec9a51f950f9157c9d562713b1 100644 --- a/Code/Mantid/MantidPlot/src/FilterDialog.cpp +++ b/Code/Mantid/MantidPlot/src/FilterDialog.cpp @@ -190,4 +190,4 @@ void FilterDialog::setGraph(Graph *g) { graph = g; boxName->addItems (g->analysableCurvesList()); -}; +} diff --git a/Code/Mantid/MantidPlot/src/FitDialog.cpp b/Code/Mantid/MantidPlot/src/FitDialog.cpp index 27936290bc3adff94fda465ce20fcf4977fd11f5..701adfc599bcca9af0f282023c6a4f1078d60d6d 100644 --- a/Code/Mantid/MantidPlot/src/FitDialog.cpp +++ b/Code/Mantid/MantidPlot/src/FitDialog.cpp @@ -559,7 +559,7 @@ void FitDialog::setGraph(Graph *g) connect (d_graph, SIGNAL(closedGraph()), this, SLOT(close())); connect (d_graph, SIGNAL(dataRangeChanged()), this, SLOT(changeDataRange())); -}; +} void FitDialog::activateCurve(const QString& curveName) { @@ -573,7 +573,7 @@ void FitDialog::activateCurve(const QString& curveName) boxTo->setValue(QMAX(start, end)); //Set the same color as the data curve chosen for fit (Feature Request #4031) boxColor->setColor(c->pen().color()); -}; +} void FitDialog::saveUserFunction() { diff --git a/Code/Mantid/MantidPlot/src/Graph.cpp b/Code/Mantid/MantidPlot/src/Graph.cpp index a36e9a89449c505d046e39a39f8c0d7b42b8bb12..92123c84c1bd6373f78c3468f2461ef7af8adf82 100644 --- a/Code/Mantid/MantidPlot/src/Graph.cpp +++ b/Code/Mantid/MantidPlot/src/Graph.cpp @@ -5360,9 +5360,11 @@ void Graph::enablePanningMagnifier(bool on) delete d_panner; QwtPlotCanvas *cnvs =d_plot->canvas(); //canvas(); - if (on){ + if (on) { cnvs->setCursor(Qt::pointingHandCursor); d_magnifier = new QwtPlotMagnifier(cnvs); + // Disable the mouse button as it causes issues with the context menu + d_magnifier->setMouseButton(Qt::NoButton); d_magnifier->setAxisEnabled(QwtPlot::yRight,false); d_magnifier->setZoomInKey(Qt::Key_Plus, Qt::ShiftModifier); diff --git a/Code/Mantid/MantidPlot/src/Graph.h b/Code/Mantid/MantidPlot/src/Graph.h index 07cab9df6848ce3f2ac8ab91b713e15e62845f1c..7480107f3b16f2e676788b11424dc8f16e71d71b 100644 --- a/Code/Mantid/MantidPlot/src/Graph.h +++ b/Code/Mantid/MantidPlot/src/Graph.h @@ -881,7 +881,7 @@ private: }; -Q_DECLARE_METATYPE(Graph::CurveType); +Q_DECLARE_METATYPE(Graph::CurveType) #endif // GRAPH_H diff --git a/Code/Mantid/MantidPlot/src/InterpolationDialog.cpp b/Code/Mantid/MantidPlot/src/InterpolationDialog.cpp index 4d0ceb1722ec6edd74468697136ee4eae62f9823..efc62a720287db9a0bf84597b542da0dbd6d2852 100644 --- a/Code/Mantid/MantidPlot/src/InterpolationDialog.cpp +++ b/Code/Mantid/MantidPlot/src/InterpolationDialog.cpp @@ -173,7 +173,7 @@ void InterpolationDialog::setGraph(Graph *g) connect (graph, SIGNAL(closedGraph()), this, SLOT(close())); connect (graph, SIGNAL(dataRangeChanged()), this, SLOT(changeDataRange())); -}; +} void InterpolationDialog::activateCurve(const QString& curveName) { @@ -189,7 +189,7 @@ void InterpolationDialog::activateCurve(const QString& curveName) graph->range(graph->curveIndex(curveName), &start, &end); boxStart->setText(QString::number(QMIN(start, end), 'g', app->d_decimal_digits)); boxEnd->setText(QString::number(QMAX(start, end), 'g', app->d_decimal_digits)); -}; +} void InterpolationDialog::changeDataRange() { diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentTreeWidget.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentTreeWidget.cpp index 6caf14cffda807df66ff555893690b33b8148823..a2649437b34be4c7d7eff4d34b7b75be00ab5b4b 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentTreeWidget.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentTreeWidget.cpp @@ -17,7 +17,7 @@ InstrumentTreeWidget::InstrumentTreeWidget(QWidget *w):QTreeView(w), m_treeModel(0) { connect(this,SIGNAL(clicked(const QModelIndex)),this,SLOT(sendComponentSelectedSignal(const QModelIndex))); -}; +} void InstrumentTreeWidget::setInstrumentActor(InstrumentActor* instrActor) { diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidSampleLogDialog.cpp b/Code/Mantid/MantidPlot/src/Mantid/MantidSampleLogDialog.cpp index fb7636c0e7603ad382120028012a2ab1e726fa38..343c6551c4120d45acc8e47449eabf88d1806a7b 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/MantidSampleLogDialog.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/MantidSampleLogDialog.cpp @@ -462,6 +462,7 @@ void MantidSampleLogDialog::init() m_tree->header()->resizeSection(3, 90); //units column m_tree->header()->setMovable(false); m_tree->setSortingEnabled(true); + m_tree->sortByColumn(0, Qt::AscendingOrder); } diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidUI.cpp b/Code/Mantid/MantidPlot/src/Mantid/MantidUI.cpp index 2ef4c3335a4734ba153ddf208f75626cebf9bf3f..e3cbe352b68a1f12721380645eb4c6d909b5ec81 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/MantidUI.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/MantidUI.cpp @@ -2310,7 +2310,7 @@ MultiLayer* MantidUI::mergePlots(MultiLayer* mlayer_1, MultiLayer* mlayer_2) mlayer_2->close(); return mlayer_1; -}; +} MantidMatrix* MantidUI::getMantidMatrix(const QString& wsName) { @@ -2519,8 +2519,8 @@ void MantidUI::importNumSeriesLog(const QString &wsName, const QString &logName, { //Seconds offset t->setColName(0, "Time (sec)"); - t->setColumnType(0, Table::Numeric); //six digits after 0 - t->setNumericPrecision(6); //six digits after 0 + t->setColumnType(0, Table::Numeric); + t->setNumericPrecision(16); //it's the number of all digits } //Make the column header with the units, if any @@ -2530,7 +2530,6 @@ void MantidUI::importNumSeriesLog(const QString &wsName, const QString &logName, t->setColName(1, column1); int iValueCurve = 0; - int iFilterCurve = 1; // Applying filters if (filter > 0) @@ -2634,9 +2633,6 @@ void MantidUI::importNumSeriesLog(const QString &wsName, const QString &logName, } } - iValueCurve = 1; - iFilterCurve = 0; - } //end (valid filter exists) } @@ -2734,19 +2730,23 @@ void MantidUI::importNumSeriesLog(const QString &wsName, const QString &logName, if (filter && flt.filter()) { + int iFilterCurve = 1; QwtPlotCurve *c = g->curve(iFilterCurve); - // Set the right axis as Y axis for the filter curve. - c->setAxis(2,1); - // Set style #3 (HorizontalSteps) for curve 1 - // Set scale of right Y-axis (#3) from 0 to 1 - g->setCurveStyle(iFilterCurve,3); - g->setScale(3,0,1); - // Fill area under the curve with a pattern - QBrush br = QBrush(Qt::gray, Qt::Dense5Pattern); - g->setCurveBrush(iFilterCurve, br); - // Set line colour - QPen pn = QPen(Qt::gray); - g->setCurvePen(iFilterCurve, pn); + if ( c ) + { + // Set the right axis as Y axis for the filter curve. + c->setAxis(2,1); + // Set style #3 (HorizontalSteps) for curve 1 + // Set scale of right Y-axis (#3) from 0 to 1 + g->setCurveStyle(iFilterCurve,3); + g->setScale(3,0,1); + // Fill area under the curve with a pattern + QBrush br = QBrush(Qt::gray, Qt::Dense5Pattern); + g->setCurveBrush(iFilterCurve, br); + // Set line colour + QPen pn = QPen(Qt::gray); + g->setCurvePen(iFilterCurve, pn); + } } g->setXAxisTitle(t->colLabel(0)); g->setYAxisTitle(t->colLabel(1).section(".",0,0)); diff --git a/Code/Mantid/MantidPlot/src/MdiSubWindow.cpp b/Code/Mantid/MantidPlot/src/MdiSubWindow.cpp index 3e003d1b593fc70e9a2f28ad13d1e442b603f64a..f0b014fb79a82d2442d714e61ad0ded817581ada 100644 --- a/Code/Mantid/MantidPlot/src/MdiSubWindow.cpp +++ b/Code/Mantid/MantidPlot/src/MdiSubWindow.cpp @@ -98,7 +98,7 @@ void MdiSubWindow::updateCaption() wrapper->setWindowTitle(windowTitle()); } emit captionChanged(objectName(), d_label); -}; +} void MdiSubWindow::resizeEvent( QResizeEvent* e ) { diff --git a/Code/Mantid/MantidPlot/src/MultiLayer.h b/Code/Mantid/MantidPlot/src/MultiLayer.h index e561a61a0fd4f9567bee65e89a9e8ab0c4d815c0..cba7586a9b750b181a036cff1dfaf046295f8308 100644 --- a/Code/Mantid/MantidPlot/src/MultiLayer.h +++ b/Code/Mantid/MantidPlot/src/MultiLayer.h @@ -266,7 +266,7 @@ signals: void clicked(LayerButton*); }; -Q_DECLARE_METATYPE(MultiLayer*); +Q_DECLARE_METATYPE(MultiLayer*) class WaterfallFillDialog : QDialog diff --git a/Code/Mantid/MantidPlot/src/Plot3DDialog.cpp b/Code/Mantid/MantidPlot/src/Plot3DDialog.cpp index f1cab9fe0ed10459a2f02bfe8adc2ed50db2a32f..a231acee361ea34a6fca21608b53fbc4ec1f0664 100644 --- a/Code/Mantid/MantidPlot/src/Plot3DDialog.cpp +++ b/Code/Mantid/MantidPlot/src/Plot3DDialog.cpp @@ -594,7 +594,7 @@ void Plot3DDialog::setPlot(Graph3D *g) connect( boxLegend, SIGNAL(toggled(bool)), d_plot, SLOT(showColorLegend(bool))); connect( boxResolution, SIGNAL(valueChanged(int)), d_plot, SLOT(setResolution(int))); connect( boxDistance, SIGNAL(valueChanged(int)), d_plot, SLOT(setLabelsDistance(int))); -}; +} void Plot3DDialog::worksheet() { diff --git a/Code/Mantid/MantidPlot/src/PlotDialog.cpp b/Code/Mantid/MantidPlot/src/PlotDialog.cpp index 839fd3f965baed883d4665401e262490c10d4a65..f2519bdc5117641ef344ea6fede0b6f21bbea9ec 100644 --- a/Code/Mantid/MantidPlot/src/PlotDialog.cpp +++ b/Code/Mantid/MantidPlot/src/PlotDialog.cpp @@ -1596,15 +1596,14 @@ void PlotDialog::updateTabWindow(QTreeWidgetItem *currentItem, QTreeWidgetItem * if (currentItem->type() == CurveTreeItem::PlotCurveTreeItem) { CurveTreeItem *curveItem = dynamic_cast<CurveTreeItem *>(currentItem); - if (!curveItem) + if (!curveItem) { + boxPlotType->blockSignals(false); return; + } CurveTreeItem *pi = dynamic_cast<CurveTreeItem *>(previousItem); - if (!pi) - return; - if (previousItem->type() != CurveTreeItem::PlotCurveTreeItem - || pi->plotItemType() != curveItem->plotItemType() + || (pi && pi->plotItemType() != curveItem->plotItemType()) || forceClearTabs) { clearTabWidget(); diff --git a/Code/Mantid/MantidPlot/src/PlotDialog.h b/Code/Mantid/MantidPlot/src/PlotDialog.h index f5e1d9017a55c6a0d674c07571a836d8ed58e960..bd58dfa8dfaaf4db744a12a1a0f60e2e29ede80f 100644 --- a/Code/Mantid/MantidPlot/src/PlotDialog.h +++ b/Code/Mantid/MantidPlot/src/PlotDialog.h @@ -181,7 +181,7 @@ private: ColorMapEditor *colorMapEditor; QPushButton* mSelectColormap; QString mCurrentColorMap; - QWidget *curvePlotTypeBox, *layerPage, *layerGeometryPage, *piePage, *fontsPage, *printPage, *contourLinesPage;; + QWidget *curvePlotTypeBox, *layerPage, *layerGeometryPage, *piePage, *fontsPage, *printPage, *contourLinesPage; QTreeWidget* listBox; QCheckBox *boxAntialiasing, *boxAll, *boxScaleLayers, *boxPrintCrops; ColorButton *boxBorderColor, *boxBackgroundColor, *boxCanvasColor, *boxCanvasFrameColor; @@ -236,7 +236,7 @@ private: QLabel *boxRangeLabel, *whiskerCntLabel, *boxCntLabel; QGroupBox *GroupBoxVectEnd; QComboBox *vectPosBox, *boxXAxis, *boxYAxis, *colorScaleBox;//, *boxContourStyle; - PenStyleBox *penContourStyle,*boxContourStyle;; + PenStyleBox *penContourStyle,*boxContourStyle; QSpinBox *levelsBox, *colorScaleWidthBox; DoubleSpinBox *contourWidthBox; QGroupBox *levelsGroupBox, *axisScaleBox, *imageGroupBox; diff --git a/Code/Mantid/MantidPlot/src/PluginFit.cpp b/Code/Mantid/MantidPlot/src/PluginFit.cpp index 708994c0bbb4d94eb4b2fa8896499affaa8a54c0..7ca2fdbe6df82f93d1b97c2ba8e036374d4be53c 100644 --- a/Code/Mantid/MantidPlot/src/PluginFit.cpp +++ b/Code/Mantid/MantidPlot/src/PluginFit.cpp @@ -64,6 +64,39 @@ void PluginFit::init() d_fit_type = Plugin; } + +namespace{ +typedef union { + double (*func)(const gsl_vector *, void *); + void* ptr; +} simplex_union; + +typedef union { + int (*func)(const gsl_vector *, void *, gsl_vector *); + void* ptr; +} f_union; + +typedef union { + int (*func)(const gsl_vector *, void *,gsl_matrix *); + void* ptr; +} df_union; + +typedef union { + int (*func)(const gsl_vector *, void *, gsl_vector *, gsl_matrix *); + void* ptr; +} fdf_union; + +typedef union { + double (*func)(double, double *); + void* ptr; +} ffe_union; + +typedef union { + char* (*func)(); + void* ptr; +} ff_union; +} + bool PluginFit::load(const QString& pluginName) { if (!QFile::exists (pluginName)){ @@ -75,40 +108,52 @@ bool PluginFit::load(const QString& pluginName) QLibrary lib(pluginName); lib.setAutoUnload(false); - d_fsimplex = (fit_function_simplex) lib.resolve( "function_d" ); + simplex_union simplex; + simplex.ptr = lib.resolve( "function_d" ); + d_fsimplex = simplex.func; if (!d_fsimplex){ QMessageBox::critical(static_cast<ApplicationWindow*>(parent()), tr("MantidPlot - Plugin Error"), tr("The plugin does not implement a %1 method necessary for simplex fitting.").arg("function_d")); return false; } - d_f = (fit_function) lib.resolve( "function_f" ); + f_union f; + f.ptr = lib.resolve( "function_f" ); + d_f = f.func; if (!d_f){ QMessageBox::critical(static_cast<ApplicationWindow*>(parent()), tr("MantidPlot - Plugin Error"), tr("The plugin does not implement a %1 method necessary for Levenberg-Marquardt fitting.").arg("function_f")); return false; } - d_df = (fit_function_df) lib.resolve( "function_df" ); - if (!d_df){ + df_union df; + df.ptr = lib.resolve( "function_df" ); + d_df = df.func; + if (!(df.ptr)){ QMessageBox::critical(static_cast<ApplicationWindow*>(parent()), tr("MantidPlot - Plugin Error"), tr("The plugin does not implement a %1 method necessary for Levenberg-Marquardt fitting.").arg("function_df")); return false; } - d_fdf = (fit_function_fdf) lib.resolve( "function_fdf" ); + fdf_union fdf; + fdf.ptr = lib.resolve( "function_fdf" ); + d_fdf = fdf.func; if (!d_fdf){ QMessageBox::critical(static_cast<ApplicationWindow*>(parent()), tr("MantidPlot - Plugin Error"), tr("The plugin does not implement a %1 method necessary for Levenberg-Marquardt fitting.").arg("function_fdf")); return false; } - f_eval = (fitFunctionEval) lib.resolve("function_eval"); + ffe_union ffe; + ffe.ptr = lib.resolve("function_eval"); + f_eval = ffe.func; if (!f_eval) return false; typedef char* (*fitFunc)(); - fitFunc fitFunction = (fitFunc) lib.resolve("parameters"); + ff_union ff; + ff.ptr = lib.resolve("parameters"); + fitFunc fitFunction = ff.func; if (fitFunction){ d_param_names = QString(fitFunction()).split(",", QString::SkipEmptyParts); d_p = (int)d_param_names.count(); @@ -116,17 +161,20 @@ bool PluginFit::load(const QString& pluginName) } else return false; - fitFunc fitExplain = (fitFunc) lib.resolve("explanations"); + ff.ptr = lib.resolve("explanations"); + fitFunc fitExplain = ff.func; if (fitExplain) d_param_explain = QString(fitExplain()).split(",", QString::SkipEmptyParts); else for (int i=0; i<d_p; i++) d_param_explain << ""; - fitFunction = (fitFunc) lib.resolve( "name" ); + ff.ptr = lib.resolve("name"); + fitFunction = ff.func; setObjectName(QString(fitFunction())); - fitFunction = (fitFunc) lib.resolve( "function" ); + ff.ptr = lib.resolve("function"); + fitFunction = ff.func; if (fitFunction) d_formula = QString(fitFunction()); else diff --git a/Code/Mantid/MantidPlot/src/PolynomFitDialog.cpp b/Code/Mantid/MantidPlot/src/PolynomFitDialog.cpp index ae9655bcc774897cf2dd33f27db9f87431a94236..f1e19dc48096b0edbdc3adcb1ea3f9b4651a67fa 100644 --- a/Code/Mantid/MantidPlot/src/PolynomFitDialog.cpp +++ b/Code/Mantid/MantidPlot/src/PolynomFitDialog.cpp @@ -146,7 +146,7 @@ void PolynomFitDialog::setGraph(Graph *g) connect (graph, SIGNAL(closedGraph()), this, SLOT(close())); connect (graph, SIGNAL(dataRangeChanged()), this, SLOT(changeDataRange())); -}; +} void PolynomFitDialog::activateCurve(const QString& curveName) { @@ -156,7 +156,7 @@ void PolynomFitDialog::activateCurve(const QString& curveName) boxStart->setText(QString::number(start, 'g', 15)); boxEnd->setText(QString::number(end, 'g', 15)); boxPoints->setValue(QMAX(n_points, 100)); -}; +} void PolynomFitDialog::changeDataRange() { diff --git a/Code/Mantid/MantidPlot/src/PythonScript.cpp b/Code/Mantid/MantidPlot/src/PythonScript.cpp index 990bcbf2ab777dd7de3061ad244eab585c3400e0..6396aef2af399c082fa1611402faaeb6306965c2 100644 --- a/Code/Mantid/MantidPlot/src/PythonScript.cpp +++ b/Code/Mantid/MantidPlot/src/PythonScript.cpp @@ -686,7 +686,7 @@ namespace } private: InstallTrace(); - Q_DISABLE_COPY(InstallTrace); + Q_DISABLE_COPY(InstallTrace) PyObject *m_sipWrappedScript; }; } diff --git a/Code/Mantid/MantidPlot/src/PythonThreading.h b/Code/Mantid/MantidPlot/src/PythonThreading.h index 663b68568f40f0ae39b84d31aa67373f4596ef06..83a659aa76fca55f63209a32aed3285b7cf12194 100644 --- a/Code/Mantid/MantidPlot/src/PythonThreading.h +++ b/Code/Mantid/MantidPlot/src/PythonThreading.h @@ -18,7 +18,7 @@ struct GlobalInterpreterLock PyGILState_Release(m_state); } private: - Q_DISABLE_COPY(GlobalInterpreterLock); + Q_DISABLE_COPY(GlobalInterpreterLock) /// Current GIL state PyGILState_STATE m_state; }; diff --git a/Code/Mantid/MantidPlot/src/ScriptFileInterpreter.h b/Code/Mantid/MantidPlot/src/ScriptFileInterpreter.h index 785f6119a25fe2b688b1409399942880adbc48aa..705efe9a4ebe730cd9e051e4285ef079cbc0ee3c 100644 --- a/Code/Mantid/MantidPlot/src/ScriptFileInterpreter.h +++ b/Code/Mantid/MantidPlot/src/ScriptFileInterpreter.h @@ -123,7 +123,7 @@ private slots: void setStoppedStatus(); private: - Q_DISABLE_COPY(ScriptFileInterpreter); + Q_DISABLE_COPY(ScriptFileInterpreter) void setupChildWidgets(); void setupEditor(const ScriptingEnv & environ, const QString & identifier); diff --git a/Code/Mantid/MantidPlot/src/Spectrogram.cpp b/Code/Mantid/MantidPlot/src/Spectrogram.cpp index ed8eef7ce6e26f89fb72ca9c3fd32c8f24eb1588..413ab6d07ea9bafe861bcae1f00c011a6c7c60f4 100644 --- a/Code/Mantid/MantidPlot/src/Spectrogram.cpp +++ b/Code/Mantid/MantidPlot/src/Spectrogram.cpp @@ -35,11 +35,15 @@ #include <qwt_scale_engine.h> #include <QPainter> #include <qwt_symbol.h> + #include "Mantid/MantidMatrix.h" #include "Mantid/MantidMatrixFunction.h" +#include "MantidAPI/IMDIterator.h" + +#include "MantidQtAPI/PlotAxis.h" #include "MantidQtAPI/QwtRasterDataMD.h" #include "MantidQtAPI/SignalRange.h" -#include "MantidAPI/IMDIterator.h" + #include "TSVSerialiser.h" #include <iostream> @@ -266,6 +270,17 @@ void Spectrogram::postDataUpdate() plot->setAxisScale(color_axis, data().range().minValue(), data().range().maxValue()); + if ( d_wsData ) + { + auto workspace = d_wsData->getWorkspace(); + if ( workspace ) + { + using MantidQt::API::PlotAxis; + plot->setAxisTitle(QwtPlot::xBottom, PlotAxis(*workspace, 0).title()); + plot->setAxisTitle(QwtPlot::yLeft, PlotAxis(*workspace, 1).title()); + } + } + plot->replot(); } diff --git a/Code/Mantid/MantidPlot/src/qti.sip b/Code/Mantid/MantidPlot/src/qti.sip index 2d12a0cb2431f98d15c8afda373768a9d0009603..b241c862b0d93b5ec2ed9beecfc4e98f66d41c86 100644 --- a/Code/Mantid/MantidPlot/src/qti.sip +++ b/Code/Mantid/MantidPlot/src/qti.sip @@ -31,6 +31,12 @@ %Module _qti +%UnitCode + #if defined(__GNUC__) && !(defined(__INTEL_COMPILER)) + #pragma GCC system_header + #endif +%End + %Import QtCore/QtCoremod.sip %Import QtGui/QtGuimod.sip %Import mantidqt.sip diff --git a/Code/Mantid/MantidPlot/src/sipqti.cpp.in b/Code/Mantid/MantidPlot/src/sipqti.cpp.in index 750399d6d8f9f43b7ead0aee905f0940246ccef5..b7661e1452641623eb1bc54378f8902f76850f3f 100644 --- a/Code/Mantid/MantidPlot/src/sipqti.cpp.in +++ b/Code/Mantid/MantidPlot/src/sipqti.cpp.in @@ -1,13 +1,7 @@ //------------------------------------------------------------------------------ // A wrapper for the auto-generated sipqtipart?.cpp files to disable warnings -// that we can't control +// that we can't control. The warnings are actually suppressed in qti.sip +// with '#pragma GCC system_header' but that pragma only works if it occurs +// in a file that has been included with '#include' //------------------------------------------------------------------------------ -#if defined(__GNUC__) && !(defined(__INTEL_COMPILER)) - #pragma GCC diagnostic ignored "-Wuninitialized" - #pragma GCC diagnostic ignored "-Wconversion" - #pragma GCC diagnostic ignored "-Wunused-variable" - #pragma GCC diagnostic ignored "-Wparentheses" - #pragma GCC diagnostic ignored "-Wcast-qual" -#endif - #include "sip_qtipart0.cpp" diff --git a/Code/Mantid/MantidPlot/src/zlib123/minigzip.c b/Code/Mantid/MantidPlot/src/zlib123/minigzip.c index 5df454d1a8218d8b19bfeadef430f665b52b8fb1..6f12762c8ecedb7a71ddf33c3f7f848178ba3075 100644 --- a/Code/Mantid/MantidPlot/src/zlib123/minigzip.c +++ b/Code/Mantid/MantidPlot/src/zlib123/minigzip.c @@ -252,7 +252,7 @@ void file_uncompress(file) { outfile = file; infile = buf; - // Add the .gz suffix to the filename in buf/infile + /* Add the .gz suffix to the filename in buf/infile */ strcat(buf, GZ_SUFFIX); } in = gzopen(infile, "rb"); diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdSettings.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdSettings.h index 40c0ae9e8547f6823f1b2f677cef38a240b32723..a8a8e87cab0dc97a605399f6d61cd6ec5faa5ec8 100644 --- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdSettings.h +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdSettings.h @@ -65,7 +65,7 @@ namespace MantidQt /** * Set the LastSession color map - * @param colormap The colormap for the VSI. + * @param colorMap The colormap for the VSI. */ void setLastSessionColorMap(QString colorMap); diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/Message.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/Message.h index 0f5c32d37b4c8cec55d5faa814b035faeb5da83a..c14f3a1fd7adab22e8c8ca8bcb1d494179fc9b99 100644 --- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/Message.h +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/Message.h @@ -58,6 +58,6 @@ namespace MantidQt } /// Required to operate in signals/slots -Q_DECLARE_METATYPE(MantidQt::API::Message); +Q_DECLARE_METATYPE(MantidQt::API::Message) #endif //MESSAGE_H_ diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/PlotAxis.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/PlotAxis.h index 6da97440087d0fe165412791ef41846ca96ea888..6cf577e0b7c7a0c003ee919574d374e03559b8ac 100644 --- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/PlotAxis.h +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/PlotAxis.h @@ -50,7 +50,7 @@ namespace MantidQt QString title() const; private: - DISABLE_DEFAULT_CONSTRUCT(PlotAxis); + DISABLE_DEFAULT_CONSTRUCT(PlotAxis) /// Creates a title suitable for an axis attached to the given index void titleFromIndex(const Mantid::API::IMDWorkspace & workspace, diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/QtSignalChannel.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/QtSignalChannel.h index 50dfe80ca77d443cfb590bd030e324acc4c6f5bd..b598204b47d0944f731d8d7c1384c3014f2b0b97 100644 --- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/QtSignalChannel.h +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/QtSignalChannel.h @@ -66,7 +66,7 @@ namespace MantidQt void messageReceived(const Message & msg); private: - Q_DISABLE_COPY(QtSignalChannel); + Q_DISABLE_COPY(QtSignalChannel) /// Optional source (use std::string to avoid conversion in comparison) QString m_source; diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/QwtRasterDataMD.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/QwtRasterDataMD.h index 8cd434537d5947de889dccc6b4abcbff8417889e..0297da3fd1b19c9ed12084367c1dfd74ad898d6e 100644 --- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/QwtRasterDataMD.h +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/QwtRasterDataMD.h @@ -36,6 +36,7 @@ public: QwtRasterDataMD* copy() const; virtual void setWorkspace(Mantid::API::IMDWorkspace_const_sptr ws); + Mantid::API::IMDWorkspace_const_sptr getWorkspace() const; void setOverlayWorkspace(Mantid::API::IMDWorkspace_const_sptr ws); diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/RepoModel.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/RepoModel.h index 8ecc05547ef1fa50b8c1bf1d9048f4a3313ceb9d..f630804187fa97a659a7f9f8212ed5b0346f6c28 100644 --- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/RepoModel.h +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/RepoModel.h @@ -223,7 +223,7 @@ private: /// auxiliary method to help populating the model RepoItem * getParent(const QString & folder, QList<RepoItem*>&parents); - Q_DISABLE_COPY(RepoModel); + Q_DISABLE_COPY(RepoModel) /// auxiliary method to deal with exceptions void handleExceptions(const Mantid::API::ScriptRepoException & ex, @@ -257,7 +257,7 @@ private: }; -}; // namespace API -};// namespace Mantid +} // namespace API +} // namespace Mantid #endif /* MANTID_API_SCRIPTREPOSITORYVIEW_H_ */ diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/SignalRange.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/SignalRange.h index 5e8cf13d92773e82fa1a196f5adcd90f8bf9c2d7..99a9ebba7ea66fca3ab2bd18a755ab9630b984ae 100644 --- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/SignalRange.h +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/SignalRange.h @@ -47,7 +47,7 @@ namespace MantidQt QwtDoubleInterval interval() const; private: - DISABLE_DEFAULT_CONSTRUCT(SignalRange); + DISABLE_DEFAULT_CONSTRUCT(SignalRange) /// Find the min/max signal values in the entire workspace void findFullRange(const Mantid::API::IMDWorkspace & workspace, diff --git a/Code/Mantid/MantidQt/API/src/MdConstants.cpp b/Code/Mantid/MantidQt/API/src/MdConstants.cpp index d07c67b26b2edbad35472f1cbaea85883b490f5a..5eae091543035e64d667dcf69114833dae30c329 100644 --- a/Code/Mantid/MantidQt/API/src/MdConstants.cpp +++ b/Code/Mantid/MantidQt/API/src/MdConstants.cpp @@ -12,9 +12,9 @@ namespace MantidQt { initializeSettingsConstants(); initializeViewConstants(); - }; + } - MdConstants::~MdConstants(){}; + MdConstants::~MdConstants(){} void MdConstants::initializeSettingsConstants() { diff --git a/Code/Mantid/MantidQt/API/src/PropertyWidget.cpp b/Code/Mantid/MantidQt/API/src/PropertyWidget.cpp index 4b938ef3b9454bdb92eb9a48627ee80101aa7e22..2af591dd93965559c09b3a47daef8e4975725b75 100644 --- a/Code/Mantid/MantidQt/API/src/PropertyWidget.cpp +++ b/Code/Mantid/MantidQt/API/src/PropertyWidget.cpp @@ -171,7 +171,7 @@ namespace API /** * Destructor. */ - ClickableLabel::~ClickableLabel() {}; + ClickableLabel::~ClickableLabel() {} /** * Catches the mouse press event and emits the signal. diff --git a/Code/Mantid/MantidQt/API/src/QwtRasterDataMD.cpp b/Code/Mantid/MantidQt/API/src/QwtRasterDataMD.cpp index 897926b8bc072d7884f2eb30e4b68a39e27792de..1a1267c3382f48eaee3cea268e10658fbcee43c6 100644 --- a/Code/Mantid/MantidQt/API/src/QwtRasterDataMD.cpp +++ b/Code/Mantid/MantidQt/API/src/QwtRasterDataMD.cpp @@ -199,6 +199,14 @@ void QwtRasterDataMD::setWorkspace(IMDWorkspace_const_sptr ws) m_slicePoint = new coord_t[m_nd]; } +//------------------------------------------------------------------------------------------------------ +/** Gets the workspace being displayed + */ +Mantid::API::IMDWorkspace_const_sptr QwtRasterDataMD::getWorkspace() const +{ + return m_ws; +} + //------------------------------------------------------------------------------------------------------ /** Sets the workspace that will be displayed ON TOP of the original workspace. * For dynamic rebinning. diff --git a/Code/Mantid/MantidQt/API/src/RepoModel.cpp b/Code/Mantid/MantidQt/API/src/RepoModel.cpp index 14e3a8ebbc84bc57c1bcfd3944fe184ac9d30b84..0fd6e88b36bcf864f97927794d3ed9674a201295 100644 --- a/Code/Mantid/MantidQt/API/src/RepoModel.cpp +++ b/Code/Mantid/MantidQt/API/src/RepoModel.cpp @@ -940,21 +940,21 @@ bool RepoModel::isUploading(const QModelIndex & index)const{ /// @return string to define the LOCAL_ONLY state -const QString & RepoModel::localOnlySt(){return LOCALONLY;}; +const QString & RepoModel::localOnlySt(){return LOCALONLY;} /// @return string to define the REMOTE_ONLY state -const QString & RepoModel::remoteOnlySt(){return REMOTEONLY;}; +const QString & RepoModel::remoteOnlySt(){return REMOTEONLY;} /// @return string to define the LOCAL_CHANGED state -const QString & RepoModel::localChangedSt(){return LOCALCHANGED;}; +const QString & RepoModel::localChangedSt(){return LOCALCHANGED;} /// @return string to define the REMOTE_CHANGED state -const QString & RepoModel::remoteChangedSt(){return REMOTECHANGED;}; +const QString & RepoModel::remoteChangedSt(){return REMOTECHANGED;} /// @return string to define the BOTH_UNCHANGED state -const QString & RepoModel::updatedSt(){return BOTHUNCHANGED;}; +const QString & RepoModel::updatedSt(){return BOTHUNCHANGED;} /// @return string to define the BOTH_CHANGED state -const QString & RepoModel::bothChangedSt(){return BOTHCHANGED;}; +const QString & RepoModel::bothChangedSt(){return BOTHCHANGED;} /// @return string to define the downloading state -const QString & RepoModel::downloadSt(){return DOWNLOADST;}; +const QString & RepoModel::downloadSt(){return DOWNLOADST;} /// @return string to define the uploading state -const QString & RepoModel::uploadSt(){return UPLOADST;}; +const QString & RepoModel::uploadSt(){return UPLOADST;} diff --git a/Code/Mantid/MantidQt/API/src/ScriptRepositoryView.cpp b/Code/Mantid/MantidQt/API/src/ScriptRepositoryView.cpp index 96cd7bcd4f4b3b742ae7006a272f36d329aa225c..5f76e642dc0ec7aab6683f0c939dbfc7f2ecebd0 100644 --- a/Code/Mantid/MantidQt/API/src/ScriptRepositoryView.cpp +++ b/Code/Mantid/MantidQt/API/src/ScriptRepositoryView.cpp @@ -377,7 +377,7 @@ bool ScriptRepositoryView::RepoDelegate::editorEvent(QEvent *event, QSize ScriptRepositoryView::RepoDelegate::sizeHint(const QStyleOptionViewItem & /*option*/, const QModelIndex & /*index*/ ) const{ return QSize(35,35); -} ; +} ////////////////////////////////////////////////// diff --git a/Code/Mantid/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/SampleShapeHelpers.h b/Code/Mantid/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/SampleShapeHelpers.h index 4a774a9bfdf3883949c0b5c69976e898ecf78940..a83e99cb3bcba6f67e08876855e0a3ab96bddd38 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/SampleShapeHelpers.h +++ b/Code/Mantid/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/SampleShapeHelpers.h @@ -34,7 +34,7 @@ class ShapeDetails; */ class PointGroupBox : public QGroupBox { - Q_OBJECT; + Q_OBJECT public: //Default constructor diff --git a/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp b/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp index 1cad4d1c3eed2aa02c91eb775887ec5117678447..e16e6621686daa9fbd125bc94dddf8ed62462ac6 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp +++ b/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp @@ -14,7 +14,7 @@ namespace MantidQt { namespace CustomDialogs { - DECLARE_DIALOG(CatalogPublishDialog); + DECLARE_DIALOG(CatalogPublishDialog) /** * Default constructor. diff --git a/Code/Mantid/MantidQt/CustomDialogs/src/ConvertTableToMatrixWorkspaceDialog.cpp b/Code/Mantid/MantidQt/CustomDialogs/src/ConvertTableToMatrixWorkspaceDialog.cpp index 96b80b7c1a10d8c9bd49bcb0de432e4d3fb7af0f..314e3b9d9e81a95567f8f941eb6110ab35e6c222 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/src/ConvertTableToMatrixWorkspaceDialog.cpp +++ b/Code/Mantid/MantidQt/CustomDialogs/src/ConvertTableToMatrixWorkspaceDialog.cpp @@ -22,7 +22,7 @@ namespace MantidQt namespace CustomDialogs { // Declare the dialog. Name must match the class name - DECLARE_DIALOG(ConvertTableToMatrixWorkspaceDialog); + DECLARE_DIALOG(ConvertTableToMatrixWorkspaceDialog) //-------------------------------------------------------------------------- // Public methods diff --git a/Code/Mantid/MantidQt/CustomDialogs/src/CreateSampleShapeDialog.cpp b/Code/Mantid/MantidQt/CustomDialogs/src/CreateSampleShapeDialog.cpp index c0345f3727b179b415cb8d877a1bb3642a76a87a..02aa58ba0026daf06094976a5a807d40226ee04c 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/src/CreateSampleShapeDialog.cpp +++ b/Code/Mantid/MantidQt/CustomDialogs/src/CreateSampleShapeDialog.cpp @@ -24,7 +24,7 @@ namespace MantidQt { namespace CustomDialogs { - DECLARE_DIALOG(CreateSampleShapeDialog); + DECLARE_DIALOG(CreateSampleShapeDialog) } } diff --git a/Code/Mantid/MantidQt/CustomDialogs/src/FitDialog.cpp b/Code/Mantid/MantidQt/CustomDialogs/src/FitDialog.cpp index 7b4217a2dc42a1c363509643b2f6cfe3c7849d7c..d39863b1b7767173d76e1c7b7024b48fab709f25 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/src/FitDialog.cpp +++ b/Code/Mantid/MantidQt/CustomDialogs/src/FitDialog.cpp @@ -31,7 +31,7 @@ namespace CustomDialogs { // Declare the dialog. Name must match the class name -DECLARE_DIALOG(FitDialog); +DECLARE_DIALOG(FitDialog) //------------------------------------------------------ // InputWorkspaceWidget methods diff --git a/Code/Mantid/MantidQt/CustomDialogs/src/LOQScriptInputDialog.cpp b/Code/Mantid/MantidQt/CustomDialogs/src/LOQScriptInputDialog.cpp index 5fdda1e5b182bbbbc9a093bd6bbf840dc01bdf38..15280c6c137d709330b7f28fcdd760c936618603 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/src/LOQScriptInputDialog.cpp +++ b/Code/Mantid/MantidQt/CustomDialogs/src/LOQScriptInputDialog.cpp @@ -13,7 +13,7 @@ namespace MantidQt { namespace CustomDialogs { - DECLARE_DIALOG(LOQScriptInputDialog); + DECLARE_DIALOG(LOQScriptInputDialog) } } diff --git a/Code/Mantid/MantidQt/CustomDialogs/src/LoadDialog.cpp b/Code/Mantid/MantidQt/CustomDialogs/src/LoadDialog.cpp index 2f88ee8c8972a01ab23344eebd9e4b6545bded73..7c4f993de8deda0bdbbf36c86f8a933d1323bd2a 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/src/LoadDialog.cpp +++ b/Code/Mantid/MantidQt/CustomDialogs/src/LoadDialog.cpp @@ -41,7 +41,7 @@ namespace MantidQt } // Declare the dialog. Name must match the class name - DECLARE_DIALOG(LoadDialog); + DECLARE_DIALOG(LoadDialog) //-------------------------------------------------------------------------- // Public methods diff --git a/Code/Mantid/MantidQt/CustomDialogs/src/LoadInstrumentDialog.cpp b/Code/Mantid/MantidQt/CustomDialogs/src/LoadInstrumentDialog.cpp index 37192b4c29992eacad85712ece2b9f4edfbca603..5716406111d92270b3c458c55d12be125a332c2b 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/src/LoadInstrumentDialog.cpp +++ b/Code/Mantid/MantidQt/CustomDialogs/src/LoadInstrumentDialog.cpp @@ -11,7 +11,7 @@ namespace MantidQt { namespace CustomDialogs { - DECLARE_DIALOG(LoadInstrumentDialog); + DECLARE_DIALOG(LoadInstrumentDialog) /** Constructor diff --git a/Code/Mantid/MantidQt/CustomDialogs/src/SortTableWorkspaceDialog.cpp b/Code/Mantid/MantidQt/CustomDialogs/src/SortTableWorkspaceDialog.cpp index 5b2a0dc90887d7f12a5feccb3c54ecdaadb478c9..7a81d7a310dc9bce13ba71f3205d938db5bf6736 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/src/SortTableWorkspaceDialog.cpp +++ b/Code/Mantid/MantidQt/CustomDialogs/src/SortTableWorkspaceDialog.cpp @@ -15,7 +15,7 @@ namespace CustomDialogs { // Declare the dialog. Name must match the class name -DECLARE_DIALOG(SortTableWorkspaceDialog); +DECLARE_DIALOG(SortTableWorkspaceDialog) /// Default constructor diff --git a/Code/Mantid/MantidQt/CustomDialogs/src/StartLiveDataDialog.cpp b/Code/Mantid/MantidQt/CustomDialogs/src/StartLiveDataDialog.cpp index 65330a4d7d5f02c2605754fc78f702ab9470dc9e..0450d6bd8eaf6fa7e9de4db4d790a0a66bc3f5d9 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/src/StartLiveDataDialog.cpp +++ b/Code/Mantid/MantidQt/CustomDialogs/src/StartLiveDataDialog.cpp @@ -64,7 +64,7 @@ namespace MantidQt { namespace CustomDialogs { - DECLARE_DIALOG(StartLiveDataDialog); + DECLARE_DIALOG(StartLiveDataDialog) //---------------------- // Public member functions diff --git a/Code/Mantid/MantidQt/CustomInterfaces/icons/CustomInterfacesIcons.qrc b/Code/Mantid/MantidQt/CustomInterfaces/icons/CustomInterfacesIcons.qrc index a9dba762f557dc591637a434ab628092634b27c5..d6f4340e93961cc9ac7f00cb763d6ad1ded4af40 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/icons/CustomInterfacesIcons.qrc +++ b/Code/Mantid/MantidQt/CustomInterfaces/icons/CustomInterfacesIcons.qrc @@ -2,5 +2,6 @@ <qresource prefix="/MultiDatasetFit/icons"> <file>zoom.png</file> <file>panning.png</file> + <file>range.png</file> </qresource> </RCC> diff --git a/Code/Mantid/MantidQt/CustomInterfaces/icons/range.png b/Code/Mantid/MantidQt/CustomInterfaces/icons/range.png new file mode 100644 index 0000000000000000000000000000000000000000..3c1552f3b6376019dfec585084bdadea76c6cc26 Binary files /dev/null and b/Code/Mantid/MantidQt/CustomInterfaces/icons/range.png differ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IReflPresenter.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IReflPresenter.h index 52720837cbe2bacaba64f456483a9add0410a43c..9acf1b47564a38313f2d7b1cdeecaf941a68f1a2 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IReflPresenter.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IReflPresenter.h @@ -64,7 +64,7 @@ namespace MantidQt ImportTableFlag, ExportTableFlag, PlotRowFlag, - PlotGroupFlag, + PlotGroupFlag }; //Tell the presenter something happened diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/CalcCorr.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/CalcCorr.ui index 4329c2f27e0825e1d4fd665df56f2836ba3b6abb..6ec1670e1868361294f35eff5b84a65fd214d164 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/CalcCorr.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/CalcCorr.ui @@ -209,7 +209,7 @@ <number>1</number> </property> <property name="currentIndex"> - <number>1</number> + <number>0</number> </property> <widget class="QWidget" name="pageFlat"> <layout class="QVBoxLayout" name="verticalLayout_4"> diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTab.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTab.h index 1c6750a08434ed347528256c1637a1fcac3422ae..2664203f1fc7f8d0aa4341d4e4a5a252938ae462 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTab.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTab.h @@ -42,7 +42,9 @@ namespace MantidQt { namespace CustomInterfaces { - /** IndirectTab : TODO: DESCRIPTION + /** IndirectTab + + Provided common functionality of all indirect interface tabs. @author Dan Nixon @date 08/10/2014 @@ -90,9 +92,13 @@ namespace CustomInterfaces bool loadFile(const QString& filename, const QString& outputName, const int specMin = -1, const int specMax = -1); /// Function to set the range limits of the plot - void setPlotPropertyRange(const QString& rsID, QtProperty* min, QtProperty* max, const QPair<double, double> & bounds); + void setPlotPropertyRange(MantidQt::MantidWidgets::RangeSelector * rs, + QtProperty* min, QtProperty* max, + const QPair<double, double> & bounds); /// Function to set the range selector on the mini plot - void setRangeSelector(const QString& rsID, QtProperty* lower, QtProperty* upper, const QPair<double, double> & bounds); + void setRangeSelector(MantidQt::MantidWidgets::RangeSelector * rs, + QtProperty* lower, QtProperty* upper, + const QPair<double, double> & bounds); /// Function to run an algorithm on a seperate thread void runAlgorithm(const Mantid::API::IAlgorithm_sptr algorithm); @@ -102,8 +108,6 @@ namespace CustomInterfaces /// Parent QWidget (if applicable) QWidget *m_parentWidget; - /// Range selector widget for mini plot - std::map<QString, MantidQt::MantidWidgets::RangeSelector *> m_rangeSelectors; /// Tree of the properties std::map<QString, QtTreePropertyBrowser *> m_propTrees; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MantidEV.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MantidEV.h index 2bb6f7f0130a9b2020af35f140cb87c8e0afda6b..d521c6f5df8cd3f1a374792c42cad55cefb69eef 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MantidEV.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MantidEV.h @@ -310,6 +310,12 @@ private slots: /// Slot to load a peaks workspace to the current MantidEV named workspace void loadIsawPeaks_slot(); + /// Slot to save the current MantidEV peaks workspace + void saveNexusPeaks_slot(); + + /// Slot to load a peaks workspace to the current MantidEV named workspace + void loadNexusPeaks_slot(); + /// Slot to show the UB matrix void showUB_slot(); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MantidEV.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MantidEV.ui index bffc3627533b62b8a837bb18c45adffc169d2487..4906f166dbcb095a57fff07ca31a045459a3fce7 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MantidEV.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MantidEV.ui @@ -20,3442 +20,3435 @@ <string>SCD Event Data Reduction</string> </property> <widget class="QWidget" name="centralwidget"> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QMenuBar" name="menubar"> - <widget class="QMenu" name="menuFile"> - <property name="title"> - <string>File</string> - </property> - <addaction name="actionSave_Isaw_UB"/> - <addaction name="actionLoad_Isaw_UB"/> - <addaction name="actionSave_Isaw_Peaks"/> - <addaction name="actionLoad_Isaw_Peaks"/> - <addaction name="actionSave_State"/> - <addaction name="actionLoad_State"/> - <addaction name="actionReset_Default_Settings"/> - </widget> - <widget class="QMenu" name="menuView"> - <property name="title"> - <string>View</string> - </property> - <addaction name="actionShow_UB"/> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QMenuBar" name="menubar"> + <widget class="QMenu" name="menuFile"> + <property name="title"> + <string>File</string> + </property> + <addaction name="actionSave_Isaw_UB"/> + <addaction name="actionLoad_Isaw_UB"/> + <addaction name="actionSave_Isaw_Peaks"/> + <addaction name="actionLoad_Isaw_Peaks"/> + <addaction name="actionSave_Nexus_Peaks"/> + <addaction name="actionLoad_Nexus_Peaks"/> + <addaction name="actionSave_State"/> + <addaction name="actionLoad_State"/> + <addaction name="actionReset_Default_Settings"/> + </widget> + <widget class="QMenu" name="menuView"> + <property name="title"> + <string>View</string> + </property> + <addaction name="actionShow_UB"/> + </widget> + <widget class="QMenu" name="menuHelp"> + <property name="title"> + <string>Help</string> + </property> + <addaction name="actionOnline_Help_Page"/> + </widget> + <addaction name="menuFile"/> + <addaction name="menuView"/> + <addaction name="menuHelp"/> </widget> - <widget class="QMenu" name="menuHelp"> - <property name="title"> - <string>Help</string> + </item> + <item> + <widget class="QTabWidget" name="MantidEV_tabwidg"> + <property name="toolTip"> + <string/> </property> - <addaction name="actionOnline_Help_Page"/> - </widget> - <addaction name="menuFile"/> - <addaction name="menuView"/> - <addaction name="menuHelp"/> - </widget> - </item> - <item> - <widget class="QTabWidget" name="MantidEV_tabwidg"> - <property name="toolTip"> - <string/> - </property> - <property name="currentIndex"> - <number>3</number> - </property> - <widget class="QWidget" name="SelectData"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <property name="currentIndex"> + <number>1</number> </property> - <attribute name="title"> - <string>Select Data</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <item> - <widget class="QScrollArea" name="selectDataScrollArea"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="baseSize"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="frameShape"> - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Plain</enum> - </property> - <property name="lineWidth"> - <number>0</number> - </property> - <property name="verticalScrollBarPolicy"> - <enum>Qt::ScrollBarAsNeeded</enum> - </property> - <property name="widgetResizable"> - <bool>true</bool> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - <widget class="QWidget" name="scrollAreaWidgetContents"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>903</width> - <height>708</height> - </rect> + <widget class="QWidget" name="SelectData"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <attribute name="title"> + <string>Select Data</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QScrollArea" name="selectDataScrollArea"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> </property> <property name="minimumSize"> <size> - <width>500</width> - <height>500</height> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>0</width> + <height>0</height> </size> </property> - <property name="autoFillBackground"> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + <property name="lineWidth"> + <number>0</number> + </property> + <property name="verticalScrollBarPolicy"> + <enum>Qt::ScrollBarAsNeeded</enum> + </property> + <property name="widgetResizable"> <bool>true</bool> </property> - <layout class="QVBoxLayout" name="verticalLayout_7"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_7"> - <property name="sizeConstraint"> - <enum>QLayout::SetDefaultConstraint</enum> - </property> - <item> - <widget class="QLabel" name="SelectEventWorkspace_lbl"> - <property name="text"> - <string>Event Workspace Name</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_6"> - <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="QLineEdit" name="SelectEventWorkspace_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>200</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string>Name of the event workspace to use. This name is set by default,<br> if data is loaded from an event file and mapped to an MD workspace.</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_8"> - <item> - <widget class="QLabel" name="SelectMDWorkspace_lbl"> - <property name="text"> - <string>MD Workspace Name</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_7"> - <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="QLineEdit" name="MDworkspace_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>200</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string>Name of the MD workspace to use. This name is set<br>by default, if data is loaded from an event file and mapped to an MD workspace.</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QGroupBox" name="convertToMDGroupBox"> - <property name="minimumSize"> - <size> - <width>0</width> - <height>160</height> - </size> - </property> - <property name="toolTip"> - <string>Not doing this will use existing workspace</string> - </property> - <property name="title"> - <string>Convert to MD</string> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout_8"> - <item> - <layout class="QVBoxLayout" name="verticalLayout_4"> - <property name="sizeConstraint"> - <enum>QLayout::SetDefaultConstraint</enum> - </property> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_3"> - <item> - <widget class="QLabel" name="MinMagQ_lbl"> - <property name="text"> - <string>Min |Q| to Map to MD</string> - </property> - </widget> - </item> - <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="QLineEdit" name="MinMagQ_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>50</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string>Specify value to use as bound on |Qx|, |Qy| and |Qz|</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QLabel" name="MaxMagQ_lbl"> - <property name="text"> - <string>Max |Q| to Map to MD</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <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="QLineEdit" name="MaxMagQ_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>50</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string>Specify value to use as bound on |Qx|, |Qy| and |Qz|</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QCheckBox" name="LorentzCorrection_ckbx"> - <property name="toolTip"> - <string>Apply the Lorentz Correction as<br> data is mapped to reciprocal space and stored in the MD workspace. This helps with finding peaks with larger |Q|.</string> - </property> - <property name="text"> - <string>Apply Lorentz Correction</string> - </property> - </widget> - </item> - </layout> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>903</width> + <height>696</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>500</width> + <height>500</height> + </size> + </property> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_7"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_7"> + <property name="sizeConstraint"> + <enum>QLayout::SetDefaultConstraint</enum> + </property> + <item> + <widget class="QLabel" name="SelectEventWorkspace_lbl"> + <property name="text"> + <string>Event Workspace Name</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_6"> + <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="QLineEdit" name="SelectEventWorkspace_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>200</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Name of the event workspace to use. This name is set by default,<br> if data is loaded from an event file and mapped to an MD workspace.</string> + </property> + </widget> </item> </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="loadDataGroupBox"> - <property name="minimumSize"> - <size> - <width>0</width> - <height>200</height> - </size> - </property> - <property name="toolTip"> - <string>If disabled then use existing workspaces</string> - </property> - <property name="title"> - <string>Load Event Data</string> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <item> - <layout class="QVBoxLayout" name="verticalLayout_6"> - <property name="sizeConstraint"> - <enum>QLayout::SetDefaultConstraint</enum> - </property> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_6"> - <item> - <widget class="QLabel" name="EventFileName_lbl"> - <property name="text"> - <string>Filename</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_5"> - <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="QLineEdit" name="EventFileName_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>400</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string>Specify the name of the data file to load. Press<br> return to set default names for Event, MD and Peaks workspaces.</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="SelectEventFile_btn"> - <property name="toolTip"> - <string>Browse for the event file to be loaded.</string> - </property> - <property name="text"> - <string>Browse</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QCheckBox" name="LoadDetCal_ckbx"> - <property name="toolTip"> - <string>Optionally, apply<br> calibration information from the specified .DetCal file(s).</string> - </property> - <property name="text"> - <string> Load ISAW Detector Calibration</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_5"> - <item> - <widget class="QLabel" name="CalFileName_lbl"> - <property name="text"> - <string>Filename</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_4"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLineEdit" name="CalFileName_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>400</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string>Select the .DetCal file to apply.</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="SelectCalFile_btn"> - <property name="toolTip"> - <string>Browse for the first .DetCal file to be used.</string> - </property> - <property name="text"> - <string>Browse</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_4"> - <item> - <widget class="QLabel" name="CalFileName2_lbl"> - <property name="text"> - <string>Filename2</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_3"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLineEdit" name="CalFileName2_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>400</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string>Select the second .DetCal file for the second detector<br> panel on the SNAP instrument at the SNS.</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="SelectCalFile2_btn"> - <property name="toolTip"> - <string>Browse for the second .DetCal file to be used<br> for the second panel on SNAP.</string> - </property> - <property name="text"> - <string>Browse</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_8"> + <item> + <widget class="QLabel" name="SelectMDWorkspace_lbl"> + <property name="text"> + <string>MD Workspace Name</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_7"> + <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="QLineEdit" name="MDworkspace_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>200</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Name of the MD workspace to use. This name is set<br>by default, if data is loaded from an event file and mapped to an MD workspace.</string> + </property> + </widget> </item> </layout> - </widget> - </item> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_9"> - <property name="sizeConstraint"> - <enum>QLayout::SetDefaultConstraint</enum> - </property> - <item> - <spacer name="horizontalSpacer_10"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="ApplySelectData_btn"> - <property name="toolTip"> - <string>Actually load the data and convert to MD, or just<br> proceed to the next tab using previously loaded data.</string> - </property> - <property name="text"> - <string>Apply</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> + </item> + <item> + <widget class="QGroupBox" name="convertToMDGroupBox"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>160</height> + </size> + </property> + <property name="toolTip"> + <string>Not doing this will use existing workspace</string> + </property> + <property name="title"> + <string>Convert to MD</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_8"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <property name="sizeConstraint"> + <enum>QLayout::SetDefaultConstraint</enum> + </property> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QLabel" name="MinMagQ_lbl"> + <property name="text"> + <string>Min |Q| to Map to MD</string> + </property> + </widget> + </item> + <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="QLineEdit" name="MinMagQ_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Specify value to use as bound on |Qx|, |Qy| and |Qz|</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="MaxMagQ_lbl"> + <property name="text"> + <string>Max |Q| to Map to MD</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <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="QLineEdit" name="MaxMagQ_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Specify value to use as bound on |Qx|, |Qy| and |Qz|</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QCheckBox" name="LorentzCorrection_ckbx"> + <property name="toolTip"> + <string>Apply the Lorentz Correction as<br> data is mapped to reciprocal space and stored in the MD workspace. This helps with finding peaks with larger |Q|.</string> + </property> + <property name="text"> + <string>Apply Lorentz Correction</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="loadDataGroupBox"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>200</height> + </size> + </property> + <property name="toolTip"> + <string>If disabled then use existing workspaces</string> + </property> + <property name="title"> + <string>Load Event Data</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <property name="sizeConstraint"> + <enum>QLayout::SetDefaultConstraint</enum> + </property> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_6"> + <item> + <widget class="QLabel" name="EventFileName_lbl"> + <property name="text"> + <string>Filename</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_5"> + <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="QLineEdit" name="EventFileName_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>400</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Specify the name of the data file to load. Press<br> return to set default names for Event, MD and Peaks workspaces.</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="SelectEventFile_btn"> + <property name="toolTip"> + <string>Browse for the event file to be loaded.</string> + </property> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QCheckBox" name="LoadDetCal_ckbx"> + <property name="toolTip"> + <string>Optionally, apply<br> calibration information from the specified .DetCal file(s).</string> + </property> + <property name="text"> + <string> Load ISAW Detector Calibration</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_5"> + <item> + <widget class="QLabel" name="CalFileName_lbl"> + <property name="text"> + <string>Filename</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLineEdit" name="CalFileName_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>400</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Select the .DetCal file to apply.</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="SelectCalFile_btn"> + <property name="toolTip"> + <string>Browse for the first .DetCal file to be used.</string> + </property> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <widget class="QLabel" name="CalFileName2_lbl"> + <property name="text"> + <string>Filename2</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLineEdit" name="CalFileName2_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>400</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Select the second .DetCal file for the second detector<br> panel on the SNAP instrument at the SNS.</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="SelectCalFile2_btn"> + <property name="toolTip"> + <string>Browse for the second .DetCal file to be used<br> for the second panel on SNAP.</string> + </property> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_9"> + <property name="sizeConstraint"> + <enum>QLayout::SetDefaultConstraint</enum> + </property> + <item> + <spacer name="horizontalSpacer_10"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="ApplySelectData_btn"> + <property name="toolTip"> + <string>Actually load the data and convert to MD, or just<br> proceed to the next tab using previously loaded data.</string> + </property> + <property name="text"> + <string>Apply</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> </widget> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="FindPeaks"> - <attribute name="title"> - <string>Find Peaks</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_9"> - <item> - <widget class="QScrollArea" name="scrollArea"> - <property name="frameShape"> - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Plain</enum> - </property> - <property name="widgetResizable"> - <bool>true</bool> - </property> - <widget class="QWidget" name="scrollAreaWidgetContents_2"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>903</width> - <height>708</height> - </rect> + </item> + </layout> + </widget> + <widget class="QWidget" name="FindPeaks"> + <attribute name="title"> + <string>Find Peaks</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_9"> + <item> + <widget class="QScrollArea" name="scrollArea"> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> </property> - <layout class="QVBoxLayout" name="verticalLayout_10"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_10"> - <item> - <widget class="QLabel" name="PeaksWorkspace_lbl"> - <property name="text"> - <string>Peaks Workspace Name</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_18"> - <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="QLineEdit" name="PeaksWorkspace_ledt"> - <property name="toolTip"> - <string>Name of the peaks workspace to use. This name is set by default,<br> if data is loaded from an event file and mapped to an MD workspace on the Select Data tab.</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="Line" name="line_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="FindPeaks_rbtn"> - <property name="toolTip"> - <string>Search through the MD workspace to find Bragg peaks.</string> - </property> - <property name="text"> - <string>Find Peaks</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_11"> - <item> - <spacer name="horizontalSpacer_9"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="MaxABC_lbl"> - <property name="text"> - <string>Estimated Max of a,b,c</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_14"> - <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="QLineEdit" name="MaxABC_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Estimated maximum for real<br> space cell edge length in Angstroms. This is used to get an approximate lower bound on the possible distances between peaks.</string> - </property> - <property name="text"> - <string>15</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_12"> - <item> - <spacer name="horizontalSpacer_11"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="NumToFind_lbl"> - <property name="text"> - <string>Number of Peaks to Find</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_15"> - <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="QLineEdit" name="NumToFind_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Maximum number of peaks to find. Boxes with progressively<br> lower local intensity will be tried, until the specified number of peaks is found, or until the intensity falls below the specified Min Intensity.</string> - </property> - <property name="text"> - <string>50</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_13"> - <item> - <spacer name="horizontalSpacer_12"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="MinIntensity_lbl"> - <property name="text"> - <string>Min Intensity(above ave)</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_16"> - <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="QLineEdit" name="MinIntensity_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Lower bound on the local intensity of MD boxes to consider as possible peaks, expressed as a multiple of the overall average intensity of the entire MD workspace region. Boxes with progressively<br> lower local intensity will be tried, until the specified number of peaks is found, or until the intensity falls below the specified Min Intensity.</string> - </property> - <property name="text"> - <string>10000</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QRadioButton" name="UseExistingPeaksWorkspace_rbtn"> - <property name="toolTip"> - <string>Use a peaks workspace with peaks that have been<br> been previously found, predicted, or loaded. </string> - </property> - <property name="text"> - <string>Use Existing Peaks Workspace</string> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="LoadIsawPeaks_rbtn"> - <property name="toolTip"> - <string>Load the peaks workspace from a file of peaks<br> that have been previously found or predicted.</string> - </property> - <property name="text"> - <string>Load ISAW Peaks (or Integrate) File</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_14"> - <item> - <spacer name="horizontalSpacer_13"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="SelectPeaksFile_lbl"> - <property name="text"> - <string>Filename</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_17"> - <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="QLineEdit" name="SelectPeaksFile_ledt"> - <property name="toolTip"> - <string>Name of the peaks file that should be loaded.</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="SelectPeaksFile_btn"> - <property name="toolTip"> - <string>Browse for the file of peaks to load.</string> - </property> - <property name="text"> - <string>Browse</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <spacer name="verticalSpacer_2"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_15"> - <item> - <spacer name="horizontalSpacer_8"> - <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="ApplyFindPeaks_btn"> - <property name="toolTip"> - <string>Proceed to actually get the<br> peaks or use the existing peaks, as specified..</string> - </property> - <property name="text"> - <string>Apply</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="FindUB"> - <attribute name="title"> - <string>Find UB</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_11"> - <item> - <widget class="QScrollArea" name="scrollArea_2"> - <property name="frameShape"> - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Plain</enum> - </property> - <property name="widgetResizable"> - <bool>true</bool> - </property> - <widget class="QWidget" name="scrollAreaWidgetContents_4"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>903</width> - <height>708</height> - </rect> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> </property> - <layout class="QVBoxLayout" name="verticalLayout_12"> - <item> - <widget class="QRadioButton" name="FindUBUsingFFT_rbtn"> - <property name="toolTip"> - <string>Find a UB matrix using the<br> FindUBUsingFFT algorithm. This will produce a UB matrix corresponding to the Niggli reduced cell for the lattice.</string> - </property> - <property name="text"> - <string>Find UB Using FFT</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_20"> - <item> - <spacer name="horizontalSpacer_28"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="MinD_lbl"> - <property name="text"> - <string>Estimated Lower Bound for a,b,c</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_29"> - <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="QLineEdit" name="MinD_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Set this to a value that is<br> about 50%-90% of the shortest real space edge length, in Angstroms.</string> - </property> - <property name="text"> - <string>3</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_21"> - <item> - <spacer name="horizontalSpacer_27"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="MaxD_lbl"> - <property name="text"> - <string>Estimated Upper Bound for a,b,c</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_30"> - <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="QLineEdit" name="MaxD_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Set this to a value that is<br> about 110%-150% of the longest real space edge length, in Angstroms.</string> - </property> - <property name="text"> - <string>15</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_22"> - <item> - <spacer name="horizontalSpacer_26"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="FFTTolerance_lbl"> - <property name="text"> - <string>Tolerance</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_31"> - <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="QLineEdit" name="FFTTolerance_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Maximum distance of h,k or l from integer values to<br> consider a peak to be indexed.</string> - </property> - <property name="text"> - <string>0.12</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QRadioButton" name="FindUBUsingIndexedPeaks_rbtn"> - <property name="toolTip"> - <string>Find the UB matrix using the FindUBUsingIndexedPeaks algorithm. Specifically, if the<br> peaks in the peaks workspace have already been indexed, find the UB matrix that corresponds to that indexing.</string> - </property> - <property name="text"> - <string>Find UB Using Indexed Peaks</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_23"> - <item> - <spacer name="horizontalSpacer_25"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="IndexedPeaksTolerance_lbl"> - <property name="text"> - <string>Tolerance</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_32"> - <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="QLineEdit" name="IndexedPeaksTolerance_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Maximum distance of h,k or l from integer values to<br> consider a peak to be indexed.</string> - </property> - <property name="text"> - <string>0.1</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QRadioButton" name="LoadISAWUB_rbtn"> - <property name="toolTip"> - <string>Load the UB matrix from a file.</string> - </property> - <property name="text"> - <string>Load Isaw UB</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_24"> - <item> - <spacer name="horizontalSpacer_24"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="SelectUBFile_lbl"> - <property name="text"> - <string>Filename</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_33"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::MinimumExpanding</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLineEdit" name="SelectUBFile_ledt"> - <property name="toolTip"> - <string>Name of the file with the UB matrix.</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="SelectUBFile_btn"> - <property name="toolTip"> - <string>Browse for the file with the UB matrix.</string> - </property> - <property name="text"> - <string>Browse</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_31"> - <item> - <spacer name="horizontalSpacer_23"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QCheckBox" name="OptimizeGoniometerAngles_ckbx"> - <property name="toolTip"> - <string>Optimize the goniometer<br> angles, to index the peaks as accurately as possible using the UB matrix that was loaded.</string> - </property> - <property name="text"> - <string>Optimize Phi, Chi and Omega</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_25"> - <item> - <spacer name="horizontalSpacer_22"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="MaxGoniometerChange_lbl"> - <property name="text"> - <string>Maximum Change (degrees)</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_34"> - <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="QLineEdit" name="MaxGoniometerChange_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Maximum number of degrees that CHI, PHI<br> or OMEGA can be changed.</string> - </property> - <property name="text"> - <string>5</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_30"> - <item> - <widget class="QRadioButton" name="UseCurrentUB_rbtn"> - <property name="toolTip"> - <string>If the peaks workspace<br> already has a UB matrix, just use that UB.</string> - </property> - <property name="text"> - <string>Use Current UB (if already found or loaded)</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="Line" name="line"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_29"> - <item> - <widget class="QCheckBox" name="IndexPeaks_ckbx"> - <property name="toolTip"> - <string>After obtaining the UB<br> matrix, index the peaks using that UB.</string> - </property> - <property name="text"> - <string>Index Peaks Using UB</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_26"> - <item> - <spacer name="horizontalSpacer_20"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="IndexingTolerance_lbl"> - <property name="text"> - <string>Indexing Tolerance</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_35"> - <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="QLineEdit" name="IndexingTolerance_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Only set the h,k,l values on peaks for which the maximum distance of h,k or l from integer values<br> is less than this tolerance.</string> - </property> - <property name="text"> - <string>0.12</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_28"> - <item> - <spacer name="horizontalSpacer_21"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QCheckBox" name="RoundHKLs_ckbx"> - <property name="toolTip"> - <string>Round the h,k,l values to the nearest integer.</string> - </property> - <property name="text"> - <string>Round HKLs</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QCheckBox" name="PredictPeaks_ckbx"> - <property name="text"> - <string>Predict Peaks</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_16"> - <item> - <spacer name="horizontalSpacer_91"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="min_pred_wl_lbl"> - <property name="maximumSize"> - <size> - <width>160</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>Minimum wavelength</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_64"> - <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="QLineEdit" name="min_pred_wl_ledt"> - <property name="minimumSize"> - <size> - <width>146</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>146</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>0.4</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_17"> - <item> - <spacer name="horizontalSpacer_92"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="max_pred_wl_lbl"> - <property name="maximumSize"> - <size> - <width>160</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>Maximum wavelength</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_65"> - <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="QLineEdit" name="max_pred_wl_ledt"> - <property name="maximumSize"> - <size> - <width>146</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>3.5</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_18"> - <item> - <spacer name="horizontalSpacer_93"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="min_pred_dspacing_lbl"> - <property name="maximumSize"> - <size> - <width>160</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>Minimum d-spacing</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_66"> - <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="QLineEdit" name="min_pred_dspacing_ledt"> - <property name="maximumSize"> - <size> - <width>146</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>0.4</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_19"> - <item> - <spacer name="horizontalSpacer_94"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="max_pred_dspacing_lbl"> - <property name="maximumSize"> - <size> - <width>160</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>Maximum d-spacing</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_67"> - <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="QLineEdit" name="max_pred_dspacing_ledt"> - <property name="maximumSize"> - <size> - <width>146</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>8.5</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <spacer name="verticalSpacer_3"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_27"> - <item> - <spacer name="horizontalSpacer_19"> - <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="ApplyFindUB_btn"> - <property name="toolTip"> - <string>Proceed to actually get the<br> UB matrix and (optionally) index the peaks.</string> - </property> - <property name="text"> - <string>Apply</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="ChooseCell"> - <attribute name="title"> - <string>Choose Cell</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_13"> - <item> - <widget class="QScrollArea" name="scrollArea_3"> - <property name="frameShape"> - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Plain</enum> - </property> - <property name="widgetResizable"> - <bool>true</bool> - </property> - <widget class="QWidget" name="scrollAreaWidgetContents_5"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>903</width> - <height>708</height> - </rect> + <property name="widgetResizable"> + <bool>true</bool> </property> - <layout class="QVBoxLayout" name="verticalLayout_14"> - <item> - <widget class="QRadioButton" name="ShowPossibleCells_rbtn"> - <property name="toolTip"> - <string>Show a list of the possible<br> conventional cells in the MantidPlot Results Log window. NOTE: The current UB must correspond to a Niggli reduced cell for these to be valid.</string> - </property> - <property name="text"> - <string>Show Possible Cells</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_36"> - <item> - <spacer name="horizontalSpacer_38"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="MaxScalarError_lbl"> - <property name="text"> - <string>Max Scalar Error </string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_41"> - <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="QLineEdit" name="MaxScalarError_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Maximum error allowed in the cell<br> scalars. If this is set very large, all possible conventional cells will be shown, including those that don't really match the current cell. If this is set too small, the desired correct cell may be missing from the list due to experimental error. The default value of 0.2 should usually work.</string> - </property> - <property name="text"> - <string>0.2</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_35"> - <item> - <spacer name="horizontalSpacer_37"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QCheckBox" name="BestCellOnly_ckbx"> - <property name="toolTip"> - <string>Only show the best fitting<br> cell for each cell type and centering that is in the list of possible cells.</string> - </property> - <property name="text"> - <string>Best Only</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_351"> - <item> - <spacer name="horizontalSpacer_371"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QCheckBox" name="AllowPermutations_ckbx"> - <property name="toolTip"> - <string>Allow permutations of conventional cells.</string> - </property> - <property name="text"> - <string>Allow Permutations</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QRadioButton" name="SelectCellOfType_rbtn"> - <property name="toolTip"> - <string>Transform the current UB<br> matrix and indexing to correspond to the best fitting cell with the specified cell-type and centering.</string> - </property> - <property name="text"> - <string>Select Cell of Type</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_33"> - <item> - <spacer name="horizontalSpacer_39"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QComboBox" name="CellType_cmbx"> - <property name="toolTip"> - <string>The cell-type to be used.</string> - </property> - <item> + <widget class="QWidget" name="scrollAreaWidgetContents_2"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>903</width> + <height>696</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout_10"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_10"> + <item> + <widget class="QLabel" name="PeaksWorkspace_lbl"> + <property name="text"> + <string>Peaks Workspace Name</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_18"> + <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="QLineEdit" name="PeaksWorkspace_ledt"> + <property name="toolTip"> + <string>Name of the peaks workspace to use. This name is set by default,<br> if data is loaded from an event file and mapped to an MD workspace on the Select Data tab.</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="Line" name="line_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="FindPeaks_rbtn"> + <property name="toolTip"> + <string>Search through the MD workspace to find Bragg peaks.</string> + </property> + <property name="text"> + <string>Find Peaks</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_11"> + <item> + <spacer name="horizontalSpacer_9"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="MaxABC_lbl"> + <property name="text"> + <string>Estimated Max of a,b,c</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_14"> + <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="QLineEdit" name="MaxABC_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Estimated maximum for real<br> space cell edge length in Angstroms. This is used to get an approximate lower bound on the possible distances between peaks.</string> + </property> + <property name="text"> + <string>15</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_12"> + <item> + <spacer name="horizontalSpacer_11"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="NumToFind_lbl"> + <property name="text"> + <string>Number of Peaks to Find</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_15"> + <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="QLineEdit" name="NumToFind_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Maximum number of peaks to find. Boxes with progressively<br> lower local intensity will be tried, until the specified number of peaks is found, or until the intensity falls below the specified Min Intensity.</string> + </property> + <property name="text"> + <string>50</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_13"> + <item> + <spacer name="horizontalSpacer_12"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="MinIntensity_lbl"> + <property name="text"> + <string>Min Intensity(above ave)</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_16"> + <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="QLineEdit" name="MinIntensity_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Lower bound on the local intensity of MD boxes to consider as possible peaks, expressed as a multiple of the overall average intensity of the entire MD workspace region. Boxes with progressively<br> lower local intensity will be tried, until the specified number of peaks is found, or until the intensity falls below the specified Min Intensity.</string> + </property> + <property name="text"> + <string>10000</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QRadioButton" name="UseExistingPeaksWorkspace_rbtn"> + <property name="toolTip"> + <string>Use a peaks workspace with peaks that have been<br> been previously found, predicted, or loaded. </string> + </property> + <property name="text"> + <string>Use Existing Peaks Workspace</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="LoadIsawPeaks_rbtn"> + <property name="toolTip"> + <string>Load the peaks workspace from a file of peaks<br> that have been previously found or predicted.</string> + </property> + <property name="text"> + <string>Load ISAW Peaks (or Integrate or Nexus) File</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_14"> + <item> + <spacer name="horizontalSpacer_13"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="SelectPeaksFile_lbl"> + <property name="text"> + <string>Filename</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_17"> + <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="QLineEdit" name="SelectPeaksFile_ledt"> + <property name="toolTip"> + <string>Name of the peaks file that should be loaded.</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="SelectPeaksFile_btn"> + <property name="toolTip"> + <string>Browse for the file of peaks to load.</string> + </property> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_15"> + <item> + <spacer name="horizontalSpacer_8"> + <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="ApplyFindPeaks_btn"> + <property name="toolTip"> + <string>Proceed to actually get the<br> peaks or use the existing peaks, as specified..</string> + </property> + <property name="text"> + <string>Apply</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="FindUB"> + <attribute name="title"> + <string>Find UB</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_11"> + <item> + <widget class="QScrollArea" name="scrollArea_2"> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents_4"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>903</width> + <height>696</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout_12"> + <item> + <widget class="QRadioButton" name="FindUBUsingFFT_rbtn"> + <property name="toolTip"> + <string>Find a UB matrix using the<br> FindUBUsingFFT algorithm. This will produce a UB matrix corresponding to the Niggli reduced cell for the lattice.</string> + </property> + <property name="text"> + <string>Find UB Using FFT</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_20"> + <item> + <spacer name="horizontalSpacer_28"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="MinD_lbl"> + <property name="text"> + <string>Estimated Lower Bound for a,b,c</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_29"> + <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="QLineEdit" name="MinD_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Set this to a value that is<br> about 50%-90% of the shortest real space edge length, in Angstroms.</string> + </property> + <property name="text"> + <string>3</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_21"> + <item> + <spacer name="horizontalSpacer_27"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="MaxD_lbl"> + <property name="text"> + <string>Estimated Upper Bound for a,b,c</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_30"> + <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="QLineEdit" name="MaxD_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Set this to a value that is<br> about 110%-150% of the longest real space edge length, in Angstroms.</string> + </property> + <property name="text"> + <string>15</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_22"> + <item> + <spacer name="horizontalSpacer_26"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="FFTTolerance_lbl"> + <property name="text"> + <string>Tolerance</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_31"> + <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="QLineEdit" name="FFTTolerance_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Maximum distance of h,k or l from integer values to<br> consider a peak to be indexed.</string> + </property> + <property name="text"> + <string>0.12</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QRadioButton" name="FindUBUsingIndexedPeaks_rbtn"> + <property name="toolTip"> + <string>Find the UB matrix using the FindUBUsingIndexedPeaks algorithm. Specifically, if the<br> peaks in the peaks workspace have already been indexed, find the UB matrix that corresponds to that indexing.</string> + </property> + <property name="text"> + <string>Find UB Using Indexed Peaks</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_23"> + <item> + <spacer name="horizontalSpacer_25"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="IndexedPeaksTolerance_lbl"> + <property name="text"> + <string>Tolerance</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_32"> + <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="QLineEdit" name="IndexedPeaksTolerance_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Maximum distance of h,k or l from integer values to<br> consider a peak to be indexed.</string> + </property> + <property name="text"> + <string>0.1</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QRadioButton" name="LoadISAWUB_rbtn"> + <property name="toolTip"> + <string>Load the UB matrix from a file.</string> + </property> + <property name="text"> + <string>Load Isaw UB</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_24"> + <item> + <spacer name="horizontalSpacer_24"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="SelectUBFile_lbl"> + <property name="text"> + <string>Filename</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_33"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::MinimumExpanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLineEdit" name="SelectUBFile_ledt"> + <property name="toolTip"> + <string>Name of the file with the UB matrix.</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="SelectUBFile_btn"> + <property name="toolTip"> + <string>Browse for the file with the UB matrix.</string> + </property> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_31"> + <item> + <spacer name="horizontalSpacer_23"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QCheckBox" name="OptimizeGoniometerAngles_ckbx"> + <property name="toolTip"> + <string>Optimize the goniometer<br> angles, to index the peaks as accurately as possible using the UB matrix that was loaded.</string> + </property> + <property name="text"> + <string>Optimize Phi, Chi and Omega</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_25"> + <item> + <spacer name="horizontalSpacer_22"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="MaxGoniometerChange_lbl"> + <property name="text"> + <string>Maximum Change (degrees)</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_34"> + <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="QLineEdit" name="MaxGoniometerChange_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Maximum number of degrees that CHI, PHI<br> or OMEGA can be changed.</string> + </property> + <property name="text"> + <string>5</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_30"> + <item> + <widget class="QRadioButton" name="UseCurrentUB_rbtn"> + <property name="toolTip"> + <string>If the peaks workspace<br> already has a UB matrix, just use that UB.</string> + </property> + <property name="text"> + <string>Use Current UB (if already found or loaded)</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_29"> + <item> + <widget class="QCheckBox" name="IndexPeaks_ckbx"> + <property name="toolTip"> + <string>After obtaining the UB<br> matrix, index the peaks using that UB.</string> + </property> + <property name="text"> + <string>Index Peaks Using UB</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_26"> + <item> + <spacer name="horizontalSpacer_20"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="IndexingTolerance_lbl"> + <property name="text"> + <string>Indexing Tolerance</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_35"> + <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="QLineEdit" name="IndexingTolerance_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Only set the h,k,l values on peaks for which the maximum distance of h,k or l from integer values<br> is less than this tolerance.</string> + </property> + <property name="text"> + <string>0.12</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_28"> + <item> + <spacer name="horizontalSpacer_21"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QCheckBox" name="RoundHKLs_ckbx"> + <property name="toolTip"> + <string>Round the h,k,l values to the nearest integer.</string> + </property> + <property name="text"> + <string>Round HKLs</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QCheckBox" name="PredictPeaks_ckbx"> + <property name="text"> + <string>Predict Peaks</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_16"> + <item> + <spacer name="horizontalSpacer_91"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="min_pred_wl_lbl"> + <property name="maximumSize"> + <size> + <width>160</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Minimum wavelength</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_64"> + <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="QLineEdit" name="min_pred_wl_ledt"> + <property name="minimumSize"> + <size> + <width>146</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>146</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>0.4</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_17"> + <item> + <spacer name="horizontalSpacer_92"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="max_pred_wl_lbl"> + <property name="maximumSize"> + <size> + <width>160</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Maximum wavelength</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_65"> + <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="QLineEdit" name="max_pred_wl_ledt"> + <property name="maximumSize"> + <size> + <width>146</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>3.5</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_18"> + <item> + <spacer name="horizontalSpacer_93"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="min_pred_dspacing_lbl"> + <property name="maximumSize"> + <size> + <width>160</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Minimum d-spacing</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_66"> + <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="QLineEdit" name="min_pred_dspacing_ledt"> + <property name="maximumSize"> + <size> + <width>146</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>0.4</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_19"> + <item> + <spacer name="horizontalSpacer_94"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="max_pred_dspacing_lbl"> + <property name="maximumSize"> + <size> + <width>160</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Maximum d-spacing</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_67"> + <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="QLineEdit" name="max_pred_dspacing_ledt"> + <property name="maximumSize"> + <size> + <width>146</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>8.5</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_27"> + <item> + <spacer name="horizontalSpacer_19"> + <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="ApplyFindUB_btn"> + <property name="toolTip"> + <string>Proceed to actually get the<br> UB matrix and (optionally) index the peaks.</string> + </property> + <property name="text"> + <string>Apply</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="ChooseCell"> + <attribute name="title"> + <string>Choose Cell</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_13"> + <item> + <widget class="QScrollArea" name="scrollArea_3"> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents_5"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>903</width> + <height>696</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout_14"> + <item> + <widget class="QRadioButton" name="ShowPossibleCells_rbtn"> + <property name="toolTip"> + <string>Show a list of the possible<br> conventional cells in the MantidPlot Results Log window. NOTE: The current UB must correspond to a Niggli reduced cell for these to be valid.</string> + </property> + <property name="text"> + <string>Show Possible Cells</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_36"> + <item> + <spacer name="horizontalSpacer_38"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="MaxScalarError_lbl"> + <property name="text"> + <string>Max Scalar Error </string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_41"> + <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="QLineEdit" name="MaxScalarError_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Maximum error allowed in the cell<br> scalars. If this is set very large, all possible conventional cells will be shown, including those that don't really match the current cell. If this is set too small, the desired correct cell may be missing from the list due to experimental error. The default value of 0.2 should usually work.</string> + </property> + <property name="text"> + <string>0.2</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_35"> + <item> + <spacer name="horizontalSpacer_37"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QCheckBox" name="BestCellOnly_ckbx"> + <property name="toolTip"> + <string>Only show the best fitting<br> cell for each cell type and centering that is in the list of possible cells.</string> + </property> + <property name="text"> + <string>Best Only</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_351"> + <item> + <spacer name="horizontalSpacer_371"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QCheckBox" name="AllowPermutations_ckbx"> + <property name="toolTip"> + <string>Allow permutations of conventional cells.</string> + </property> + <property name="text"> + <string>Allow Permutations</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QRadioButton" name="SelectCellOfType_rbtn"> + <property name="toolTip"> + <string>Transform the current UB<br> matrix and indexing to correspond to the best fitting cell with the specified cell-type and centering.</string> + </property> + <property name="text"> + <string>Select Cell of Type</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_33"> + <item> + <spacer name="horizontalSpacer_39"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QComboBox" name="CellType_cmbx"> + <property name="toolTip"> + <string>The cell-type to be used.</string> + </property> + <item> + <property name="text"> + <string>Cubic</string> + </property> + </item> + <item> + <property name="text"> + <string>Hexagonal</string> + </property> + </item> + <item> + <property name="text"> + <string>Monoclinic</string> + </property> + </item> + <item> + <property name="text"> + <string>Orthorhombic</string> + </property> + </item> + <item> + <property name="text"> + <string>Rhombohedral</string> + </property> + </item> + <item> + <property name="text"> + <string>Tetragonal</string> + </property> + </item> + <item> + <property name="text"> + <string>Triclinic</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="QComboBox" name="CellCentering_cmbx"> + <property name="toolTip"> + <string>The centering to be used.</string> + </property> + <item> + <property name="text"> + <string>C</string> + </property> + </item> + <item> + <property name="text"> + <string>F</string> + </property> + </item> + <item> + <property name="text"> + <string>I</string> + </property> + </item> + <item> + <property name="text"> + <string>P</string> + </property> + </item> + <item> + <property name="text"> + <string>R</string> + </property> + </item> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_42"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="QRadioButton" name="SelectCellWithForm_rbtn"> + <property name="toolTip"> + <string>Transform the current UB<br> matrix and indexing to correspond to the cell with the specified Form number, as shown in the list of possible cells.</string> + </property> + <property name="text"> + <string>Select Cell With Form</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_34"> + <item> + <spacer name="horizontalSpacer_40"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QComboBox" name="CellFormNumber_cmbx"> + <property name="toolTip"> + <string>The Form number of the<br> desired conventional cell.</string> + </property> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + <item> + <property name="text"> + <string>9</string> + </property> + </item> + <item> + <property name="text"> + <string>10</string> + </property> + </item> + <item> + <property name="text"> + <string>11</string> + </property> + </item> + <item> + <property name="text"> + <string>12</string> + </property> + </item> + <item> + <property name="text"> + <string>13</string> + </property> + </item> + <item> + <property name="text"> + <string>14</string> + </property> + </item> + <item> + <property name="text"> + <string>15</string> + </property> + </item> + <item> + <property name="text"> + <string>16</string> + </property> + </item> + <item> + <property name="text"> + <string>17</string> + </property> + </item> + <item> + <property name="text"> + <string>18</string> + </property> + </item> + <item> + <property name="text"> + <string>19</string> + </property> + </item> + <item> + <property name="text"> + <string>20</string> + </property> + </item> + <item> + <property name="text"> + <string>21</string> + </property> + </item> + <item> + <property name="text"> + <string>22</string> + </property> + </item> + <item> + <property name="text"> + <string>23</string> + </property> + </item> + <item> + <property name="text"> + <string>24</string> + </property> + </item> + <item> + <property name="text"> + <string>25</string> + </property> + </item> + <item> + <property name="text"> + <string>26</string> + </property> + </item> + <item> + <property name="text"> + <string>27</string> + </property> + </item> + <item> + <property name="text"> + <string>28</string> + </property> + </item> + <item> + <property name="text"> + <string>29</string> + </property> + </item> + <item> + <property name="text"> + <string>30</string> + </property> + </item> + <item> + <property name="text"> + <string>31</string> + </property> + </item> + <item> + <property name="text"> + <string>32</string> + </property> + </item> + <item> + <property name="text"> + <string>33</string> + </property> + </item> + <item> + <property name="text"> + <string>34</string> + </property> + </item> + <item> + <property name="text"> + <string>35</string> + </property> + </item> + <item> + <property name="text"> + <string>36</string> + </property> + </item> + <item> + <property name="text"> + <string>37</string> + </property> + </item> + <item> + <property name="text"> + <string>38</string> + </property> + </item> + <item> + <property name="text"> + <string>39</string> + </property> + </item> + <item> + <property name="text"> + <string>40</string> + </property> + </item> + <item> + <property name="text"> + <string>41</string> + </property> + </item> + <item> + <property name="text"> + <string>42</string> + </property> + </item> + <item> + <property name="text"> + <string>43</string> + </property> + </item> + <item> + <property name="text"> + <string>44</string> + </property> + </item> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_43"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer_4"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_32"> + <item> + <spacer name="horizontalSpacer_36"> + <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="ApplyChooseCell_btn"> + <property name="toolTip"> + <string>Proceed to show the<br> possible cells, or change the UB matrix and indexing, according to the options selected.</string> + </property> <property name="text"> - <string>Cubic</string> + <string>Apply</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="ChangeHKL"> + <attribute name="title"> + <string>Change HKL</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_15"> + <item> + <widget class="QScrollArea" name="scrollArea_4"> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents_6"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>903</width> + <height>696</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout_16"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_37"> + <item> + <widget class="QLabel" name="HKL_Transfrom_lbl"> + <property name="toolTip"> + <string>Transform the UB matrix<br> and peak indexes using the specified 3X3 matrix.</string> </property> - </item> - <item> <property name="text"> - <string>Hexagonal</string> + <string>Specify 3x3 Matrix to Apply to HKL</string> </property> - </item> - <item> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_38"> + <item> + <spacer name="horizontalSpacer_48"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="HKL_Tran_Row_1_lbl"> <property name="text"> - <string>Monoclinic</string> + <string>HKL Transformation, Row 1</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_45"> + <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="QLineEdit" name="HKL_tran_row_1_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>First row of the<br> transformation matrix to apply the HKL indexes.</string> </property> - </item> - <item> <property name="text"> - <string>Orthorhombic</string> + <string>1, 0, 0</string> </property> - </item> - <item> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_39"> + <item> + <spacer name="horizontalSpacer_49"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="HKL_Tran_Row_2_lbl"> <property name="text"> - <string>Rhombohedral</string> + <string>HKL Transformation, Row 2</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_46"> + <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="QLineEdit" name="HKL_tran_row_2_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Second row of the<br> transformation matrix to apply the HKL indexes.</string> </property> - </item> - <item> <property name="text"> - <string>Tetragonal</string> + <string>0, 1, 0</string> </property> - </item> - <item> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_40"> + <item> + <spacer name="horizontalSpacer_50"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="HKL_Tran_Row_3_lbl"> <property name="text"> - <string>Triclinic</string> + <string>HKL Transformation, Row 3</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_47"> + <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="QLineEdit" name="HKL_tran_row_3_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Third row of the<br> transformation matrix to apply the HKL indexes.</string> </property> - </item> - </widget> - </item> - <item> - <widget class="QComboBox" name="CellCentering_cmbx"> - <property name="toolTip"> - <string>The centering to be used.</string> - </property> - <item> <property name="text"> - <string>C</string> + <string>0, 0, 1</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer_5"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_42"> + <item> + <spacer name="horizontalSpacer_44"> + <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="ApplyChangeHKL_btn"> + <property name="toolTip"> + <string>Use the specified matrix<br> to update the peak indexes and UB matrix.</string> </property> - </item> - <item> <property name="text"> - <string>F</string> + <string>Apply</string> </property> - </item> - <item> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="Integrate"> + <attribute name="title"> + <string>Integrate</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_18"> + <item> + <widget class="QScrollArea" name="scrollArea_5"> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents_7"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>903</width> + <height>696</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout_17"> + <item> + <widget class="QRadioButton" name="SphereIntegration_rbtn"> + <property name="toolTip"> + <string>Apply the IntegratePeaksMD<br> algorithm to integrate the current list of peaks, using spherical regions around the peaks in reciprocal space. This is the fastest of the integration methods. See the algorithm documentation for more details.</string> + </property> + <property name="text"> + <string>Spherical or Cylindrical Integration</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_55"> + <item> + <spacer name="horizontalSpacer_63"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="PeakRadius_lbl"> <property name="text"> - <string>I</string> + <string>Peak Radius (A^-1)</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="PeakRadius_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Radius of the spherical<br> region that will be considered the body of the peak.</string> </property> - </item> - <item> <property name="text"> - <string>P</string> + <string>0.20</string> </property> - </item> - <item> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_54"> + <item> + <spacer name="horizontalSpacer_62"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="BackgroundInnerRadius_lbl"> <property name="text"> - <string>R</string> + <string>Background Inner Radius (A^-1)</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="BackgroundInnerRadius_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Radius of the inner surface<br> of the spherical shell that will be used for the background estimate.</string> </property> - </item> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_42"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <widget class="QRadioButton" name="SelectCellWithForm_rbtn"> - <property name="toolTip"> - <string>Transform the current UB<br> matrix and indexing to correspond to the cell with the specified Form number, as shown in the list of possible cells.</string> - </property> - <property name="text"> - <string>Select Cell With Form</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_34"> - <item> - <spacer name="horizontalSpacer_40"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QComboBox" name="CellFormNumber_cmbx"> - <property name="toolTip"> - <string>The Form number of the<br> desired conventional cell.</string> - </property> - <item> <property name="text"> - <string>1</string> + <string>0.20</string> </property> - </item> - <item> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_53"> + <item> + <spacer name="horizontalSpacer_61"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="BackgroundOuterRadius_lbl"> <property name="text"> - <string>2</string> + <string>Background Outer Radius (A^-1)</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="BackgroundOuterRadius_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Radius of the outer surface<br> of the spherical shell that will be used for the background estimate.</string> </property> - </item> - <item> <property name="text"> - <string>3</string> + <string>0.25</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_52"> + <item> + <spacer name="horizontalSpacer_55"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QCheckBox" name="IntegrateEdge_ckbx"> + <property name="toolTip"> + <string>If true, all peaks will be<br> integrated. If false, any peak for which the background shell goes off the edge of the detector will not be integrated.</string> </property> - </item> - <item> <property name="text"> - <string>4</string> + <string>Integrate if on Edge</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="Cylinder_ckbx"> + <property name="toolTip"> + <string>If true, cylinder instead of sphere..</string> </property> - </item> - <item> <property name="text"> - <string>5</string> + <string>Integrate with cylinder</string> </property> - </item> - <item> + </widget> + </item> + <item> + <widget class="QComboBox" name="CylinderProfileFit_cmbx"> + <property name="toolTip"> + <string>Fit cylinder profile with function</string> + </property> + <item> + <property name="text"> + <string>BackToBackExponential</string> + </property> + </item> + <item> + <property name="text"> + <string>Bk2BKExpConvPV</string> + </property> + </item> + <item> + <property name="text"> + <string>DeltaFunction</string> + </property> + </item> + <item> + <property name="text"> + <string>ElasticDiffSphere</string> + </property> + </item> + <item> + <property name="text"> + <string>ExamplePeakFunction</string> + </property> + </item> + <item> + <property name="text"> + <string>Gaussian</string> + </property> + </item> + <item> + <property name="text"> + <string>IkedaCarpenterPV</string> + </property> + </item> + <item> + <property name="text"> + <string>Lorentzian</string> + </property> + </item> + <item> + <property name="text"> + <string>NoFit</string> + </property> + </item> + <item> + <property name="text"> + <string>Voigt</string> + </property> + </item> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_53a"> + <item> + <spacer name="horizontalSpacer_61a"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="CylinderLength_lbl"> <property name="text"> - <string>6</string> + <string>Cylinder Length (A^-1)</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="CylinderLength_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Length of the cylinder used for integration.</string> </property> - </item> - <item> <property name="text"> - <string>7</string> + <string>0.4</string> </property> - </item> - <item> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_53b"> + <item> + <spacer name="horizontalSpacer_61b"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="CylinderPercentBkg_lbl"> <property name="text"> - <string>8</string> + <string>Percent of cylinder length that is background.</string> </property> - </item> - <item> + </widget> + </item> + <item> + <widget class="QLineEdit" name="CylinderPercentBkg_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Radius of the outer surface<br> of the spherical shell that will be used for the background estimate.</string> + </property> + <property name="text"> + <string>0.25</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QRadioButton" name="TwoDFitIntegration_rbtn"> + <property name="toolTip"> + <string>Apply the PeakIntegration<br> algorithm to integrate the current list of peaks, by combining the integrated intensities on multiple time-of-flight slices. This method is much slower than the Spherical Integration method, so please allow time for the calculation to complete. See the algorithm documentation for more details.</string> + </property> + <property name="text"> + <string>2-D Fitting Integration</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_51"> + <item> + <spacer name="horizontalSpacer_60"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="FitRebinParams_lbl"> <property name="text"> - <string>9</string> + <string>Rebin Parameters</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="FitRebinParams_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Parameters used to form<br> histograms from the event data. The first and last values are the start and end times-of-flight. The middle value is the step size. If the step size is negative it represents the decimal fraction increase in the bin boundary at each step, instead of the actual bin size.</string> + </property> + <property name="text"> + <string>1000,-0.004,16000</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_50"> + <item> + <spacer name="horizontalSpacer_59"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="NBadEdgePixels_lbl"> + <property name="text"> + <string>Number of Bad Edge Pixels</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="NBadEdgePixels_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>The width of the border of<br> bad pixels around the edge of each detector that should be omitted.</string> + </property> + <property name="text"> + <string>5</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_49"> + <item> + <spacer name="horizontalSpacer_54"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QCheckBox" name="IkedaCarpenter_ckbx"> + <property name="toolTip"> + <string>If true, the Ikeda-Carpenter<br> function will be used to fit the results of integrating the various time-of-flight slices, to obtain the final integrated result.</string> </property> - </item> - <item> <property name="text"> - <string>10</string> + <string>Ikeda-Carpenter TOF</string> </property> - </item> - <item> - <property name="text"> - <string>11</string> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QRadioButton" name="EllipsoidIntegration_rbtn"> + <property name="toolTip"> + <string>Apply the IntegrateEllipsoids<br> algorithm to integrate the current list of peaks, by finding the principal axes of the 3D events in regions around each peak. This method is a little slower than the Spherical Integration method. See the algorithm documentation for more details.</string> + </property> + <property name="text"> + <string>Ellipsoidal Integration (Integer HKL only)</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_48"> + <item> + <spacer name="horizontalSpacer_58"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> </property> - </item> - <item> - <property name="text"> - <string>12</string> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> </property> - </item> - <item> - <property name="text"> - <string>13</string> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> </property> - </item> - <item> + </spacer> + </item> + <item> + <widget class="QLabel" name="RegionRadius_lbl"> <property name="text"> - <string>14</string> + <string>Region Radius (A^-1)</string> </property> - </item> - <item> - <property name="text"> - <string>15</string> + </widget> + </item> + <item> + <widget class="QLineEdit" name="RegionRadius_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> </property> - </item> - <item> - <property name="text"> - <string>16</string> + <property name="toolTip"> + <string>Radius of a spherical region<br> around each peak that will be used when finding the principal axes. This should be large enough to include the entire peak and nearby background region, but not much larger.</string> </property> - </item> - <item> <property name="text"> - <string>17</string> + <string>0.25</string> </property> - </item> - <item> - <property name="text"> - <string>18</string> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_47"> + <item> + <spacer name="horizontalSpacer_52"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> </property> - </item> - <item> - <property name="text"> - <string>19</string> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> </property> - </item> - <item> - <property name="text"> - <string>20</string> + <property name="sizeHint" stdset="0"> + <size> + <width>15</width> + <height>0</height> + </size> </property> - </item> - <item> - <property name="text"> - <string>21</string> + </spacer> + </item> + <item> + <widget class="QCheckBox" name="SpecifySize_ckbx"> + <property name="toolTip"> + <string>If this is set true, the major axis<br> size of each ellipsoidal region will be constant for all peaks, and will be set by the following three parameters. If this is set false, the major axis sizes will be calculated based on the standard deviation in the direction of the major axis.</string> </property> - </item> - <item> <property name="text"> - <string>22</string> + <string>Specify Size</string> </property> - </item> - <item> - <property name="text"> - <string>23</string> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_46"> + <item> + <spacer name="horizontalSpacer_57"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> </property> - </item> - <item> - <property name="text"> - <string>24</string> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> </property> - </item> - <item> - <property name="text"> - <string>25</string> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>0</height> + </size> </property> - </item> - <item> + </spacer> + </item> + <item> + <widget class="QLabel" name="PeakSize_lbl"> <property name="text"> - <string>26</string> + <string>Peak Size (A^-1)</string> </property> - </item> - <item> - <property name="text"> - <string>27</string> + </widget> + </item> + <item> + <widget class="QLineEdit" name="PeakSize_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> </property> - </item> - <item> - <property name="text"> - <string>28</string> + <property name="toolTip"> + <string>Length of the major axis<br> to use for the ellipsoidal peak region.</string> </property> - </item> - <item> <property name="text"> - <string>29</string> + <string>0.20</string> </property> - </item> - <item> - <property name="text"> - <string>30</string> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_45"> + <item> + <spacer name="horizontalSpacer_56"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> </property> - </item> - <item> - <property name="text"> - <string>31</string> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> </property> - </item> - <item> - <property name="text"> - <string>32</string> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>0</height> + </size> </property> - </item> - <item> + </spacer> + </item> + <item> + <widget class="QLabel" name="BackgroundInnerSize_lbl"> <property name="text"> - <string>33</string> + <string>Background Inner Size (A^-1)</string> </property> - </item> - <item> - <property name="text"> - <string>34</string> + </widget> + </item> + <item> + <widget class="QLineEdit" name="BackgroundInnerSize_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> </property> - </item> - <item> - <property name="text"> - <string>35</string> + <property name="toolTip"> + <string>Length of the major axis<br> of the inner surface of the ellipsoidal shell used for the background region.</string> </property> - </item> - <item> <property name="text"> - <string>36</string> + <string>0.20</string> </property> - </item> - <item> - <property name="text"> - <string>37</string> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_44"> + <item> + <spacer name="horizontalSpacer_53"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> </property> - </item> - <item> - <property name="text"> - <string>38</string> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> </property> - </item> - <item> - <property name="text"> - <string>39</string> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>0</height> + </size> </property> - </item> - <item> + </spacer> + </item> + <item> + <widget class="QLabel" name="BackgroundOuterSize_lbl"> <property name="text"> - <string>40</string> + <string>Background Outer Size (A^-1) </string> </property> - </item> - <item> - <property name="text"> - <string>41</string> + </widget> + </item> + <item> + <widget class="QLineEdit" name="BackgroundOuterSize_ledt"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> </property> - </item> - <item> - <property name="text"> - <string>42</string> + <property name="toolTip"> + <string>Length of the major axis<br> of the outer surface of the ellipsoidal shell used for the background region.</string> </property> - </item> - <item> <property name="text"> - <string>43</string> + <string>0.25</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer_6"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_43"> + <item> + <spacer name="horizontalSpacer_51"> + <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="ApplyIntegrate_btn"> + <property name="toolTip"> + <string>Proceed to actually do the peak integration as specified.</string> </property> - </item> - <item> <property name="text"> - <string>44</string> + <string>Apply</string> </property> - </item> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_43"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <spacer name="verticalSpacer_4"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_32"> - <item> - <spacer name="horizontalSpacer_36"> - <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="ApplyChooseCell_btn"> - <property name="toolTip"> - <string>Proceed to show the<br> possible cells, or change the UB matrix and indexing, according to the options selected.</string> - </property> - <property name="text"> - <string>Apply</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> + </widget> + </item> + </layout> + </item> + </layout> + </widget> </widget> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="ChangeHKL"> - <attribute name="title"> - <string>Change HKL</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_15"> - <item> - <widget class="QScrollArea" name="scrollArea_4"> - <property name="frameShape"> - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Plain</enum> - </property> - <property name="widgetResizable"> - <bool>true</bool> - </property> - <widget class="QWidget" name="scrollAreaWidgetContents_6"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>903</width> - <height>708</height> - </rect> + </item> + </layout> + </widget> + <widget class="QWidget" name="PointInfo_tab"> + <attribute name="title"> + <string>Point Info</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <widget class="QGroupBox" name="SelectedPoint_grpbx"> + <property name="title"> + <string>Selected Point Info</string> </property> - <layout class="QVBoxLayout" name="verticalLayout_16"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_37"> - <item> - <widget class="QLabel" name="HKL_Transfrom_lbl"> - <property name="toolTip"> - <string>Transform the UB matrix<br> and peak indexes using the specified 3X3 matrix.</string> - </property> - <property name="text"> - <string>Specify 3x3 Matrix to Apply to HKL</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_38"> - <item> - <spacer name="horizontalSpacer_48"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="HKL_Tran_Row_1_lbl"> - <property name="text"> - <string>HKL Transformation, Row 1</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_45"> - <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="QLineEdit" name="HKL_tran_row_1_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>First row of the<br> transformation matrix to apply the HKL indexes.</string> - </property> - <property name="text"> - <string>1, 0, 0</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_39"> - <item> - <spacer name="horizontalSpacer_49"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="HKL_Tran_Row_2_lbl"> - <property name="text"> - <string>HKL Transformation, Row 2</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_46"> - <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="QLineEdit" name="HKL_tran_row_2_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Second row of the<br> transformation matrix to apply the HKL indexes.</string> - </property> - <property name="text"> - <string>0, 1, 0</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_40"> - <item> - <spacer name="horizontalSpacer_50"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="HKL_Tran_Row_3_lbl"> - <property name="text"> - <string>HKL Transformation, Row 3</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_47"> - <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="QLineEdit" name="HKL_tran_row_3_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Third row of the<br> transformation matrix to apply the HKL indexes.</string> - </property> - <property name="text"> - <string>0, 0, 1</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <spacer name="verticalSpacer_5"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> + <layout class="QVBoxLayout" name="verticalLayout_2"> <item> - <layout class="QHBoxLayout" name="horizontalLayout_42"> - <item> - <spacer name="horizontalSpacer_44"> - <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="ApplyChangeHKL_btn"> - <property name="toolTip"> - <string>Use the specified matrix<br> to update the peak indexes and UB matrix.</string> - </property> - <property name="text"> - <string>Apply</string> - </property> - </widget> - </item> - </layout> + <widget class="QTableWidget" name="SelectedPoint_tbl"/> </item> - </layout> - </widget> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="Integrate"> - <attribute name="title"> - <string>Integrate</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_18"> - <item> - <widget class="QScrollArea" name="scrollArea_5"> - <property name="frameShape"> - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Plain</enum> - </property> - <property name="widgetResizable"> - <bool>true</bool> - </property> - <widget class="QWidget" name="scrollAreaWidgetContents_7"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>903</width> - <height>708</height> - </rect> - </property> - <layout class="QVBoxLayout" name="verticalLayout_17"> <item> - <widget class="QRadioButton" name="SphereIntegration_rbtn"> - <property name="toolTip"> - <string>Apply the IntegratePeaksMD<br> algorithm to integrate the current list of peaks, using spherical regions around the peaks in reciprocal space. This is the fastest of the integration methods. See the algorithm documentation for more details.</string> - </property> - <property name="text"> - <string>Spherical or Cylindrical Integration</string> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Specify Qx Qy Qz</string> </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_55"> - <item> - <spacer name="horizontalSpacer_63"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="PeakRadius_lbl"> - <property name="text"> - <string>Peak Radius (A^-1)</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="PeakRadius_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Radius of the spherical<br> region that will be considered the body of the peak.</string> - </property> - <property name="text"> - <string>0.20</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_54"> - <item> - <spacer name="horizontalSpacer_62"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="BackgroundInnerRadius_lbl"> - <property name="text"> - <string>Background Inner Radius (A^-1)</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="BackgroundInnerRadius_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Radius of the inner surface<br> of the spherical shell that will be used for the background estimate.</string> - </property> - <property name="text"> - <string>0.20</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_53"> - <item> - <spacer name="horizontalSpacer_61"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="BackgroundOuterRadius_lbl"> - <property name="text"> - <string>Background Outer Radius (A^-1)</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="BackgroundOuterRadius_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Radius of the outer surface<br> of the spherical shell that will be used for the background estimate.</string> - </property> - <property name="text"> - <string>0.25</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_52"> - <item> - <spacer name="horizontalSpacer_55"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QCheckBox" name="IntegrateEdge_ckbx"> - <property name="toolTip"> - <string>If true, all peaks will be<br> integrated. If false, any peak for which the background shell goes off the edge of the detector will not be integrated.</string> - </property> - <property name="text"> - <string>Integrate if on Edge</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="Cylinder_ckbx"> - <property name="toolTip"> - <string>If true, cylinder instead of sphere..</string> - </property> - <property name="text"> - <string>Integrate with cylinder</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="CylinderProfileFit_cmbx"> - <property name="toolTip"> - <string>Fit cylinder profile with function</string> - </property> - <item> - <property name="text"> - <string>BackToBackExponential</string> - </property> - </item> - <item> - <property name="text"> - <string>Bk2BKExpConvPV</string> - </property> - </item> - <item> - <property name="text"> - <string>DeltaFunction</string> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLineEdit" name="Qx_ledt"> + <property name="toolTip"> + <string>The X-coordinate of a point<br> of interest in reciprocal space specified in lab coordinates.</string> </property> - </item> - <item> <property name="text"> - <string>ElasticDiffSphere</string> + <string>0.0</string> </property> - </item> - <item> - <property name="text"> - <string>ExamplePeakFunction</string> + </widget> + </item> + <item> + <widget class="QLineEdit" name="Qy_ledt"> + <property name="toolTip"> + <string>The Y-coordinate of a point<br> of interest in reciprocal space specified in lab coordinates.</string> </property> - </item> - <item> <property name="text"> - <string>Gaussian</string> + <string>0.0</string> </property> - </item> - <item> - <property name="text"> - <string>IkedaCarpenterPV</string> + </widget> + </item> + <item> + <widget class="QLineEdit" name="Qz_ledt"> + <property name="toolTip"> + <string>The Z-coordinate of a point<br> of interest in reciprocal space specified in lab coordinates.</string> </property> - </item> - <item> <property name="text"> - <string>Lorentzian</string> + <string>0.0</string> </property> - </item> - <item> - <property name="text"> - <string>NoFit</string> + </widget> + </item> + <item> + <widget class="QPushButton" name="ShowInfo_btn"> + <property name="toolTip"> + <string>Press this after entering<br> Qx,Qy,Qz in lab coordinates to display information about that point in the Selected Point Info table.</string> </property> - </item> - <item> <property name="text"> - <string>Voigt</string> + <string>Show Info</string> </property> - </item> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_53a"> - <item> - <spacer name="horizontalSpacer_61a"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="CylinderLength_lbl"> - <property name="text"> - <string>Cylinder Length (A^-1)</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="CylinderLength_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Length of the cylinder used for integration.</string> - </property> - <property name="text"> - <string>0.4</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_53b"> - <item> - <spacer name="horizontalSpacer_61b"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="CylinderPercentBkg_lbl"> - <property name="text"> - <string>Percent of cylinder length that is background.</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="CylinderPercentBkg_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Radius of the outer surface<br> of the spherical shell that will be used for the background estimate.</string> - </property> - <property name="text"> - <string>0.25</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QRadioButton" name="TwoDFitIntegration_rbtn"> - <property name="toolTip"> - <string>Apply the PeakIntegration<br> algorithm to integrate the current list of peaks, by combining the integrated intensities on multiple time-of-flight slices. This method is much slower than the Spherical Integration method, so please allow time for the calculation to complete. See the algorithm documentation for more details.</string> - </property> - <property name="text"> - <string>2-D Fitting Integration</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_51"> - <item> - <spacer name="horizontalSpacer_60"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="FitRebinParams_lbl"> - <property name="text"> - <string>Rebin Parameters</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="FitRebinParams_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Parameters used to form<br> histograms from the event data. The first and last values are the start and end times-of-flight. The middle value is the step size. If the step size is negative it represents the decimal fraction increase in the bin boundary at each step, instead of the actual bin size.</string> - </property> - <property name="text"> - <string>1000,-0.004,16000</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_50"> - <item> - <spacer name="horizontalSpacer_59"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="NBadEdgePixels_lbl"> - <property name="text"> - <string>Number of Bad Edge Pixels</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="NBadEdgePixels_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>The width of the border of<br> bad pixels around the edge of each detector that should be omitted.</string> - </property> - <property name="text"> - <string>5</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_49"> - <item> - <spacer name="horizontalSpacer_54"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QCheckBox" name="IkedaCarpenter_ckbx"> - <property name="toolTip"> - <string>If true, the Ikeda-Carpenter<br> function will be used to fit the results of integrating the various time-of-flight slices, to obtain the final integrated result.</string> - </property> - <property name="text"> - <string>Ikeda-Carpenter TOF</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QRadioButton" name="EllipsoidIntegration_rbtn"> - <property name="toolTip"> - <string>Apply the IntegrateEllipsoids<br> algorithm to integrate the current list of peaks, by finding the principal axes of the 3D events in regions around each peak. This method is a little slower than the Spherical Integration method. See the algorithm documentation for more details.</string> - </property> - <property name="text"> - <string>Ellipsoidal Integration (Integer HKL only)</string> - </property> + </widget> + </item> + </layout> </widget> </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_48"> - <item> - <spacer name="horizontalSpacer_58"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="RegionRadius_lbl"> - <property name="text"> - <string>Region Radius (A^-1)</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="RegionRadius_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Radius of a spherical region<br> around each peak that will be used when finding the principal axes. This should be large enough to include the entire peak and nearby background region, but not much larger.</string> - </property> - <property name="text"> - <string>0.25</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_47"> - <item> - <spacer name="horizontalSpacer_52"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>15</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QCheckBox" name="SpecifySize_ckbx"> - <property name="toolTip"> - <string>If this is set true, the major axis<br> size of each ellipsoidal region will be constant for all peaks, and will be set by the following three parameters. If this is set false, the major axis sizes will be calculated based on the standard deviation in the direction of the major axis.</string> - </property> - <property name="text"> - <string>Specify Size</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_46"> - <item> - <spacer name="horizontalSpacer_57"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="PeakSize_lbl"> - <property name="text"> - <string>Peak Size (A^-1)</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="PeakSize_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Length of the major axis<br> to use for the ellipsoidal peak region.</string> - </property> - <property name="text"> - <string>0.20</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_45"> - <item> - <spacer name="horizontalSpacer_56"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="BackgroundInnerSize_lbl"> - <property name="text"> - <string>Background Inner Size (A^-1)</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="BackgroundInnerSize_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Length of the major axis<br> of the inner surface of the ellipsoidal shell used for the background region.</string> - </property> - <property name="text"> - <string>0.20</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_44"> - <item> - <spacer name="horizontalSpacer_53"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="BackgroundOuterSize_lbl"> - <property name="text"> - <string>Background Outer Size (A^-1) </string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="BackgroundOuterSize_ledt"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Length of the major axis<br> of the outer surface of the ellipsoidal shell used for the background region.</string> - </property> - <property name="text"> - <string>0.25</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <spacer name="verticalSpacer_6"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_43"> - <item> - <spacer name="horizontalSpacer_51"> - <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="ApplyIntegrate_btn"> - <property name="toolTip"> - <string>Proceed to actually do the peak integration as specified.</string> - </property> - <property name="text"> - <string>Apply</string> - </property> - </widget> - </item> - </layout> - </item> </layout> </widget> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="PointInfo_tab"> - <attribute name="title"> - <string>Point Info</string> - </attribute> - <layout class="QGridLayout" name="gridLayout_3"> - <item row="0" column="0"> - <widget class="QGroupBox" name="SelectedPoint_grpbx"> - <property name="title"> - <string>Selected Point Info</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QTableWidget" name="SelectedPoint_tbl"/> - </item> - <item> - <widget class="QGroupBox" name="groupBox"> - <property name="title"> - <string>Specify Qx Qy Qz</string> - </property> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QLineEdit" name="Qx_ledt"> - <property name="toolTip"> - <string>The X-coordinate of a point<br> of interest in reciprocal space specified in lab coordinates.</string> - </property> - <property name="text"> - <string>0.0</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="Qy_ledt"> - <property name="toolTip"> - <string>The Y-coordinate of a point<br> of interest in reciprocal space specified in lab coordinates.</string> - </property> - <property name="text"> - <string>0.0</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="Qz_ledt"> - <property name="toolTip"> - <string>The Z-coordinate of a point<br> of interest in reciprocal space specified in lab coordinates.</string> - </property> - <property name="text"> - <string>0.0</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="ShowInfo_btn"> - <property name="toolTip"> - <string>Press this after entering<br> Qx,Qy,Qz in lab coordinates to display information about that point in the Selected Point Info table.</string> - </property> - <property name="text"> - <string>Show Info</string> - </property> - </widget> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - </item> - </layout> + </item> + </layout> + </widget> </widget> - </widget> - </item> - </layout> - </widget> - <widget class="QStatusBar" name="statusbar"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>3</width> - <height>27</height> - </rect> - </property> + </item> + </layout> </widget> + <widget class="QStatusBar" name="statusbar"/> <action name="actionSave_State"> <property name="text"> <string>Save Settings</string> @@ -3529,6 +3522,16 @@ <string>Online Help Page</string> </property> </action> + <action name="actionSave_Nexus_Peaks"> + <property name="text"> + <string>Save Nexus Peaks</string> + </property> + </action> + <action name="actionLoad_Nexus_Peaks"> + <property name="text"> + <string>Load Nexus Peaks</string> + </property> + </action> </widget> <resources/> <connections/> diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MantidEVWorker.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MantidEVWorker.h index af3a2a596b9f7a586c39a05f0975e6e6e2f02ab6..5f92a905fa2eb2ad2d050a7bdb9ae23c4fc470f6 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MantidEVWorker.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MantidEVWorker.h @@ -95,11 +95,19 @@ public: bool loadIsawPeaks( const std::string & peaks_ws_name, const std::string & file_name ); + bool loadNexusPeaks( const std::string & peaks_ws_name, + const std::string & file_name ); + /// Save the peaks workspace to a .peaks or .integrate file bool saveIsawPeaks( const std::string & peaks_ws_name, const std::string & file_name, bool append ); + /// Save the peaks workspace to a .nxs file + bool saveNexusPeaks( const std::string & peaks_ws_name, + const std::string & file_name, + bool append ); + /// Index the peaks using the FFT method bool findUBUsingFFT( const std::string & peaks_ws_name, double min_abc, diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit.h index b87017e4256ad7a5342f924495724fcb2140b6ad..e7bb2158cd7eaf37893eeb56c29f97fbfd299a89 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit.h @@ -1,6 +1,7 @@ #ifndef MULTIDATASETFIT_H_ #define MULTIDATASETFIT_H_ +#include "MantidQtCustomInterfaces/DllConfig.h" #include "MantidQtAPI/UserSubWindow.h" #include "MantidAPI/AlgorithmObserver.h" #include "MantidQtAPI/WorkspaceObserver.h" @@ -27,6 +28,7 @@ namespace API { class IFunction; class IAlgorithm; + class MatrixWorkspace; } } @@ -37,6 +39,7 @@ namespace MantidQt namespace MantidWidgets { class FunctionBrowser; + class RangeSelector; class FitOptionsBrowser; } @@ -51,13 +54,14 @@ namespace CustomInterfaces // Forward declarations class PlotController; class DatasetPlotData; +class DataController; /** * Class MultiDatasetFitDialog implements a dialog for setting up a multi-dataset fit * and displaying the results. */ -class MultiDatasetFit: public API::UserSubWindow +class MANTIDQT_CUSTOMINTERFACES_DLL MultiDatasetFit: public API::UserSubWindow { Q_OBJECT public: @@ -74,6 +78,8 @@ public: std::string getWorkspaceName(int i) const; /// Workspace index of the i-th spectrum int getWorkspaceIndex(int i) const; + /// Get the fitting range for the i-th spectrum + std::pair<double,double> getFittingRange(int i) const; /// Total number of spectra (datasets). int getNumberOfSpectra() const; /// Get value of a local parameter @@ -83,21 +89,18 @@ public: /// Check that the data sets in the table are valid void checkDataSets(); -signals: - void dataTableUpdated(); - public slots: void setLocalParameterValue(const QString& parName, int i, double value); void reset(); private slots: - void addWorkspace(); - void workspaceSelectionChanged(); - void removeSelectedSpectra(); void fit(); void editLocalParameterValues(const QString& parName); void finishFit(bool); void updateLocalParameters(int index); + void enableZoom(); + void enablePan(); + void enableRange(); protected: /// To be overridden to set the appropriate layout @@ -105,7 +108,6 @@ protected: private: void createPlotToolbar(); - void addWorkspaceSpectrum(const QString &wsName, int wsIndex); boost::shared_ptr<Mantid::API::IFunction> createFunction() const; void initLocalParameter(const QString& parName)const; void updateParameters(const Mantid::API::IFunction& fun); @@ -122,6 +124,8 @@ private: Ui::MultiDatasetFit m_uiForm; /// Controls the plot and plotted data. PlotController *m_plotController; + /// Contains all logic of dealing with data sets. + DataController *m_dataController; /// Function editor MantidWidgets::FunctionBrowser *m_functionBrowser; /// Browser for setting other Fit properties @@ -175,26 +179,45 @@ public: int getCurrentIndex() const {return m_currentIndex;} bool isZoomEnabled() const; bool isPanEnabled() const; + bool isRangeSelectorEnabled() const; signals: void currentIndexChanged(int); + void fittingRangeChanged(int, double, double); public slots: void enableZoom(); void enablePan(); + void enableRange(); + void updateRange(int index); private slots: void tableUpdated(); void prevPlot(); void nextPlot(); void plotDataSet(int); + void updateFittingRange(double startX, double endX); private: MultiDatasetFit *owner() const {return static_cast<MultiDatasetFit*>(parent());} + void disableAllTools(); + template<class Tool> + void enableTool(Tool* tool, int cursor); + bool eventFilter(QObject *widget, QEvent *evn); + void resetRange(); + void zoomToRange(); + boost::shared_ptr<DatasetPlotData> getData(int i); + /// The plot widget QwtPlot *m_plot; + + ///@name Plot tools + ///@{ /// The zoomer QwtPlotZoomer *m_zoomer; /// The panner QwtPlotPanner *m_panner; /// The magnifier QwtPlotMagnifier *m_magnifier; + /// The fitting range selector + MantidWidgets::RangeSelector* m_rangeSelector; + ///@} /// The workspace table QTableWidget *m_table; @@ -224,7 +247,49 @@ private: QString m_parName; }; +/*==========================================================================================*/ +/** + * A class for controlling the plot widget and the displayed data. + */ +class DataController: public QObject +{ + Q_OBJECT +public: + DataController(MultiDatasetFit *parent, QTableWidget *dataTable); + std::string getWorkspaceName(int i) const; + int getWorkspaceIndex(int i) const; + int getNumberOfSpectra() const; + void checkDataSets(); + std::pair<double,double> getFittingRange(int i) const; + +signals: + void dataTableUpdated(); + void dataSetUpdated(int i); + void hasSelection(bool); + +public slots: + void setFittingRangeGlobal(bool); + void setFittingRange(int, double, double); + +private slots: + void addWorkspace(); + void workspaceSelectionChanged(); + void removeSelectedSpectra(); + void updateDataset(int, int); + +private: + MultiDatasetFit *owner() const {return static_cast<MultiDatasetFit*>(parent());} + void addWorkspaceSpectrum(const QString &wsName, int wsIndex, const Mantid::API::MatrixWorkspace& ws); + void removeDataSets(std::vector<int>& rows); + + /// Table with data set names and other data. + QTableWidget *m_dataTable; + /// Flag for setting the fitting range. + bool m_isFittingRangeGlobal; +}; + } // CustomInterfaces } // MantidQt + #endif /*MULTIDATASETFITDIALOG_H_*/ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit.ui index c2b680fd31c25c646e454c2d30e1e7b77f37c6bc..e78765d31f80b67c61a4166640f126921b3ec3e3 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>895</width> - <height>604</height> + <height>621</height> </rect> </property> <property name="windowTitle"> @@ -60,7 +60,7 @@ <item> <widget class="QTableWidget" name="dataTable"> <property name="editTriggers"> - <set>QAbstractItemView::NoEditTriggers</set> + <set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set> </property> <column> <property name="text"> @@ -72,6 +72,16 @@ <string>WS Index</string> </property> </column> + <column> + <property name="text"> + <string>Start X</string> + </property> + </column> + <column> + <property name="text"> + <string>End X</string> + </property> + </column> </widget> </item> <item> @@ -115,6 +125,9 @@ </widget> <widget class="QWidget" name="verticalLayoutWidget"> <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>6</number> + </property> <item> <layout class="QHBoxLayout" name="horizontalLayout"> <item> @@ -152,7 +165,7 @@ <item> <widget class="QPushButton" name="btnNext"> <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> @@ -189,6 +202,54 @@ </item> </layout> </item> + <item> + <widget class="QStackedWidget" name="toolOptions"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="ZoomPage"> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <property name="margin"> + <number>0</number> + </property> + </layout> + </widget> + <widget class="QWidget" name="PanPage"/> + <widget class="QWidget" name="RangePage"> + <layout class="QHBoxLayout" name="horizontalLayout_5"> + <property name="margin"> + <number>0</number> + </property> + <item> + <widget class="QCheckBox" name="cb_applyRangeToAll"> + <property name="text"> + <string>Apply to all spectra</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>543</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </widget> + </item> <item> <widget class="QwtPlot" name="plot"> <property name="frameShape"> @@ -231,6 +292,8 @@ <tabstop>btnNext</tabstop> <tabstop>cbPlotSelector</tabstop> </tabstops> - <resources/> + <resources> + <include location="../../icons/CustomInterfacesIcons.qrc"/> + </resources> <connections/> </ui> diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCBaselineModellingView.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCBaselineModellingView.h index c4c76a2f20c0180b275673952ec0dba2975747a7..61187efc11761ce0a0e6ec0a81ef74872f2fba7f 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCBaselineModellingView.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCBaselineModellingView.h @@ -67,6 +67,7 @@ namespace CustomInterfaces void deleteSectionSelector(int index); void updateSectionSelector(int index, SectionSelector values); void displayError(const QString& message); + void help(); // -- End of IALCBaselineModellingView interface ------------------------------------------------- private slots: diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCBaselineModellingView.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCBaselineModellingView.ui index eefba920a9c76ae708c89a6f212140da536f0881..cd4faa0b2f67b33381356e619be601629134b162 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCBaselineModellingView.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCBaselineModellingView.ui @@ -92,7 +92,20 @@ </item> <item> <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> + <item> + <widget class="QPushButton" name="help"> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>?</string> + </property> + </widget> + </item> + <item> <spacer name="horizontalSpacer"> <property name="orientation"> <enum>Qt::Horizontal</enum> diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCDataLoadingView.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCDataLoadingView.h index c7c9ea26d321523b394438358e7528c48ef4ff2f..119a4b206db4cbd5f13e90c4cfb44a8f39d1b84e 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCDataLoadingView.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCDataLoadingView.h @@ -68,8 +68,11 @@ namespace CustomInterfaces void displayError(const std::string &error); void setAvailableLogs(const std::vector<std::string> &logs); void setAvailablePeriods(const std::vector<std::string> &periods); + void setTimeLimits(double tMin, double tMax); + void setTimeRange (double tMin, double tMax); void setWaitingCursor(); void restoreCursor(); + void help(); // -- End of IALCDataLoadingView interface ----------------------------------------------------- diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCDataLoadingView.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCDataLoadingView.ui index dfb8c5c30abfed92ed1639dd795427b3d2ba2a99..ebd0214679a8790968ec3c8b6f175f30520d54a4 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCDataLoadingView.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCDataLoadingView.ui @@ -364,17 +364,10 @@ </item> <item> <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QCheckBox" name="timeLimit"> - <property name="text"> - <string>Time limit:</string> - </property> - </widget> - </item> <item> <widget class="QWidget" name="timeLimits" native="true"> <property name="enabled"> - <bool>false</bool> + <bool>true</bool> </property> <property name="minimumSize"> <size> @@ -394,7 +387,17 @@ </widget> </item> <item> - <widget class="QDoubleSpinBox" name="minTime"/> + <widget class="QDoubleSpinBox" name="minTime"> + <property name="minimum"> + <double>-6</double> + </property> + <property name="maximum"> + <double>33</double> + </property> + <property name="decimals"> + <number>3</number> + </property> + </widget> </item> <item> <widget class="QLabel" name="label_5"> @@ -404,7 +407,17 @@ </widget> </item> <item> - <widget class="QDoubleSpinBox" name="maxTime"/> + <widget class="QDoubleSpinBox" name="maxTime"> + <property name="minimum"> + <double>-6</double> + </property> + <property name="maximum"> + <double>33</double> + </property> + <property name="decimals"> + <number>3</number> + </property> + </widget> </item> </layout> </widget> @@ -442,6 +455,19 @@ </item> <item> <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QPushButton" name="help"> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>?</string> + </property> + </widget> + </item> <item> <spacer name="horizontalSpacer"> <property name="orientation"> @@ -503,29 +529,13 @@ <tabstop>log</tabstop> <tabstop>integral</tabstop> <tabstop>differential</tabstop> - <tabstop>timeLimit</tabstop> <tabstop>minTime</tabstop> <tabstop>maxTime</tabstop> + <tabstop>help</tabstop> <tabstop>load</tabstop> </tabstops> <resources/> <connections> - <connection> - <sender>timeLimit</sender> - <signal>toggled(bool)</signal> - <receiver>timeLimits</receiver> - <slot>setEnabled(bool)</slot> - <hints> - <hint type="sourcelabel"> - <x>94</x> - <y>193</y> - </hint> - <hint type="destinationlabel"> - <x>264</x> - <y>205</y> - </hint> - </hints> - </connection> <connection> <sender>fromCustomFile</sender> <signal>toggled(bool)</signal> diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCPeakFittingView.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCPeakFittingView.h index 50bba6a0348f42fb87f0e6b892b4a32c23c27ed8..4768632e3b7790dba370202c497aee51d41ece50 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCPeakFittingView.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCPeakFittingView.h @@ -59,6 +59,7 @@ namespace CustomInterfaces void setParameter(const QString& funcIndex, const QString& paramName, double value); void setPeakPickerEnabled(bool enabled); void setPeakPicker(const IPeakFunction_const_sptr& peak); + void help(); // -- End of IALCPeakFitting interface --------------------------------------------------------- diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCPeakFittingView.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCPeakFittingView.ui index 3e078a57def0fb6e9634c7e22aeab8e36d4affc2..6b78d095490f41f27f73690539b857a8b84b1319 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCPeakFittingView.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCPeakFittingView.ui @@ -36,7 +36,20 @@ </item> <item> <layout class="QHBoxLayout" name="horizontalLayout"> - <item> + <item> + <widget class="QPushButton" name="help"> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>?</string> + </property> + </widget> + </item> + <item> <spacer name="horizontalSpacer"> <property name="orientation"> <enum>Qt::Horizontal</enum> diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCBaselineModellingView.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCBaselineModellingView.h index b158aa6311b29a24b53f176e116d909dfd539741..1c385f48460270788000a5c5011cbeff26e33ddf 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCBaselineModellingView.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCBaselineModellingView.h @@ -131,6 +131,9 @@ namespace CustomInterfaces */ virtual void displayError(const QString& message) = 0; + /// Links help button to wiki page + virtual void help() = 0; + signals: /// Fit requested void fitRequested(); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCDataLoadingView.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCDataLoadingView.h index bf6bbc99ad8a15edee68eea6b281e3e51007ce34..54ec12db0a804fe6e9a5667054c5f37bdf52116f 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCDataLoadingView.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCDataLoadingView.h @@ -103,18 +103,32 @@ namespace CustomInterfaces /// @param periods :: New list of periods virtual void setAvailablePeriods(const std::vector<std::string>& periods) = 0; + /// Update the time limits + /// @param tMin :: Minimum X value available + /// @param tMax :: Maximum X value available + virtual void setTimeLimits(double tMin, double tMax) = 0; + + /// Update the time limits + /// @param tMin :: Minimum X value available + /// @param tMax :: Maximum X value available + virtual void setTimeRange(double tMin, double tMax) = 0; + /// Set waiting cursor for long operation virtual void setWaitingCursor() = 0; /// Restore the original cursor virtual void restoreCursor() = 0; + /// Opens the Mantid Wiki web page + virtual void help() = 0; + signals: /// Request to load data void loadRequested(); /// User has selected the first run void firstRunSelected(); + }; } // namespace CustomInterfaces diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCPeakFittingView.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCPeakFittingView.h index 150bdc6850ff9353358c313586c78aed96e4e6da..34a4704f73582f8e8db260a0b73dcfad0aea9097 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCPeakFittingView.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCPeakFittingView.h @@ -86,6 +86,9 @@ namespace CustomInterfaces /// @param peak :: A new peak to represent virtual void setPeakPicker(const IPeakFunction_const_sptr& peak) = 0; + /// Opens the Mantid Wiki web page + virtual void help() = 0; + signals: /// Request to perform peak fitting void fitRequested(); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/SANSRunWindow.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/SANSRunWindow.h index 5535d1f82c211c3c6857dabdda0e1e6b5bffc610..c8bf9318f1bab48052e05f9d991d10d79f1834df 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/SANSRunWindow.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/SANSRunWindow.h @@ -105,7 +105,7 @@ private: enum Tab { RUN_NUMBERS, REDUCTION_SETTINGS, GEOMETRY, MASKING, - LOGGING, ADD_RUNS, DIAGNOSTICS, ONE_D_ANALYSIS, + LOGGING, ADD_RUNS, DIAGNOSTICS, ONE_D_ANALYSIS }; /// Initialize the layout diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/DataComparison.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/DataComparison.cpp index ef9f33f7c4f1b33132aa670fdb3de9434659704b..240476a99036c5c7b49b8b01c4ad1ea6aa630814 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/DataComparison.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/DataComparison.cpp @@ -17,7 +17,7 @@ namespace MantidQt { namespace CustomInterfaces { - DECLARE_SUBWINDOW(DataComparison); + DECLARE_SUBWINDOW(DataComparison) } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/DirectConvertToEnergy.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/DirectConvertToEnergy.cpp index 2220d18b31e6bf0e1e51e0b8964ee4e0f580eb61..bbb7e3d71242d485f3a1cc8a93ebc36b5b2f2e44 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/DirectConvertToEnergy.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/DirectConvertToEnergy.cpp @@ -21,7 +21,7 @@ namespace MantidQt { namespace CustomInterfaces { - DECLARE_SUBWINDOW(DirectConvertToEnergy); + DECLARE_SUBWINDOW(DirectConvertToEnergy) } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/CalcCorr.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/CalcCorr.cpp index 21b2211abb35bfd44542d75c30b7dc1b21bfaf61..2f19360e2dff1c784596a81c776ef7d29e670985 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/CalcCorr.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/CalcCorr.cpp @@ -365,13 +365,13 @@ namespace IDA switch(m_uiForm.cbSampleInputType->currentIndex()) { case 0: - //using direct input - uiv.checkFieldIsValid("Sample Scattering Cross-Section", m_uiForm.lesamsigs, m_uiForm.valSamsigs); - uiv.checkFieldIsValid("Sample Absorption Cross-Section", m_uiForm.lesamsiga, m_uiForm.valSamsiga); + //input using formula + uiv.checkFieldIsValid("Sample Formula", m_uiForm.leSampleFormula, m_uiForm.valSampleFormula); break; case 1: - //input using formula - uiv.checkFieldIsValid("Sample Formula", m_uiForm.leSampleFormula, m_uiForm.valSampleFormula); + //using direct input + uiv.checkFieldIsValid("Sample Scattering Cross-Section", m_uiForm.lesamsigs, m_uiForm.valSamsigs); + uiv.checkFieldIsValid("Sample Absorption Cross-Section", m_uiForm.lesamsiga, m_uiForm.valSamsiga); break; } @@ -390,13 +390,13 @@ namespace IDA switch(m_uiForm.cbCanInputType->currentIndex()) { case 0: - // using direct input - uiv.checkFieldIsValid("Can Scattering Cross-Section", m_uiForm.lecansigs, m_uiForm.valCansigs); - uiv.checkFieldIsValid("Can Absorption Cross-Section", m_uiForm.lecansiga, m_uiForm.valCansiga); + //input using formula + uiv.checkFieldIsValid("Can Formula", m_uiForm.leCanFormula, m_uiForm.valCanFormula); break; case 1: - //input using formula - uiv.checkFieldIsValid("Can Formula", m_uiForm.leCanFormula, m_uiForm.valCanFormula); + // using direct input + uiv.checkFieldIsValid("Can Scattering Cross-Section", m_uiForm.lecansigs, m_uiForm.valCansigs); + uiv.checkFieldIsValid("Can Absorption Cross-Section", m_uiForm.lecansiga, m_uiForm.valCansiga); break; } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp index 58ba4caaaf9e33ab65a7c9785485f442e4c2045e..56fbf8531693c779d2364677204574fa333949a8 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp @@ -51,13 +51,13 @@ namespace IDA m_cfTree->setFactoryForManager(m_dblManager, m_dblEdFac); // Create Range Selectors - m_rangeSelectors["ConvFitRange"] = new MantidQt::MantidWidgets::RangeSelector(m_uiForm.ppPlot); - m_rangeSelectors["ConvFitBackRange"] = new MantidQt::MantidWidgets::RangeSelector(m_uiForm.ppPlot, - MantidQt::MantidWidgets::RangeSelector::YSINGLE); - m_rangeSelectors["ConvFitBackRange"]->setColour(Qt::darkGreen); - m_rangeSelectors["ConvFitBackRange"]->setRange(0.0, 1.0); - m_rangeSelectors["ConvFitHWHM"] = new MantidQt::MantidWidgets::RangeSelector(m_uiForm.ppPlot); - m_rangeSelectors["ConvFitHWHM"]->setColour(Qt::red); + auto fitRangeSelector = m_uiForm.ppPlot->addRangeSelector("ConvFitRange"); + auto backRangeSelector = m_uiForm.ppPlot->addRangeSelector("ConvFitBackRange", + MantidWidgets::RangeSelector::YSINGLE); + auto hwhmRangeSelector = m_uiForm.ppPlot->addRangeSelector("ConvFitHWHM"); + backRangeSelector->setColour(Qt::darkGreen); + backRangeSelector->setRange(0.0, 1.0); + hwhmRangeSelector->setColour(Qt::red); // Populate Property Widget @@ -98,11 +98,11 @@ namespace IDA m_uiForm.leTempCorrection->setValidator(new QDoubleValidator(m_parentWidget)); // Connections - connect(m_rangeSelectors["ConvFitRange"], SIGNAL(minValueChanged(double)), this, SLOT(minChanged(double))); - connect(m_rangeSelectors["ConvFitRange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double))); - connect(m_rangeSelectors["ConvFitBackRange"], SIGNAL(minValueChanged(double)), this, SLOT(backgLevel(double))); - connect(m_rangeSelectors["ConvFitHWHM"], SIGNAL(minValueChanged(double)), this, SLOT(hwhmChanged(double))); - connect(m_rangeSelectors["ConvFitHWHM"], SIGNAL(maxValueChanged(double)), this, SLOT(hwhmChanged(double))); + connect(fitRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(minChanged(double))); + connect(fitRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double))); + connect(backRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(backgLevel(double))); + connect(hwhmRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(hwhmChanged(double))); + connect(hwhmRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(hwhmChanged(double))); connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updateRS(QtProperty*, double))); connect(m_blnManager, SIGNAL(valueChanged(QtProperty*, bool)), this, SLOT(checkBoxUpdate(QtProperty*, bool))); connect(m_uiForm.ckTempCorrection, SIGNAL(toggled(bool)), m_uiForm.leTempCorrection, SLOT(setEnabled(bool))); @@ -113,8 +113,9 @@ namespace IDA connect(m_uiForm.ckPlotGuess, SIGNAL(stateChanged(int)), this, SLOT(plotGuess())); // Have FWHM Range linked to Fit Start/End Range - connect(m_rangeSelectors["ConvFitRange"], SIGNAL(rangeChanged(double, double)), m_rangeSelectors["ConvFitHWHM"], SLOT(setRange(double, double))); - m_rangeSelectors["ConvFitHWHM"]->setRange(-1.0,1.0); + connect(fitRangeSelector, SIGNAL(rangeChanged(double, double)), + hwhmRangeSelector, SLOT(setRange(double, double))); + hwhmRangeSelector->setRange(-1.0,1.0); hwhmUpdateRS(0.02); typeSelection(m_uiForm.cbFitType->currentIndex()); @@ -643,19 +644,21 @@ namespace IDA m_cfTree->removeProperty(m_properties["Lorentzian1"]); m_cfTree->removeProperty(m_properties["Lorentzian2"]); + auto hwhmRangeSelector = m_uiForm.ppPlot->getRangeSelector("ConvFitHWHM"); + switch ( index ) { case 0: - m_rangeSelectors["ConvFitHWHM"]->setVisible(false); + hwhmRangeSelector->setVisible(false); break; case 1: m_cfTree->addProperty(m_properties["Lorentzian1"]); - m_rangeSelectors["ConvFitHWHM"]->setVisible(true); + hwhmRangeSelector->setVisible(true); break; case 2: m_cfTree->addProperty(m_properties["Lorentzian1"]); m_cfTree->addProperty(m_properties["Lorentzian2"]); - m_rangeSelectors["ConvFitHWHM"]->setVisible(true); + hwhmRangeSelector->setVisible(true); break; } } @@ -694,7 +697,7 @@ namespace IDA { const QPair<double, double> curveRange = m_uiForm.ppPlot->getCurveRange("Sample"); const std::pair<double, double> range(curveRange.first, curveRange.second); - m_rangeSelectors["ConvFitRange"]->setRange(range.first, range.second); + m_uiForm.ppPlot->getRangeSelector("ConvFitRange")->setRange(range.first, range.second); m_uiForm.ckPlotGuess->setChecked(plotGuess); } catch(std::invalid_argument & exc) @@ -954,9 +957,10 @@ namespace IDA // Always want FWHM to display as positive. const double hwhm = std::fabs(val-peakCentre); // Update the property - m_rangeSelectors["ConvFitHWHM"]->blockSignals(true); + auto hwhmRangeSelector = m_uiForm.ppPlot->getRangeSelector("ConvFitHWHM"); + hwhmRangeSelector->blockSignals(true); m_dblManager->setValue(m_properties["Lorentzian 1.FWHM"], hwhm*2); - m_rangeSelectors["ConvFitHWHM"]->blockSignals(false); + hwhmRangeSelector->blockSignals(false); } void ConvFit::backgLevel(double val) @@ -966,9 +970,12 @@ namespace IDA void ConvFit::updateRS(QtProperty* prop, double val) { - if ( prop == m_properties["StartX"] ) { m_rangeSelectors["ConvFitRange"]->setMinimum(val); } - else if ( prop == m_properties["EndX"] ) { m_rangeSelectors["ConvFitRange"]->setMaximum(val); } - else if ( prop == m_properties["BGA0"] ) { m_rangeSelectors["ConvFitBackRange"]->setMinimum(val); } + auto fitRangeSelector = m_uiForm.ppPlot->getRangeSelector("ConvFitRange"); + auto backRangeSelector = m_uiForm.ppPlot->getRangeSelector("ConvFitBackRange"); + + if ( prop == m_properties["StartX"] ) { fitRangeSelector->setMinimum(val); } + else if ( prop == m_properties["EndX"] ) { fitRangeSelector->setMaximum(val); } + else if ( prop == m_properties["BGA0"] ) { backRangeSelector->setMinimum(val); } else if ( prop == m_properties["Lorentzian 1.FWHM"] ) { hwhmUpdateRS(val); } else if ( prop == m_properties["Lorentzian 1.PeakCentre"] ) { @@ -979,8 +986,9 @@ namespace IDA void ConvFit::hwhmUpdateRS(double val) { const double peakCentre = m_dblManager->value(m_properties["Lorentzian 1.PeakCentre"]); - m_rangeSelectors["ConvFitHWHM"]->setMinimum(peakCentre-val/2); - m_rangeSelectors["ConvFitHWHM"]->setMaximum(peakCentre+val/2); + auto hwhmRangeSelector = m_uiForm.ppPlot->getRangeSelector("ConvFitHWHM"); + hwhmRangeSelector->setMinimum(peakCentre-val/2); + hwhmRangeSelector->setMaximum(peakCentre+val/2); } void ConvFit::checkBoxUpdate(QtProperty* prop, bool checked) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Elwin.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Elwin.cpp index db1e27990a7cbd21d225c3d37aeebbe4d8b6c98d..3cc9867a2a20e66c5ebabce68ce73de73aed9f8f 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Elwin.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Elwin.cpp @@ -65,16 +65,17 @@ namespace IDA // We always want one range selector... the second one can be controlled from // within the elwinTwoRanges(bool state) function - m_rangeSelectors["ElwinIntegrationRange"] = new MantidWidgets::RangeSelector(m_uiForm.ppPlot); - connect(m_rangeSelectors["ElwinIntegrationRange"], SIGNAL(minValueChanged(double)), this, SLOT(minChanged(double))); - connect(m_rangeSelectors["ElwinIntegrationRange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double))); + auto integrationRangeSelector = m_uiForm.ppPlot->addRangeSelector("ElwinIntegrationRange"); + connect(integrationRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(minChanged(double))); + connect(integrationRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double))); // create the second range - m_rangeSelectors["ElwinBackgroundRange"] = new MantidWidgets::RangeSelector(m_uiForm.ppPlot); - m_rangeSelectors["ElwinBackgroundRange"]->setColour(Qt::darkGreen); // dark green for background - connect(m_rangeSelectors["ElwinIntegrationRange"], SIGNAL(rangeChanged(double, double)), m_rangeSelectors["ElwinBackgroundRange"], SLOT(setRange(double, double))); - connect(m_rangeSelectors["ElwinBackgroundRange"], SIGNAL(minValueChanged(double)), this, SLOT(minChanged(double))); - connect(m_rangeSelectors["ElwinBackgroundRange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double))); - m_rangeSelectors["ElwinBackgroundRange"]->setRange(m_rangeSelectors["ElwinIntegrationRange"]->getRange()); + auto backgroundRangeSelector = m_uiForm.ppPlot->addRangeSelector("ElwinBackgroundRange"); + backgroundRangeSelector->setColour(Qt::darkGreen); // dark green for background + connect(integrationRangeSelector, SIGNAL(rangeChanged(double, double)), + backgroundRangeSelector, SLOT(setRange(double, double))); + connect(backgroundRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(minChanged(double))); + connect(backgroundRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double))); + backgroundRangeSelector->setRange(integrationRangeSelector->getRange()); connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updateRS(QtProperty*, double))); connect(m_blnManager, SIGNAL(valueChanged(QtProperty*, bool)), this, SLOT(twoRanges(QtProperty*, bool))); @@ -360,7 +361,7 @@ namespace IDA try { QPair<double, double> range = m_uiForm.ppPlot->getCurveRange("Sample"); - m_rangeSelectors["ElwinIntegrationRange"]->setRange(range.first, range.second); + m_uiForm.ppPlot->getRangeSelector("ElwinIntegrationRange")->setRange(range.first, range.second); } catch(std::invalid_argument & exc) { @@ -371,17 +372,21 @@ namespace IDA void Elwin::twoRanges(QtProperty* prop, bool val) { if(prop == m_properties["BackgroundSubtraction"]) - m_rangeSelectors["ElwinBackgroundRange"]->setVisible(val); + m_uiForm.ppPlot->getRangeSelector("ElwinBackgroundRange")->setVisible(val); } void Elwin::minChanged(double val) { + auto integrationRangeSelector = m_uiForm.ppPlot->getRangeSelector("ElwinIntegrationRange"); + auto backgroundRangeSelector = m_uiForm.ppPlot->getRangeSelector("ElwinBackgroundRange"); + MantidWidgets::RangeSelector* from = qobject_cast<MantidWidgets::RangeSelector*>(sender()); - if ( from == m_rangeSelectors["ElwinIntegrationRange"] ) + + if(from == integrationRangeSelector) { m_dblManager->setValue(m_properties["IntegrationStart"], val); } - else if ( from == m_rangeSelectors["ElwinBackgroundRange"] ) + else if(from == backgroundRangeSelector) { m_dblManager->setValue(m_properties["BackgroundStart"], val); } @@ -389,12 +394,16 @@ namespace IDA void Elwin::maxChanged(double val) { + auto integrationRangeSelector = m_uiForm.ppPlot->getRangeSelector("ElwinIntegrationRange"); + auto backgroundRangeSelector = m_uiForm.ppPlot->getRangeSelector("ElwinBackgroundRange"); + MantidWidgets::RangeSelector* from = qobject_cast<MantidWidgets::RangeSelector*>(sender()); - if ( from == m_rangeSelectors["ElwinIntegrationRange"] ) + + if(from == integrationRangeSelector) { m_dblManager->setValue(m_properties["IntegrationEnd"], val); } - else if ( from == m_rangeSelectors["ElwinBackgroundRange"] ) + else if(from == backgroundRangeSelector) { m_dblManager->setValue(m_properties["BackgroundEnd"], val); } @@ -402,11 +411,15 @@ namespace IDA void Elwin::updateRS(QtProperty* prop, double val) { - if ( prop == m_properties["IntegrationStart"] ) m_rangeSelectors["ElwinIntegrationRange"]->setMinimum(val); - else if ( prop == m_properties["IntegrationEnd"] ) m_rangeSelectors["ElwinIntegrationRange"]->setMaximum(val); - else if ( prop == m_properties["BackgroundStart"] ) m_rangeSelectors["ElwinBackgroundRange"]->setMinimum(val); - else if ( prop == m_properties["BackgroundEnd"] ) m_rangeSelectors["ElwinBackgroundRange"]->setMaximum(val); + auto integrationRangeSelector = m_uiForm.ppPlot->getRangeSelector("ElwinIntegrationRange"); + auto backgroundRangeSelector = m_uiForm.ppPlot->getRangeSelector("ElwinBackgroundRange"); + + if ( prop == m_properties["IntegrationStart"] ) integrationRangeSelector->setMinimum(val); + else if ( prop == m_properties["IntegrationEnd"] ) integrationRangeSelector->setMaximum(val); + else if ( prop == m_properties["BackgroundStart"] ) backgroundRangeSelector->setMinimum(val); + else if ( prop == m_properties["BackgroundEnd"] ) backgroundRangeSelector->setMaximum(val); } + } // namespace IDA } // namespace CustomInterfaces } // namespace MantidQt diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Fury.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Fury.cpp index e131644b51ea61023537690fe00db8d975b25f8d..d1f64dc1bcc2e7b197c66ee3d8896b230585af8f 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Fury.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Fury.cpp @@ -68,10 +68,10 @@ namespace IDA m_furTree->setFactoryForManager(m_dblManager, m_dblEdFac); - m_rangeSelectors["FuryRange"] = new MantidQt::MantidWidgets::RangeSelector(m_uiForm.ppPlot); + auto xRangeSelector = m_uiForm.ppPlot->addRangeSelector("FuryRange"); // signals / slots & validators - connect(m_rangeSelectors["FuryRange"], SIGNAL(selectionChangedLazy(double, double)), this, SLOT(rsRangeChangedLazy(double, double))); + connect(xRangeSelector, SIGNAL(selectionChangedLazy(double, double)), this, SLOT(rsRangeChangedLazy(double, double))); connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updateRS(QtProperty*, double))); connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updatePropertyValues(QtProperty*, double))); connect(m_uiForm.dsInput, SIGNAL(dataReady(const QString&)), this, SLOT(plotInput(const QString&))); @@ -89,20 +89,20 @@ namespace IDA double energyMin = m_dblManager->value(m_properties["ELow"]); double energyMax = m_dblManager->value(m_properties["EHigh"]); - long numBins = static_cast<long>(m_dblManager->value(m_properties["SampleBinning"])); + double numBins = m_dblManager->value(m_properties["SampleBinning"]); bool plot = m_uiForm.ckPlot->isChecked(); bool save = m_uiForm.ckSave->isChecked(); - IAlgorithm_sptr furyAlg = AlgorithmManager::Instance().create("Fury", -1); + IAlgorithm_sptr furyAlg = AlgorithmManager::Instance().create("TransformToIqt", -1); furyAlg->initialize(); - furyAlg->setProperty("Sample", wsName.toStdString()); - furyAlg->setProperty("Resolution", resName.toStdString()); + furyAlg->setProperty("SampleWorkspace", wsName.toStdString()); + furyAlg->setProperty("ResolutionWorkspace", resName.toStdString()); furyAlg->setProperty("EnergyMin", energyMin); furyAlg->setProperty("EnergyMax", energyMax); - furyAlg->setProperty("NumBins", numBins); + furyAlg->setProperty("BinReductionFactor", numBins); furyAlg->setProperty("Plot", plot); furyAlg->setProperty("Save", save); @@ -188,20 +188,20 @@ namespace IDA double energyMin = m_dblManager->value(m_properties["ELow"]); double energyMax = m_dblManager->value(m_properties["EHigh"]); - long numBins = static_cast<long>(m_dblManager->value(m_properties["SampleBinning"])); // Default value + double numBins = m_dblManager->value(m_properties["SampleBinning"]); if(numBins == 0) return; - IAlgorithm_sptr furyAlg = AlgorithmManager::Instance().create("Fury"); + IAlgorithm_sptr furyAlg = AlgorithmManager::Instance().create("TransformToIqt"); furyAlg->initialize(); - furyAlg->setProperty("Sample", wsName.toStdString()); - furyAlg->setProperty("Resolution", resName.toStdString()); + furyAlg->setProperty("SampleWorkspace", wsName.toStdString()); + furyAlg->setProperty("ResolutionWorkspace", resName.toStdString()); furyAlg->setProperty("ParameterWorkspace", "__FuryProperties_temp"); furyAlg->setProperty("EnergyMin", energyMin); furyAlg->setProperty("EnergyMax", energyMax); - furyAlg->setProperty("NumBins", numBins); + furyAlg->setProperty("BinReductionFactor", numBins); furyAlg->setProperty("Plot", false); furyAlg->setProperty("Save", false); @@ -252,6 +252,8 @@ namespace IDA m_uiForm.ppPlot->clear(); m_uiForm.ppPlot->addSpectrum("Sample", workspace, 0); + auto xRangeSelector = m_uiForm.ppPlot->getRangeSelector("FuryRange"); + try { QPair<double, double> range = m_uiForm.ppPlot->getCurveRange("Sample"); @@ -260,7 +262,7 @@ namespace IDA const std::string instrName(workspace->getInstrument()->getName()); if(instrName == "BASIS") { - m_rangeSelectors["FuryRange"]->setRange(range.first, range.second); + xRangeSelector->setRange(range.first, range.second); m_dblManager->setValue(m_properties["ELow"], rounded_min); m_dblManager->setValue(m_properties["EHigh"], rounded_max); m_dblManager->setValue(m_properties["EWidth"], 0.0004); @@ -285,13 +287,13 @@ namespace IDA //check incase we have a really small range if (fabs(rounded_min) > 0 && fabs(rounded_max) > 0) { - m_rangeSelectors["FuryRange"]->setRange(rounded_min, rounded_max); + xRangeSelector->setRange(rounded_min, rounded_max); m_dblManager->setValue(m_properties["ELow"], rounded_min); m_dblManager->setValue(m_properties["EHigh"], rounded_max); } else { - m_rangeSelectors["FuryRange"]->setRange(range.first, range.second); + xRangeSelector->setRange(range.first, range.second); m_dblManager->setValue(m_properties["ELow"], range.first); m_dblManager->setValue(m_properties["EHigh"], range.second); } @@ -327,10 +329,12 @@ namespace IDA void Fury::updateRS(QtProperty* prop, double val) { + auto xRangeSelector = m_uiForm.ppPlot->getRangeSelector("FuryRange"); + if(prop == m_properties["ELow"]) - m_rangeSelectors["FuryRange"]->setMinimum(val); + xRangeSelector->setMinimum(val); else if(prop == m_properties["EHigh"]) - m_rangeSelectors["FuryRange"]->setMaximum(val); + xRangeSelector->setMaximum(val); } } // namespace IDA diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/FuryFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/FuryFit.cpp index 8c8840ab7ace64910c13941f344f8c07b0f7815a..e806dabff5c11fc2f283f0d9b54ef741095ab6bf 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/FuryFit.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/FuryFit.cpp @@ -47,15 +47,15 @@ namespace IDA m_ffTree = new QtTreePropertyBrowser(m_parentWidget); m_uiForm.properties->addWidget(m_ffTree); - m_rangeSelectors["FuryFitRange"] = new MantidQt::MantidWidgets::RangeSelector(m_uiForm.ppPlot); - connect(m_rangeSelectors["FuryFitRange"], SIGNAL(minValueChanged(double)), this, SLOT(xMinSelected(double))); - connect(m_rangeSelectors["FuryFitRange"], SIGNAL(maxValueChanged(double)), this, SLOT(xMaxSelected(double))); + auto fitRangeSelector = m_uiForm.ppPlot->addRangeSelector("FuryFitRange"); + connect(fitRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(xMinSelected(double))); + connect(fitRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(xMaxSelected(double))); - m_rangeSelectors["FuryFitBackground"] = new MantidQt::MantidWidgets::RangeSelector(m_uiForm.ppPlot, - MantidQt::MantidWidgets::RangeSelector::YSINGLE); - m_rangeSelectors["FuryFitBackground"]->setRange(0.0,1.0); - m_rangeSelectors["FuryFitBackground"]->setColour(Qt::darkGreen); - connect(m_rangeSelectors["FuryFitBackground"], SIGNAL(minValueChanged(double)), this, SLOT(backgroundSelected(double))); + auto backgroundRangeSelector = m_uiForm.ppPlot->addRangeSelector("FuryFitBackground", + MantidWidgets::RangeSelector::YSINGLE); + backgroundRangeSelector->setRange(0.0,1.0); + backgroundRangeSelector->setColour(Qt::darkGreen); + connect(backgroundRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(backgroundSelected(double))); // setupTreePropertyBrowser m_ffRangeManager = new QtDoublePropertyManager(m_parentWidget); @@ -399,7 +399,7 @@ namespace IDA { const QPair<double, double> curveRange = m_uiForm.ppPlot->getCurveRange("Sample"); const std::pair<double, double> range(curveRange.first, curveRange.second); - m_rangeSelectors["FuryFitRange"]->setRange(range.first, range.second); + m_uiForm.ppPlot->getRangeSelector("FuryFitRange")->setRange(range.first, range.second); m_ffRangeManager->setRange(m_properties["StartX"], range.first, range.second); m_ffRangeManager->setRange(m_properties["EndX"], range.first, range.second); @@ -489,17 +489,20 @@ namespace IDA void FuryFit::propertyChanged(QtProperty* prop, double val) { + auto fitRangeSelector = m_uiForm.ppPlot->getRangeSelector("FuryFitRange"); + auto backgroundRangeSelector = m_uiForm.ppPlot->getRangeSelector("FuryFitBackground"); + if ( prop == m_properties["StartX"] ) { - m_rangeSelectors["FuryFitRange"]->setMinimum(val); + fitRangeSelector->setMinimum(val); } else if ( prop == m_properties["EndX"] ) { - m_rangeSelectors["FuryFitRange"]->setMaximum(val); + fitRangeSelector->setMaximum(val); } else if ( prop == m_properties["BackgroundA0"]) { - m_rangeSelectors["FuryFitBackground"]->setMinimum(val); + backgroundRangeSelector->setMinimum(val); m_dblManager->setValue(m_properties["Exponential1.Intensity"], 1.0-val); m_dblManager->setValue(m_properties["Exponential2.Intensity"], 1.0-val); m_dblManager->setValue(m_properties["StretchedExp.Intensity"], 1.0-val); @@ -508,7 +511,7 @@ namespace IDA || prop == m_properties["Exponential2.Intensity"] || prop == m_properties["StretchedExp.Intensity"]) { - m_rangeSelectors["FuryFitBackground"]->setMinimum(1.0-val); + backgroundRangeSelector->setMinimum(1.0-val); m_dblManager->setValue(m_properties["Exponential1.Intensity"], val); m_dblManager->setValue(m_properties["Exponential2.Intensity"], val); m_dblManager->setValue(m_properties["StretchedExp.Intensity"], val); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp index 058459d8cc980e131cf80bdc5f905b5307184e60..e314f961f1178053c045b732cc7fc5400d4c9d7c 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp @@ -46,9 +46,9 @@ namespace CustomInterfaces m_propTrees["CalPropTree"]->addProperty(m_properties["CalBackMax"]); // Cal plot range selectors - m_rangeSelectors["CalPeak"] = new MantidWidgets::RangeSelector(m_uiForm.ppCalibration); - m_rangeSelectors["CalBackground"] = new MantidWidgets::RangeSelector(m_uiForm.ppCalibration); - m_rangeSelectors["CalBackground"]->setColour(Qt::darkGreen); //Dark green to signify background range + auto calPeak = m_uiForm.ppCalibration->addRangeSelector("CalPeak"); + auto calBackground = m_uiForm.ppCalibration->addRangeSelector("CalBackground"); + calBackground->setColour(Qt::darkGreen); //Dark green to signify background range // RES PROPERTY TREE m_propTrees["ResPropTree"] = new QtTreePropertyBrowser(); @@ -97,27 +97,28 @@ namespace CustomInterfaces // Res plot range selectors // Create ResBackground first so ResPeak is drawn above it - m_rangeSelectors["ResBackground"] = new MantidWidgets::RangeSelector(m_uiForm.ppResolution, - MantidQt::MantidWidgets::RangeSelector::XMINMAX, true, false); - m_rangeSelectors["ResBackground"]->setColour(Qt::darkGreen); - m_rangeSelectors["ResPeak"] = new MantidWidgets::RangeSelector(m_uiForm.ppResolution, - MantidQt::MantidWidgets::RangeSelector::XMINMAX, true, true); + auto resBackground = m_uiForm.ppResolution->addRangeSelector("ResBackground"); + resBackground->setColour(Qt::darkGreen); + auto resPeak = m_uiForm.ppResolution->addRangeSelector("ResPeak"); + resPeak->setInfoOnly(true); // SIGNAL/SLOT CONNECTIONS // Update instrument information when a new instrument config is selected connect(this, SIGNAL(newInstrumentConfiguration()), this, SLOT(setDefaultInstDetails())); - connect(m_rangeSelectors["ResPeak"], SIGNAL(rangeChanged(double, double)), m_rangeSelectors["ResBackground"], SLOT(setRange(double, double))); + connect(resPeak, SIGNAL(rangeChanged(double, double)), + resBackground, SLOT(setRange(double, double))); // Update property map when a range seclector is moved - connect(m_rangeSelectors["CalPeak"], SIGNAL(minValueChanged(double)), this, SLOT(calMinChanged(double))); - connect(m_rangeSelectors["CalPeak"], SIGNAL(maxValueChanged(double)), this, SLOT(calMaxChanged(double))); - connect(m_rangeSelectors["CalBackground"], SIGNAL(minValueChanged(double)), this, SLOT(calMinChanged(double))); - connect(m_rangeSelectors["CalBackground"], SIGNAL(maxValueChanged(double)), this, SLOT(calMaxChanged(double))); - connect(m_rangeSelectors["ResPeak"], SIGNAL(minValueChanged(double)), this, SLOT(calMinChanged(double))); - connect(m_rangeSelectors["ResPeak"], SIGNAL(maxValueChanged(double)), this, SLOT(calMaxChanged(double))); - connect(m_rangeSelectors["ResBackground"], SIGNAL(minValueChanged(double)), this, SLOT(calMinChanged(double))); - connect(m_rangeSelectors["ResBackground"], SIGNAL(maxValueChanged(double)), this, SLOT(calMaxChanged(double))); + connect(calPeak, SIGNAL(minValueChanged(double)), this, SLOT(calMinChanged(double))); + connect(calPeak, SIGNAL(maxValueChanged(double)), this, SLOT(calMaxChanged(double))); + connect(calBackground, SIGNAL(minValueChanged(double)), this, SLOT(calMinChanged(double))); + connect(calBackground, SIGNAL(maxValueChanged(double)), this, SLOT(calMaxChanged(double))); + connect(resPeak, SIGNAL(minValueChanged(double)), this, SLOT(calMinChanged(double))); + connect(resPeak, SIGNAL(maxValueChanged(double)), this, SLOT(calMaxChanged(double))); + connect(resBackground, SIGNAL(minValueChanged(double)), this, SLOT(calMinChanged(double))); + connect(resBackground, SIGNAL(maxValueChanged(double)), this, SLOT(calMaxChanged(double))); + // Update range selctor positions when a value in the double manager changes connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(calUpdateRS(QtProperty*, double))); // Plot miniplots after a file has loaded @@ -170,7 +171,7 @@ namespace CustomInterfaces QString calibrationWsName = outputWorkspaceNameStem + "_calib"; // Configure the calibration algorithm - IAlgorithm_sptr calibrationAlg = AlgorithmManager::Instance().create("CreateCalibrationWorkspace"); + IAlgorithm_sptr calibrationAlg = AlgorithmManager::Instance().create("IndirectCalibration"); calibrationAlg->initialize(); calibrationAlg->setProperty("InputFiles", filenames.toStdString()); @@ -348,8 +349,10 @@ namespace CustomInterfaces QPair<double, double> peakRange(ranges["peak-start-tof"], ranges["peak-end-tof"]); QPair<double, double> backgroundRange(ranges["back-start-tof"], ranges["back-end-tof"]); - setRangeSelector("CalPeak", m_properties["CalPeakMin"], m_properties["CalPeakMax"], peakRange); - setRangeSelector("CalBackground", m_properties["CalBackMin"], m_properties["CalBackMax"], backgroundRange); + auto calPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak"); + auto calBackground = m_uiForm.ppCalibration->getRangeSelector("CalBackground"); + setRangeSelector(calPeak, m_properties["CalPeakMin"], m_properties["CalPeakMax"], peakRange); + setRangeSelector(calBackground, m_properties["CalBackMin"], m_properties["CalBackMax"], backgroundRange); } /** @@ -396,8 +399,10 @@ namespace CustomInterfaces m_uiForm.ppCalibration->addSpectrum("Raw", input, 0); m_uiForm.ppCalibration->resizeX(); - setPlotPropertyRange("CalPeak", m_properties["CalELow"], m_properties["CalEHigh"], range); - setPlotPropertyRange("CalBackground", m_properties["CalStart"], m_properties["CalEnd"], range); + auto calPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak"); + auto calBackground = m_uiForm.ppCalibration->getRangeSelector("CalBackground"); + setPlotPropertyRange(calPeak, m_properties["CalELow"], m_properties["CalEHigh"], range); + setPlotPropertyRange(calBackground, m_properties["CalStart"], m_properties["CalEnd"], range); m_uiForm.ppCalibration->replot(); @@ -456,7 +461,8 @@ namespace CustomInterfaces const Mantid::MantidVec & dataX = energyWs->readX(0); QPair<double, double> range(dataX.front(), dataX.back()); - setPlotPropertyRange("ResBackground", m_properties["ResStart"], m_properties["ResEnd"], range); + auto resBackground = m_uiForm.ppResolution->getRangeSelector("ResBackground"); + setPlotPropertyRange(resBackground, m_properties["ResStart"], m_properties["ResEnd"], range); m_uiForm.ppResolution->clear(); m_uiForm.ppResolution->addSpectrum("Energy", energyWs, 0); @@ -494,11 +500,13 @@ namespace CustomInterfaces // Set default rebinning bounds QPair<double, double> peakRange(-res*10, res*10); - setRangeSelector("ResPeak", m_properties["ResELow"], m_properties["ResEHigh"], peakRange); + auto resPeak = m_uiForm.ppResolution->getRangeSelector("ResPeak"); + setRangeSelector(resPeak, m_properties["ResELow"], m_properties["ResEHigh"], peakRange); // Set default background bounds QPair<double, double> backgroundRange(-res*9, -res*8); - setRangeSelector("ResBackground", m_properties["ResStart"], m_properties["ResEnd"], backgroundRange); + auto resBackground = m_uiForm.ppResolution->getRangeSelector("ResBackground"); + setRangeSelector(resBackground, m_properties["ResStart"], m_properties["ResEnd"], backgroundRange); } } } @@ -511,20 +519,26 @@ namespace CustomInterfaces */ void ISISCalibration::calMinChanged(double val) { + auto calPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak"); + auto calBackground = m_uiForm.ppCalibration->getRangeSelector("CalBackground"); + auto resPeak = m_uiForm.ppResolution->getRangeSelector("ResPeak"); + auto resBackground = m_uiForm.ppResolution->getRangeSelector("ResBackground"); + MantidWidgets::RangeSelector* from = qobject_cast<MantidWidgets::RangeSelector*>(sender()); - if ( from == m_rangeSelectors["CalPeak"] ) + + if(from == calPeak) { m_dblManager->setValue(m_properties["CalPeakMin"], val); } - else if ( from == m_rangeSelectors["CalBackground"] ) + else if(from == calBackground) { m_dblManager->setValue(m_properties["CalBackMin"], val); } - else if ( from == m_rangeSelectors["ResPeak"] ) + else if(from == resPeak) { m_dblManager->setValue(m_properties["ResELow"], val); } - else if ( from == m_rangeSelectors["ResBackground"] ) + else if(from == resBackground) { m_dblManager->setValue(m_properties["ResStart"], val); } @@ -538,20 +552,26 @@ namespace CustomInterfaces */ void ISISCalibration::calMaxChanged(double val) { + auto calPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak"); + auto calBackground = m_uiForm.ppCalibration->getRangeSelector("CalBackground"); + auto resPeak = m_uiForm.ppResolution->getRangeSelector("ResPeak"); + auto resBackground = m_uiForm.ppResolution->getRangeSelector("ResBackground"); + MantidWidgets::RangeSelector* from = qobject_cast<MantidWidgets::RangeSelector*>(sender()); - if ( from == m_rangeSelectors["CalPeak"] ) + + if(from == calPeak) { m_dblManager->setValue(m_properties["CalPeakMax"], val); } - else if ( from == m_rangeSelectors["CalBackground"] ) + else if(from == calBackground) { m_dblManager->setValue(m_properties["CalBackMax"], val); } - else if ( from == m_rangeSelectors["ResPeak"] ) + else if(from == resPeak) { m_dblManager->setValue(m_properties["ResEHigh"], val); } - else if ( from == m_rangeSelectors["ResBackground"] ) + else if(from == resBackground) { m_dblManager->setValue(m_properties["ResEnd"], val); } @@ -565,14 +585,19 @@ namespace CustomInterfaces */ void ISISCalibration::calUpdateRS(QtProperty* prop, double val) { - if ( prop == m_properties["CalPeakMin"] ) m_rangeSelectors["CalPeak"]->setMinimum(val); - else if ( prop == m_properties["CalPeakMax"] ) m_rangeSelectors["CalPeak"]->setMaximum(val); - else if ( prop == m_properties["CalBackMin"] ) m_rangeSelectors["CalBackground"]->setMinimum(val); - else if ( prop == m_properties["CalBackMax"] ) m_rangeSelectors["CalBackground"]->setMaximum(val); - else if ( prop == m_properties["ResStart"] ) m_rangeSelectors["ResBackground"]->setMinimum(val); - else if ( prop == m_properties["ResEnd"] ) m_rangeSelectors["ResBackground"]->setMaximum(val); - else if ( prop == m_properties["ResELow"] ) m_rangeSelectors["ResPeak"]->setMinimum(val); - else if ( prop == m_properties["ResEHigh"] ) m_rangeSelectors["ResPeak"]->setMaximum(val); + auto calPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak"); + auto calBackground = m_uiForm.ppCalibration->getRangeSelector("CalBackground"); + auto resPeak = m_uiForm.ppResolution->getRangeSelector("ResPeak"); + auto resBackground = m_uiForm.ppResolution->getRangeSelector("ResBackground"); + + if ( prop == m_properties["CalPeakMin"] ) calPeak->setMinimum(val); + else if ( prop == m_properties["CalPeakMax"] ) calPeak->setMaximum(val); + else if ( prop == m_properties["CalBackMin"] ) calBackground->setMinimum(val); + else if ( prop == m_properties["CalBackMax"] ) calBackground->setMaximum(val); + else if ( prop == m_properties["ResStart"] ) resBackground->setMinimum(val); + else if ( prop == m_properties["ResEnd"] ) resBackground->setMaximum(val); + else if ( prop == m_properties["ResELow"] ) resPeak->setMinimum(val); + else if ( prop == m_properties["ResEHigh"] ) resPeak->setMaximum(val); } /** @@ -582,8 +607,8 @@ namespace CustomInterfaces */ void ISISCalibration::resCheck(bool state) { - m_rangeSelectors["ResPeak"]->setVisible(state); - m_rangeSelectors["ResBackground"]->setVisible(state); + m_uiForm.ppResolution->getRangeSelector("ResPeak")->setVisible(state); + m_uiForm.ppResolution->getRangeSelector("ResBackground")->setVisible(state); // Toggle scale and smooth options m_uiForm.ckResolutionScale->setEnabled(state); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISDiagnostics.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISDiagnostics.cpp index 2150358f795ba0846ceaf0ddb101a5e47a633a5a..45119aee24dc67ff1224b2de335968b854a726d4 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISDiagnostics.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISDiagnostics.cpp @@ -72,12 +72,12 @@ namespace CustomInterfaces m_propTrees["SlicePropTree"]->addProperty(m_properties["BackgroundRange"]); // Slice plot - m_rangeSelectors["SlicePeak"] = new MantidWidgets::RangeSelector(m_uiForm.ppRawPlot); - m_rangeSelectors["SliceBackground"] = new MantidWidgets::RangeSelector(m_uiForm.ppRawPlot); + auto peakRangeSelector = m_uiForm.ppRawPlot->addRangeSelector("SlicePeak"); + auto backgroundRangeSelector = m_uiForm.ppRawPlot->addRangeSelector("SliceBackground"); // Setup second range - m_rangeSelectors["SliceBackground"]->setColour(Qt::darkGreen); // Dark green for background - m_rangeSelectors["SliceBackground"]->setRange(m_rangeSelectors["SlicePeak"]->getRange()); + backgroundRangeSelector->setColour(Qt::darkGreen); // Dark green for background + backgroundRangeSelector->setRange(peakRangeSelector->getRange()); // SIGNAL/SLOT CONNECTIONS @@ -85,8 +85,8 @@ namespace CustomInterfaces connect(this, SIGNAL(newInstrumentConfiguration()), this, SLOT(setDefaultInstDetails())); // Update properties when a range selector is changed - connect(m_rangeSelectors["SlicePeak"], SIGNAL(selectionChangedLazy(double, double)), this, SLOT(rangeSelectorDropped(double, double))); - connect(m_rangeSelectors["SliceBackground"], SIGNAL(selectionChangedLazy(double, double)), this, SLOT(rangeSelectorDropped(double, double))); + connect(peakRangeSelector, SIGNAL(selectionChangedLazy(double, double)), this, SLOT(rangeSelectorDropped(double, double))); + connect(backgroundRangeSelector, SIGNAL(selectionChangedLazy(double, double)), this, SLOT(rangeSelectorDropped(double, double))); // Update range selctors when a property is changed connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(doublePropertyChanged(QtProperty*, double))); @@ -235,10 +235,13 @@ namespace CustomInterfaces // Set peak and background ranges if(instDetails.size() >= 8) { - setRangeSelector("SlicePeak", m_properties["PeakStart"], m_properties["PeakEnd"], - qMakePair(instDetails["peak-start"].toDouble(), instDetails["peak-end"].toDouble())); - setRangeSelector("SliceBackground", m_properties["BackgroundStart"], m_properties["BackgroundEnd"], - qMakePair(instDetails["back-start"].toDouble(), instDetails["back-end"].toDouble())); + setRangeSelector(m_uiForm.ppRawPlot->getRangeSelector("SlicePeak"), + m_properties["PeakStart"], m_properties["PeakEnd"], + qMakePair(instDetails["peak-start"].toDouble(), instDetails["peak-end"].toDouble())); + + setRangeSelector(m_uiForm.ppRawPlot->getRangeSelector("SliceBackground"), + m_properties["BackgroundStart"], m_properties["BackgroundEnd"], + qMakePair(instDetails["back-start"].toDouble(), instDetails["back-end"].toDouble())); } } @@ -271,8 +274,10 @@ namespace CustomInterfaces m_uiForm.ppRawPlot->clear(); m_uiForm.ppRawPlot->addSpectrum("Raw", input, previewSpec); - setPlotPropertyRange("SlicePeak", m_properties["PeakStart"], m_properties["PeakEnd"], range); - setPlotPropertyRange("SliceBackground", m_properties["BackgroundStart"], m_properties["BackgroundEnd"], range); + setPlotPropertyRange(m_uiForm.ppRawPlot->getRangeSelector("SlicePeak"), + m_properties["PeakStart"], m_properties["PeakEnd"], range); + setPlotPropertyRange(m_uiForm.ppRawPlot->getRangeSelector("SliceBackground"), + m_properties["BackgroundStart"], m_properties["BackgroundEnd"], range); m_uiForm.ppRawPlot->resizeX(); } @@ -284,7 +289,7 @@ namespace CustomInterfaces */ void ISISDiagnostics::sliceTwoRanges(QtProperty*, bool state) { - m_rangeSelectors["SliceBackground"]->setVisible(state); + m_uiForm.ppRawPlot->getRangeSelector("SliceBackground")->setVisible(state); } /** @@ -301,12 +306,12 @@ namespace CustomInterfaces { MantidWidgets::RangeSelector* from = qobject_cast<MantidWidgets::RangeSelector*>(sender()); - if(from == m_rangeSelectors["SlicePeak"]) + if(from == m_uiForm.ppRawPlot->getRangeSelector("SlicePeak")) { m_dblManager->setValue(m_properties["PeakStart"], min); m_dblManager->setValue(m_properties["PeakEnd"], max); } - else if(from == m_rangeSelectors["SliceBackground"]) + else if(from == m_uiForm.ppRawPlot->getRangeSelector("SliceBackground")) { m_dblManager->setValue(m_properties["BackgroundStart"], min); m_dblManager->setValue(m_properties["BackgroundEnd"], max); @@ -321,10 +326,13 @@ namespace CustomInterfaces */ void ISISDiagnostics::doublePropertyChanged(QtProperty* prop, double val) { - if(prop == m_properties["PeakStart"]) m_rangeSelectors["SlicePeak"]->setMinimum(val); - else if(prop == m_properties["PeakEnd"]) m_rangeSelectors["SlicePeak"]->setMaximum(val); - else if(prop == m_properties["BackgroundStart"]) m_rangeSelectors["SliceBackground"]->setMinimum(val); - else if(prop == m_properties["BackgroundEnd"]) m_rangeSelectors["SliceBackground"]->setMaximum(val); + auto peakRangeSelector = m_uiForm.ppRawPlot->getRangeSelector("SlicePeak"); + auto backgroundRangeSelector = m_uiForm.ppRawPlot->getRangeSelector("SliceBackground"); + + if(prop == m_properties["PeakStart"]) peakRangeSelector->setMinimum(val); + else if(prop == m_properties["PeakEnd"]) peakRangeSelector->setMaximum(val); + else if(prop == m_properties["BackgroundStart"]) backgroundRangeSelector->setMinimum(val); + else if(prop == m_properties["BackgroundEnd"]) backgroundRangeSelector->setMaximum(val); else if(prop == m_properties["PreviewSpec"]) handleNewFile(); if(prop != m_properties["PreviewSpec"]) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectBayes.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectBayes.cpp index b1c8f32029d5c4e00ec093512dcf3f0e3f492bad..5b804a41d51346611690e28960ba8c15dab8bbc5 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectBayes.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectBayes.cpp @@ -14,7 +14,7 @@ namespace MantidQt { namespace CustomInterfaces { - DECLARE_SUBWINDOW(IndirectBayes); + DECLARE_SUBWINDOW(IndirectBayes) } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataAnalysis.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataAnalysis.cpp index fccc4b5d9b65ff6670c9fae894744f2560e148e6..c4e6b705319331cd2ab47f9fe87fb79ce65ec875 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataAnalysis.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataAnalysis.cpp @@ -27,7 +27,7 @@ namespace CustomInterfaces namespace IDA { // Add this class to the list of specialised dialogs in this namespace - DECLARE_SUBWINDOW(IndirectDataAnalysis); + DECLARE_SUBWINDOW(IndirectDataAnalysis) /** * Constructor. diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataReduction.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataReduction.cpp index f167fa71ea6ea714b4fdbb91813e32aa4c66bcd1..3bc7f982fb8738ef2db888419b97e1f06509c6c7 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataReduction.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataReduction.cpp @@ -29,7 +29,7 @@ namespace MantidQt { namespace CustomInterfaces { - DECLARE_SUBWINDOW(IndirectDataReduction); + DECLARE_SUBWINDOW(IndirectDataReduction) } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDiffractionReduction.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDiffractionReduction.cpp index ec4de290209dffb88b4e6be4939c98af143baa28..9516a1d50162596e62d2b2cf206f41d93fd02377 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDiffractionReduction.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDiffractionReduction.cpp @@ -33,7 +33,7 @@ namespace // anon } } // anon namespace -DECLARE_SUBWINDOW(IndirectDiffractionReduction); +DECLARE_SUBWINDOW(IndirectDiffractionReduction) using namespace Mantid::API; using namespace MantidQt::CustomInterfaces; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectMoments.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectMoments.cpp index 48f35777924b0f3f8bde237f3508b7de8903ee93..dc1563504a4f114ac471271c79f5afd13c4e333e 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectMoments.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectMoments.cpp @@ -23,8 +23,8 @@ namespace CustomInterfaces const unsigned int NUM_DECIMALS = 6; // RAW PLOT - m_rangeSelectors["MomentsRangeSelector"] = new MantidWidgets::RangeSelector(m_uiForm.ppRawPlot); - m_rangeSelectors["MomentsRangeSelector"]->setInfoOnly(false); + auto xRangeSelector = m_uiForm.ppRawPlot->addRangeSelector("XRange"); + xRangeSelector->setInfoOnly(false); // PROPERTY TREE m_propTrees["MomentsPropTree"] = new QtTreePropertyBrowser(); @@ -41,7 +41,7 @@ namespace CustomInterfaces connect(m_uiForm.dsInput, SIGNAL(dataReady(const QString&)), this, SLOT(handleSampleInputReady(const QString&))); - connect(m_rangeSelectors["MomentsRangeSelector"], SIGNAL(selectionChangedLazy(double, double)), this, SLOT(rangeChanged(double, double))); + connect(xRangeSelector, SIGNAL(selectionChangedLazy(double, double)), this, SLOT(rangeChanged(double, double))); connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updateProperties(QtProperty*, double))); // Update the preview plot when the algorithm completes @@ -114,8 +114,10 @@ namespace CustomInterfaces m_uiForm.ppRawPlot->clear(); m_uiForm.ppRawPlot->addSpectrum("Raw", filename, 0); QPair<double, double> range = m_uiForm.ppRawPlot->getCurveRange("Raw"); - setRangeSelector("MomentsRangeSelector", m_properties["EMin"], m_properties["EMax"], range); - setPlotPropertyRange("MomentsRangeSelector", m_properties["EMin"], m_properties["EMax"], range); + + auto xRangeSelector = m_uiForm.ppRawPlot->getRangeSelector("XRange"); + setRangeSelector(xRangeSelector, m_properties["EMin"], m_properties["EMax"], range); + setPlotPropertyRange(xRangeSelector, m_properties["EMin"], m_properties["EMax"], range); connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updateProperties(QtProperty*, double))); @@ -154,7 +156,7 @@ namespace CustomInterfaces } else { - m_rangeSelectors["MomentsRangeSelector"]->setMinimum(val); + m_uiForm.ppRawPlot->getRangeSelector("XRange")->setMinimum(val); } } else if (prop == m_properties["EMax"]) @@ -166,7 +168,7 @@ namespace CustomInterfaces } else { - m_rangeSelectors["MomentsRangeSelector"]->setMaximum(val); + m_uiForm.ppRawPlot->getRangeSelector("XRange")->setMaximum(val); } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSimulation.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSimulation.cpp index d0e38f7b34a0a8b34d47a19bfb904715e7bf6cd0..79454dfac0308058917c5f2ee0a935292af33a31 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSimulation.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSimulation.cpp @@ -14,7 +14,7 @@ namespace MantidQt { namespace CustomInterfaces { - DECLARE_SUBWINDOW(IndirectSimulation); + DECLARE_SUBWINDOW(IndirectSimulation) } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSymmetrise.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSymmetrise.cpp index 127a699513cdc01953a36e5b5e32fdfc528d0607..b5de049ce9573a3de4f6ff19193b0c7fbd4e9466 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSymmetrise.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSymmetrise.cpp @@ -69,46 +69,50 @@ namespace CustomInterfaces m_propTrees["SymmPVPropTree"]->addProperty(m_properties["DeltaY"]); // Indicators for Y value at each EMin position - m_rangeSelectors["NegativeEMinYPos"] = new MantidWidgets::RangeSelector(m_uiForm.ppRawPlot, - MantidWidgets::RangeSelector::YSINGLE, true, true); - m_rangeSelectors["PositiveEMinYPos"] = new MantidWidgets::RangeSelector(m_uiForm.ppRawPlot, - MantidWidgets::RangeSelector::YSINGLE, true, true); - - m_rangeSelectors["NegativeEMinYPos"]->setColour(Qt::red); - m_rangeSelectors["PositiveEMinYPos"]->setColour(Qt::blue); - m_rangeSelectors["NegativeEMinYPos"]->setMinimum(0); - m_rangeSelectors["PositiveEMinYPos"]->setMinimum(0); + auto negativeEMinYPos = m_uiForm.ppRawPlot->addRangeSelector("NegativeEMinYPos", + MantidWidgets::RangeSelector::YSINGLE); + negativeEMinYPos->setInfoOnly(true); + negativeEMinYPos->setColour(Qt::blue); + negativeEMinYPos->setMinimum(0.0); + + auto positiveEMinYPos = m_uiForm.ppRawPlot->addRangeSelector("PositiveEMinYPos", + MantidWidgets::RangeSelector::YSINGLE); + positiveEMinYPos->setInfoOnly(true); + positiveEMinYPos->setColour(Qt::red); + positiveEMinYPos->setMinimum(0.0); // Indicator for centre of symmetry (x=0) - m_rangeSelectors["CentreMark_Raw"] = new MantidWidgets::RangeSelector(m_uiForm.ppRawPlot, - MantidWidgets::RangeSelector::XSINGLE, true, true); - m_rangeSelectors["CentreMark_Raw"]->setColour(Qt::cyan); - m_rangeSelectors["CentreMark_Raw"]->setMinimum(0.0); + auto centreMarkRaw = m_uiForm.ppRawPlot->addRangeSelector("CentreMark", + MantidWidgets::RangeSelector::XSINGLE); + centreMarkRaw->setInfoOnly(true); + centreMarkRaw->setColour(Qt::cyan); + centreMarkRaw->setMinimum(0.0); // Indicators for negative and positive X range values on X axis // The user can use these to move the X range // Note that the max and min of the negative range selector corespond to the opposite X value // i.e. RS min is X max - m_rangeSelectors["NegativeE_Raw"] = new MantidWidgets::RangeSelector(m_uiForm.ppRawPlot); - m_rangeSelectors["PositiveE_Raw"] = new MantidWidgets::RangeSelector(m_uiForm.ppRawPlot); + auto negativeERaw = m_uiForm.ppRawPlot->addRangeSelector("NegativeE"); + negativeERaw->setColour(Qt::darkGreen); - m_rangeSelectors["NegativeE_Raw"]->setColour(Qt::darkGreen); - m_rangeSelectors["PositiveE_Raw"]->setColour(Qt::darkGreen); + auto positiveERaw = m_uiForm.ppRawPlot->addRangeSelector("PositiveE"); + positiveERaw->setColour(Qt::darkGreen); // Indicators for negative and positive X range values on X axis - m_rangeSelectors["NegativeE_PV"] = new MantidWidgets::RangeSelector(m_uiForm.ppPreviewPlot, - MantidWidgets::RangeSelector::XMINMAX, true, true); - m_rangeSelectors["PositiveE_PV"] = new MantidWidgets::RangeSelector(m_uiForm.ppPreviewPlot, - MantidWidgets::RangeSelector::XMINMAX, true, true); + auto negativeEPV = m_uiForm.ppPreviewPlot->addRangeSelector("NegativeE"); + negativeEPV->setInfoOnly(true); + negativeEPV->setColour(Qt::darkGreen); - m_rangeSelectors["NegativeE_PV"]->setColour(Qt::darkGreen); - m_rangeSelectors["PositiveE_PV"]->setColour(Qt::darkGreen); + auto positiveEPV = m_uiForm.ppPreviewPlot->addRangeSelector("PositiveE"); + positiveEPV->setInfoOnly(true); + positiveEPV->setColour(Qt::darkGreen); // Indicator for centre of symmetry (x=0) - m_rangeSelectors["CentreMark_PV"] = new MantidWidgets::RangeSelector(m_uiForm.ppPreviewPlot, - MantidWidgets::RangeSelector::XSINGLE, true, true); - m_rangeSelectors["CentreMark_PV"]->setColour(Qt::cyan); - m_rangeSelectors["CentreMark_PV"]->setMinimum(0.0); + auto centreMarkPV = m_uiForm.ppPreviewPlot->addRangeSelector("CentreMark", + MantidWidgets::RangeSelector::XSINGLE); + centreMarkPV->setInfoOnly(true); + centreMarkPV->setColour(Qt::cyan); + centreMarkPV->setMinimum(0.0); // SIGNAL/SLOT CONNECTIONS // Validate the E range when it is changed @@ -120,10 +124,10 @@ namespace CustomInterfaces // Preview symmetrise connect(m_uiForm.pbPreview, SIGNAL(clicked()), this, SLOT(preview())); // X range selectors - connect(m_rangeSelectors["PositiveE_Raw"], SIGNAL(minValueChanged(double)), this, SLOT(xRangeMinChanged(double))); - connect(m_rangeSelectors["PositiveE_Raw"], SIGNAL(maxValueChanged(double)), this, SLOT(xRangeMaxChanged(double))); - connect(m_rangeSelectors["NegativeE_Raw"], SIGNAL(minValueChanged(double)), this, SLOT(xRangeMinChanged(double))); - connect(m_rangeSelectors["NegativeE_Raw"], SIGNAL(maxValueChanged(double)), this, SLOT(xRangeMaxChanged(double))); + connect(positiveERaw, SIGNAL(minValueChanged(double)), this, SLOT(xRangeMinChanged(double))); + connect(positiveERaw, SIGNAL(maxValueChanged(double)), this, SLOT(xRangeMaxChanged(double))); + connect(negativeERaw, SIGNAL(minValueChanged(double)), this, SLOT(xRangeMinChanged(double))); + connect(negativeERaw, SIGNAL(maxValueChanged(double)), this, SLOT(xRangeMaxChanged(double))); // Set default X range values m_dblManager->setValue(m_properties["EMin"], 0.1); @@ -208,8 +212,8 @@ namespace CustomInterfaces double symmRange = std::max(fabs(axisRange.first), fabs(axisRange.second)); // Set valid range for range selectors - m_rangeSelectors["NegativeE_Raw"]->setRange(-symmRange, 0); - m_rangeSelectors["PositiveE_Raw"]->setRange(0, symmRange); + m_uiForm.ppRawPlot->getRangeSelector("NegativeE")->setRange(-symmRange, 0); + m_uiForm.ppRawPlot->getRangeSelector("PositiveE")->setRange(0, symmRange); // Set some default (and valid) values for E range m_dblManager->setValue(m_properties["EMax"], axisRange.second); @@ -401,8 +405,8 @@ namespace CustomInterfaces m_dblManager->setValue(m_properties["DeltaY"], deltaY); // Set indicator positions - m_rangeSelectors["NegativeEMinYPos"]->setMinimum(negativeY); - m_rangeSelectors["PositiveEMinYPos"]->setMinimum(positiveY); + m_uiForm.ppRawPlot->getRangeSelector("NegativeEMinYPos")->setMinimum(negativeY); + m_uiForm.ppRawPlot->getRangeSelector("PositiveEMinYPos")->setMinimum(positiveY); // Plot preview plot size_t spectrumIndex = symmWS->getIndexFromSpectrumNumber(spectrumNumber); @@ -421,24 +425,29 @@ namespace CustomInterfaces */ void IndirectSymmetrise::updateRangeSelectors(QtProperty *prop, double value) { + auto negativeERaw = m_uiForm.ppRawPlot->getRangeSelector("NegativeE"); + auto positiveERaw = m_uiForm.ppRawPlot->getRangeSelector("PositiveE"); + auto negativeEPV = m_uiForm.ppPreviewPlot->getRangeSelector("NegativeE"); + auto positiveEPV = m_uiForm.ppPreviewPlot->getRangeSelector("PositiveE"); + value = fabs(value); if(prop == m_properties["EMin"]) { - m_rangeSelectors["NegativeE_Raw"]->setMaximum(-value); - m_rangeSelectors["PositiveE_Raw"]->setMinimum(value); + negativeERaw->setMaximum(-value); + positiveERaw->setMinimum(value); - m_rangeSelectors["NegativeE_PV"]->setMinimum(-value); - m_rangeSelectors["PositiveE_PV"]->setMinimum(value); + negativeEPV->setMinimum(-value); + positiveEPV->setMinimum(value); } if(prop == m_properties["EMax"]) { - m_rangeSelectors["NegativeE_Raw"]->setMinimum(-value); - m_rangeSelectors["PositiveE_Raw"]->setMaximum(value); + negativeERaw->setMinimum(-value); + positiveERaw->setMaximum(value); - m_rangeSelectors["NegativeE_PV"]->setMaximum(-value); - m_rangeSelectors["PositiveE_PV"]->setMaximum(value); + negativeEPV->setMaximum(-value); + positiveEPV->setMaximum(value); } } @@ -449,13 +458,16 @@ namespace CustomInterfaces */ void IndirectSymmetrise::xRangeMinChanged(double value) { + auto negativeERaw = m_uiForm.ppRawPlot->getRangeSelector("NegativeE"); + auto positiveERaw = m_uiForm.ppRawPlot->getRangeSelector("PositiveE"); + MantidWidgets::RangeSelector *from = qobject_cast<MantidWidgets::RangeSelector*>(sender()); - if(from == m_rangeSelectors["PositiveE_Raw"]) + if(from == positiveERaw) { m_dblManager->setValue(m_properties["EMin"], std::abs(value)); } - else if(from == m_rangeSelectors["NegativeE_Raw"]) + else if(from == negativeERaw) { m_dblManager->setValue(m_properties["EMax"], std::abs(value)); } @@ -468,13 +480,16 @@ namespace CustomInterfaces */ void IndirectSymmetrise::xRangeMaxChanged(double value) { + auto negativeERaw = m_uiForm.ppRawPlot->getRangeSelector("NegativeE"); + auto positiveERaw = m_uiForm.ppRawPlot->getRangeSelector("PositiveE"); + MantidWidgets::RangeSelector *from = qobject_cast<MantidWidgets::RangeSelector*>(sender()); - if(from == m_rangeSelectors["PositiveE_Raw"]) + if(from == positiveERaw) { m_dblManager->setValue(m_properties["EMax"], std::abs(value)); } - else if(from == m_rangeSelectors["NegativeE_Raw"]) + else if(from == negativeERaw) { m_dblManager->setValue(m_properties["EMin"], std::abs(value)); } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectTab.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectTab.cpp index 62e87cf653f4d83d78de43ac8888096869d8b2e5..2e35ed5775cab275e89d46d050334fe3a8412936 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectTab.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectTab.cpp @@ -4,10 +4,12 @@ #include "MantidKernel/Logger.h" #include "MantidQtAPI/AlgorithmDialog.h" #include "MantidQtAPI/InterfaceManager.h" +#include "MantidQtMantidWidgets/RangeSelector.h" using namespace Mantid::API; using namespace Mantid::Geometry; using namespace Mantid::Kernel; +using namespace MantidQt::MantidWidgets; namespace { @@ -22,7 +24,7 @@ namespace CustomInterfaces /** Constructor */ IndirectTab::IndirectTab(QObject* parent) : QObject(parent), - m_rangeSelectors(), m_properties(), + m_properties(), m_dblManager(new QtDoublePropertyManager()), m_blnManager(new QtBoolPropertyManager()), m_grpManager(new QtGroupPropertyManager()), m_dblEdFac(new DoubleEditorFactory()), m_pythonRunner(), @@ -146,36 +148,36 @@ namespace CustomInterfaces * Sets the edge bounds of plot to prevent the user inputting invalid values * Also sets limits for range selector movement * - * @param rsID :: The string index of the range selector in the map m_rangeSelectors + * @param rs :: Pointer to the RangeSelector * @param min :: The lower bound property in the property browser * @param max :: The upper bound property in the property browser * @param bounds :: The upper and lower bounds to be set */ - void IndirectTab::setPlotPropertyRange(const QString& rsID, QtProperty* min, QtProperty* max, + void IndirectTab::setPlotPropertyRange(RangeSelector * rs, QtProperty* min, QtProperty* max, const QPair<double, double> & bounds) { m_dblManager->setMinimum(min, bounds.first); m_dblManager->setMaximum(min, bounds.second); m_dblManager->setMinimum(max, bounds.first); m_dblManager->setMaximum(max, bounds.second); - m_rangeSelectors[rsID]->setRange(bounds.first, bounds.second); + rs->setRange(bounds.first, bounds.second); } /** * Set the position of the range selectors on the mini plot * - * @param rsID :: The string index of the range selector in the map m_rangeSelectors + * @param rs :: Pointer to the RangeSelector * @param lower :: The lower bound property in the property browser * @param upper :: The upper bound property in the property browser * @param bounds :: The upper and lower bounds to be set */ - void IndirectTab::setRangeSelector(const QString& rsID, QtProperty* lower, QtProperty* upper, + void IndirectTab::setRangeSelector(RangeSelector * rs, QtProperty* lower, QtProperty* upper, const QPair<double, double> & bounds) { m_dblManager->setValue(lower, bounds.first); m_dblManager->setValue(upper, bounds.second); - m_rangeSelectors[rsID]->setMinimum(bounds.first); - m_rangeSelectors[rsID]->setMaximum(bounds.second); + rs->setMinimum(bounds.first); + rs->setMaximum(bounds.second); } /** diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectTools.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectTools.cpp index f1f20f03fe2e7f9330d3e8b49e64e11bc5ace019..12d5730862cb9175e31470ae701d84ba7f1e0f87 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectTools.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectTools.cpp @@ -13,7 +13,7 @@ namespace MantidQt { namespace CustomInterfaces { - DECLARE_SUBWINDOW(IndirectTools); + DECLARE_SUBWINDOW(IndirectTools) } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/JumpFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/JumpFit.cpp index 5fa2ba6da67deafac4326c88de9ce8fbd94a3a28..8e4f96c8d6df3ee2305d9ef3d25a7c96f12c57a4 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/JumpFit.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/JumpFit.cpp @@ -19,8 +19,8 @@ namespace MantidQt m_uiForm.setupUi(parent); // Create range selector - m_rangeSelectors["JumpFitQ"] = new MantidWidgets::RangeSelector(m_uiForm.ppPlot); - connect(m_rangeSelectors["JumpFitQ"], SIGNAL(selectionChangedLazy(double, double)), this, SLOT(qRangeChanged(double, double))); + auto qRangeSelector = m_uiForm.ppPlot->addRangeSelector("JumpFitQ"); + connect(qRangeSelector, SIGNAL(selectionChangedLazy(double, double)), this, SLOT(qRangeChanged(double, double))); // Add the properties browser to the ui form m_uiForm.treeSpace->addWidget(m_propTree); @@ -213,6 +213,8 @@ namespace MantidQt findAllWidths(mws); + auto qRangeSelector = m_uiForm.ppPlot->getRangeSelector("JumpFitQ"); + if(m_spectraList.size() > 0) { m_uiForm.cbWidth->setEnabled(true); @@ -227,11 +229,11 @@ namespace MantidQt // Use the values from the instrument parameter file if we can if(getInstrumentResolution(filename, res)) - setRangeSelector("JumpFitQ", m_properties["QMin"], m_properties["QMax"], res); + setRangeSelector(qRangeSelector, m_properties["QMin"], m_properties["QMax"], res); else - setRangeSelector("JumpFitQ", m_properties["QMin"], m_properties["QMax"], range); + setRangeSelector(qRangeSelector, m_properties["QMin"], m_properties["QMax"], range); - setPlotPropertyRange("JumpFitQ", m_properties["QMin"], m_properties["QMax"], range); + setPlotPropertyRange(qRangeSelector, m_properties["QMin"], m_properties["QMax"], range); } else { @@ -341,13 +343,15 @@ namespace MantidQt */ void JumpFit::updateProperties(QtProperty* prop, double val) { + auto qRangeSelector = m_uiForm.ppPlot->getRangeSelector("JumpFitQ"); + if(prop == m_properties["QMin"]) { - updateLowerGuide(m_rangeSelectors["JumpFitQ"], m_properties["QMin"], m_properties["QMax"], val); + updateLowerGuide(qRangeSelector, m_properties["QMin"], m_properties["QMax"], val); } else if (prop == m_properties["QMax"]) { - updateUpperGuide(m_rangeSelectors["JumpFitQ"], m_properties["QMin"], m_properties["QMax"], val); + updateUpperGuide(qRangeSelector, m_properties["QMin"], m_properties["QMax"], val); } } } // namespace CustomInterfaces diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/MSDFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/MSDFit.cpp index 945d2d64ba0e5f2455e3f7e6ffd8ed5112c8753a..5b25bbf90a387579a68aac84e3158d482fa51e65 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/MSDFit.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/MSDFit.cpp @@ -44,10 +44,10 @@ namespace IDA m_msdTree->addProperty(m_properties["Start"]); m_msdTree->addProperty(m_properties["End"]); - m_rangeSelectors["MSDRange"] = new MantidWidgets::RangeSelector(m_uiForm.ppPlot); + auto fitRangeSelector = m_uiForm.ppPlot->addRangeSelector("MSDRange"); - connect(m_rangeSelectors["MSDRange"], SIGNAL(minValueChanged(double)), this, SLOT(minChanged(double))); - connect(m_rangeSelectors["MSDRange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double))); + connect(fitRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(minChanged(double))); + connect(fitRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double))); connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updateRS(QtProperty*, double))); connect(m_uiForm.dsSampleInput, SIGNAL(dataReady(const QString&)), this, SLOT(newDataLoaded(const QString&))); @@ -57,36 +57,53 @@ namespace IDA connect(m_uiForm.spSpectraMin, SIGNAL(valueChanged(int)), this, SLOT(specMinChanged(int))); connect(m_uiForm.spSpectraMax, SIGNAL(valueChanged(int)), this, SLOT(specMaxChanged(int))); + + connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(plotFit())); } void MSDFit::run() { - QString pyInput = - "from IndirectDataAnalysis import msdfit\n" - "startX = " + QString::number(m_dblManager->value(m_properties["Start"])) +"\n" - "endX = " + QString::number(m_dblManager->value(m_properties["End"])) +"\n" - "specMin = " + m_uiForm.spSpectraMin->text() + "\n" - "specMax = " + m_uiForm.spSpectraMax->text() + "\n" - "input = '" + m_uiForm.dsSampleInput->getCurrentDataName() + "'\n"; - - if ( m_uiForm.ckPlot->isChecked() ) pyInput += "plot = True\n"; - else pyInput += "plot = False\n"; - - if ( m_uiForm.ckSave->isChecked() ) pyInput += "save = True\n"; - else pyInput += "save = False\n"; - - pyInput += - "msdfit(input, startX, endX, spec_min=specMin, spec_max=specMax, Save=save, Plot=plot)\n"; - - QString pyOutput = runPythonCode(pyInput); - UNUSED_ARG(pyOutput); + if(!validate()) + return; // Set the result workspace for Python script export QString dataName = m_uiForm.dsSampleInput->getCurrentDataName(); m_pythonExportWsName = dataName.left(dataName.lastIndexOf("_")).toStdString() + "_msd"; - // Plot the fit result - plotFit(); + QString wsName = m_uiForm.dsSampleInput->getCurrentDataName(); + double xStart = m_dblManager->value(m_properties["Start"]); + double xEnd = m_dblManager->value(m_properties["End"]); + long specMin = m_uiForm.spSpectraMin->value(); + long specMax = m_uiForm.spSpectraMax->value(); + bool plot = m_uiForm.ckPlot->isChecked(); + bool save = m_uiForm.ckSave->isChecked(); + + IAlgorithm_sptr msdAlg = AlgorithmManager::Instance().create("MSDFit"); + msdAlg->initialize(); + msdAlg->setProperty("InputWorkspace", wsName.toStdString()); + msdAlg->setProperty("XStart", xStart); + msdAlg->setProperty("XEnd", xEnd); + msdAlg->setProperty("SpecMin", specMin); + msdAlg->setProperty("SpecMax", specMax); + msdAlg->setProperty("Plot", plot); + msdAlg->setProperty("OutputWorkspace", m_pythonExportWsName); + + m_batchAlgoRunner->addAlgorithm(msdAlg); + + // Handle saving results + if(save) + { + API::BatchAlgorithmRunner::AlgorithmRuntimeProps saveInputProps; + saveInputProps["InputWorkspace"] = m_pythonExportWsName; + + IAlgorithm_sptr saveAlg = AlgorithmManager::Instance().create("SaveNexusProcessed"); + saveAlg->initialize(); + saveAlg->setProperty("Filename", m_pythonExportWsName + ".nxs"); + + m_batchAlgoRunner->addAlgorithm(saveAlg, saveInputProps); + } + + m_batchAlgoRunner->executeBatchAsync(); } void MSDFit::singleFit() @@ -94,20 +111,27 @@ namespace IDA if(!validate()) return; - QString pyInput = - "from IndirectDataAnalysis import msdfit\n" - "startX = " + QString::number(m_dblManager->value(m_properties["Start"])) +"\n" - "endX = " + QString::number(m_dblManager->value(m_properties["End"])) +"\n" - "specMin = " + m_uiForm.spPlotSpectrum->text() + "\n" - "specMax = " + m_uiForm.spPlotSpectrum->text() + "\n" - "input = '" + m_uiForm.dsSampleInput->getCurrentDataName() + "'\n"; + // Set the result workspace for Python script export + QString dataName = m_uiForm.dsSampleInput->getCurrentDataName(); + m_pythonExportWsName = dataName.left(dataName.lastIndexOf("_")).toStdString() + "_msd"; + + QString wsName = m_uiForm.dsSampleInput->getCurrentDataName(); + double xStart = m_dblManager->value(m_properties["Start"]); + double xEnd = m_dblManager->value(m_properties["End"]); + long fitSpec = m_uiForm.spPlotSpectrum->value(); - pyInput += - "output = msdfit(input, startX, endX, spec_min=specMin, spec_max=specMax, Save=False, Plot=False)\n" - "print output \n"; + IAlgorithm_sptr msdAlg = AlgorithmManager::Instance().create("MSDFit"); + msdAlg->initialize(); + msdAlg->setProperty("InputWorkspace", wsName.toStdString()); + msdAlg->setProperty("XStart", xStart); + msdAlg->setProperty("XEnd", xEnd); + msdAlg->setProperty("SpecMin", fitSpec); + msdAlg->setProperty("SpecMax", fitSpec); + msdAlg->setProperty("OutputWorkspace", m_pythonExportWsName); - QString pyOutput = runPythonCode(pyInput).trimmed(); - plotFit(pyOutput, 0); + m_batchAlgoRunner->addAlgorithm(msdAlg); + + m_batchAlgoRunner->executeBatchAsync(); } bool MSDFit::validate() @@ -157,17 +181,25 @@ namespace IDA m_uiForm.ppPlot->removeSpectrum("Fit"); // Get the workspace - auto groupWs = Mantid::API::AnalysisDataService::Instance().retrieveWS<const Mantid::API::WorkspaceGroup>(wsName.toStdString()); - - // If the user has just done a single fit then we probably havent got a workspace to plot - // when the change the spectrum selector - if(specNo >= static_cast<int>(groupWs->size())) - return; - - auto ws = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(groupWs->getItem(specNo)); - - // Plot the new fit - m_uiForm.ppPlot->addSpectrum("Fit", ws, 1, Qt::red); + auto groupWs = AnalysisDataService::Instance().retrieveWS<const WorkspaceGroup>(wsName.toStdString()); + auto groupWsNames = groupWs->getNames(); + + // Find the correct fit workspace and plot it + std::stringstream searchString; + searchString << "_" << specNo << "_Workspace"; + for(auto it = groupWsNames.begin(); it != groupWsNames.end(); ++it) + { + std::string wsName = *it; + if(wsName.find(searchString.str()) != std::string::npos) + { + // Get the fit workspace + auto ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(wsName); + // Plot the new fit + m_uiForm.ppPlot->addSpectrum("Fit", ws, 1, Qt::red); + // Nothing else to do + return; + } + } } } @@ -217,7 +249,7 @@ namespace IDA try { QPair<double, double> range = m_uiForm.ppPlot->getCurveRange("Sample"); - m_rangeSelectors["MSDRange"]->setRange(range.first, range.second); + m_uiForm.ppPlot->getRangeSelector("MSDRange")->setRange(range.first, range.second); } catch(std::invalid_argument & exc) { @@ -263,8 +295,10 @@ namespace IDA void MSDFit::updateRS(QtProperty* prop, double val) { - if ( prop == m_properties["Start"] ) m_rangeSelectors["MSDRange"]->setMinimum(val); - else if ( prop == m_properties["End"] ) m_rangeSelectors["MSDRange"]->setMaximum(val); + auto fitRangeSelector = m_uiForm.ppPlot->getRangeSelector("MSDRange"); + + if(prop == m_properties["Start"]) fitRangeSelector->setMinimum(val); + else if(prop == m_properties["End"]) fitRangeSelector->setMaximum(val); } } // namespace IDA diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Quasi.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Quasi.cpp index b6c99479cf4fad51bbd6837c890f404e60f8b6a6..45f9cfb9f52c6980186d1fea721f2f2fbaccb101 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Quasi.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Quasi.cpp @@ -15,9 +15,9 @@ namespace MantidQt m_uiForm.setupUi(parent); // Create range selector - m_rangeSelectors["QuasiERange"] = new MantidWidgets::RangeSelector(m_uiForm.ppPlot); - connect(m_rangeSelectors["QuasiERange"], SIGNAL(minValueChanged(double)), this, SLOT(minValueChanged(double))); - connect(m_rangeSelectors["QuasiERange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxValueChanged(double))); + auto eRangeSelector = m_uiForm.ppPlot->addRangeSelector("QuasiERange"); + connect(eRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(minValueChanged(double))); + connect(eRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(maxValueChanged(double))); // Add the properties browser to the UI form m_uiForm.treeSpace->addWidget(m_propTree); @@ -276,8 +276,10 @@ namespace MantidQt updateMiniPlot(); QPair<double, double> range = m_uiForm.ppPlot->getCurveRange("Sample"); - setRangeSelector("QuasiERange", m_properties["EMin"], m_properties["EMax"], range); - setPlotPropertyRange("QuasiERange", m_properties["EMin"], m_properties["EMax"], range); + auto eRangeSelector = m_uiForm.ppPlot->getRangeSelector("QuasiERange"); + + setRangeSelector(eRangeSelector, m_properties["EMin"], m_properties["EMax"], range); + setPlotPropertyRange(eRangeSelector, m_properties["EMin"], m_properties["EMax"], range); } /** @@ -308,13 +310,15 @@ namespace MantidQt */ void Quasi::updateProperties(QtProperty* prop, double val) { + auto eRangeSelector = m_uiForm.ppPlot->getRangeSelector("QuasiERange"); + if(prop == m_properties["EMin"]) { - updateLowerGuide(m_rangeSelectors["QuasiERange"], m_properties["EMin"], m_properties["EMax"], val); + updateLowerGuide(eRangeSelector, m_properties["EMin"], m_properties["EMax"], val); } else if (prop == m_properties["EMax"]) { - updateUpperGuide(m_rangeSelectors["QuasiERange"], m_properties["EMin"], m_properties["EMax"], val); + updateUpperGuide(eRangeSelector, m_properties["EMin"], m_properties["EMax"], val); } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ResNorm.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ResNorm.cpp index 6cd8e4e43a6af21c1f535575b1446e728c5002ec..ff425165cfb37cb57283e491ef3cf963f17448cb 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ResNorm.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ResNorm.cpp @@ -14,9 +14,9 @@ namespace MantidQt m_uiForm.setupUi(parent); // Create range selector - m_rangeSelectors["ResNormERange"] = new MantidWidgets::RangeSelector(m_uiForm.ppPlot); - connect(m_rangeSelectors["ResNormERange"], SIGNAL(minValueChanged(double)), this, SLOT(minValueChanged(double))); - connect(m_rangeSelectors["ResNormERange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxValueChanged(double))); + auto eRangeSelector = m_uiForm.ppPlot->addRangeSelector("ResNormERange"); + connect(eRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(minValueChanged(double))); + connect(eRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(maxValueChanged(double))); // Add the properties browser to the ui form m_uiForm.treeSpace->addWidget(m_propTree); @@ -132,6 +132,8 @@ namespace MantidQt MatrixWorkspace_sptr vanWs = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(filename.toStdString()); m_uiForm.spPreviewSpectrum->setMaximum(static_cast<int>(vanWs->getNumberHistograms()) - 1); + auto eRangeSelector = m_uiForm.ppPlot->getRangeSelector("ResNormERange"); + //Use the values from the instrument parameter file if we can if(getInstrumentResolution(filename, res)) { @@ -139,14 +141,14 @@ namespace MantidQt res.first = res.first * 10; res.second = res.second * 10; - setRangeSelector("ResNormERange", m_properties["EMin"], m_properties["EMax"], res); + setRangeSelector(eRangeSelector, m_properties["EMin"], m_properties["EMax"], res); } else { - setRangeSelector("ResNormERange", m_properties["EMin"], m_properties["EMax"], range); + setRangeSelector(eRangeSelector, m_properties["EMin"], m_properties["EMax"], range); } - setPlotPropertyRange("ResNormERange", m_properties["EMin"], m_properties["EMax"], range); + setPlotPropertyRange(eRangeSelector, m_properties["EMin"], m_properties["EMax"], range); } /** @@ -177,13 +179,15 @@ namespace MantidQt */ void ResNorm::updateProperties(QtProperty* prop, double val) { + auto eRangeSelector = m_uiForm.ppPlot->getRangeSelector("ResNormERange"); + if(prop == m_properties["EMin"]) { - updateLowerGuide(m_rangeSelectors["ResNormERange"], m_properties["EMin"], m_properties["EMax"], val); + updateLowerGuide(eRangeSelector, m_properties["EMin"], m_properties["EMax"], val); } else if (prop == m_properties["EMax"]) { - updateUpperGuide(m_rangeSelectors["ResNormERange"], m_properties["EMin"], m_properties["EMax"], val); + updateUpperGuide(eRangeSelector, m_properties["EMin"], m_properties["EMax"], val); } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Stretch.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Stretch.cpp index 78f13b6113eba92606f173de483b729ec919f7ec..22186a4b8c02300cdfb290e962f2099dd43f327c 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Stretch.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Stretch.cpp @@ -17,9 +17,9 @@ namespace MantidQt // Create range selector - m_rangeSelectors["StretchERange"] = new MantidWidgets::RangeSelector(m_uiForm.ppPlot); - connect(m_rangeSelectors["StretchERange"], SIGNAL(minValueChanged(double)), this, SLOT(minValueChanged(double))); - connect(m_rangeSelectors["StretchERange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxValueChanged(double))); + auto eRangeSelector = m_uiForm.ppPlot->addRangeSelector("StretchERange"); + connect(eRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(minValueChanged(double))); + connect(eRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(maxValueChanged(double))); // Add the properties browser to the ui form m_uiForm.treeSpace->addWidget(m_propTree); @@ -153,8 +153,9 @@ namespace MantidQt { m_uiForm.ppPlot->addSpectrum("Sample", filename, 0); QPair<double, double> range = m_uiForm.ppPlot->getCurveRange("Sample"); - setRangeSelector("StretchERange", m_properties["EMin"], m_properties["EMax"], range); - setPlotPropertyRange("StretchERange", m_properties["EMin"], m_properties["EMax"], range); + auto eRangeSelector = m_uiForm.ppPlot->getRangeSelector("StretchERange"); + setRangeSelector(eRangeSelector, m_properties["EMin"], m_properties["EMax"], range); + setPlotPropertyRange(eRangeSelector, m_properties["EMin"], m_properties["EMax"], range); } /** @@ -185,13 +186,15 @@ namespace MantidQt */ void Stretch::updateProperties(QtProperty* prop, double val) { + auto eRangeSelector = m_uiForm.ppPlot->getRangeSelector("StretchERange"); + if(prop == m_properties["EMin"]) { - updateLowerGuide(m_rangeSelectors["StretchERange"], m_properties["EMin"], m_properties["EMax"], val); + updateLowerGuide(eRangeSelector, m_properties["EMin"], m_properties["EMax"], val); } else if (prop == m_properties["EMax"]) { - updateUpperGuide(m_rangeSelectors["StretchERange"], m_properties["EMin"], m_properties["EMax"], val); + updateUpperGuide(eRangeSelector, m_properties["EMin"], m_properties["EMax"], val); } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/MantidEV.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/MantidEV.cpp index 12e730113c93f845e337af4abc2c69cff1ad69de..5ac92097495116849472d24de678d91822f465b9 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/MantidEV.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/MantidEV.cpp @@ -4,6 +4,7 @@ #include <QSettings> #include <QDesktopServices> #include <QDesktopWidget> +#include <Poco/Path.h> #include "MantidQtCustomInterfaces/MantidEV.h" #include "MantidAPI/AlgorithmManager.h" @@ -16,7 +17,7 @@ namespace CustomInterfaces { //Register the class with the factory -DECLARE_SUBWINDOW(MantidEV); +DECLARE_SUBWINDOW(MantidEV) using namespace Mantid::Kernel; using namespace Mantid::API; @@ -319,6 +320,12 @@ void MantidEV::initLayout() QObject::connect( m_uiForm.actionLoad_Isaw_Peaks, SIGNAL(triggered()), this, SLOT(loadIsawPeaks_slot()) ); + QObject::connect( m_uiForm.actionSave_Nexus_Peaks, SIGNAL(triggered()), + this, SLOT(saveNexusPeaks_slot()) ); + + QObject::connect( m_uiForm.actionLoad_Nexus_Peaks, SIGNAL(triggered()), + this, SLOT(loadNexusPeaks_slot()) ); + QObject::connect( m_uiForm.actionShow_UB, SIGNAL(triggered()), this, SLOT(showUB_slot()) ); @@ -765,15 +772,22 @@ void MantidEV::findPeaks_slot() else if ( load_peaks ) { std::string file_name = m_uiForm.SelectPeaksFile_ledt->text().trimmed().toStdString(); + std::string extension = Poco::Path(file_name).getExtension(); if ( file_name.length() == 0 ) { errorMessage("Specify a peaks file with the peaks to be loaded."); return; } - - if ( !worker->loadIsawPeaks( peaks_ws_name, file_name ) ) - { - errorMessage("Could not load requested peaks file"); + if (extension.compare("nxs") == 0 || extension.compare("h5") == 0){ + if ( !worker->loadNexusPeaks( peaks_ws_name, file_name ) ){ + errorMessage("Could not load requested peaks file"); + } + } + else { + if ( !worker->loadIsawPeaks( peaks_ws_name, file_name ) ) + { + errorMessage("Could not load requested NeXus file"); + } } } } @@ -788,7 +802,7 @@ void MantidEV::getLoadPeaksFileName_slot() QString Qfile_name = QFileDialog::getOpenFileName( this, tr("Load peaks file"), file_path, - tr("Peaks Files (*.peaks *.integrate);; All files(*.*)")); + tr("Peaks Files (*.peaks *.integrate *.nxs *.h5);; All files(*.*)")); if ( Qfile_name.length()> 0 ) { @@ -808,7 +822,7 @@ void MantidEV::getSavePeaksFileName() QString Qfile_name = QFileDialog::getSaveFileName( this, tr("Save peaks file"), file_path, - tr("Peaks Files (*.peaks *.integrate);; All files(*.*) "), + tr("Peaks Files (*.peaks *.integrate *.nxs *.h5);; All files(*.*)"), 0, QFileDialog::DontConfirmOverwrite ); if ( Qfile_name.length() > 0 ) @@ -1495,6 +1509,67 @@ void MantidEV::saveIsawPeaks_slot() } } +/** + * Slot called when the Save Nexus Peaks action is selected from the File menu. + */ +void MantidEV::saveNexusPeaks_slot() +{ + std::string peaks_ws_name = m_uiForm.PeaksWorkspace_ledt->text().trimmed().toStdString(); + if ( peaks_ws_name.length() == 0 ) + { + errorMessage("Specify a peaks workspace name on the Find Peaks tab."); + return; + } + + getSavePeaksFileName(); + + std::string file_name = m_uiForm.SelectPeaksFile_ledt->text().trimmed().toStdString(); + if ( file_name.length() == 0 ) + { + errorMessage("Specify a peaks file name for saving the peaks workspace."); + return; + } + else + { + // if the file exists, check for overwrite or append + bool append = false; + QFile peaks_file( QString::fromStdString( file_name ) ); + if ( peaks_file.exists() ) + { + QMessageBox message_box( this->window() ); + message_box.setText( tr("File Exists") ); + message_box.setInformativeText("Replace file, or append peaks to file?"); + QAbstractButton *replace_btn = message_box.addButton( tr("Replace"), QMessageBox::NoRole ); + QAbstractButton *append_btn = message_box.addButton( tr("Append"), QMessageBox::YesRole ); + message_box.setIcon( QMessageBox::Question ); + // it should not be necessary to do the next + // four lines, but without them the message box + // appears at random locations on RHEL 6 + message_box.show(); + QSize box_size = message_box.sizeHint(); + QRect screen_rect = QDesktopWidget().screen()->rect(); + message_box.move( QPoint( screen_rect.width()/2 - box_size.width()/2, + screen_rect.height()/2 - box_size.height()/2 ) ); + message_box.exec(); + + if ( message_box.clickedButton() == append_btn ) + { + append = true; + } + else if ( message_box.clickedButton() == replace_btn ) // no strictly needed, but clearer + { + append = false; + } + } + + if ( !worker->saveNexusPeaks( peaks_ws_name, file_name, append ) ) + { + errorMessage( "Failed to save peaks to file" ); + return; + } + } +} + /** * Slot called when the Load Isaw Peaks action is selected from the File menu. @@ -1526,6 +1601,36 @@ void MantidEV::loadIsawPeaks_slot() } } +/** + * Slot called when the Load Nexus Peaks action is selected from the File menu. + */ +void MantidEV::loadNexusPeaks_slot() +{ + std::string peaks_ws_name = m_uiForm.PeaksWorkspace_ledt->text().trimmed().toStdString(); + if ( peaks_ws_name.length() == 0 ) + { + errorMessage("Specify a peaks workspace name on the Find Peaks tab."); + return; + } + + getLoadPeaksFileName_slot(); + + std::string file_name = m_uiForm.SelectPeaksFile_ledt->text().trimmed().toStdString(); + if ( file_name.length() == 0 ) + { + errorMessage("Select a peaks file to be loaded."); + return; + } + else + { + if ( !worker->loadNexusPeaks( peaks_ws_name, file_name ) ) + { + errorMessage( "Failed to Load Peaks File" ); + return; + } + } +} + /** * Slot called when the Show UB action is selected from the View menu. diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/MantidEVWorker.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/MantidEVWorker.cpp index 0cba832b97f19448f1f25cf4cb021a12722ce7c8..6200f7641430ba30e3eef5835c6b14bfe9f1e36e 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/MantidEVWorker.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/MantidEVWorker.cpp @@ -397,9 +397,31 @@ bool MantidEVWorker::loadIsawPeaks( const std::string & peaks_ws_name, return false; } +/** + * Load the specified peaks workspace from the specified NeXus file. + * + * @param peaks_ws_name The name of the peaks workspace to load/create. + * @param file_name The name of the NeXus file to load. + * + * @return true if LoadNexusPeaks completed successfully. + */ +bool MantidEVWorker::loadNexusPeaks( const std::string & peaks_ws_name, + const std::string & file_name ) +{ + + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("Load"); + alg->setProperty("Filename",file_name ); + + alg->setProperty("OutputWorkspace", peaks_ws_name ); + + if ( alg->execute() ) + return true; + + return false; +} /** - * Load the specified peaks workspace to the specified peaks file. + * Save the specified peaks workspace to the specified peaks file. * * @param peaks_ws_name The name of the peaks workspace to save. * @param file_name The name of the peaks file to write to. @@ -425,6 +447,43 @@ bool MantidEVWorker::saveIsawPeaks( const std::string & peaks_ws_name, return false; } +/** + * Save the specified peaks workspace to the specified peaks file. + * + * @param peaks_ws_name The name of the peaks workspace to save. + * @param file_name The name of the NeXus file to write to. + * + * @return true if SaveNexusPeaks completed successfully. + */ +bool MantidEVWorker::saveNexusPeaks( const std::string & peaks_ws_name, + const std::string & file_name, + bool append ) +{ + if (append){ + std::string temp_peaks_ws_name = "__MantidEVWorker_peaks_ws"; + IAlgorithm_sptr load = AlgorithmManager::Instance().create("Load"); + load->setProperty("OutputWorkspace", temp_peaks_ws_name ); + load->setProperty("Filename",file_name ); + + load->execute(); + + IAlgorithm_sptr combine = AlgorithmManager::Instance().create("CombinePeaksWorkspaces"); + combine->setProperty("LHSWorkspace", temp_peaks_ws_name ); + combine->setProperty("RHSWorkspace", peaks_ws_name ); + combine->setProperty("OutputWorkspace", peaks_ws_name ); + + combine->execute(); + } + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("SaveNexus"); + alg->setProperty("InputWorkspace", peaks_ws_name ); + alg->setProperty("Filename",file_name ); + + if ( alg->execute() ) + return true; + + return false; +} + /** * Find an optimized UB matrix that indexes the peaks in the specified diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/MultiDatasetFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/MultiDatasetFit.cpp index b2f22a1df402b4129aa2eb74b24b6b0665d7edcf..096dd495cc22e961564d3e4aa4aed52ddea52010 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/MultiDatasetFit.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/MultiDatasetFit.cpp @@ -1,17 +1,21 @@ #include "MantidQtCustomInterfaces/MultiDatasetFit.h" -#include "MantidQtMantidWidgets/FunctionBrowser.h" -#include "MantidQtMantidWidgets/FitOptionsBrowser.h" -#include "MantidQtAPI/AlgorithmRunner.h" +#include "MantidAPI/AlgorithmManager.h" #include "MantidAPI/AnalysisDataService.h" #include "MantidAPI/FunctionFactory.h" +#include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/MultiDomainFunction.h" -#include "MantidAPI/AlgorithmManager.h" #include "MantidAPI/ParameterTie.h" + #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/ArrayBoundedValidator.h" #include "MantidKernel/Exception.h" +#include "MantidQtAPI/AlgorithmRunner.h" +#include "MantidQtMantidWidgets/FitOptionsBrowser.h" +#include "MantidQtMantidWidgets/FunctionBrowser.h" +#include "MantidQtMantidWidgets/RangeSelector.h" + #include "qtpropertybrowser.h" #include <QDialog> @@ -27,14 +31,25 @@ #include <qwt_plot_zoomer.h> #include <qwt_plot_panner.h> #include <qwt_plot_magnifier.h> +#include <qwt_scale_div.h> #include <Poco/ActiveResult.h> #include <vector> #include <algorithm> namespace{ - const int wsColumn = 0; + // columns in the data table + const int wsColumn = 0; const int wsIndexColumn = 1; + const int startXColumn = 2; + const int endXColumn = 3; + // tool options pages + const int zoomToolPage = 0; + const int panToolPage = 1; + const int rangeToolPage = 2; + // colours of the fitting range selector + QColor rangeSelectorDisabledColor(Qt::darkGray); + QColor rangeSelectorEnabledColor(Qt::blue); } namespace MantidQt @@ -249,6 +264,7 @@ DatasetPlotData::~DatasetPlotData() */ void DatasetPlotData::setData(const Mantid::API::MatrixWorkspace *ws, int wsIndex, const Mantid::API::MatrixWorkspace *outputWS) { + bool haveFitCurves = outputWS && outputWS->getNumberHistograms() >= 3; std::vector<double> xValues = ws->readX(wsIndex); if ( ws->isHistogramData() ) { @@ -261,14 +277,19 @@ void DatasetPlotData::setData(const Mantid::API::MatrixWorkspace *ws, int wsInde } m_dataCurve->setData( xValues.data(), ws->readY(wsIndex).data(), static_cast<int>(xValues.size()) ); - if ( outputWS && outputWS->getNumberHistograms() >= 3 ) + if ( haveFitCurves ) { + auto xBegin = std::lower_bound(xValues.begin(),xValues.end(), outputWS->readX(1).front()); + if ( xBegin == xValues.end() ) return; + int i0 = static_cast<int>(std::distance(xValues.begin(),xBegin)); + int n = static_cast<int>(outputWS->readY(1).size()); + if ( i0 + n > static_cast<int>(xValues.size()) ) return; m_calcCurve = new QwtPlotCurve("calc"); - m_calcCurve->setData( xValues.data(), outputWS->readY(1).data(), static_cast<int>(xValues.size()) ); + m_calcCurve->setData( xValues.data() + i0, outputWS->readY(1).data(), n ); QPen penCalc("red"); m_calcCurve->setPen(penCalc); m_diffCurve = new QwtPlotCurve("diff"); - m_diffCurve->setData( xValues.data(), outputWS->readY(2).data(), static_cast<int>(xValues.size()) ); + m_diffCurve->setData( xValues.data() + i0, outputWS->readY(2).data(), n ); QPen penDiff("green"); m_diffCurve->setPen(penDiff); } @@ -327,10 +348,14 @@ QwtDoubleRect DatasetPlotData::boundingRect() const /* PlotController */ /*==========================================================================================*/ -PlotController::PlotController(MultiDatasetFit *parent,QwtPlot *plot, QTableWidget *table, QComboBox *plotSelector, QPushButton *prev, QPushButton *next): +PlotController::PlotController(MultiDatasetFit *parent, + QwtPlot *plot, + QTableWidget *table, + QComboBox *plotSelector, + QPushButton *prev, + QPushButton *next): QObject(parent),m_plot(plot),m_table(table),m_plotSelector(plotSelector),m_prevPlot(prev),m_nextPlot(next),m_currentIndex(-1) { - connect(parent,SIGNAL(dataTableUpdated()),this,SLOT(tableUpdated())); connect(prev,SIGNAL(clicked()),this,SLOT(prevPlot())); connect(next,SIGNAL(clicked()),this,SLOT(nextPlot())); connect(plotSelector,SIGNAL(currentIndexChanged(int)),this,SLOT(plotDataSet(int))); @@ -339,10 +364,19 @@ PlotController::PlotController(MultiDatasetFit *parent,QwtPlot *plot, QTableWidg QwtPicker::DragSelection | QwtPicker::CornerToCorner, QwtPicker::AlwaysOff, plot->canvas()); m_panner = new QwtPlotPanner( plot->canvas() ); - m_panner->setEnabled(false); m_magnifier = new QwtPlotMagnifier( plot->canvas() ); - m_magnifier->setEnabled( false ); + + m_rangeSelector = new MantidWidgets::RangeSelector(m_plot); + m_rangeSelector->setRange( -1e30, 1e30 ); + m_rangeSelector->setMinimum(10); + m_rangeSelector->setMaximum(990); + connect(m_rangeSelector,SIGNAL(selectionChanged(double, double)),this,SLOT(updateFittingRange(double, double))); + + disableAllTools(); + + m_plot->canvas()->installEventFilter(this); + } PlotController::~PlotController() @@ -350,6 +384,22 @@ PlotController::~PlotController() m_plotData.clear(); } +bool PlotController::eventFilter(QObject *, QEvent *evn) +{ + if ( evn->type() == QEvent::MouseButtonDblClick ) + { + if ( isRangeSelectorEnabled() ) + { + resetRange(); + } + else if ( isZoomEnabled() ) + { + zoomToRange(); + } + } + return false; +} + /** * Slot. Respond to changes in the data table. */ @@ -395,23 +445,10 @@ void PlotController::nextPlot() } } -/** - * Plot a data set. - * @param index :: Index (row) of the data set in the table. - */ -void PlotController::plotDataSet(int index) +/// Get a pointer to a dataset data. +/// @param index :: Index of a dataset. +boost::shared_ptr<DatasetPlotData> PlotController::getData(int index) { - if ( index < 0 || index >= m_table->rowCount() ) - { - clear(); - owner()->checkDataSets(); - m_plot->replot(); - return; - } - - bool resetZoom = m_plotData.isEmpty(); - - // create data if index is displayed for the first time if ( !m_plotData.contains(index) ) { QString wsName = m_table->item( index, wsColumn )->text(); @@ -425,6 +462,7 @@ void PlotController::plotDataSet(int index) { auto value = boost::make_shared<DatasetPlotData>( wsName, wsIndex, outputWorkspaceName ); m_plotData.insert(index, value ); + return value; } catch(std::exception& e) { @@ -432,10 +470,31 @@ void PlotController::plotDataSet(int index) clear(); owner()->checkDataSets(); m_plot->replot(); - return; + return boost::shared_ptr<DatasetPlotData>(); } } + return m_plotData[index]; +} + +/** + * Plot a data set. + * @param index :: Index (row) of the data set in the table. + */ +void PlotController::plotDataSet(int index) +{ + if ( index < 0 || index >= m_table->rowCount() ) + { + clear(); + owner()->checkDataSets(); + m_plot->replot(); + return; + } + + bool resetZoom = m_plotData.isEmpty(); + + auto plotData = getData(index); + // hide the previously shown data if ( m_currentIndex > -1 ) { @@ -451,9 +510,12 @@ void PlotController::plotDataSet(int index) m_plot->setAxisAutoScale(QwtPlot::xBottom); m_plot->setAxisAutoScale(QwtPlot::yLeft); } - + // change the current data set index + m_currentIndex = index; + updateRange(index); + // show the new data - m_plotData[index]->show( m_plot ); + plotData->show( m_plot ); m_plot->replot(); // the idea is to set the zoom base (the largest view) to the data's bounding rect // but it looks like the base is set to the union of dataRect and current zoomRect @@ -464,8 +526,6 @@ void PlotController::plotDataSet(int index) { m_zoomer->setZoomBase(true); } - // change the current data set index - m_currentIndex = index; emit currentIndexChanged( index ); } @@ -479,22 +539,78 @@ void PlotController::update() plotDataSet( m_currentIndex ); } -void PlotController::enableZoom() +/** + * Reset the fitting range to the current limits on the x axis. + */ +void PlotController::resetRange() { - m_zoomer->setEnabled(true); + QwtScaleMap xMap = m_plot->canvasMap(QwtPlot::xBottom); + double startX = xMap.s1(); + double endX = xMap.s2(); + m_rangeSelector->setMinimum( startX ); + m_rangeSelector->setMaximum( endX ); +} + +/** + * Set zooming to the current fitting range. + */ +void PlotController::zoomToRange() +{ + QwtDoubleRect rect = m_zoomer->zoomRect(); + rect.setX( m_rangeSelector->getMinimum() ); + rect.setRight( m_rangeSelector->getMaximum() ); + m_zoomer->zoom( rect ); +} + +/** + * Disable all plot tools. It is a helper method + * to simplify switchig between tools. + */ +void PlotController::disableAllTools() +{ + m_zoomer->setEnabled(false); m_panner->setEnabled(false); m_magnifier->setEnabled(false); - m_plot->canvas()->setCursor(QCursor(Qt::CrossCursor)); + m_rangeSelector->setEnabled(false); + m_rangeSelector->setColour(rangeSelectorDisabledColor); +} + +template<class Tool> +void PlotController::enableTool(Tool* tool, int cursor) +{ + disableAllTools(); + tool->setEnabled(true); + m_plot->canvas()->setCursor(QCursor(static_cast<Qt::CursorShape>(cursor))); + m_plot->replot(); owner()->showPlotInfo(); } + +/** + * Enable zooming tool. + */ +void PlotController::enableZoom() +{ + enableTool(m_zoomer,Qt::CrossCursor); +} + +/** + * Enable panning tool. + */ void PlotController::enablePan() { - m_zoomer->setEnabled(false); - m_panner->setEnabled(true); + enableTool(m_panner,Qt::pointingHandCursor); m_magnifier->setEnabled(true); - m_plot->canvas()->setCursor(Qt::pointingHandCursor); - owner()->showPlotInfo(); +} + +/** + * Enable range selector tool. + */ +void PlotController::enableRange() +{ + enableTool(m_rangeSelector,Qt::pointingHandCursor); + m_rangeSelector->setColour(rangeSelectorEnabledColor); + m_plot->replot(); } bool PlotController::isZoomEnabled() const @@ -507,6 +623,31 @@ bool PlotController::isPanEnabled() const return m_panner->isEnabled(); } +bool PlotController::isRangeSelectorEnabled() const +{ + return m_rangeSelector->isEnabled(); +} + +/// Signal others that fitting range has been updated. +void PlotController::updateFittingRange(double startX, double endX) +{ + emit fittingRangeChanged(m_currentIndex, startX, endX); +} + +void PlotController::updateRange(int index) +{ + if ( index >= 0 && index == m_currentIndex ) + { + const double startX = m_table->item(index,startXColumn)->text().toDouble(); + const double endX = m_table->item(index,endXColumn)->text().toDouble(); + m_rangeSelector->blockSignals(true); + m_rangeSelector->setMinimum(startX); + m_rangeSelector->setMaximum(endX); + m_rangeSelector->blockSignals(false); + } +} + + /*==========================================================================================*/ /* EditLocalParameterDialog */ /*==========================================================================================*/ @@ -560,7 +701,7 @@ void EditLocalParameterDialog::valueChanged(int row, int col) /*==========================================================================================*/ //Register the class with the factory -DECLARE_SUBWINDOW(MultiDatasetFit); +DECLARE_SUBWINDOW(MultiDatasetFit) /** * Constructor @@ -594,11 +735,14 @@ void MultiDatasetFit::initLayout() m_uiForm.btnRemove->setEnabled( false ); - connect(m_uiForm.btnAddWorkspace,SIGNAL(clicked()),this,SLOT(addWorkspace())); - connect(m_uiForm.btnRemove,SIGNAL(clicked()),this,SLOT(removeSelectedSpectra())); - connect(m_uiForm.dataTable,SIGNAL(itemSelectionChanged()), this,SLOT(workspaceSelectionChanged())); connect(m_uiForm.btnFit,SIGNAL(clicked()),this,SLOT(fit())); - connect(this,SIGNAL(dataTableUpdated()),this,SLOT(reset())); + + m_dataController = new DataController(this, m_uiForm.dataTable); + connect(m_dataController,SIGNAL(dataTableUpdated()),this,SLOT(reset())); + connect(m_dataController,SIGNAL(hasSelection(bool)), m_uiForm.btnRemove, SLOT(setEnabled(bool))); + connect(m_uiForm.btnAddWorkspace,SIGNAL(clicked()),m_dataController,SLOT(addWorkspace())); + connect(m_uiForm.btnRemove,SIGNAL(clicked()),m_dataController,SLOT(removeSelectedSpectra())); + connect(m_uiForm.cb_applyRangeToAll,SIGNAL(toggled(bool)),m_dataController,SLOT(setFittingRangeGlobal(bool))); m_plotController = new PlotController(this, m_uiForm.plot, @@ -606,6 +750,9 @@ void MultiDatasetFit::initLayout() m_uiForm.cbPlotSelector, m_uiForm.btnPrev, m_uiForm.btnNext); + connect(m_dataController,SIGNAL(dataTableUpdated()),m_plotController,SLOT(tableUpdated())); + connect(m_dataController,SIGNAL(dataSetUpdated(int)),m_plotController,SLOT(updateRange(int))); + connect(m_plotController,SIGNAL(fittingRangeChanged(int, double, double)),m_dataController,SLOT(setFittingRange(int, double, double))); connect(m_plotController,SIGNAL(currentIndexChanged(int)),this,SLOT(updateLocalParameters(int))); QSplitter* splitter = new QSplitter(Qt::Vertical,this); @@ -628,6 +775,7 @@ void MultiDatasetFit::initLayout() m_uiForm.plot->installEventFilter( this ); m_uiForm.dataTable->installEventFilter( this ); + m_plotController->enableZoom(); showInfo( "Add some data, define fitting function" ); loadSettings(); @@ -635,7 +783,9 @@ void MultiDatasetFit::initLayout() void MultiDatasetFit::createPlotToolbar() { + // ----- Main tool bar -------- auto toolBar = new QToolBar(this); + toolBar->setIconSize(QSize(16,16)); auto group = new QActionGroup(this); auto action = new QAction(this); @@ -643,95 +793,27 @@ void MultiDatasetFit::createPlotToolbar() action->setCheckable(true); action->setChecked(true); action->setToolTip("Zooming tool"); - connect(action,SIGNAL(triggered()),m_plotController,SLOT(enableZoom())); + connect(action,SIGNAL(triggered()),this,SLOT(enableZoom())); group->addAction(action); action = new QAction(this); action->setIcon(QIcon(":/MultiDatasetFit/icons/panning.png")); action->setCheckable(true); action->setToolTip("Panning tool"); - connect(action,SIGNAL(triggered()),m_plotController,SLOT(enablePan())); + connect(action,SIGNAL(triggered()),this,SLOT(enablePan())); + group->addAction(action); + + action = new QAction(this); + action->setIcon(QIcon(":/MultiDatasetFit/icons/range.png")); + action->setCheckable(true); + action->setToolTip("Set fitting range"); + connect(action,SIGNAL(triggered()),this,SLOT(enableRange())); group->addAction(action); toolBar->addActions(group->actions()); m_uiForm.horizontalLayout->insertWidget(3,toolBar); -} - -/** - * Show a dialog to select a workspace. - */ -void MultiDatasetFit::addWorkspace() -{ - AddWorkspaceDialog dialog(this); - if ( dialog.exec() == QDialog::Accepted ) - { - QString wsName = dialog.workspaceName().stripWhiteSpace(); - // if name is empty assume that there are no workspaces in the ADS - if ( wsName.isEmpty() ) return; - if ( Mantid::API::AnalysisDataService::Instance().doesExist( wsName.toStdString()) ) - { - auto indices = dialog.workspaceIndices(); - for(auto i = indices.begin(); i != indices.end(); ++i) - { - addWorkspaceSpectrum( wsName, *i ); - } - emit dataTableUpdated(); - } - else - { - QMessageBox::warning(this,"MantidPlot - Warning",QString("Workspace \"%1\" doesn't exist.").arg(wsName)); - } - } -} - -/** - * Add a spectrum from a workspace to the table. - * @param wsName :: Name of a workspace. - * @param wsIndex :: Index of a spectrum in the workspace (workspace index). - */ -void MultiDatasetFit::addWorkspaceSpectrum(const QString &wsName, int wsIndex) -{ - int row = m_uiForm.dataTable->rowCount(); - m_uiForm.dataTable->insertRow(row); - - auto cell = new QTableWidgetItem( wsName ); - m_uiForm.dataTable->setItem( row, wsColumn, cell ); - cell = new QTableWidgetItem( QString::number(wsIndex) ); - m_uiForm.dataTable->setItem( row, wsIndexColumn, cell ); -} - -/** - * Slot. Called when selection in the data table changes. - */ -void MultiDatasetFit::workspaceSelectionChanged() -{ - auto selection = m_uiForm.dataTable->selectionModel(); - bool enableRemoveButton = selection->hasSelection(); - if ( enableRemoveButton ) - { - enableRemoveButton = selection->selectedRows().size() > 0; - } - - m_uiForm.btnRemove->setEnabled( enableRemoveButton ); -} -/** - * Slot. Called when "Remove" button is pressed. - */ -void MultiDatasetFit::removeSelectedSpectra() -{ - auto ranges = m_uiForm.dataTable->selectedRanges(); - if ( ranges.isEmpty() ) return; - std::vector<int> rows; - for(auto range = ranges.begin(); range != ranges.end(); ++range) - { - for(int row = range->topRow(); row <= range->bottomRow(); ++row) - { - rows.push_back( row ); - } - } - removeDataSets( rows ); } /** @@ -861,6 +943,9 @@ void MultiDatasetFit::fit() fit->setProperty("Function", fun ); fit->setPropertyValue("InputWorkspace", getWorkspaceName(0)); fit->setProperty("WorkspaceIndex", getWorkspaceIndex(0)); + auto range = getFittingRange(0); + fit->setProperty( "StartX", range.first ); + fit->setProperty( "EndX", range.second ); int n = getNumberOfSpectra(); for(int ispec = 1; ispec < n; ++ispec) @@ -868,6 +953,9 @@ void MultiDatasetFit::fit() std::string suffix = boost::lexical_cast<std::string>(ispec); fit->setPropertyValue( "InputWorkspace_" + suffix, getWorkspaceName(ispec) ); fit->setProperty( "WorkspaceIndex_" + suffix, getWorkspaceIndex(ispec) ); + auto range = getFittingRange(ispec); + fit->setProperty( "StartX_" + suffix, range.first ); + fit->setProperty( "EndX_" + suffix, range.second ); } m_fitOptionsBrowser->copyPropertiesToAlgorithm(*fit); @@ -906,7 +994,7 @@ void MultiDatasetFit::fit() */ std::string MultiDatasetFit::getWorkspaceName(int i) const { - return m_uiForm.dataTable->item(i, wsColumn)->text().toStdString(); + return m_dataController->getWorkspaceName(i); } /** @@ -915,7 +1003,14 @@ std::string MultiDatasetFit::getWorkspaceName(int i) const */ int MultiDatasetFit::getWorkspaceIndex(int i) const { - return m_uiForm.dataTable->item(i, wsIndexColumn)->text().toInt(); + return m_dataController->getWorkspaceIndex(i); +} + +/// Get the fitting range for the i-th spectrum +/// @param i :: Index of a spectrum in the data table. +std::pair<double,double> MultiDatasetFit::getFittingRange(int i) const +{ + return m_dataController->getFittingRange(i); } /** @@ -923,7 +1018,7 @@ int MultiDatasetFit::getWorkspaceIndex(int i) const */ int MultiDatasetFit::getNumberOfSpectra() const { - return m_uiForm.dataTable->rowCount(); + return m_dataController->getNumberOfSpectra(); } /** @@ -1113,6 +1208,10 @@ void MultiDatasetFit::showPlotInfo() { text += "Click and drag to move. Use mouse wheel to zoom in and out."; } + else if ( m_plotController->isRangeSelectorEnabled() ) + { + text += "Drag the vertical dashed lines to adjust the fitting range."; + } showInfo( text ); } @@ -1133,6 +1232,147 @@ void MultiDatasetFit::showTableInfo() * Check that the data sets in the table are valid and remove invalid ones. */ void MultiDatasetFit::checkDataSets() +{ + m_dataController->checkDataSets(); +} + +void MultiDatasetFit::enableZoom() +{ + m_plotController->enableZoom(); + m_uiForm.toolOptions->setCurrentIndex(zoomToolPage); +} + +void MultiDatasetFit::enablePan() +{ + m_plotController->enablePan(); + m_uiForm.toolOptions->setCurrentIndex(panToolPage); +} + +void MultiDatasetFit::enableRange() +{ + m_plotController->enableRange(); + m_uiForm.toolOptions->setCurrentIndex(rangeToolPage); +} + +/*==========================================================================================*/ +/* DataController */ +/*==========================================================================================*/ + +DataController::DataController(MultiDatasetFit *parent, QTableWidget *dataTable): + QObject(parent),m_dataTable(dataTable),m_isFittingRangeGlobal(false) +{ + connect(dataTable,SIGNAL(itemSelectionChanged()), this,SLOT(workspaceSelectionChanged())); + connect(dataTable,SIGNAL(cellChanged(int,int)),this,SLOT(updateDataset(int,int))); +} + +/** + * Show a dialog to select a workspace from the ADS. + */ +void DataController::addWorkspace() +{ + AddWorkspaceDialog dialog(owner()); + if ( dialog.exec() == QDialog::Accepted ) + { + QString wsName = dialog.workspaceName().stripWhiteSpace(); + // if name is empty assume that there are no workspaces in the ADS + if ( wsName.isEmpty() ) return; + if ( Mantid::API::AnalysisDataService::Instance().doesExist( wsName.toStdString()) ) + { + auto ws = Mantid::API::AnalysisDataService::Instance().retrieveWS<Mantid::API::MatrixWorkspace>( wsName.toStdString() ); + auto indices = dialog.workspaceIndices(); + for(auto i = indices.begin(); i != indices.end(); ++i) + { + addWorkspaceSpectrum( wsName, *i, *ws ); + } + emit dataTableUpdated(); + } + else + { + QMessageBox::warning(owner(),"MantidPlot - Warning",QString("Workspace \"%1\" doesn't exist.").arg(wsName)); + } + } +} + +/** + * Add a spectrum from a workspace to the table. + * @param wsName :: Name of a workspace. + * @param wsIndex :: Index of a spectrum in the workspace (workspace index). + * @param ws :: The workspace. + */ +void DataController::addWorkspaceSpectrum(const QString &wsName, int wsIndex, const Mantid::API::MatrixWorkspace& ws) +{ + int row = m_dataTable->rowCount(); + m_dataTable->insertRow(row); + + auto cell = new QTableWidgetItem( wsName ); + m_dataTable->setItem( row, wsColumn, cell ); + auto flags = cell->flags(); + flags ^= Qt::ItemIsEditable; + cell->setFlags(flags); + + cell = new QTableWidgetItem( QString::number(wsIndex) ); + m_dataTable->setItem( row, wsIndexColumn, cell ); + flags = cell->flags(); + flags ^= Qt::ItemIsEditable; + cell->setFlags(flags); + + const double startX = ws.readX(wsIndex).front(); + cell = new QTableWidgetItem( QString::number(startX) ); + m_dataTable->setItem( row, startXColumn, cell ); + + const double endX = ws.readX(wsIndex).back(); + cell = new QTableWidgetItem( QString::number(endX) ); + m_dataTable->setItem( row, endXColumn, cell ); +} + +/** + * Slot. Called when selection in the data table changes. + */ +void DataController::workspaceSelectionChanged() +{ + auto selection = m_dataTable->selectionModel(); + bool enableRemoveButton = selection->hasSelection(); + if ( enableRemoveButton ) + { + enableRemoveButton = selection->selectedRows().size() > 0; + } + + emit hasSelection(enableRemoveButton); +} + +/** + * Slot. Called when "Remove" button is pressed. + */ +void DataController::removeSelectedSpectra() +{ + auto ranges = m_dataTable->selectedRanges(); + if ( ranges.isEmpty() ) return; + std::vector<int> rows; + for(auto range = ranges.begin(); range != ranges.end(); ++range) + { + for(int row = range->topRow(); row <= range->bottomRow(); ++row) + { + rows.push_back( row ); + } + } + removeDataSets( rows ); +} + +void DataController::removeDataSets( std::vector<int>& rows ) +{ + if ( rows.empty() ) return; + std::sort( rows.begin(), rows.end() ); + for(auto row = rows.rbegin(); row != rows.rend(); ++row) + { + m_dataTable->removeRow( *row ); + } + emit dataTableUpdated(); +} + +/** + * Check that the data sets in the table are valid and remove invalid ones. + */ +void DataController::checkDataSets() { std::vector<int> rows; int nrows = getNumberOfSpectra(); @@ -1157,15 +1397,82 @@ void MultiDatasetFit::checkDataSets() removeDataSets( rows ); } -void MultiDatasetFit::removeDataSets( std::vector<int>& rows ) +/** + * Get the workspace name of the i-th spectrum. + * @param i :: Index of a spectrum in the data table. + */ +std::string DataController::getWorkspaceName(int i) const { - if ( rows.empty() ) return; - std::sort( rows.begin(), rows.end() ); - for(auto row = rows.rbegin(); row != rows.rend(); ++row) + return m_dataTable->item(i, wsColumn)->text().toStdString(); +} + +/** + * Get the workspace index of the i-th spectrum. + * @param i :: Index of a spectrum in the data table. + */ +int DataController::getWorkspaceIndex(int i) const +{ + return m_dataTable->item(i, wsIndexColumn)->text().toInt(); +} + +/** + * Get the number of spectra to fit to. + */ +int DataController::getNumberOfSpectra() const +{ + return m_dataTable->rowCount(); +} + +/** + * Enable global setting of fitting range (calls to setFittingRage(...) + * will set ranges of all datasets.) + * @param on :: True for global setting, false for individual. + */ +void DataController::setFittingRangeGlobal(bool on) +{ + m_isFittingRangeGlobal = on; +} + +/** + * Set the fitting range for a data set or all data sets. + * @param i :: Index of a data set (spectrum). If m_isFittingRangeGlobal == true + * the index is ignored and fitting range is set for all spectra. + * @param startX :: Start of the fitting range. + * @param endX :: End of the fitting range. + */ +void DataController::setFittingRange(int i, double startX, double endX) +{ + if ( i < 0 || i >= m_dataTable->rowCount() ) return; + auto start = QString::number(startX); + auto end = QString::number(endX); + if ( m_isFittingRangeGlobal ) { - m_uiForm.dataTable->removeRow( *row ); + for(int k = 0; k < getNumberOfSpectra(); ++k) + { + m_dataTable->item(k, startXColumn)->setText(start); + m_dataTable->item(k, endXColumn)->setText(end); + } } - emit dataTableUpdated(); + else + { + m_dataTable->item(i, startXColumn)->setText(start); + m_dataTable->item(i, endXColumn)->setText(end); + } +} + +/// Get the fitting range for a i-th data set. +/// @param i :: Index of a dataset. +std::pair<double,double> DataController::getFittingRange(int i) const +{ + double startX = m_dataTable->item(i, startXColumn)->text().toDouble(); + double endX = m_dataTable->item(i, endXColumn)->text().toDouble(); + return std::make_pair(startX,endX); +} + +/// Inform the others that a dataset was updated. +void DataController::updateDataset(int row, int) +{ + emit dataSetUpdated(row); } void MultiDatasetFit::loadSettings() diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCBaselineModellingView.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCBaselineModellingView.cpp index 4c285e12dfc91e8a8de065e898c3757e13095beb..136de6465559dbb12334db32d3f0c59af23b1c4b 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCBaselineModellingView.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCBaselineModellingView.cpp @@ -3,6 +3,7 @@ #include "MantidAPI/FunctionFactory.h" #include "MantidAPI/FunctionDomain1D.h" #include "MantidAPI/AlgorithmManager.h" +#include "MantidQtAPI/HelpWindow.h" #include <boost/scoped_array.hpp> @@ -63,6 +64,8 @@ namespace CustomInterfaces connect(m_ui.sections, SIGNAL(cellChanged(int,int)), SIGNAL(sectionRowModified(int))); connect(m_selectorModifiedMapper, SIGNAL(mapped(int)), SIGNAL(sectionSelectorModified(int))); + + connect(m_ui.help, SIGNAL(clicked()), this, SLOT(help())); } QString ALCBaselineModellingView::function() const @@ -201,5 +204,9 @@ namespace CustomInterfaces selector->setMaximum(values.second); } + void ALCBaselineModellingView::help() { + MantidQt::API::HelpWindow::showCustomInterface(NULL, QString("Muon_ALC")); + } + } // namespace CustomInterfaces } // namespace MantidQt diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingPresenter.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingPresenter.cpp index 4205e4ba18f50bbfe01db08d98a18d0b4e8c5375..1e42a20b0d5a59e29a08c47d4a832bb993333f5f 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingPresenter.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingPresenter.cpp @@ -9,6 +9,7 @@ #include <QApplication> #include <QFileInfo> #include <QDir> +#include <sstream> using namespace Mantid::Kernel; using namespace Mantid::API; @@ -35,6 +36,22 @@ namespace CustomInterfaces { m_view->setWaitingCursor(); + // Check time limits + if (auto timeRange = m_view->timeRange()) { + + double tmin = (*timeRange).first; + double tmax = (*timeRange).second; + if ( tmin >= tmax ){ + m_view->restoreCursor(); + m_view->displayError("Invalid time interval"); + return; + } + } else { + m_view->restoreCursor(); + m_view->displayError("No time interval"); + return; + } + try { IAlgorithm_sptr alg = AlgorithmManager::Instance().create("PlotAsymmetryByLogValue"); @@ -120,6 +137,7 @@ namespace CustomInterfaces { m_view->setAvailableLogs(std::vector<std::string>()); // Empty logs list m_view->setAvailablePeriods(std::vector<std::string>()); // Empty period list + m_view->setTimeLimits(0,0); // "Empty" time limits return; } @@ -139,9 +157,16 @@ namespace CustomInterfaces std::vector<std::string> periods; for (size_t i=0; i<numPeriods; i++) { - periods.push_back(std::to_string(static_cast<long long int>(i)+1)); + std::stringstream buffer; + buffer << i + 1; + periods.push_back(buffer.str()); } m_view->setAvailablePeriods(periods); + + // Set time limits + m_view->setTimeLimits(ws->readX(0).front(),ws->readX(0).back()); + // Set allowed time range + m_view->setTimeRange (ws->readX(0).front(),ws->readX(0).back()); } } // namespace CustomInterfaces diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingView.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingView.cpp index 5dc2f6910a3da63766491e0ff97c7c0660023574..6cea3759e0f926c01a1289b7d673dd3100963327 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingView.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingView.cpp @@ -1,5 +1,7 @@ #include "MantidQtCustomInterfaces/Muon/ALCDataLoadingView.h" +#include "MantidQtAPI/HelpWindow.h" + #include <QMessageBox> #include <qwt_symbol.h> @@ -18,6 +20,8 @@ namespace CustomInterfaces connect(m_ui.load, SIGNAL(clicked()), SIGNAL(loadRequested())); connect(m_ui.firstRun, SIGNAL(fileFindingFinished()), SIGNAL(firstRunSelected())); + connect(m_ui.help, SIGNAL(clicked()), this, SLOT(help())); + m_ui.dataPlot->setCanvasBackground(Qt::white); m_ui.dataPlot->setAxisFont(QwtPlot::xBottom, m_widget->font()); m_ui.dataPlot->setAxisFont(QwtPlot::yLeft, m_widget->font()); @@ -118,15 +122,8 @@ namespace CustomInterfaces boost::optional< std::pair<double,double> > ALCDataLoadingView::timeRange() const { - if (m_ui.timeLimit->isChecked()) - { - auto range = std::make_pair(m_ui.minTime->value(), m_ui.maxTime->value()); - return boost::make_optional(range); - } - else - { - return boost::none; - } + auto range = std::make_pair(m_ui.minTime->value(), m_ui.maxTime->value()); + return boost::make_optional(range); } void ALCDataLoadingView::setDataCurve(const QwtData& data) @@ -166,6 +163,28 @@ namespace CustomInterfaces } } + void ALCDataLoadingView::setTimeLimits(double tMin, double tMax) + { + // Set initial values + m_ui.minTime->setValue(tMin); + m_ui.maxTime->setValue(tMax); + } + + void ALCDataLoadingView::setTimeRange(double tMin, double tMax) + { + // Set range for minTime + m_ui.minTime->setMinimum(tMin); + m_ui.minTime->setMaximum(tMax); + // Set range for maxTime + m_ui.maxTime->setMinimum(tMin); + m_ui.maxTime->setMaximum(tMax); + } + + void ALCDataLoadingView::help() + { + MantidQt::API::HelpWindow::showCustomInterface(NULL, QString("Muon_ALC")); + } + void ALCDataLoadingView::setWaitingCursor() { QApplication::setOverrideCursor(Qt::WaitCursor); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCInterface.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCInterface.cpp index cfcce6e7aaef299491d61ac6a85b5f2f25b14f71..4de693e73db68b5a1563337d426d0c040a396f37 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCInterface.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCInterface.cpp @@ -15,7 +15,7 @@ namespace MantidQt { namespace CustomInterfaces { - DECLARE_SUBWINDOW(ALCInterface); + DECLARE_SUBWINDOW(ALCInterface) const QStringList ALCInterface::STEP_NAMES = QStringList() << "Data loading" << "Baseline modelling" << "Peak fitting"; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCPeakFittingView.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCPeakFittingView.cpp index 99c3f9ca4815814572a2e471d720fdf484f25ce6..d8183fe40bf20cce35c5a291c4c6d091cfea6cd6 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCPeakFittingView.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCPeakFittingView.cpp @@ -1,5 +1,7 @@ #include "MantidQtCustomInterfaces/Muon/ALCPeakFittingView.h" +#include "MantidQtAPI/HelpWindow.h" + #include <qwt_symbol.h> namespace MantidQt @@ -54,6 +56,8 @@ void ALCPeakFittingView::initialize() connect(m_ui.peaks, SIGNAL(currentFunctionChanged()), SIGNAL(currentFunctionChanged())); connect(m_ui.peaks, SIGNAL(parameterChanged(QString,QString)), SIGNAL(parameterChanged(QString,QString))); + + connect(m_ui.help, SIGNAL(clicked()), this, SLOT(help())); } void ALCPeakFittingView::setDataCurve(const QwtData& data) @@ -100,6 +104,11 @@ void ALCPeakFittingView::setPeakPicker(const IPeakFunction_const_sptr& peak) m_ui.plot->replot(); } +void ALCPeakFittingView::help() +{ + MantidQt::API::HelpWindow::showCustomInterface(NULL, QString("Muon_ALC")); +} + } // namespace CustomInterfaces } // namespace Mantid diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/MuonAnalysis.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/MuonAnalysis.cpp index 22c2f7fd75ae174cb3780ea84d4a835187038369..cb0ee68ee1a4ae2db334523a394655418f9b1c32 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/MuonAnalysis.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/MuonAnalysis.cpp @@ -63,7 +63,7 @@ namespace MantidQt { namespace CustomInterfaces { - DECLARE_SUBWINDOW(MuonAnalysis); + DECLARE_SUBWINDOW(MuonAnalysis) using namespace Mantid::API; using namespace Mantid::Kernel; @@ -1999,15 +1999,12 @@ void MuonAnalysis::plotSpectrum(const QString& wsName, bool logScale) { QStringList& s = acquireWindowScript; // To keep short - s << "w = graph('%WSNAME%-1')"; - s << "if w == None:"; - s << " pw = newGraph('%WSNAME%', 0)"; - s << " w = plotSpectrum('%WSNAME%', 0, %ERRORS%, %CONNECT%, window = pw)"; - s << " w.setObjectName('%WSNAME%')"; - s << "else:"; - s << " plotSpectrum('%WSNAME%', 0, %ERRORS%, %CONNECT%, window = w, clearWindow = True)"; - s << " w.show()"; - s << " w.setFocus()"; + s << "pw = newGraph('%WSNAME%-1', 0)"; + s << "w = plotSpectrum('%WSNAME%', 0, %ERRORS%, %CONNECT%, window = pw, clearWindow = True)"; + s << "w.setName('%WSNAME%-1')"; + s << "w.setObjectName('%WSNAME%')"; + s << "w.show()"; + s << "w.setFocus()"; } QString pyS; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/QtReflMainView.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/QtReflMainView.cpp index 7882684398a58cd2c7b56a8589207ad780db5f78..11776a19d3524bc3b89477d470504c222530fce1 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/QtReflMainView.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/QtReflMainView.cpp @@ -14,7 +14,7 @@ namespace MantidQt { using namespace Mantid::API; - DECLARE_SUBWINDOW(QtReflMainView); + DECLARE_SUBWINDOW(QtReflMainView) //---------------------------------------------------------------------------------------------- /** Constructor diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/SANSRunWindow.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/SANSRunWindow.cpp index 38d14813a3a4e3d4fdd135749a87bdba4b5442ea..10c42a32c5867dcb7f7a617adea1f1523b80f563 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/SANSRunWindow.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/SANSRunWindow.cpp @@ -59,7 +59,7 @@ namespace MantidQt { namespace CustomInterfaces { - DECLARE_SUBWINDOW(SANSRunWindow); + DECLARE_SUBWINDOW(SANSRunWindow) using namespace MantidQt::MantidWidgets; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/SampleTransmission.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/SampleTransmission.cpp index c44be8a5c1cd9b77393efe04622e08e3c2b54826..6a95f432c7da1345f3a802eb4e3acd13ac4e67b7 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/SampleTransmission.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/SampleTransmission.cpp @@ -19,7 +19,7 @@ namespace MantidQt { namespace CustomInterfaces { - DECLARE_SUBWINDOW(SampleTransmission); + DECLARE_SUBWINDOW(SampleTransmission) } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/StepScan.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/StepScan.cpp index 1281594d11f4654e9cd96fd8aeaed82e0bfc01ad..9b5df3cf3c275fdc4fe4cd28b84d9f92c3d07016 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/StepScan.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/StepScan.cpp @@ -21,7 +21,7 @@ namespace CustomInterfaces { //Register the class with the factory -DECLARE_SUBWINDOW(StepScan); +DECLARE_SUBWINDOW(StepScan) using namespace Mantid::Kernel; using namespace Mantid::API; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/test/ALCBaselineModellingPresenterTest.h b/Code/Mantid/MantidQt/CustomInterfaces/test/ALCBaselineModellingPresenterTest.h index 85159616f13a2f3cc86a4925e6f8873180a3c78d..f597c130acc03d277b07949bdd246fe917c017ec 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/test/ALCBaselineModellingPresenterTest.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/test/ALCBaselineModellingPresenterTest.h @@ -49,6 +49,8 @@ public: MOCK_METHOD3(updateSectionSelector, void(size_t, double, double)); MOCK_METHOD1(displayError, void(const QString&)); + + MOCK_METHOD0(help, void()); }; class MockALCBaselineModellingModel : public IALCBaselineModellingModel @@ -338,6 +340,12 @@ public: m_view->requestFit(); } + + void test_helpPage () + { + EXPECT_CALL(*m_view, help()).Times(1); + m_view->help(); + } }; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/test/ALCDataLoadingPresenterTest.h b/Code/Mantid/MantidQt/CustomInterfaces/test/ALCDataLoadingPresenterTest.h index b0f54ee8d647e0465f75cd03804d1e91fde0b2ee..e61879312c74af0428c2825ca5acd6ba8308326c 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/test/ALCDataLoadingPresenterTest.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/test/ALCDataLoadingPresenterTest.h @@ -48,8 +48,11 @@ public: MOCK_METHOD1(displayError, void(const std::string&)); MOCK_METHOD1(setAvailableLogs, void(const std::vector<std::string>&)); MOCK_METHOD1(setAvailablePeriods, void(const std::vector<std::string>&)); + MOCK_METHOD2(setTimeLimits, void(double,double)); + MOCK_METHOD2(setTimeRange, void(double,double)); MOCK_METHOD0(setWaitingCursor, void()); MOCK_METHOD0(restoreCursor, void()); + MOCK_METHOD0(help, void()); void requestLoading() { emit loadRequested(); } void selectFirstRun() { emit firstRunSelected(); } @@ -85,7 +88,7 @@ public: ON_CALL(*m_view, lastRun()).WillByDefault(Return("MUSR00015191.nxs")); ON_CALL(*m_view, calculationType()).WillByDefault(Return("Integral")); ON_CALL(*m_view, log()).WillByDefault(Return("sample_magn_field")); - ON_CALL(*m_view, timeRange()).WillByDefault(Return(boost::none)); + ON_CALL(*m_view, timeRange()).WillByDefault(Return(boost::make_optional(std::make_pair(-6.0,32.0)))); ON_CALL(*m_view, deadTimeType()).WillByDefault(Return("None")); ON_CALL(*m_view, detectorGroupingType()).WillByDefault(Return("Auto")); ON_CALL(*m_view, redPeriod()).WillByDefault(Return("1")); @@ -260,6 +263,12 @@ public: QwtDataY(2, 0.038717, 1E-6)))); m_view->requestLoading(); } + + void test_helpPage () + { + EXPECT_CALL(*m_view, help()).Times(1); + m_view->help(); + } }; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/test/ALCPeakFittingPresenterTest.h b/Code/Mantid/MantidQt/CustomInterfaces/test/ALCPeakFittingPresenterTest.h index 192811e0ab1502ca2c7f78c14a22c9c62f7fa336..36b8851b2caf33b3371c1e855787d6afe2417340 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/test/ALCPeakFittingPresenterTest.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/test/ALCPeakFittingPresenterTest.h @@ -50,6 +50,7 @@ public: MOCK_METHOD1(setPeakPicker, void(const IPeakFunction_const_sptr&)); MOCK_METHOD1(setFunction, void(const IFunction_const_sptr&)); MOCK_METHOD3(setParameter, void(const QString&, const QString&, double)); + MOCK_METHOD0(help, void()); }; class MockALCPeakFittingModel : public IALCPeakFittingModel @@ -258,6 +259,12 @@ public: m_view->changeParameter(QString("f1"), QString("A0")); } + + void test_helpPage () + { + EXPECT_CALL(*m_view, help()).Times(1); + m_view->help(); + } }; diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MessageDisplay.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MessageDisplay.h index 5b5a1393bcb92a14c331b14694614fbb309b04df..11d940adb38fd2ad0ae43f9d9ff983fa584be371 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MessageDisplay.h +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MessageDisplay.h @@ -41,7 +41,7 @@ namespace MantidQt class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS MessageDisplay : public QWidget { Q_OBJECT - Q_PROPERTY(QString source READ source WRITE setSource); + Q_PROPERTY(QString source READ source WRITE setSource) public: /// Controls whether the display is allowed to set the log levels @@ -106,7 +106,7 @@ namespace MantidQt void setGlobalLogLevel(int priority); private: - Q_DISABLE_COPY(MessageDisplay); + Q_DISABLE_COPY(MessageDisplay) /// Setup the actions void initActions(); /// Initialize the text formats diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/PreviewPlot.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/PreviewPlot.h index 13250323b0455137caf1528d1cb21b6e26e1babb..b33d9f330f01014ba3af9be08736d10c90244c83 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/PreviewPlot.h +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/PreviewPlot.h @@ -4,6 +4,7 @@ #include "ui_PreviewPlot.h" #include "WidgetDllOption.h" +#include "MantidQtMantidWidgets/RangeSelector.h" #include "MantidQtAPI/MantidWidget.h" #include "MantidAPI/MatrixWorkspace.h" @@ -11,6 +12,7 @@ #include <QActionGroup> #include <QHBoxLayout> #include <QLabel> +#include <QMap> #include <QMenu> #include <qwt_plot.h> @@ -81,10 +83,21 @@ namespace MantidWidgets bool hasCurve(const QString & curveName); + RangeSelector * addRangeSelector(const QString & rsName, + RangeSelector::SelectType type = RangeSelector::XMINMAX); + RangeSelector * getRangeSelector(const QString & rsName); + void removeRangeSelector(const QString & rsName, bool del); + + bool hasRangeSelector(const QString & rsName); + + QString getAxisType(int axisID); + signals: /// Signals that the plot should be refreshed void needToReplot(); void needToHardReplot(); + /// Signals that the axis scale has been changed + void axisScaleChanged(); public slots: void showLegend(bool show); @@ -118,7 +131,6 @@ namespace MantidWidgets QList<QAction *> addOptionsToMenus(QString menuName, QActionGroup *group, QStringList items, QString defaultItem); - QString getAxisType(int axisID); QStringList getCurvesForWorkspace(const Mantid::API::MatrixWorkspace_sptr ws); private slots: @@ -129,6 +141,11 @@ namespace MantidWidgets private: Ui::PreviewPlot m_uiForm; + /// Range selector widget for mini plot + QMap<QString, MantidQt::MantidWidgets::RangeSelector *> m_rangeSelectors; + /// Cache of range selector visibility + QMap<QString, bool> m_rsVisibility; + /// Poco Observers for ADS Notifications Poco::NObserver<PreviewPlot, Mantid::API::WorkspacePreDeleteNotification> m_removeObserver; Poco::NObserver<PreviewPlot, Mantid::API::WorkspaceAfterReplaceNotification> m_replaceObserver; @@ -136,7 +153,6 @@ namespace MantidWidgets /// If the widget was initialised bool m_init; - /// The plot its self friend class RangeSelector; /// Map of curve key to plot info diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/RangeSelector.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/RangeSelector.h index 0b16b896cdcef8ec2005359653ddd98df9a21604..38c4235775d9da75a4c95fdf405c6ccbef1e902d 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/RangeSelector.h +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/RangeSelector.h @@ -2,7 +2,6 @@ #define MANTIDQT_MANTIDWIDGET_POSHPLOTTING_H #include "WidgetDllOption.h" -#include "PreviewPlot.h" #include <qwt_plot_picker.h> #include <qwt_plot.h> @@ -14,6 +13,8 @@ namespace MantidQt { namespace MantidWidgets { + class PreviewPlot; + /** * Allows for simpler (in a way) selection of a range on a QwtPlot in MantidQt. * @author Michael Whitty, RAL ISIS @@ -35,6 +36,9 @@ namespace MantidWidgets double getMinimum() { return m_min; } ///< Returns current min value double getMaximum() { return m_max; } ///< Reutnrs current max value + SelectType getType() { return m_type; } + bool isVisible() { return m_visible; } + signals: void minValueChanged(double); void maxValueChanged(double); diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/ScriptEditor.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/ScriptEditor.h index db4b9699f40ad2a60784a5fd150877212a23173f..357f91374e038b9e1d2733a6549e161b1376583f 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/ScriptEditor.h +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/ScriptEditor.h @@ -81,7 +81,7 @@ private: class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS ScriptEditor : public QsciScintilla { // Qt macro - Q_OBJECT; + Q_OBJECT public: /** diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/DataSelector.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/DataSelector.cpp index 7b0f2ae93709cdbff11739a31e0c495f8e050b10..cad804da02199856bfdf4a15bdb0f676bb4286e4 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/DataSelector.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/DataSelector.cpp @@ -24,7 +24,7 @@ namespace MantidQt connect(m_uiForm.pbLoadFile, SIGNAL(clicked()), this, SIGNAL(loadClicked())); //data selected changes - connect(m_uiForm.rfFileInput, SIGNAL(filesFound()), this, SLOT(handleFileInput())); + connect(m_uiForm.rfFileInput, SIGNAL(filesFoundChanged()), this, SLOT(handleFileInput())); connect(m_uiForm.wsWorkspaceInput, SIGNAL(currentIndexChanged(int)), this, SLOT(handleWorkspaceInput())); connect(m_uiForm.pbLoadFile, SIGNAL(clicked()), this, SLOT(handleFileInput())); @@ -66,7 +66,7 @@ namespace MantidQt /** * Get if the file selector is currently being shown. * - * @return :: true if it is visible, otherwise false + * @return :: true if it is visible, otherwise false */ bool DataSelector::isFileSelectorVisible() const { @@ -77,7 +77,7 @@ namespace MantidQt /** * Get if the workspace selector is currently being shown. * - * @return :: true if it is visible, otherwise false + * @return :: true if it is visible, otherwise false */ bool DataSelector::isWorkspaceSelectorVisible() const { @@ -107,7 +107,7 @@ namespace MantidQt if(isValid && m_autoLoad) { const QString wsName = getCurrentDataName(); - + if(!AnalysisDataService::Instance().doesExist(wsName.toStdString())) { //attempt to reload if we can @@ -118,9 +118,9 @@ namespace MantidQt loadAlg->setProperty("Filename", filepath.toStdString()); loadAlg->setProperty("OutputWorkspace", wsName.toStdString()); loadAlg->execute(); - + isValid = AnalysisDataService::Instance().doesExist(wsName.toStdString()); - + if(!isValid) { m_uiForm.rfFileInput->setFileProblem("The specified workspace is missing from the analysis data service"); @@ -448,18 +448,18 @@ namespace MantidQt */ void DataSelector::dropEvent(QDropEvent *de) { - const QMimeData *mimeData = de->mimeData(); + const QMimeData *mimeData = de->mimeData(); auto before_action = de->dropAction(); if (de->mimeData() && mimeData->text().contains(" = mtd[\"")){ m_uiForm.wsWorkspaceInput->dropEvent(de); - if (de->dropAction() == before_action){ + if (de->dropAction() == before_action){ m_uiForm.cbInputType->setCurrentIndex(1); return; } - de->setDropAction(before_action); + de->setDropAction(before_action); } - + m_uiForm.rfFileInput->dropEvent(de); if (de->dropAction() == before_action){ m_uiForm.cbInputType->setCurrentIndex(0); diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/PreviewPlot.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/PreviewPlot.cpp index b235a39355910a550a22584e52e0c94e01a5e8d2..2d239741f84dedb88b01c8f8884f92e94974da74 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/PreviewPlot.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/PreviewPlot.cpp @@ -5,7 +5,6 @@ #include "MantidAPI/AnalysisDataService.h" #include "MantidAPI/AlgorithmManager.h" -#include "MantidQtAPI/QwtWorkspaceSpectrumData.h" #include <Poco/Notification.h> #include <Poco/NotificationCenter.h> @@ -17,6 +16,8 @@ #include <QPalette> #include <QVBoxLayout> +#include <qwt_array.h> +#include <qwt_data.h> #include <qwt_scale_engine.h> using namespace MantidQt::MantidWidgets; @@ -25,6 +26,7 @@ using namespace Mantid::API; namespace { Mantid::Kernel::Logger g_log("PreviewPlot"); + bool isNegative(double v) { return v <= 0.0; } } @@ -327,6 +329,71 @@ bool PreviewPlot::hasCurve(const QString & curveName) } +/** + * Creates a RangeSelector, adds it to the plot and stores it. + * + * @param rsName Name of range selector + * @param type Type of range selector to add + * @return RangeSelector object + */ +RangeSelector * PreviewPlot::addRangeSelector(const QString & rsName, + RangeSelector::SelectType type) +{ + if(hasRangeSelector(rsName)) + throw std::runtime_error("RangeSelector already exists on PreviewPlot"); + + m_rangeSelectors[rsName] = new MantidWidgets::RangeSelector(m_uiForm.plot, type); + m_rsVisibility[rsName] = m_rangeSelectors[rsName]->isVisible(); + + return m_rangeSelectors[rsName]; +} + + +/** + * Gets a RangeSelector. + * + * @param rsName Name of range selector + * @return RangeSelector object + */ +RangeSelector * PreviewPlot::getRangeSelector(const QString & rsName) +{ + if(!hasRangeSelector(rsName)) + throw std::runtime_error("RangeSelector not found on PreviewPlot"); + + return m_rangeSelectors[rsName]; +} + + +/** + * Removes a RangeSelector from the plot. + * + * @param rsName Name of range selector + * @param del If the object should be deleted + */ +void PreviewPlot::removeRangeSelector(const QString & rsName, bool del = true) +{ + if(!hasRangeSelector(rsName)) + return; + + if(del) + delete m_rangeSelectors[rsName]; + + m_rangeSelectors.remove(rsName); +} + + +/** + * Checks to see if a range selector with a given name is on the plot. + * + * @param rsName Name of range selector + * @return True if the plot has a range selector with the given name + */ +bool PreviewPlot::hasRangeSelector(const QString & rsName) +{ + return m_rangeSelectors.contains(rsName); +} + + /** * Shows or hides the plot legend. * @@ -531,11 +598,31 @@ QwtPlotCurve * PreviewPlot::addCurve(MatrixWorkspace_sptr ws, const size_t specI ws = convertXAlg->getProperty("OutputWorkspace"); } - // Create the plot data - QwtWorkspaceSpectrumData wsData(*ws, static_cast<int>(specIndex), false, false); + std::vector<double> wsDataY = ws->readY(specIndex); + + // If using log scale need to remove all negative Y values + bool logYScale = getAxisType(QwtPlot::yLeft) == "Logarithmic"; + if(logYScale) + { + // Remove negative data in order to search for minimum positive value + std::vector<double> validData(wsDataY.size()); + auto it = std::remove_copy_if(wsDataY.begin(), wsDataY.end(), validData.begin(), isNegative); + validData.resize(std::distance(validData.begin(), it)); + + // Get minimum positive value + double minY = *std::min_element(validData.begin(), validData.end()); + + // Set all negative values to minimum positive value + std::replace_if(wsDataY.begin(), wsDataY.end(), isNegative, minY); + } + + // Create the Qwt data + QwtArray<double> dataX = QVector<double>::fromStdVector(ws->readX(specIndex)); + QwtArray<double> dataY = QVector<double>::fromStdVector(wsDataY); + QwtArrayData wsData(dataX, dataY); // Create the new curve - QwtPlotCurve *curve = new QwtPlotCurve(); + QwtPlotCurve * curve = new QwtPlotCurve(); curve->setData(wsData); curve->setPen(curveColour); curve->attach(m_uiForm.plot); @@ -723,6 +810,31 @@ void PreviewPlot::handleAxisTypeSelect() if(yEngine) m_uiForm.plot->setAxisScaleEngine(QwtPlot::yLeft, yEngine); + emit axisScaleChanged(); + + // Hide range selectors on X axis when X axis scale is X^2 + bool xIsSquared = xAxisType == "Squared"; + for(auto it = m_rangeSelectors.begin(); it != m_rangeSelectors.end(); ++it) + { + QString rsName = it.key(); + RangeSelector * rs = it.value(); + RangeSelector::SelectType type = rs->getType(); + + if(type == RangeSelector:: XMINMAX || type == RangeSelector::XSINGLE) + { + // When setting to invisible save the last visibility setting + if(xIsSquared) + { + m_rsVisibility[rsName] = rs->isVisible(); + rs->setVisible(false); + } + else + { + rs->setVisible(m_rsVisibility[rsName]); + } + } + } + // Update the plot emit needToHardReplot(); } diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/RangeSelector.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/RangeSelector.cpp index 30334d6da2cbcb18b9c5d0a5c93a69c66db2c092..ad084ec45389bb207c207f52120a9241493d3287 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/RangeSelector.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/RangeSelector.cpp @@ -5,6 +5,8 @@ #include <QEvent> #include <QMouseEvent> +#include "MantidQtMantidWidgets/PreviewPlot.h" + using namespace MantidQt::MantidWidgets; RangeSelector::RangeSelector(QwtPlot* plot, SelectType type, bool visible, bool infoOnly) diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/SlicingAlgorithmDialog.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/SlicingAlgorithmDialog.cpp index e44a8a5f785d6a35a43608f091ed04f9679a54be..61a4e257246bafb4a8b61222f6f709c85e87ca92 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/SlicingAlgorithmDialog.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/SlicingAlgorithmDialog.cpp @@ -16,8 +16,8 @@ namespace MantidQt { namespace MantidWidgets { - DECLARE_DIALOG(SliceMDDialog); - DECLARE_DIALOG(BinMDDialog); + DECLARE_DIALOG(SliceMDDialog) + DECLARE_DIALOG(BinMDDialog) /** Constructor @@ -459,7 +459,7 @@ namespace MantidQt /** * Resets the axis dimensions externally. - * @param propertyName The name of the axis dimension. + * @param index The property index. * @param propertyValue The new value of the axis dimension. */ void SlicingAlgorithmDialog::resestAlignedDimProperty(size_t index, QString propertyValue) diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/pqHelpWindow.cxx b/Code/Mantid/MantidQt/MantidWidgets/src/pqHelpWindow.cxx index d1254e69fec2fa11108818d17da4150c03dd66fe..82bb4d84743c31afd9166d4a5a00469f8e949c6b 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/pqHelpWindow.cxx +++ b/Code/Mantid/MantidQt/MantidWidgets/src/pqHelpWindow.cxx @@ -170,7 +170,7 @@ protected: } private: - Q_DISABLE_COPY(pqNetworkAccessManager); + Q_DISABLE_COPY(pqNetworkAccessManager) }; // **************************************************************************** diff --git a/Code/Mantid/MantidQt/Python/CMakeLists.txt b/Code/Mantid/MantidQt/Python/CMakeLists.txt index 0624231af29b862ae944506786baf9f0deee4902..92a7f22f8f992ec7b5177a0d6c92fbc48b0afc6d 100644 --- a/Code/Mantid/MantidQt/Python/CMakeLists.txt +++ b/Code/Mantid/MantidQt/Python/CMakeLists.txt @@ -49,7 +49,7 @@ add_custom_command ( OUTPUT ${SIP_SRC} ) # Needed for sip.h header that can end up in a different place to to the main Python include directory -include_directories ( ${SIP_INCLUDE_DIR} ) +include_directories ( SYSTEM ${SIP_INCLUDE_DIR} ) # Needed for sip generated files to find includes in src include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ) diff --git a/Code/Mantid/MantidQt/Python/mantidqt.sip b/Code/Mantid/MantidQt/Python/mantidqt.sip index a4f514df9c8a9d020475ae54d72bdbdb5cdf156e..89b157802ef4eb028147b0af50470e9ab5506ac7 100644 --- a/Code/Mantid/MantidQt/Python/mantidqt.sip +++ b/Code/Mantid/MantidQt/Python/mantidqt.sip @@ -10,6 +10,12 @@ // Define the module name. This has to match the library filename %Module mantidqtpython +%UnitCode + #if defined(__GNUC__) && !(defined(__INTEL_COMPILER)) + #pragma GCC system_header + #endif +%End + /******************************** SIP Imports ****************/ %Import QtCore/QtCoremod.sip %Import QtGui/QtGuimod.sip diff --git a/Code/Mantid/MantidQt/Python/sip_mantidqt.cpp.in b/Code/Mantid/MantidQt/Python/sip_mantidqt.cpp.in index 6e64f1e2b3da4717fee67b9fdff519fba0d76517..c72a0a422afcb44d08b6b03ba779d2fab03d0fa7 100644 --- a/Code/Mantid/MantidQt/Python/sip_mantidqt.cpp.in +++ b/Code/Mantid/MantidQt/Python/sip_mantidqt.cpp.in @@ -1,13 +1,7 @@ -//------------------------------------------------------------------------------ -// A wrapper for the auto-generated sip*.cpp files to disable warnings -// that we can't control -//------------------------------------------------------------------------------ -#if defined(__GNUC__) && !(defined(__INTEL_COMPILER)) - #pragma GCC diagnostic ignored "-Wuninitialized" - #pragma GCC diagnostic ignored "-Wconversion" - #pragma GCC diagnostic ignored "-Wunused-variable" - #pragma GCC diagnostic ignored "-Wparentheses" - #pragma GCC diagnostic ignored "-Wcast-qual" -#endif - +//-------------------------------------------------------------------------------------- +// A wrapper for the auto-generated sipmantidqtpythonpart?.cpp files to disable warnings +// that we can't control. The warnings are actually suppressed in qti.sip +// with '#pragma GCC system_header' but that pragma only works if it occurs +// in a file that has been included with '#include' +//------------------------------------------------------------------------------------- #include "sipmantidqtpythonpart0.cpp" diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayViewFactorySelector.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayViewFactorySelector.h index bdd50ce73d422544a5f013e406419d1dac0de2fe..e4b413e2f8a9c343dc0d3c8be11154db5bbf9fd6 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayViewFactorySelector.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/PeakOverlayViewFactorySelector.h @@ -21,7 +21,7 @@ namespace MantidQt private: typedef std::set<PeakOverlayViewFactory_sptr> PeakOverlayViewFactorySet; PeakOverlayViewFactorySet m_candidates; - DISABLE_COPY_AND_ASSIGN(PeakOverlayViewFactorySelector); + DISABLE_COPY_AND_ASSIGN(PeakOverlayViewFactorySelector) public: PeakOverlayViewFactorySelector(); ~PeakOverlayViewFactorySelector(); diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/QPeaksTableModel.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/QPeaksTableModel.h index a95b7fd55e33f3b9a5593228fe0f8e1e1280fe60..775f269a859e69a905042904de78d53e56020326 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/QPeaksTableModel.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/QPeaksTableModel.h @@ -1,4 +1,5 @@ #include <QAbstractTableModel> +#include "DllOption.h" #include <boost/shared_ptr.hpp> #include "boost/bind.hpp" #include "boost/function.hpp" @@ -47,7 +48,7 @@ namespace MantidQt File change history is stored at: <https://github.com/mantidproject/mantid>. Code Documentation is available at: <http://doxygen.mantidproject.org> */ - class QPeaksTableModel : public QAbstractTableModel + class EXPORT_OPT_MANTIDQT_SLICEVIEWER QPeaksTableModel : public QAbstractTableModel { Q_OBJECT public: diff --git a/Code/Mantid/Testing/Data/DocTest/PawleySilicon.nxs.md5 b/Code/Mantid/Testing/Data/DocTest/PawleySilicon.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..dfb0fc386fc0b27d0792f7fdcc48840d77941bd6 --- /dev/null +++ b/Code/Mantid/Testing/Data/DocTest/PawleySilicon.nxs.md5 @@ -0,0 +1 @@ +f814c587c2dbe2df89b153f1ad95d4f6 diff --git a/Code/Mantid/Testing/Data/DocTest/PoldiCrystalFileExample.dat.md5 b/Code/Mantid/Testing/Data/DocTest/PoldiCrystalFileExample.dat.md5 new file mode 100644 index 0000000000000000000000000000000000000000..fb77808522c795bde838bad1aba33b5ddb7f8afb --- /dev/null +++ b/Code/Mantid/Testing/Data/DocTest/PoldiCrystalFileExample.dat.md5 @@ -0,0 +1 @@ +0a93f7213e39cf02f7cb7ddb27f4d6f9 diff --git a/Code/Mantid/Testing/Data/DocTest/irs26173_graphite002_red.nxs.md5 b/Code/Mantid/Testing/Data/DocTest/irs26173_graphite002_red.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..dd49338b31255373fb60d986554ea8a6ce46902c --- /dev/null +++ b/Code/Mantid/Testing/Data/DocTest/irs26173_graphite002_red.nxs.md5 @@ -0,0 +1 @@ +f52ac64ec23fb50b6d4649592aee4fdb \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/DocTest/irs26176_graphite002_conv_2LFixF_s0_to_9_Result.nxs.md5 b/Code/Mantid/Testing/Data/DocTest/irs26176_graphite002_conv_2LFixF_s0_to_9_Result.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..39b449b5e2f2c76935a29871f597067e6a12ba01 --- /dev/null +++ b/Code/Mantid/Testing/Data/DocTest/irs26176_graphite002_conv_2LFixF_s0_to_9_Result.nxs.md5 @@ -0,0 +1 @@ +f1e31d0b4e7b40f4e8777c2653892df2 diff --git a/Code/Mantid/Testing/Data/DocTest/irs26176_graphite002_cyl_Abs.nxs.md5 b/Code/Mantid/Testing/Data/DocTest/irs26176_graphite002_cyl_Abs.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..98a9172ca63dedcff46b07b47068f93ff1951a2b --- /dev/null +++ b/Code/Mantid/Testing/Data/DocTest/irs26176_graphite002_cyl_Abs.nxs.md5 @@ -0,0 +1 @@ +f4b31e993d1747f22074cd17365cf0eb \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/DocTest/irs26176_graphite002_red.nxs.md5 b/Code/Mantid/Testing/Data/DocTest/irs26176_graphite002_red.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..1c698d0a291b8ff23c2663d216bc8082b9061928 --- /dev/null +++ b/Code/Mantid/Testing/Data/DocTest/irs26176_graphite002_red.nxs.md5 @@ -0,0 +1 @@ +a69078cfcdf156b59327798cc71f4d51 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/REF_L_119690_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/REF_L_119690_event.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..b6a45fd7261ef11bd82a7a9940b308d54ad4c0a8 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/REF_L_119690_event.nxs.md5 @@ -0,0 +1 @@ +79694adb3d0d8a7573e0d9b0ff210edc diff --git a/Code/Mantid/Testing/Data/SystemTest/REF_L_119814_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/REF_L_119814_event.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..e25141c4c3c67967dcd18a50e4b17f0d0e85ae14 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/REF_L_119814_event.nxs.md5 @@ -0,0 +1 @@ +43d80c791f44419e242ec2e5ff34ec46 diff --git a/Code/Mantid/Testing/Data/SystemTest/directBeamDatabaseFall2014_IPTS_11601_2.cfg.md5 b/Code/Mantid/Testing/Data/SystemTest/directBeamDatabaseFall2014_IPTS_11601_2.cfg.md5 new file mode 100644 index 0000000000000000000000000000000000000000..5c1e010c0bbeae3ea7efc981bbad3e2e81d6ccb2 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/directBeamDatabaseFall2014_IPTS_11601_2.cfg.md5 @@ -0,0 +1 @@ +0f14c83d41bad464038778d2dd02424d diff --git a/Code/Mantid/Testing/Data/UnitTest/dn134011vana.d_dat.md5 b/Code/Mantid/Testing/Data/UnitTest/dn134011vana.d_dat.md5 new file mode 100644 index 0000000000000000000000000000000000000000..e99469630d6e0dcdb7a224f83817cb20eb2d2a24 --- /dev/null +++ b/Code/Mantid/Testing/Data/UnitTest/dn134011vana.d_dat.md5 @@ -0,0 +1 @@ +28151e3198f9f57b18b97d87627eadf6 diff --git a/Code/Mantid/Testing/Data/UnitTest/irs26173_graphite002_res.nxs.md5 b/Code/Mantid/Testing/Data/UnitTest/irs26173_graphite002_res.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..f8094ffb61e4994fb5350f25c238d1d2730c85b6 --- /dev/null +++ b/Code/Mantid/Testing/Data/UnitTest/irs26173_graphite002_res.nxs.md5 @@ -0,0 +1 @@ +4a322a634e527c87fbef27f1cc9559d2 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/UnitTest/irs26176_graphite002_cyl_Abs.nxs.md5 b/Code/Mantid/Testing/Data/UnitTest/irs26176_graphite002_cyl_Abs.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..98a9172ca63dedcff46b07b47068f93ff1951a2b --- /dev/null +++ b/Code/Mantid/Testing/Data/UnitTest/irs26176_graphite002_cyl_Abs.nxs.md5 @@ -0,0 +1 @@ +f4b31e993d1747f22074cd17365cf0eb \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/CodeConventions.py b/Code/Mantid/Testing/SystemTests/tests/analysis/CodeConventions.py index ceb618874de196fe64eb1c4b9a26fd5a50983f53..b87cc677be768a642d06adbc26f83ca5e8405fba 100644 --- a/Code/Mantid/Testing/SystemTests/tests/analysis/CodeConventions.py +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/CodeConventions.py @@ -53,7 +53,9 @@ FUNC_BAD_PARAMS = { "f0_Xoffset", "f0_Yoffset", "f0_Zoffset", "f0_Xrot", "f0_Yrot", "f0_Zrot", "l0", "t0"), - "StretchedExpFT":("height", "tau", "beta") + "StretchedExpFT":("height", "tau", "beta"), + "PawleyParameterFunction":("a","b","c"), + "PawleyFunction":("f0.a","f0.b","f0.c", "f0.Alpha", "f0.Beta", "f0.Gamma", "f0.ZeroShift"), } class Algorithms(stresstesting.MantidStressTest): diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISDirectReductionComponents.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISDirectReductionComponents.py index a7677cb70662eaf5ea25d44a2ce71d15b1064a23..1e556601d2e32ba363d7564ffeecaf87e2a3c8a8 100644 --- a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISDirectReductionComponents.py +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISDirectReductionComponents.py @@ -136,6 +136,8 @@ class ISISLoadFilesRAW(stresstesting.MantidStressTest): self.assertTrue(isinstance(ws,Workspace)) self.assertEqual(ws.getNumberHistograms(),41472) self.assertEqual(mon_ws.getNumberHistograms(),4) + + # self.valid = True @@ -180,26 +182,36 @@ class ISISLoadFilesMER(stresstesting.MantidStressTest): propman.sample_run = 18492 # (histogram nxs file ) propman.det_cal_file = None mon_ws = PropertyManager.sample_run.get_monitors_ws() + self.assertTrue('SR_MER018492' in mtd) self.assertTrue(not mon_ws is None) ws = PropertyManager.sample_run.get_workspace() self.assertTrue(isinstance(ws,Workspace)) self.assertEqual(ws.getNumberHistograms(),69641) self.assertEqual(mon_ws.getNumberHistograms(),69641) + self.assertEqual(mon_ws.getIndexFromSpectrumNumber(69638),69637) + det = mon_ws.getDetector(69632) + self.assertTrue(det.isMonitor()) + det = mon_ws.getDetector(69631) + self.assertFalse(det.isMonitor()) - self.valid = True - return # enable when bug #10980 is fixed + propman.sample_run = None # delete all + self.assertFalse('SR_MER018492' in mtd) propman.sample_run = 18492 # (histogram nxs file ) + propman.load_monitors_with_workspace = False propman.det_cal_file = None mon_ws = PropertyManager.sample_run.get_monitors_ws() self.assertTrue(not mon_ws is None) + self.assertTrue('SR_MER018492_monitors' in mtd) ws = PropertyManager.sample_run.get_workspace() self.assertTrue(isinstance(ws,Workspace)) self.assertEqual(ws.getNumberHistograms(),69632) self.assertEqual(mon_ws.getNumberHistograms(),9) - + self.assertEqual(mon_ws.getIndexFromSpectrumNumber(69633),0) + det = mon_ws.getDetector(0) + self.assertTrue(det.isMonitor()) self.valid = True diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectAnalysisTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectAnalysisTest.py index 92e54edd1f4c9c1eca7134d7de9d1643a8513d76..774a0101e46685db6ce92d70767383206c150145 100644 --- a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectAnalysisTest.py +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectAnalysisTest.py @@ -9,23 +9,20 @@ class ElasticWindowMultipleTest(stresstesting.MantidStressTest): def runTest(self): Load(Filename='osi92762_graphite002_red.nxs,osi92763_graphite002_red.nxs', - OutputWorkspace='__ElWinMulti_InputWS') + OutputWorkspace='__ElWinMulti_InputWS') - ElasticWindowMultiple( - InputWorkspaces='__ElWinMulti_InputWS', - Range1Start=-0.2, - Range1End=0.2, - Range2Start='-0.24', - Range2End='-0.22', - OutputInQ='eq', - OutputInQSquared='eq2', - OutputELF='elf', - OutputELT='elt') + ElasticWindowMultiple(InputWorkspaces='__ElWinMulti_InputWS', + Range1Start=-0.2, + Range1End=0.2, + Range2Start='-0.24', + Range2End='-0.22', + OutputInQ='eq', + OutputInQSquared='eq2', + OutputELF='elf', + OutputELT='elt') GroupWorkspaces(InputWorkspaces=['elf', 'elt'], - OutputWorkspace='__ElWinMulti_OutputWS') - - SaveNexus(Filename='__ElWinMulti_OutputWS', InputWorkspace='__ElWinMulti_OutputWS') + OutputWorkspace='__ElWinMulti_OutputWS') def validate(self): self.tolerance = 1e-10 diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py index 435a08ab9b57efa6a6f9488bfd88a5ae54f4ce12..60c6e04a961de78ed7c22d955ade098454380b06 100644 --- a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py @@ -11,8 +11,7 @@ from mantid.api import FileFinder # Import our workflows. from inelastic_indirect_reducer import IndirectReducer -from inelastic_indirect_reduction_steps import CreateCalibrationWorkspace -from IndirectDataAnalysis import msdfit, furyfitSeq, furyfitMult, confitSeq, abscorFeeder +from IndirectDataAnalysis import furyfitSeq, furyfitMult, confitSeq, abscorFeeder ''' - TOSCA only supported by "Reduction" (the Energy Transfer tab of C2E). @@ -468,11 +467,11 @@ class ISISIndirectInelasticCalibration(ISISIndirectInelasticBase): self.result_names = ['IndirectCalibration_Output'] - CreateCalibrationWorkspace(InputFiles=self.data_file, - OutputWorkspace='IndirectCalibration_Output', - DetectorRange=self.detector_range, - PeakRange=self.peak, - BackgroundRange=self.back) + IndirectCalibration(InputFiles=self.data_file, + OutputWorkspace='IndirectCalibration_Output', + DetectorRange=self.detector_range, + PeakRange=self.peak, + BackgroundRange=self.back) def _validate_properties(self): '''Check the object properties are in an expected state to continue''' @@ -683,7 +682,7 @@ class OSIRISDiagnostics(ISISIndirectInelasticDiagnostics): #============================================================================== class ISISIndirectInelasticMoments(ISISIndirectInelasticBase): - '''A base class for the ISIS indirect inelastic Fury/FuryFit tests + '''A base class for the ISIS indirect inelastic TransformToIqt/TransformToIqtFit tests The output of Elwin is usually used with MSDFit and so we plug one into the other in this test. @@ -780,21 +779,12 @@ class ISISIndirectInelasticElwinAndMSDFit(ISISIndirectInelasticBase): InputWorkspace=ws) eq2_file = elwin_results[1] - msdfit_result = msdfit(eq2_file, - startX=self.startX, - endX=self.endX, - Save=False, + msdfit_result = MSDFit(InputWorkspace=eq2_file, + XStart=self.startX, + XEnd=self.endX, + SpecMax=1, Plot=False) - # @TODO: MSDFit has some other, as yet unfinalised, workspaces as its - # output. We need to test these too, eventually. - - # Annoyingly, MSDFit eats the EQ2 workspaces we feed it, so let's - # reload them for checking against the reference files later. - for ws, filename in zip(elwin_results, int_files): - LoadNexusProcessed(Filename=filename, - OutputWorkspace=ws) - # Clean up the intermediate files. for filename in int_files: os.remove(filename) @@ -803,17 +793,15 @@ class ISISIndirectInelasticElwinAndMSDFit(ISISIndirectInelasticBase): # final MSDFit result. self.result_names = [elwin_results[0], # EQ1 elwin_results[1], # EQ2 - msdfit_result] + msdfit_result[2].name()] # Fit workspace def _validate_properties(self): """Check the object properties are in an expected state to continue""" if type(self.files) != list or len(self.files) != 2: - raise RuntimeError("files should be a list of exactly 2 " - "strings") + raise RuntimeError("files should be a list of exactly 2 strings") if type(self.eRange) != list or len(self.eRange) != 2: - raise RuntimeError("eRange should be a list of exactly 2 " - "values") + raise RuntimeError("eRange should be a list of exactly 2 values") if type(self.startX) != float: raise RuntimeError("startX should be a float") if type(self.endX) != float: @@ -861,7 +849,7 @@ class ISISIndirectInelasticFuryAndFuryFit(ISISIndirectInelasticBase): ''' A base class for the ISIS indirect inelastic Fury/FuryFit tests - The output of Fury is usually used with FuryFit and so we plug one into + The output of TransformToIqt is usually used with FuryFit and so we plug one into the other in this test. ''' @@ -877,14 +865,14 @@ class ISISIndirectInelasticFuryAndFuryFit(ISISIndirectInelasticBase): LoadNexus(sample, OutputWorkspace=sample) LoadNexus(self.resolution, OutputWorkspace=self.resolution) - fury_props, fury_ws = Fury(Sample=self.samples[0], - Resolution=self.resolution, - EnergyMin=self.e_min, - EnergyMax=self.e_max, - NumBins=self.num_bins, - DryRun=False, - Save=False, - Plot=False) + fury_props, fury_ws = TransformToIqt(SampleWorkspace=self.samples[0], + ResolutionWorkspace=self.resolution, + EnergyMin=self.e_min, + EnergyMax=self.e_max, + BinReductionFactor=self.num_bins, + DryRun=False, + Save=False, + Plot=False) # Test FuryFit Sequential furyfitSeq_ws = furyfitSeq(fury_ws.getName(), @@ -934,7 +922,7 @@ class OSIRISFuryAndFuryFit(ISISIndirectInelasticFuryAndFuryFit): def __init__(self): ISISIndirectInelasticFuryAndFuryFit.__init__(self) - # Fury + # TransformToIqt self.samples = ['osi97935_graphite002_red.nxs'] self.resolution = 'osi97935_graphite002_res.nxs' self.e_min = -0.4 @@ -959,7 +947,7 @@ class IRISFuryAndFuryFit(ISISIndirectInelasticFuryAndFuryFit): def __init__(self): ISISIndirectInelasticFuryAndFuryFit.__init__(self) - # Fury + # TransformToIqt self.samples = ['irs53664_graphite002_red.nxs'] self.resolution = 'irs53664_graphite002_res.nxs' self.e_min = -0.4 @@ -998,14 +986,14 @@ class ISISIndirectInelasticFuryAndFuryFitMulti(ISISIndirectInelasticBase): LoadNexus(sample, OutputWorkspace=sample) LoadNexus(self.resolution, OutputWorkspace=self.resolution) - fury_props, fury_ws = Fury(Sample=self.samples[0], - Resolution=self.resolution, - EnergyMin=self.e_min, - EnergyMax=self.e_max, - NumBins=self.num_bins, - DryRun=False, - Save=False, - Plot=False) + fury_props, fury_ws = TransformToIqt(SampleWorkspace=self.samples[0], + ResolutionWorkspace=self.resolution, + EnergyMin=self.e_min, + EnergyMax=self.e_max, + BinReductionFactor=self.num_bins, + DryRun=False, + Save=False, + Plot=False) # Test FuryFit Sequential furyfitSeq_ws = furyfitMult(fury_ws.getName(), @@ -1057,7 +1045,7 @@ class OSIRISFuryAndFuryFitMulti(ISISIndirectInelasticFuryAndFuryFitMulti): def __init__(self): ISISIndirectInelasticFuryAndFuryFitMulti.__init__(self) - # Fury + # TransformToIqt self.samples = ['osi97935_graphite002_red.nxs'] self.resolution = 'osi97935_graphite002_res.nxs' self.e_min = -0.4 @@ -1082,7 +1070,7 @@ class IRISFuryAndFuryFitMulti(ISISIndirectInelasticFuryAndFuryFitMulti): def __init__(self): ISISIndirectInelasticFuryAndFuryFitMulti.__init__(self) - # Fury + # TransformToIqt self.samples = ['irs53664_graphite002_red.nxs'] self.resolution = 'irs53664_graphite002_res.nxs' self.e_min = -0.4 diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_LETReduction.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_LETReduction.py index d030a5185bcfc3a47c1b75b164ad12aa5bae98c1..29f0d2b372a03d0e0c86cb037950e4801ba4566f 100644 --- a/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_LETReduction.py +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_LETReduction.py @@ -190,6 +190,8 @@ class ReduceLET_MultiRep2015(ReductionWrapper): # Should be possibility to define spectra_to_monitors_list to just monitors list, if # spectra_to_monitors_list remains undefined prop['spectra_to_monitors_list']=5506 + # similar to the one above. old IDF do not contain this property + prop['multirep_tof_specta_list']="12416,21761" return prop # @iliad @@ -226,7 +228,7 @@ class ReduceLET_MultiRep2015(ReductionWrapper): """ # Note -- properties have the same names as the list of advanced and # main properties - ei = prop_man.incident_energy + ei = PropertyManager.incident_energy.get_current() # sample run is more then just list of runs, so we use # the formalization below to access its methods run_num = PropertyManager.sample_run.run_number() @@ -236,7 +238,7 @@ class ReduceLET_MultiRep2015(ReductionWrapper): # Uncomment this to use custom filename function # Note: the properties are stored in prop_man class accessed as # below. - #return custom_name(self.reducer.prop_man) + #return lambda : custom_name(self.reducer.prop_man) # use this method to use standard file name generating function return None diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_MAPS_DGSReduction.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_MAPS_DGSReduction.py index 33f32227f94ebec6488034ee9618f4eef9bed3ed..3f93c239ea8758e14f7798143a72792ef38a7815 100644 --- a/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_MAPS_DGSReduction.py +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_MAPS_DGSReduction.py @@ -90,7 +90,7 @@ class ReduceMAPS(ReductionWrapper): # Uncomment this to use custom filename function # Note: the properties are stored in prop_man class accessed as # below. - #return custom_name(self.reducer.prop_man) + #return lambda : custom_name(self.reducer.prop_man) # use this method to use standard file name generating function return None diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_MariReduction.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_MariReduction.py index e3611b6e2112cc1f0d2167557625203b57216de7..0cd60bad6ddfb12c13a43f93062b57536217f2eb 100644 --- a/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_MariReduction.py +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_MariReduction.py @@ -73,13 +73,13 @@ class ReduceMARIFromFile(ReductionWrapper): # sample run is more then just list of runs, so we use # the formalization below to access its methods run_num = PropertyManager.sample_run.run_number() - name = "RUN{0}atEi{1:<4.1f}meV_One2One".format(run_num ,ei) + name = "RUN{0}atEi{1:<3.2f}meV_One2One".format(run_num ,ei) return name # Uncomment this to use custom filename function # Note: the properties are stored in prop_man class accessed as # below. - #return custom_name(self.reducer.prop_man) + #return lambda : custom_name(self.reducer.prop_man) # use this method to use standard file name generating function return None diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/LoadLotsOfFiles.py b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadLotsOfFiles.py index 90d43f759c002ebde70b65a4c1c903b8ae76f075..253085eb8971a12c7346cd6fa455170b8931d639 100644 --- a/Code/Mantid/Testing/SystemTests/tests/analysis/LoadLotsOfFiles.py +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadLotsOfFiles.py @@ -7,6 +7,7 @@ import re import stresstesting BANNED_FILES = ['992 Descriptions.txt', + 'directBeamDatabaseFall2014_IPTS_11601_2.cfg', 'BASIS_AutoReduction_Mask.xml', 'BioSANS_dark_current.xml', 'BioSANS_empty_cell.xml', diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/REFLReduction.py b/Code/Mantid/Testing/SystemTests/tests/analysis/REFLReduction.py new file mode 100644 index 0000000000000000000000000000000000000000..7c9e50ae3c20f77e6f58cbf38dd65f4eb0c5938e --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/REFLReduction.py @@ -0,0 +1,44 @@ +#pylint: disable=no-init +import stresstesting +from mantid import * + +from mantid.simpleapi import * + +class REFLReduction(stresstesting.MantidStressTest): + def runTest(self): + #TODO: The reduction algorithm should not require an absolute path + scaling_factor_file = FileFinder.getFullPath("directBeamDatabaseFall2014_IPTS_11601_2.cfg") + + RefLReduction(RunNumbers=[119814], + NormalizationRunNumber=119690, + SignalPeakPixelRange=[154, 166], + SubtractSignalBackground=True, + SignalBackgroundPixelRange=[151, 169], + NormFlag=True, + NormPeakPixelRange=[154, 160], + NormBackgroundPixelRange=[151, 163], + SubtractNormBackground=True, + LowResDataAxisPixelRangeFlag=True, + LowResDataAxisPixelRange=[99, 158], + LowResNormAxisPixelRangeFlag=True, + LowResNormAxisPixelRange=[98, 158], + TOFRange=[29623.0, 42438.0], + IncidentMediumSelected='2InDiamSi', + GeometryCorrectionFlag=False, + QMin=0.005, + QStep=0.01, + AngleOffset=0.009, + AngleOffsetError=0.001, + ScalingFactorFile=scaling_factor_file, + SlitsWidthFlag=True, + OutputWorkspace='reflectivity_119814') + + def validate(self): + # Be more tolerant with the output. + self.tolerance = 0.0001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "reflectivity_119814", 'REFL_119814_combined_data.nxs' + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SphinxWarnings.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SphinxWarnings.py index 84f88f9391b7fe88dbad7727786feab66d35e513..3080f3c64855bf74606414254cc9ad3296cde379 100644 --- a/Code/Mantid/Testing/SystemTests/tests/analysis/SphinxWarnings.py +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SphinxWarnings.py @@ -30,6 +30,7 @@ class SphinxWarnings(stresstesting.MantidStressTest): 'Reflectometry', 'Remote', 'SANS', + 'Simulation', 'SINQ', 'Sample', 'Transforms', diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LET14305_3_4meV2015.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LET14305_3_4meV2015.nxs.md5 index 6ed489c5d183269d37b381740d357b69880be926..db2816f3213cd365f848967e5fee8545639fb54b 100644 --- a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LET14305_3_4meV2015.nxs.md5 +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LET14305_3_4meV2015.nxs.md5 @@ -1 +1 @@ -df968e07d52c10b9c3ecf4b2c5db596a \ No newline at end of file +6441be305fa8c6d32fe322786bafa26a diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/REFL_119814_combined_data.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/REFL_119814_combined_data.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..ad207d1de237a2322bc8cd16095cc6704ccb3f6f --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/REFL_119814_combined_data.nxs.md5 @@ -0,0 +1 @@ +f7949eee903277da4a6c1fa957500546 diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/CMakeLists.txt index aabeadb41010fe5c637ed802fddb88a7c5c69e06..605b3dcadab38db0d862a808d3da37c75ed39a98 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory( SplatterPlot ) add_subdirectory( ScaleWorkspace ) +add_subdirectory( PeaksFilter ) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a9f5477cb67e0e7ec322aa736f0b5dfc34fe0aeb --- /dev/null +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/CMakeLists.txt @@ -0,0 +1,16 @@ +PROJECT(PeaksFilter) +include_directories( SYSTEM ${PARAVIEW_INCLUDE_DIRS} ) +ADD_PARAVIEW_PLUGIN(MantidParaViewPeaksFilterSMPlugin "1.0" +SERVER_MANAGER_XML PeaksFilter.xml +SERVER_MANAGER_SOURCES vtkPeaksFilter.cxx +GUI_RESOURCE_FILES PeaksFilterGUI.xml) +# Add to the 'VatesParaViewPlugins' group in VS +set_property( TARGET MantidParaViewPeaksFilterSMPlugin PROPERTY FOLDER "MantidVatesParaViewPlugins") + +target_link_libraries( MantidParaViewPeaksFilterSMPlugin +${MANTID_SUBPROJECT_LIBS} ) + +# Put library into subfolder. +SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewPeaksFilterSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR}) + +install( TARGETS MantidParaViewPeaksFilterSMPlugin ${SYSTEM_PACKAGE_TARGET} DESTINATION ${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR}) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/PeaksFilter.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/PeaksFilter.xml new file mode 100644 index 0000000000000000000000000000000000000000..1467d2c912c6d2a89b5989623140b1432bb75abf --- /dev/null +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/PeaksFilter.xml @@ -0,0 +1,40 @@ +<ServerManagerConfiguration> + <!-- Begin ScaleWorkspace --> + <ProxyGroup name="filters"> + <SourceProxy name="MantidParaViewPeaksFilter" class="vtkPeaksFilter" label="MD Peaks Filter" > + <InputProperty + name="Input" + command="SetInputConnection"> + <ProxyGroupDomain name="groups"> + <Group name="sources"/> + <Group name="filters"/> + </ProxyGroupDomain> + <DataTypeDomain name="input_type"> + <DataType value="vtkUnstructuredGrid"/> + </DataTypeDomain> + </InputProperty> + <StringVectorProperty name="PeaksWorkspace" command="SetPeaksWorkspace" number_of_elements="1" panel_visibility="never"/> + <DoubleVectorProperty name="RadiusNoShape" command="SetRadiusNoShape" number_of_elements="1" default_values="0.5"> + <DoubleRangeDomain name="range" min="0.001" max="10" /> + <Documentation> + This sets the radius for peaks without a peak shape. + </Documentation> + </DoubleVectorProperty> + <IntVectorProperty name="RadiusType" command="SetRadiusType" number_of_elements="1" default_values="0"> + <EnumerationDomain name="enum"> + <Entry value="0" text="Radius"/> + <Entry value="1" text="Outer Radius"/> + <Entry value="2" text="Inner Radius"/> + </EnumerationDomain> + <Documentation> + Set the radius type. + </Documentation> + </IntVectorProperty> + <StringVectorProperty name="Delimiter" command="SetDelimiter" number_of_elements="1" panel_visibility="never"/> + <DoubleVectorProperty name="MinValue" command="GetMinValue" information_only="1"/> + <DoubleVectorProperty name="MaxValue" command="GetMaxValue" information_only="1"/> + <StringVectorProperty name="Instrument" command="GetInstrument" number_of_elements="1" information_only="1"/> + </SourceProxy> + </ProxyGroup> + <!-- End ScaleWorkspace --> +</ServerManagerConfiguration> \ No newline at end of file diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/PeaksFilterGUI.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/PeaksFilterGUI.xml new file mode 100644 index 0000000000000000000000000000000000000000..8e06286144048cec1062833f566617891c9997d9 --- /dev/null +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/PeaksFilterGUI.xml @@ -0,0 +1,6 @@ + <ParaViewFilters> + <Category name="Mantid" menu_label="&Mantid"> + <!-- adds a new category and then adds our filter to it --> + <Filter name="MantidParaViewPeaksFilter"/> + </Category> + </ParaViewFilters> \ No newline at end of file diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/vtkPeaksFilter.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/vtkPeaksFilter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..27c35049f11bf54af934caaf89ea9be38599ffe0 --- /dev/null +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/vtkPeaksFilter.cxx @@ -0,0 +1,241 @@ +#include "vtkPeaksFilter.h" +#include "MantidVatesAPI/vtkDataSetToPeaksFilteredDataSet.h" +#include "MantidAPI/AnalysisDataService.h" +#include "MantidAPI/IPeaksWorkspace.h" +#include "MantidVatesAPI/FilteringUpdateProgressAction.h" +#include "MantidVatesAPI/FieldDataToMetadata.h" +#include "MantidVatesAPI/MetadataJsonManager.h" +#include "MantidVatesAPI/VatesConfigurations.h" + +#include <boost/scoped_ptr.hpp> + +#include <vtkInformation.h> +#include <vtkInformationVector.h> +#include <vtkNew.h> +#include <vtkObjectFactory.h> +#include <vtkUnstructuredGridAlgorithm.h> +#include <vtkUnstructuredGrid.h> +#include <vtkFieldData.h> + +vtkStandardNewMacro(vtkPeaksFilter) + +using namespace Mantid::VATES; + +vtkPeaksFilter::vtkPeaksFilter() : m_peaksWorkspaceNames(""), + m_delimiter(";"), + m_radiusNoShape(0.5), + m_radiusType(0), + m_minValue(0.1), + m_maxValue(0.1), + m_metadataJsonManager(new MetadataJsonManager()), + m_vatesConfigurations(new VatesConfigurations()), + m_coordinateSystem(0) +{ + this->SetNumberOfInputPorts(1); + this->SetNumberOfOutputPorts(1); +} + +vtkPeaksFilter::~vtkPeaksFilter() +{ +} + + +int vtkPeaksFilter::RequestData(vtkInformation*, vtkInformationVector **inputVector, vtkInformationVector *outputVector) +{ + vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); + vtkUnstructuredGrid *inputDataSet = vtkUnstructuredGrid::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT())); + + vtkInformation *outInfo = outputVector->GetInformationObject(0); + vtkUnstructuredGrid *outputDataSet = vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); + + // If the field data does not contain the metadata, then don't do anything. + try + { + vtkFieldData* fieldData = inputDataSet->GetFieldData(); + + // Extract information for meta data in Json format. + FieldDataToMetadata fieldDataToMetadata; + + std::string jsonString = fieldDataToMetadata(fieldData, m_vatesConfigurations->getMetadataIdJson()); + m_metadataJsonManager->readInSerializedJson(jsonString); + + m_minValue = m_metadataJsonManager->getMinValue(); + m_maxValue = m_metadataJsonManager->getMaxValue(); + m_instrument = m_metadataJsonManager->getInstrument(); + m_coordinateSystem = m_metadataJsonManager->getSpecialCoordinates(); + } + catch (...) + { + } + + std::vector<std::string> peaksWorkspaceNames = extractPeakWorkspaceNames(); + std::vector<Mantid::API::IPeaksWorkspace_sptr> peaksWorkspaces = getPeaksWorkspaces(peaksWorkspaceNames); + + if (peaksWorkspaces.empty()) + { + return 0; + } + FilterUpdateProgressAction<vtkPeaksFilter> drawingProgressUpdate(this, "Drawing..."); + + vtkDataSetToPeaksFilteredDataSet peaksFilter(inputDataSet, outputDataSet); + peaksFilter.initialize(peaksWorkspaces, m_radiusNoShape, m_radiusType, m_coordinateSystem); + peaksFilter.execute(drawingProgressUpdate); + return 1; +} + +int vtkPeaksFilter::RequestInformation(vtkInformation*, vtkInformationVector** inputVector, vtkInformationVector*) +{ + // Set the meta data + vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); + vtkUnstructuredGrid *inputDataSet = vtkUnstructuredGrid::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT())); + + // If the field data does not contain the metadata, then don't do anything. + try + { + vtkFieldData* fieldData = inputDataSet->GetFieldData(); + + // Extract information for meta data in Json format. + FieldDataToMetadata fieldDataToMetadata; + + std::string jsonString = fieldDataToMetadata(fieldData, m_vatesConfigurations->getMetadataIdJson()); + m_metadataJsonManager->readInSerializedJson(jsonString); + + m_minValue = m_metadataJsonManager->getMinValue(); + m_maxValue = m_metadataJsonManager->getMaxValue(); + m_instrument = m_metadataJsonManager->getInstrument(); + m_coordinateSystem = m_metadataJsonManager->getSpecialCoordinates(); + } + catch (...) + { + } + + return 1; +} + +void vtkPeaksFilter::PrintSelf(ostream& os, vtkIndent indent) +{ + this->Superclass::PrintSelf(os, indent); +} + +/** + * Set the peaks workspace name + * @param peaksWorkspaceName The peaks workspace name. +*/ +void vtkPeaksFilter::SetPeaksWorkspace(std::string peaksWorkspaceName) +{ + m_peaksWorkspaceNames = peaksWorkspaceName; + this->Modified(); +} + +/** + * Set the radius for PeakShape == NoShape. + * @param radius The radius + */ +void vtkPeaksFilter::SetRadiusNoShape(double radius) +{ + m_radiusNoShape = radius; + this->Modified(); +} + +/** + * Set the radius type. + * @param type The type of the radius + */ +void vtkPeaksFilter::SetRadiusType(int type) +{ + m_radiusType = type; + this->Modified(); +} + +/** + * Updates the progress bar. + * @param progress Progress indicator. + * @param message Progress message. + */ +void vtkPeaksFilter::updateAlgorithmProgress(double progress, const std::string& message) +{ + this->SetProgressText(message.c_str()); + this->UpdateProgress(progress); +} + +/** + * Extract the names of the peaks workspaces. + * @returns A list of peaks workspace names. + */ +std::vector<std::string> vtkPeaksFilter::extractPeakWorkspaceNames() +{ + // Split the string in to bits + size_t pos = 0; + std::string peakNames = m_peaksWorkspaceNames; + std::vector<std::string> peaksWorkspaceNamesList; + std::string token; + while ((pos = peakNames.find(m_delimiter)) != std::string::npos) { + token = peakNames.substr(0, pos); + peaksWorkspaceNamesList.push_back(token); + peakNames.erase(0, pos + m_delimiter.length()); + } + + // If there was only one element in there then push it + peaksWorkspaceNamesList.push_back(peakNames); + + return peaksWorkspaceNamesList; +} + +/** + * Set the delimiter for concatenated workspace names. + * @param delimiter The workspace name delimiter + */ +void vtkPeaksFilter::SetDelimiter(std::string delimiter){ + m_delimiter = delimiter; + this->Modified(); +} + +/** + * Get a list of peaks workspace pointers + * @returns A list of peaks workspace pointers. + */ +std::vector<Mantid::API::IPeaksWorkspace_sptr> vtkPeaksFilter::getPeaksWorkspaces(std::vector<std::string> peaksWorkspaceNames) +{ + std::vector<Mantid::API::IPeaksWorkspace_sptr> peaksWorkspaces; + + for (std::vector<std::string>::iterator it = peaksWorkspaceNames.begin(); it != peaksWorkspaceNames.end(); ++it) + { + // Check if the peaks workspace exists + if (!Mantid::API::AnalysisDataService::Instance().doesExist(*it)) + { + continue; + } + peaksWorkspaces.push_back(Mantid::API::AnalysisDataService::Instance().retrieveWS<Mantid::API::IPeaksWorkspace>(*it)); + } + + return peaksWorkspaces; +} + +/** + * Gets the minimum value of the data associated with the + * workspace. + * @returns The minimum value of the workspace data. + */ +double vtkPeaksFilter::GetMinValue() +{ + return m_minValue; +} + +/** + * Gets the maximum value of the data associated with the + * workspace. + * @returns The maximum value of the workspace data. + */ +double vtkPeaksFilter::GetMaxValue(){ + + return m_maxValue; +} + +/** + * Getst the insturment name + * @returns The name of the instrument. + */ +const char* vtkPeaksFilter::GetInstrument() { + return m_instrument.c_str(); +} + diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/vtkPeaksFilter.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/vtkPeaksFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..272795e238061dca43cbf1c8fe56192df84a3401 --- /dev/null +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/vtkPeaksFilter.h @@ -0,0 +1,45 @@ +#ifndef _VTKPEAKSFILTER_h +#define _VTKPEAKSFILTER_h +#include "vtkUnstructuredGridAlgorithm.h" +#include "MantidAPI/IPeaksWorkspace.h" +#include "MantidVatesAPI/MetadataJsonManager.h" +#include "MantidVatesAPI/VatesConfigurations.h" +#include <boost/scoped_ptr.hpp> +#include <string> +// cppcheck-suppress class_X_Y +class VTK_EXPORT vtkPeaksFilter : public vtkUnstructuredGridAlgorithm +{ +public: + static vtkPeaksFilter *New(); + vtkTypeMacro(vtkPeaksFilter, vtkUnstructuredGridAlgorithm); + void PrintSelf(ostream& os, vtkIndent indent); + void SetPeaksWorkspace(std::string peaksWorkspaceName); + void SetRadiusNoShape(double radius); + void SetRadiusType(int type); + void SetDelimiter(std::string delimiter); + void updateAlgorithmProgress(double progress, const std::string& message); + double GetMinValue(); + double GetMaxValue(); + const char* GetInstrument(); +protected: + vtkPeaksFilter(); + ~vtkPeaksFilter(); + int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *); + int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *); +private: + vtkPeaksFilter(const vtkPeaksFilter&); + void operator = (const vtkPeaksFilter&); + std::vector<std::string> extractPeakWorkspaceNames(); + std::vector<Mantid::API::IPeaksWorkspace_sptr> getPeaksWorkspaces(std::vector<std::string> peaksWorkspaceNames); + std::string m_peaksWorkspaceNames; + std::string m_delimiter; + double m_radiusNoShape; + int m_radiusType; + double m_minValue; + double m_maxValue; + std::string m_instrument; + boost::scoped_ptr<Mantid::VATES::MetadataJsonManager> m_metadataJsonManager; + boost::scoped_ptr<Mantid::VATES::VatesConfigurations> m_vatesConfigurations; + int m_coordinateSystem; +}; +#endif diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/CMakeLists.txt index 451c01cae863284680de52d19f792858dbce6778..056b2b05e3ab0277365d923b6b417f4ec79bce8d 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/CMakeLists.txt @@ -1,5 +1,5 @@ PROJECT(ScaleWorkspace) - +include_directories( SYSTEM ${PARAVIEW_INCLUDE_DIRS} ) ADD_PARAVIEW_PLUGIN(MantidParaViewScaleWorkspaceSMPlugin "1.0" SERVER_MANAGER_XML ScaleWorkspace.xml SERVER_MANAGER_SOURCES vtkScaleWorkspace.cxx diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/ScaleWorkspace.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/ScaleWorkspace.xml index 5b1454980a2078c7370b4a331e003a2cce3b3a32..380139ad7805a395a349457586995a4469fa1b5d 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/ScaleWorkspace.xml +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/ScaleWorkspace.xml @@ -19,6 +19,9 @@ <DoubleVectorProperty name="MinValue" command="GetMinValue" information_only="1"/> <DoubleVectorProperty name="MaxValue" command="GetMaxValue" information_only="1"/> <StringVectorProperty name="Instrument" command="GetInstrument" number_of_elements="1" information_only="1"/> + <IntVectorProperty name="SpecialCoordinates" command="GetSpecialCoordinates" number_of_elements="1" information_only="1" default_values="0"> + <SimpleIntInformationHelper /> + </IntVectorProperty> </SourceProxy> </ProxyGroup> <!-- End ScaleWorkspace --> diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx index 77c9dcb81e1b0141760d00a38c47fce3da865761..e9b15021d609133cb6f51eed9b88836e0b8f1f2e 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx @@ -11,7 +11,7 @@ #include <vtkUnstructuredGridAlgorithm.h> #include <vtkUnstructuredGrid.h> -vtkStandardNewMacro(vtkScaleWorkspace); +vtkStandardNewMacro(vtkScaleWorkspace) using namespace Mantid::VATES; @@ -19,6 +19,7 @@ vtkScaleWorkspace::vtkScaleWorkspace() : m_xScaling(1), m_yScaling(1), m_zScaling(1), + m_specialCoordinates(-1), m_metadataJsonManager(new MetadataJsonManager()), m_vatesConfigurations(new VatesConfigurations()) { @@ -62,6 +63,7 @@ int vtkScaleWorkspace::RequestInformation(vtkInformation*, vtkInformationVector* m_minValue = m_metadataJsonManager->getMinValue(); m_maxValue = m_metadataJsonManager->getMaxValue(); m_instrument = m_metadataJsonManager->getInstrument(); + m_specialCoordinates = m_metadataJsonManager->getSpecialCoordinates(); return 1; } @@ -137,4 +139,9 @@ double vtkScaleWorkspace::GetMaxValue() const char* vtkScaleWorkspace::GetInstrument() { return m_instrument.c_str(); +} + +int vtkScaleWorkspace::GetSpecialCoordinates() +{ + return m_specialCoordinates; } \ No newline at end of file diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.h index a48719311248e57b2880171d8c7b3198a8b5871b..1a0065a478f40816f1f19d9b90cc409470d57eff 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.h +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.h @@ -18,7 +18,7 @@ public: double GetMinValue(); double GetMaxValue(); const char* GetInstrument(); - + int GetSpecialCoordinates(); protected: vtkScaleWorkspace(); ~vtkScaleWorkspace(); @@ -35,6 +35,7 @@ private: double m_minValue; double m_maxValue; std::string m_instrument; + int m_specialCoordinates; boost::scoped_ptr<Mantid::VATES::MetadataJsonManager> m_metadataJsonManager; boost::scoped_ptr<Mantid::VATES::VatesConfigurations> m_vatesConfigurations; diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/CMakeLists.txt index d6beddcd88c7ed717d09de75be6d9176ac6c631b..3d3208936b160accd33e8118ba8f07e952fc1774 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/CMakeLists.txt @@ -1,5 +1,5 @@ PROJECT(SplatterPlot) - +include_directories( SYSTEM ${PARAVIEW_INCLUDE_DIRS} ) ADD_PARAVIEW_PLUGIN(MantidParaViewSplatterPlotSMPlugin "1.0" SERVER_MANAGER_XML SplatterPlot.xml SERVER_MANAGER_SOURCES vtkSplatterPlot.cxx diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx index 8556d6c34de26491b16c17c9371f587d79a5ef60..7a60a3852bef3d1482bc4c830864cd7eaeed2067 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx @@ -5,6 +5,7 @@ #include "vtkStreamingDemandDrivenPipeline.h" #include "vtkUnstructuredGridAlgorithm.h" #include "vtkUnstructuredGrid.h" +#include "vtkFieldData.h" #include "MantidGeometry/MDGeometry/MDGeometryXMLDefinitions.h" #include "MantidVatesAPI/ADSWorkspaceProvider.h" @@ -19,7 +20,7 @@ using namespace Mantid::API; using namespace Mantid::VATES; -vtkStandardNewMacro(vtkSplatterPlot); +vtkStandardNewMacro(vtkSplatterPlot) /// Constructor vtkSplatterPlot::vtkSplatterPlot() : m_numberPoints(0), m_topPercentile(0.0), @@ -93,8 +94,7 @@ int vtkSplatterPlot::RequestData(vtkInformation *, { // Get the info objects vtkInformation *outInfo = outputVector->GetInformationObject(0); - vtkDataSet *output = vtkDataSet::SafeDownCast( - outInfo->Get(vtkDataObject::DATA_OBJECT())); + vtkDataSet *output = vtkDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP())) { @@ -110,7 +110,10 @@ int vtkSplatterPlot::RequestData(vtkInformation *, FilterUpdateProgressAction<vtkSplatterPlot> drawUpdateProgress(this, "Drawing..."); vtkDataSet* product = m_presenter->create(drawUpdateProgress); - product->SetFieldData(input->GetFieldData()); + + // Extract the relevant metadata from the underlying source + m_presenter->setMetadata(input->GetFieldData(), product); + output->ShallowCopy(product); try diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/EventNexusReader/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/EventNexusReader/CMakeLists.txt index 798b29582c9ba409cc3678864887fd02df603ab4..5537e38b62060127c5fb4d58d948d546be8762f2 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/EventNexusReader/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/EventNexusReader/CMakeLists.txt @@ -1,5 +1,5 @@ project( MantidParaViewEventNexusReader ) - +include_directories( SYSTEM ${PARAVIEW_INCLUDE_DIRS} ) add_paraview_plugin( MantidParaViewEventNexusReaderSMPlugin "1.0" SERVER_MANAGER_XML EventNexusReader.xml SERVER_MANAGER_SOURCES vtkEventNexusReader.cxx diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/EventNexusReader/vtkEventNexusReader.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/EventNexusReader/vtkEventNexusReader.cxx index db709eb1240a81744f9e13d7a00c7cca69809f17..6edd4d02dad28f5390c1fa7bae58800858712a37 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/EventNexusReader/vtkEventNexusReader.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/EventNexusReader/vtkEventNexusReader.cxx @@ -18,7 +18,7 @@ #include "MantidVatesAPI/FilteringUpdateProgressAction.h" #include "MantidVatesAPI/MDLoadingViewAdapter.h" -vtkStandardNewMacro(vtkEventNexusReader); +vtkStandardNewMacro(vtkEventNexusReader) using namespace Mantid::VATES; using Mantid::Geometry::IMDDimension_sptr; diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/CMakeLists.txt index aa1f3a57ed9cc71f134f260ae1041af0ec297790..c7b74fc70f15a434c697c3d51ff59cb360cd2352 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/CMakeLists.txt @@ -1,5 +1,5 @@ project( MantidParaViewMDEWNexusReader ) - +include_directories( SYSTEM ${PARAVIEW_INCLUDE_DIRS} ) add_paraview_plugin( MantidParaViewMDEWNexusReaderSMPlugin "1.0" SERVER_MANAGER_XML MDEWNexusReader.xml SERVER_MANAGER_SOURCES vtkMDEWNexusReader.cxx diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/vtkMDEWNexusReader.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/vtkMDEWNexusReader.cxx index 6cd9ab74d996765a44ca49bfc67c53c13d2e8513..880b277761c1022eef60995f53879fa5a5713ca4 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/vtkMDEWNexusReader.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/vtkMDEWNexusReader.cxx @@ -21,7 +21,7 @@ #include <QtDebug> -vtkStandardNewMacro(vtkMDEWNexusReader); +vtkStandardNewMacro(vtkMDEWNexusReader) using namespace Mantid::VATES; using Mantid::Geometry::IMDDimension_sptr; diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDHWNexusReader/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDHWNexusReader/CMakeLists.txt index 6ad4b9ff3c8269fe750588f504933888e88ff74b..5607de2b63ea14c474d48f8e3e37633e3639cf5d 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDHWNexusReader/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDHWNexusReader/CMakeLists.txt @@ -1,5 +1,5 @@ project( MantidParaViewMDHWNexusReader ) - +include_directories( SYSTEM ${PARAVIEW_INCLUDE_DIRS} ) add_paraview_plugin( MantidParaViewMDHWNexusReaderSMPlugin "1.0" SERVER_MANAGER_XML MDHWNexusReader.xml SERVER_MANAGER_SOURCES vtkMDHWNexusReader.cxx diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDHWNexusReader/vtkMDHWNexusReader.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDHWNexusReader/vtkMDHWNexusReader.cxx index 95f90f535cc83a342a0d2a09ad7ee5b7ab38389a..834965eb2c5cff7b5ce314d5c66311dabffc5e7a 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDHWNexusReader/vtkMDHWNexusReader.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDHWNexusReader/vtkMDHWNexusReader.cxx @@ -19,7 +19,7 @@ #include "MantidVatesAPI/FilteringUpdateProgressAction.h" #include "MantidVatesAPI/MDLoadingViewAdapter.h" -vtkStandardNewMacro(vtkMDHWNexusReader); +vtkStandardNewMacro(vtkMDHWNexusReader) using namespace Mantid::VATES; using Mantid::Geometry::IMDDimension_sptr; diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/NexusPeaksReader/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/NexusPeaksReader/CMakeLists.txt index 685637a59d6abfc82ba8482b37eed70e9a21a90f..9a1c7182a7630e7700bc088b25d8a8931d6bf545 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/NexusPeaksReader/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/NexusPeaksReader/CMakeLists.txt @@ -1,5 +1,5 @@ project( MantidParaViewNexusPeaksReader ) - +include_directories( SYSTEM ${PARAVIEW_INCLUDE_DIRS} ) add_paraview_plugin( MantidParaViewNexusPeaksReaderSMPlugin "1.0" SERVER_MANAGER_XML NexusPeaksReader.xml SERVER_MANAGER_SOURCES vtkNexusPeaksReader.cxx diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/NexusPeaksReader/vtkNexusPeaksReader.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/NexusPeaksReader/vtkNexusPeaksReader.cxx index d04f458bb6ed8791f5eb29b5d2244037b599bd09..7e228505d0867c284eb3bfa61c8fe381d01bbcad 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/NexusPeaksReader/vtkNexusPeaksReader.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/NexusPeaksReader/vtkNexusPeaksReader.cxx @@ -23,7 +23,7 @@ #include <nexus/NeXusException.hpp> #include <boost/algorithm/string.hpp> -vtkStandardNewMacro(vtkNexusPeaksReader); +vtkStandardNewMacro(vtkNexusPeaksReader) using namespace Mantid::VATES; using Mantid::Geometry::IMDDimension_sptr; diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/PeaksReader/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/PeaksReader/CMakeLists.txt index 0944ba06626700f9a4cc93f98b49c819d45a5930..3b2407ae805533e0fb505617a7278376b6c32144 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/PeaksReader/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/PeaksReader/CMakeLists.txt @@ -1,5 +1,5 @@ project( MantidParaViewPeaksReader ) - +include_directories( SYSTEM ${PARAVIEW_INCLUDE_DIRS} ) add_paraview_plugin( MantidParaViewPeaksReaderSMPlugin "1.0" SERVER_MANAGER_XML PeaksReader.xml SERVER_MANAGER_SOURCES vtkPeaksReader.cxx diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/PeaksReader/vtkPeaksReader.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/PeaksReader/vtkPeaksReader.cxx index a63fce33d42a2124a35b59f0e88f75f36fec9fa2..70a227c7af43491c669f37378ce6624c80fb58ab 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/PeaksReader/vtkPeaksReader.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/PeaksReader/vtkPeaksReader.cxx @@ -22,7 +22,7 @@ #include <boost/algorithm/string.hpp> -vtkStandardNewMacro(vtkPeaksReader); +vtkStandardNewMacro(vtkPeaksReader) using namespace Mantid::VATES; using Mantid::Geometry::IMDDimension_sptr; diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWEventReader/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWEventReader/CMakeLists.txt index eace77b7a09ba4f29f0c27cd5fe198ca1160181f..d8d8525c52cfdb3205ce7c7e1c0f3bbbfb1ceb33 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWEventReader/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWEventReader/CMakeLists.txt @@ -1,5 +1,5 @@ project( MantidParaViewSQWEventReader ) - +include_directories( SYSTEM ${PARAVIEW_INCLUDE_DIRS} ) add_paraview_plugin( MantidParaViewSQWEventReaderSMPlugin "1.0" SERVER_MANAGER_XML SQWEventReader.xml SERVER_MANAGER_SOURCES vtkSQWEventReader.cxx diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWEventReader/vtkSQWEventReader.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWEventReader/vtkSQWEventReader.cxx index d964c50c2d613f66fe9e4f17c8ea86ee59b43b1e..ef61e72c3cc659df3fb6115e1038ea11706e8c30 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWEventReader/vtkSQWEventReader.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWEventReader/vtkSQWEventReader.cxx @@ -19,7 +19,7 @@ #include "MantidVatesAPI/FilteringUpdateProgressAction.h" #include "MantidVatesAPI/MDLoadingViewAdapter.h" -vtkStandardNewMacro(vtkSQWEventReader); +vtkStandardNewMacro(vtkSQWEventReader) using namespace Mantid::VATES; using Mantid::Geometry::IMDDimension_sptr; diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/CMakeLists.txt index cf5dd9ef299fdd3b1b109c30e5e3f2989cf3ee8e..f061505754421f1dca0feb8e1ce7c90521963636 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWReader/CMakeLists.txt @@ -1,5 +1,5 @@ project( MantidParaViewSQWReader ) - +include_directories( SYSTEM ${PARAVIEW_INCLUDE_DIRS} ) add_paraview_plugin( MantidParaViewSQWReaderSMPlugin "1.0" SERVER_MANAGER_XML SQWReader.xml SERVER_MANAGER_SOURCES vtkSQWReader.cxx diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/CMakeLists.txt index 17b30441e7f1231d79bdae83d1e858df519d91ed..9ccd9b2440cdc5b752de34bccc2eccde1283707f 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory( MDEWSource ) add_subdirectory( MDHWSource ) add_subdirectory( PeaksSource ) +add_subdirectory( SinglePeakMarkerSource ) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/CMakeLists.txt index 1719a68e0bd612ab248b72fa83132a5cf204ac28..a40f403de2a1e94f1ea15d0c303023f40dab8c75 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/CMakeLists.txt @@ -1,5 +1,5 @@ PROJECT(MantidParaViewMDEWSource) - +include_directories( SYSTEM ${PARAVIEW_INCLUDE_DIRS} ) ADD_PARAVIEW_PLUGIN(MantidParaViewMDEWSourceSMPlugin "1.0" SERVER_MANAGER_XML MDEWSource.xml SERVER_MANAGER_SOURCES vtkMDEWSource.cxx) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.cxx index 12fc54a626e157a8dae75ade5443cd399ee3a8c9..196dd73e69c89ad37b7fcd5e524f70af033017e5 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.cxx @@ -19,7 +19,7 @@ using namespace Mantid::VATES; -vtkStandardNewMacro(vtkMDEWSource); +vtkStandardNewMacro(vtkMDEWSource) /// Constructor vtkMDEWSource::vtkMDEWSource() : m_wsName(""), m_depth(1000), m_time(0), m_presenter(NULL), m_isStartup(true), m_startupTimeValue(0) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/CMakeLists.txt index d65a9066e679883bdcbb1b5c204d64293729f4e7..e3fa0dd9580eb5df2b4847d05680e77f8d7139f0 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/CMakeLists.txt @@ -1,5 +1,5 @@ PROJECT(MantidParaViewMDHWSource) - +include_directories( SYSTEM ${PARAVIEW_INCLUDE_DIRS} ) ADD_PARAVIEW_PLUGIN(MantidParaViewMDHWSourceSMPlugin "1.0" SERVER_MANAGER_XML MDHWSource.xml SERVER_MANAGER_SOURCES vtkMDHWSource.cxx) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.cxx index 26ed4e7eba59c5dda0e41098d7c1e493341cdc8c..e2757e29cacbdf39746273ce58366e5dac853dd3 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.cxx @@ -19,7 +19,7 @@ using namespace Mantid::VATES; -vtkStandardNewMacro(vtkMDHWSource); +vtkStandardNewMacro(vtkMDHWSource) /// Constructor vtkMDHWSource::vtkMDHWSource() : m_wsName(""), m_time(0), m_presenter(NULL) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/CMakeLists.txt index bbf6ca2935239268a0d0efca8690f5da4edeb9c9..188fe0c7fafd56fd6fc564e474a51c551912f43f 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/CMakeLists.txt @@ -1,5 +1,5 @@ PROJECT(MantidParaViewPeaksSource) - +include_directories( SYSTEM ${PARAVIEW_INCLUDE_DIRS} ) ADD_PARAVIEW_PLUGIN(MantidParaViewPeaksSourceSMPlugin "1.0" SERVER_MANAGER_XML PeaksSource.xml SERVER_MANAGER_SOURCES vtkPeaksSource.cxx) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.cxx index 198d57ad75e1f946784fdf5db1bd8301cca2c17d..e3ff1ab962be5ecd64eb83c51ebccf2f687db319 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.cxx @@ -16,7 +16,7 @@ #include "MantidAPI/AnalysisDataService.h" -vtkStandardNewMacro(vtkPeaksSource); +vtkStandardNewMacro(vtkPeaksSource) using namespace Mantid::VATES; using Mantid::Geometry::IMDDimension_sptr; @@ -84,48 +84,7 @@ int vtkPeaksSource::RequestData(vtkInformation *, vtkInformationVector **, m_dimToShow); p_peakFactory->initialize(m_PeakWS); - vtkDataSet *structuredMesh = p_peakFactory->create(drawingProgressUpdate); - - // Pick the radius up from the factory if possible, otherwise use the user-provided value. - vtkPolyDataAlgorithm* shapeMarker = NULL; - if(p_peakFactory->isPeaksWorkspaceIntegrated()) - { - double peakRadius = p_peakFactory->getIntegrationRadius(); - const int resolution = 6; - vtkSphereSource *sphere = vtkSphereSource::New(); - sphere->SetRadius(peakRadius); - sphere->SetPhiResolution(resolution); - sphere->SetThetaResolution(resolution); - shapeMarker = sphere; - } - else - { - vtkAxes* axis = vtkAxes::New(); - axis->SymmetricOn(); - axis->SetScaleFactor(m_uintPeakMarkerSize); - - vtkTransform* transform = vtkTransform::New(); - const double rotationDegrees = 45; - transform->RotateX(rotationDegrees); - transform->RotateY(rotationDegrees); - transform->RotateZ(rotationDegrees); - - vtkTransformPolyDataFilter* transformFilter = vtkTransformPolyDataFilter::New(); - transformFilter->SetTransform(transform); - transformFilter->SetInputConnection(axis->GetOutputPort()); - transformFilter->Update(); - shapeMarker = transformFilter; - } - - vtkPVGlyphFilter *glyphFilter = vtkPVGlyphFilter::New(); - glyphFilter->SetInputData(structuredMesh); - glyphFilter->SetSourceConnection(shapeMarker->GetOutputPort()); - glyphFilter->Update(); - vtkPolyData *glyphed = glyphFilter->GetOutput(); - - output->ShallowCopy(glyphed); - - glyphFilter->Delete(); + output->ShallowCopy(p_peakFactory->create(drawingProgressUpdate)); } return 1; } diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b713178fd46d2911ff18e3f270e4ca7cca838a7b --- /dev/null +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/CMakeLists.txt @@ -0,0 +1,16 @@ +PROJECT(MantidParaViewSinglePeakMarkerSource) +include_directories( SYSTEM ${PARAVIEW_INCLUDE_DIRS} ) +ADD_PARAVIEW_PLUGIN(MantidParaViewSinglePeakMarkerSourceSMPlugin "1.0" + SERVER_MANAGER_XML SinglePeakMarkerSource.xml + SERVER_MANAGER_SOURCES vtkSinglePeakMarkerSource.cxx) + +# Add to the 'VatesParaViewPlugins' group in VS +set_property( TARGET MantidParaViewSinglePeakMarkerSourceSMPlugin PROPERTY FOLDER "MantidVatesParaViewPlugins" ) + +target_link_libraries( MantidParaViewSinglePeakMarkerSourceSMPlugin +${MANTID_SUBPROJECT_LIBS} ) + +# Put library into subfolder. +SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewSinglePeakMarkerSourceSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR}) + +install( TARGETS MantidParaViewSinglePeakMarkerSourceSMPlugin ${SYSTEM_PACKAGE_TARGET} DESTINATION ${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR} ) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/SinglePeakMarkerSource.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/SinglePeakMarkerSource.xml new file mode 100644 index 0000000000000000000000000000000000000000..e2651bbedbedc2c09ae7472efd9340b3006afe8a --- /dev/null +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/SinglePeakMarkerSource.xml @@ -0,0 +1,12 @@ +<ServerManagerConfiguration> + <!-- Begin SinglePeakMarkerSource --> + <ProxyGroup name="sources"> + <SourceProxy name="SinglePeakMarkerSource" class="vtkSinglePeakMarkerSource"> + <DoubleVectorProperty name="Position1" command="SetPosition1" number_of_elements="1" default_values="0"/> + <DoubleVectorProperty name="Position2" command="SetPosition2" number_of_elements="1" default_values="0"/> + <DoubleVectorProperty name="Position3" command="SetPosition3" number_of_elements="1" default_values="0"/> + <DoubleVectorProperty name="RadiusMarker" command="SetRadiusMarker" number_of_elements="1" default_values="1"/> + </SourceProxy> + </ProxyGroup> + <!-- End SinglePeakMarkerSource --> +</ServerManagerConfiguration> diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/vtkSinglePeakMarkerSource.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/vtkSinglePeakMarkerSource.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d607310440f8b68c6fcdb0e63170f4530c0dddbc --- /dev/null +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/vtkSinglePeakMarkerSource.cxx @@ -0,0 +1,71 @@ +#include "vtkSinglePeakMarkerSource.h" +#include "vtkInformation.h" +#include "vtkInformationVector.h" +#include "vtkObjectFactory.h" +#include "vtkStreamingDemandDrivenPipeline.h" + +#include "MantidVatesAPI/vtkSinglePeakMarker.h" + +vtkStandardNewMacro(vtkSinglePeakMarkerSource) + +using namespace Mantid::VATES; + +/// Constructor +vtkSinglePeakMarkerSource::vtkSinglePeakMarkerSource() : m_position1(0.0), m_position2(0.0), m_position3(0.0), m_radius(0.1) +{ + this->SetNumberOfInputPorts(0); + this->SetNumberOfOutputPorts(1); +} + +/// Destructor +vtkSinglePeakMarkerSource::~vtkSinglePeakMarkerSource() +{ +} + +int vtkSinglePeakMarkerSource::RequestData(vtkInformation *, vtkInformationVector **, + vtkInformationVector *outputVector) +{ + vtkInformation *outInfo = outputVector->GetInformationObject(0); + vtkPolyData *output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); + + vtkSinglePeakMarker singlePeak; + output->ShallowCopy(singlePeak.createSinglePeakMarker(m_position1, m_position2, m_position3, m_radius)); + + return 1; +} + +int vtkSinglePeakMarkerSource::RequestInformation(vtkInformation *vtkNotUsed(request), + vtkInformationVector **vtkNotUsed(inputVector), + vtkInformationVector *vtkNotUsed(outputVector)) +{ + return 1; +} + +void vtkSinglePeakMarkerSource::PrintSelf(ostream& os, vtkIndent indent) +{ + this->Superclass::PrintSelf(os, indent); +} + +void vtkSinglePeakMarkerSource::SetRadiusMarker(double radius) +{ + m_radius = (radius*0.05); + this->Modified(); +} + +void vtkSinglePeakMarkerSource::SetPosition1(double position1) +{ + m_position1 = position1; + this->Modified(); +} + +void vtkSinglePeakMarkerSource::SetPosition2(double position2) +{ + m_position2 = position2; + this->Modified(); +} + +void vtkSinglePeakMarkerSource::SetPosition3(double position3) +{ + m_position3 = position3; + this->Modified(); +} \ No newline at end of file diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/vtkSinglePeakMarkerSource.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/vtkSinglePeakMarkerSource.h new file mode 100644 index 0000000000000000000000000000000000000000..dccef350679450a1368911c25cc0b0ed97c20dbe --- /dev/null +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/vtkSinglePeakMarkerSource.h @@ -0,0 +1,59 @@ +#ifndef _vtkSinglePeakMarkerSource_h +#define _vtkSinglePeakMarkerSource_h +#include "vtkPolyDataAlgorithm.h" + +/** + This source is used to mark a single peak. + + @date 23/02/2015 + + Copyright © 2007-11 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source + + 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://github.com/mantidproject/mantid>. + Code Documentation is available at: <http://doxygen.mantidproject.org> + +*/ + +// cppcheck-suppress class_X_Y +class VTK_EXPORT vtkSinglePeakMarkerSource : public vtkPolyDataAlgorithm +{ +public: + static vtkSinglePeakMarkerSource*New(); + vtkTypeMacro(vtkSinglePeakMarkerSource,vtkPolyDataAlgorithm); + void PrintSelf(ostream& os, vtkIndent indent); + void SetRadiusMarker(double radius); + void SetPosition1(double position1); + void SetPosition2(double position2); + void SetPosition3(double position3); +protected: + vtkSinglePeakMarkerSource(); + ~vtkSinglePeakMarkerSource(); + int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *); + int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *); + +private: + /// Position information + double m_position1; + double m_position2; + double m_position3; + double m_radius; + + vtkSinglePeakMarkerSource(const vtkSinglePeakMarkerSource&); + void operator = (const vtkSinglePeakMarkerSource&); +}; +#endif diff --git a/Code/Mantid/Vates/VatesAPI/CMakeLists.txt b/Code/Mantid/Vates/VatesAPI/CMakeLists.txt index 15c608a0266fda2746d0806d0115cb989c9d077d..927bc9468ec3127a1602d702c044bfccffe90267 100644 --- a/Code/Mantid/Vates/VatesAPI/CMakeLists.txt +++ b/Code/Mantid/Vates/VatesAPI/CMakeLists.txt @@ -6,6 +6,8 @@ project( VatesAPI ) set( SRC_FILES src/ADSWorkspaceProvider.cpp src/Common.cpp +src/CompositePeaksPresenterVsi.cpp +src/ConcretePeaksPresenterVsi.cpp src/DimensionPresenter.cpp src/EventNexusLoadingPresenter.cpp src/FieldDataToMetadata.cpp @@ -13,13 +15,14 @@ src/IgnoreZerosThresholdRange.cpp src/IMDDimensionComparitor.cpp src/LoadVTK.cpp src/MDEWEventNexusLoadingPresenter.cpp -src/MDEWInMemoryLoadingPresenter.cpp src/MDEWLoadingPresenter.cpp +src/MDEWInMemoryLoadingPresenter.cpp src/MDHWInMemoryLoadingPresenter.cpp src/MDHWLoadingPresenter.cpp src/MDHWNexusLoadingPresenter.cpp src/MedianAndBelowThresholdRange.cpp src/MetadataToFieldData.cpp +src/MetadataToFieldData.cpp src/MetaDataExtractorUtils.cpp src/MetadataJsonManager.cpp src/NoThresholdRange.cpp @@ -30,14 +33,17 @@ src/TimeToTimeStep.cpp src/UserDefinedThresholdRange.cpp src/VatesXMLDefinitions.cpp src/VatesConfigurations.cpp +src/ViewFrustum.cpp src/VatesKnowledgeSerializer.cpp src/vtkDataSetFactory.cpp src/vtkDataSetToGeometry.cpp src/vtkDataSetToImplicitFunction.cpp src/vtkDataSetToNonOrthogonalDataSet.cpp +src/vtkDataSetToPeaksFilteredDataSet.cpp src/vtkDataSetToScaledDataSet.cpp src/vtkDataSetToWsName.cpp src/vtkDataSetToWsLocation.cpp +src/vtkEllipsoidTransformer.cpp src/vtkMDLineFactory.cpp src/vtkMDQuadFactory.cpp src/vtkNullUnstructuredGrid.cpp @@ -48,12 +54,15 @@ src/vtkMDHistoHexFactory.cpp src/vtkMDHistoLineFactory.cpp src/vtkMDHistoQuadFactory.cpp src/vtkMDHistoHex4DFactory.cpp +src/vtkSinglePeakMarker.cpp src/SQWLoadingPresenter.cpp ) set( INC_FILES inc/MantidVatesAPI/ADSWorkspaceProvider.h inc/MantidVatesAPI/Common.h +inc/MantidVatesAPI/CompositePeaksPresenterVsi.h +inc/MantidVatesAPI/ConcretePeaksPresenterVsi.h inc/MantidVatesAPI/DimensionPresenter.h inc/MantidVatesAPI/DimensionView.h inc/MantidVatesAPI/DimensionViewFactory.h @@ -79,6 +88,8 @@ inc/MantidVatesAPI/IgnoreZerosThresholdRange.h inc/MantidVatesAPI/IMDDimensionComparitor.h inc/MantidVatesAPI/MetadataToFieldData.h inc/MantidVatesAPI/NoThresholdRange.h +inc/MantidVatesAPI/NullPeaksPresenterVsi.h +inc/MantidVatesAPI/PeaksPresenterVsi.h inc/MantidVatesAPI/ProgressAction.h inc/MantidVatesAPI/SQWLoadingPresenter.h inc/MantidVatesAPI/SynchronisingGeometryPresenter.h @@ -89,13 +100,16 @@ inc/MantidVatesAPI/UserDefinedThresholdRange.h inc/MantidVatesAPI/VatesXMLDefinitions.h inc/MantidVatesAPI/VatesConfigurations.h inc/MantidVatesAPI/VatesKnowledgeSerializer.h +inc/MantidVatesAPI/ViewFrustum.h inc/MantidVatesAPI/vtkDataSetFactory.h inc/MantidVatesAPI/vtkDataSetToGeometry.h inc/MantidVatesAPI/vtkDataSetToImplicitFunction.h inc/MantidVatesAPI/vtkDataSetToNonOrthogonalDataSet.h +inc/MantidVatesAPI/vtkDataSetToPeaksFilteredDataSet.h inc/MantidVatesAPI/vtkDataSetToScaledDataSet.h inc/MantidVatesAPI/vtkDataSetToWsName.h inc/MantidVatesAPI/vtkDataSetToWsLocation.h +inc/MantidVatesAPI/vtkEllipsoidTransformer.h inc/MantidVatesAPI/vtkMDLineFactory.h inc/MantidVatesAPI/vtkMDQuadFactory.h inc/MantidVatesAPI/vtkMDHexFactory.h @@ -106,6 +120,7 @@ inc/MantidVatesAPI/vtkMDHistoHexFactory.h inc/MantidVatesAPI/vtkMDHistoLineFactory.h inc/MantidVatesAPI/vtkMDHistoQuadFactory.h inc/MantidVatesAPI/vtkMDHistoHex4DFactory.h +inc/MantidVatesAPI/vtkSinglePeakMarker.h inc/MantidVatesAPI/WorkspaceProvider.h ) @@ -149,9 +164,15 @@ test/MedianAndBelowThresholdRangeTest.h test/NoThresholdRangeTest.h test/IgnoreZerosThresholdRangeTest.h test/VatesKnowledgeSerializerTest.h +test/ViewFrustumTest.h test/vtkDataSetToScaledDataSetTest.h +test/vtkDataSetToPeaksFilteredDataSetTest.h test/vtkDataSetToNonOrthogonalDataSetTest.h test/vtkNullUnstructuredGridTest.h +test/vtkEllipsoidTransformerTest.h +test/NullPeaksPresenterVsiTest.h +test/ConcretePeaksPresenterVsiTest.h +test/CompositePeaksPresenterVsiTest.h ) include_directories( inc ) @@ -180,6 +201,9 @@ ${MANTID_SUBPROJECT_LIBS} vtkCommonCore vtkCommonDataModel vtkIOLegacy +vtkFiltersExtraction +vtkFiltersSources +vtkPVVTKExtensionsDefault ${QWT_LIBRARIES} ) diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/CompositePeaksPresenterVsi.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/CompositePeaksPresenterVsi.h new file mode 100644 index 0000000000000000000000000000000000000000..19066a024046b27b7f2ed73499d26a41172468e7 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/CompositePeaksPresenterVsi.h @@ -0,0 +1,41 @@ +#ifndef MANTID_VATES_COMPOSITE_PEAKS_PRESENTER_VSI_H +#define MANTID_VATES_COMPOSITE_PEAKS_PRESENTER_VSI_H + +#include "MantidKernel/System.h" +#include "MantidVatesAPI/PeaksPresenterVsi.h" +#include "MantidAPI/PeakTransform.h" +#include "MantidAPI/IPeaksWorkspace.h" +#include "MantidVatesAPI/ViewFrustum.h" +#include "MantidGeometry/Crystal/PeakShape.h" +#include <vector> +#include <string> + +namespace Mantid +{ +namespace VATES +{ +class DLLExport CompositePeaksPresenterVsi : public PeaksPresenterVsi +{ +public: + CompositePeaksPresenterVsi(); + ~CompositePeaksPresenterVsi(); + virtual Mantid::API::IPeaksWorkspace_sptr getPeaksWorkspace(){throw std::runtime_error("The composite peaks presenter has no single peaks workspace.");} + std::vector<Mantid::API::IPeaksWorkspace_sptr> getPeaksWorkspaces(); + virtual std::vector<bool> getViewablePeaks(); + virtual void updateViewFrustum(ViewFrustum frustum); + virtual std::string getFrame(); + virtual std::string getPeaksWorkspaceName(){throw std::runtime_error("The composite peaks presenter has no peaks workspace");} + std::vector<std::string> getPeaksWorkspaceNames(); + virtual void getPeaksInfo(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, int row, Mantid::Kernel::V3D& position, double& radius); + void addPresenter(PeaksPresenterVsi_sptr presenter); + std::map<std::string, std::vector<bool>> getInitializedViewablePeaks(); + void removePresenter(std::string peaksWorkspaceName); + void updateWorkspaces(std::vector<std::string> peaksWorkspaceNames); + bool hasPeaks(); +private: + /// The list of presenters + std::vector<PeaksPresenterVsi_sptr> m_peaksPresenters; +}; +} +} +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/ConcretePeaksPresenterVsi.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/ConcretePeaksPresenterVsi.h new file mode 100644 index 0000000000000000000000000000000000000000..773eb04ac4fd0831b2b8ad74710b6440478ef6b7 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/ConcretePeaksPresenterVsi.h @@ -0,0 +1,42 @@ +#ifndef MANTID_VATES_CONCRETE_PEAKS_PRESENTER_VSI_H +#define MANTID_VATES_CONCRETE_PEAKS_PRESENTER_VSI_H + +#include "MantidKernel/System.h" +#include "MantidVatesAPI/PeaksPresenterVsi.h" +#include "MantidAPI/PeakTransform.h" +#include "MantidAPI/IPeaksWorkspace.h" +#include "MantidVatesAPI/ViewFrustum.h" +#include "MantidGeometry/Crystal/PeakShape.h" +#include <vector> + + +namespace Mantid +{ +namespace VATES +{ +class DLLExport ConcretePeaksPresenterVsi : public PeaksPresenterVsi +{ + public: + ConcretePeaksPresenterVsi(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, ViewFrustum frustum, std::string wsFrame); + ~ConcretePeaksPresenterVsi(); + virtual Mantid::API::IPeaksWorkspace_sptr getPeaksWorkspace(); + virtual std::vector<bool> getViewablePeaks(); + virtual void updateViewFrustum(ViewFrustum frustum); + virtual std::string getFrame(); + virtual std::string getPeaksWorkspaceName(); + virtual void getPeaksInfo(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, int row, Mantid::Kernel::V3D& position, double& radius); + private: + /// Get the max radius. + double getMaxRadius(Mantid::Geometry::PeakShape_sptr shape); + /// Viewable Peaks + std::vector<bool> m_viewablePeaks; + /// The viewable region + ViewFrustum m_viewableRegion; + /// The peaks workspace + Mantid::API::IPeaksWorkspace_sptr m_peaksWorkspace; + /// The frame + std::string m_frame; +}; +} +} +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataJsonManager.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataJsonManager.h index f29bc938eb9cee5da80d909b40f12e52d06000f7..7c24ceb80423476dabd3ff79f60557efd4f3150f 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataJsonManager.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataJsonManager.h @@ -1,7 +1,7 @@ #ifndef METADATA_JSON_MANAGER_H #define METADATA_JSON_MANAGER_H -#include <jsoncpp/json/json.h> +#include <json/json.h> #include "MantidKernel/System.h" #include <string> namespace Mantid @@ -54,12 +54,16 @@ namespace Mantid void setMaxValue(double maxValue); double getMaxValue(); + void setSpecialCoordinates(int specialCoordinates); + int getSpecialCoordinates(); + private: Json::Value metadataContainer; std::string instrument; double minValue; double maxValue; + int specialCoordinates; }; } } diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/NullPeaksPresenterVsi.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/NullPeaksPresenterVsi.h new file mode 100644 index 0000000000000000000000000000000000000000..72b0f84fd46509f2dd00cee1ad7a0b035a826500 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/NullPeaksPresenterVsi.h @@ -0,0 +1,30 @@ +#ifndef MANTID_VATES_NULL_PEAKS_PRESENTER +#define MANTID_VATES_NULL_PEAKS_PRESENTER + +#include "MantidKernel/System.h" +#include "MantidVatesAPI/PeaksPresenterVsi.h" +#include "MantidAPI/IPeaksWorkspace.h" +#include "MantidVatesAPI/ViewFrustum.h" +#include <vector> + +namespace Mantid +{ +namespace VATES +{ + class DLLExport NullPeaksPresenterVsi : public PeaksPresenterVsi + { + public: + NullPeaksPresenterVsi(){} + virtual ~NullPeaksPresenterVsi(){} + virtual Mantid::API::IPeaksWorkspace_sptr getPeaksWorkspace(){throw std::runtime_error("NullPeaksPresenterVsi does not implement this method. Misused");} + virtual std::vector<bool> getViewablePeaks() {throw std::runtime_error("NullPeaksPresenterVsi does not implement this method. Misused");} + virtual void updateViewFrustum(ViewFrustum ) {} + virtual std::string getFrame(){throw std::runtime_error("NullPeaksPresenterVsi does not implement this method. Misused");} + virtual std::string getPeaksWorkspaceName(){throw std::runtime_error("NullPeaksPresenterVsi does not implement this method. Misused");} + virtual void getPeaksInfo(Mantid::API::IPeaksWorkspace_sptr , int , + Mantid::Kernel::V3D& , double& ){throw std::runtime_error("NullPeaksPresenterVsi does not implement this method. Misused");} + }; +} +} + +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/PeaksPresenterVsi.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/PeaksPresenterVsi.h new file mode 100644 index 0000000000000000000000000000000000000000..5e4e7e92ff9b4380c3a8e816e9b277e5ec971cd9 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/PeaksPresenterVsi.h @@ -0,0 +1,34 @@ +#ifndef MANTID_VATES_PEAKS_PRESENTER_VSI_H +#define MANTID_VATES_PEAKS_PRESENTER_VSI_H + +#include "MantidKernel/System.h" +#include "MantidAPI/IPeaksWorkspace.h" +#include "MantidKernel/V3D.h" +#include <vector> +#include <string> + + +namespace Mantid +{ +namespace VATES +{ +class ViewFrustum; + +class DLLExport PeaksPresenterVsi +{ + public: + virtual ~PeaksPresenterVsi(){}; + virtual std::vector<bool> getViewablePeaks() = 0; + virtual Mantid::API::IPeaksWorkspace_sptr getPeaksWorkspace() = 0; + virtual void updateViewFrustum(ViewFrustum frustum) = 0; + virtual std::string getFrame() = 0; + virtual std::string getPeaksWorkspaceName() = 0; + virtual void getPeaksInfo(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, int row, + Mantid::Kernel::V3D& position, double& radius) = 0; +}; + +typedef boost::shared_ptr<PeaksPresenterVsi> PeaksPresenterVsi_sptr; +typedef boost::shared_ptr<const PeaksPresenterVsi> PeaksPresenterVsi_const_sptr; +} +} +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h new file mode 100644 index 0000000000000000000000000000000000000000..d6e6847ff2beca6d86f5c505fa32c976d8fcad8a --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h @@ -0,0 +1,175 @@ +#ifndef MANTID_PARAVIEW_VIEWFRUSTUM +#define MANTID_PARAVIEW_VIEWFRUSTUM + +#include "MantidKernel/System.h" +#include "MantidKernel/Matrix.h" +#include <stdexcept> +#include <cmath> +#include <cfloat> +#include <vector> + +namespace Mantid +{ +namespace VATES +{ + +enum PLANELOCATION{LEFTPLANE, RIGHTPLANE, BOTTOMPLANE, TOPPLANE, FARPLANE, NEARPLANE}; + +template<PLANELOCATION I, typename T> +class DLLExport FrustumPlane +{ + public: + explicit FrustumPlane(const T& paramA, const T& paramB, const T& paramC, const T& paramD) : m_paramA(paramA), + m_paramB(paramB), + m_paramC(paramC), + m_paramD(paramD){} + FrustumPlane(const FrustumPlane<I, T>& other) : m_paramA(other.m_paramA), + m_paramB(other.m_paramB), + m_paramC(other.m_paramC), + m_paramD(other.m_paramD){} + T A() {return m_paramA;} + T B() {return m_paramB;} + T C() {return m_paramC;} + T D() {return m_paramD;} + + std::vector<T> getPlaneCoefficients() + { + std::vector<T> coefficients; + coefficients.push_back(m_paramA); + coefficients.push_back(m_paramB); + coefficients.push_back(m_paramC); + coefficients.push_back(m_paramD); + + return coefficients; + } + +private: + T m_paramA; + T m_paramB; + T m_paramC; + T m_paramD; + enum{m_location = I}; +}; + +typedef FrustumPlane<LEFTPLANE, double> LeftPlane; +typedef FrustumPlane<RIGHTPLANE, double> RightPlane; +typedef FrustumPlane<BOTTOMPLANE, double> BottomPlane; +typedef FrustumPlane<TOPPLANE, double> TopPlane; +typedef FrustumPlane<FARPLANE, double> FarPlane; +typedef FrustumPlane<NEARPLANE, double> NearPlane; + + +class DLLExport ViewFrustum +{ + public: + ViewFrustum(const LeftPlane leftPlane, + const RightPlane rightPlane, + const BottomPlane bottomPlane, + const TopPlane topPlane, + const FarPlane farPlane, + const NearPlane nearPlane); + ViewFrustum(const ViewFrustum& other); + ~ViewFrustum(); + ViewFrustum& operator=(const ViewFrustum& other); + std::vector<std::pair<double, double>> toExtents() const; + std::string toExtentsAsString() const; + + private: + mutable LeftPlane m_leftPlane; + mutable RightPlane m_rightPlane; + mutable TopPlane m_topPlane; + mutable BottomPlane m_bottomPlane; + mutable FarPlane m_farPlane; + mutable NearPlane m_nearPlane; + + template<PLANELOCATION p1, PLANELOCATION p2, PLANELOCATION p3, typename T> + std::vector<T> getIntersectionPointThreePlanes(FrustumPlane<p1, T> plane1, FrustumPlane<p2, T> plane2, FrustumPlane<p3, T> plane3) const; + + template<typename T> + void initializeMatrix(Mantid::Kernel::Matrix<T>& matrix, std::vector<T> vec0, std::vector<T> vec1, std::vector<T> vec2) const; +}; + /** + * Get the intersection point of three planes using Cramer's rule. + * @param plane1 The first frustum plane + * @param plane2 The second frustum plane + * @param plane3 The third frustum plane + */ + template<PLANELOCATION p1, PLANELOCATION p2, PLANELOCATION p3, typename T> + std::vector<T> ViewFrustum::getIntersectionPointThreePlanes(FrustumPlane<p1, T> plane1, FrustumPlane<p2, T> plane2, FrustumPlane<p3, T> plane3) const + { + const size_t dim = 3; + + std::vector<T> aVec; + aVec.push_back(plane1.A()); + aVec.push_back(plane2.A()); + aVec.push_back(plane3.A()); + + std::vector<T> bVec; + bVec.push_back(plane1.B()); + bVec.push_back(plane2.B()); + bVec.push_back(plane3.B()); + + std::vector<T> cVec; + cVec.push_back(plane1.C()); + cVec.push_back(plane2.C()); + cVec.push_back(plane3.C()); + + // The input is Ax+By+Cz+D=0 but we need the form Ax+By+Cz=D + std::vector<T> dVec; + const T factor = -1; + dVec.push_back(factor*plane1.D()); + dVec.push_back(factor*plane2.D()); + dVec.push_back(factor*plane3.D()); + + // Get the different matrix permutations + Mantid::Kernel::Matrix<T> abcMatrix(dim, dim); + Mantid::Kernel::Matrix<T> dbcMatrix(dim, dim); + Mantid::Kernel::Matrix<T> adcMatrix(dim, dim); + Mantid::Kernel::Matrix<T> abdMatrix(dim, dim); + + initializeMatrix<T>(abcMatrix, aVec, bVec, cVec); + T abcDet = abcMatrix.determinant(); + if (abcDet == 0) + { + throw std::runtime_error("Determinant for view frustum is 0."); + } + + initializeMatrix<T>(dbcMatrix, dVec, bVec, cVec); + initializeMatrix<T>(adcMatrix, aVec, dVec, cVec); + initializeMatrix<T>(abdMatrix, aVec, bVec, dVec); + + T dbcDet = dbcMatrix.determinant(); + T adcDet = adcMatrix.determinant(); + T abdDet = abdMatrix.determinant(); + + std::vector<T> intersection; + intersection.push_back(dbcDet/abcDet); + intersection.push_back(adcDet/abcDet); + intersection.push_back(abdDet/abcDet); + + return intersection; + } + + /** + * Initialize the matrix with the plane coefficient vectors. + * @param matrix The matrix to initialze. + * @param vec0 The first vector. + * @param vec1 The second vector. + * @param vec2 The third vector. + */ + template<typename T> + void ViewFrustum::initializeMatrix(Mantid::Kernel::Matrix<T>& matrix, std::vector<T> vec0, std::vector<T> vec1, std::vector<T> vec2) const + { + std::pair<size_t, size_t> size = matrix.size(); + + if (size.first != 3 || size.second != 3) + { + throw std::runtime_error("Matrix for view frustum calculation has the wrong dimensionality."); + } + matrix.setColumn(0, vec0); + matrix.setColumn(1, vec1); + matrix.setColumn(2, vec2); + } +} +} +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkDataSetToPeaksFilteredDataSet.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkDataSetToPeaksFilteredDataSet.h new file mode 100644 index 0000000000000000000000000000000000000000..e59d30815622ebabe9d038a630dfbeee2de27238 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkDataSetToPeaksFilteredDataSet.h @@ -0,0 +1,72 @@ +#ifndef MANTID_VATES_PeaksFilter_H +#define MANTID_VATES_PeaksFilter_H + +#include "MantidKernel/System.h" +#include "MantidKernel/V3D.h" +#include "MantidAPI/IPeaksWorkspace.h" +#include "MantidVatesAPI/ProgressAction.h" +#include <string> + +class vtkUnstructuredGrid; + +namespace Mantid +{ +namespace VATES +{ + + /** + Class that selects only those data points which lie within the geometry of a peak. + + @date 17/02/2015 + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source + + 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://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + + class DLLExport vtkDataSetToPeaksFilteredDataSet + { + public: + vtkDataSetToPeaksFilteredDataSet(vtkUnstructuredGrid *input, vtkUnstructuredGrid *output); + virtual ~vtkDataSetToPeaksFilteredDataSet(); + /// Set the name of the peaks workspace + void initialize(std::vector<Mantid::API::IPeaksWorkspace_sptr> peaksWorkspaces, double radiusNoShape, int radiusType, int coordinateSystem); + /// Apply the peak filtering + void execute(ProgressAction& progressUpdating); + /// Get radius of no shape + double getRadiusNoShape(); + /// Get radius factor + double getRadiusFactor(); + private: + vtkDataSetToPeaksFilteredDataSet& operator=(const vtkDataSetToPeaksFilteredDataSet& other); + std::vector<std::pair<Mantid::Kernel::V3D, double>> getPeaksInfo(std::vector<Mantid::API::IPeaksWorkspace_sptr> peaksWorkspaces); + void addSinglePeak(Mantid::API::IPeak* peak, const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem, std::vector<std::pair<Mantid::Kernel::V3D, double>>& peaksInfo); + vtkUnstructuredGrid *m_inputData; ///< Data to peak filter + vtkUnstructuredGrid *m_outputData; ///< Peak filtered data + std::vector<Mantid::API::IPeaksWorkspace_sptr> m_peaksWorkspaces; ///< A list of peaks workspace names. + bool m_isInitialised; ///<Flag if the filter is initialized + double m_radiusNoShape; ///< The radius for peaks with no peak shape. + int m_radiusType; + double m_radiusFactor;///< By how much we want to trim the data set. + double m_defaultRadius; ///< A default radius. + int m_coordinateSystem;///< A coordinate system. + }; +} +} +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkEllipsoidTransformer.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkEllipsoidTransformer.h new file mode 100644 index 0000000000000000000000000000000000000000..c049b20e4820e31c693c31a0a2283982e0b750f6 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkEllipsoidTransformer.h @@ -0,0 +1,56 @@ +#ifndef MANTID_VATES_VTKELLIPSOIDTRANSFORMER_H_ +#define MANTID_VATES_VTKELLIPSOIDTRANSFORMER_H_ + +#include "MantidKernel/System.h" +#include <vtkSmartPointer.h> +#include <vector> +class vtkTransform; +namespace Mantid +{ +namespace Kernel +{ + class V3D; +} +} + +namespace Mantid +{ +namespace VATES +{ +/** + * Creates a vtkTransform for ellipsoids to rotate them into the correct direction. + @date 122/02/2015 + + Copyright © 2010 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source + + 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://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + +class DLLExport vtkEllipsoidTransformer +{ +public: + vtkEllipsoidTransformer(); + ~vtkEllipsoidTransformer(); + vtkSmartPointer<vtkTransform> generateTransform(std::vector<Mantid::Kernel::V3D> directions); +private: + Mantid::Kernel::V3D rotateVector(Mantid::Kernel::V3D original, Mantid::Kernel::V3D rotationAxis, double angle); +}; +} +} +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkPeakMarkerFactory.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkPeakMarkerFactory.h index c523a6859d83afd866f0f087a33443b7555d30ae..6f7cba3bbc0917e41a132bcd0719a3b4ff546270 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkPeakMarkerFactory.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkPeakMarkerFactory.h @@ -35,6 +35,8 @@ #include "MantidAPI/IPeaksWorkspace.h" #include "MantidVatesAPI/vtkDataSetFactory.h" +class vtkPolyData; + namespace Mantid { namespace VATES @@ -70,7 +72,7 @@ public: virtual void initialize(Mantid::API::Workspace_sptr workspace); /// Factory method - vtkDataSet* create(ProgressAction& progressUpdating) const; + vtkPolyData* create(ProgressAction& progressUpdating) const; virtual std::string getFactoryTypeName() const { @@ -88,7 +90,6 @@ protected: virtual void validate() const; private: - void validateWsNotNull() const; void validateDimensionsPresent() const; diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSinglePeakMarker.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSinglePeakMarker.h new file mode 100644 index 0000000000000000000000000000000000000000..a51f32bb1f0d2301130713c1ade8bbe87dc35d27 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSinglePeakMarker.h @@ -0,0 +1,47 @@ +#ifndef MANTID_VATES_SINGLEPEAKMARKER_H_ +#define MANTID_VATES_SINGLEPEAKMARKER_H_ + +#include "MantidKernel/System.h" +/** + Creates a single marker at a given position + + @date 23/02/2015 + + Copyright © 2010 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source + + 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://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + + +class vtkPolyData; + +namespace Mantid +{ +namespace VATES +{ + class DLLExport vtkSinglePeakMarker + { + public: + vtkSinglePeakMarker(); + ~vtkSinglePeakMarker(); + vtkPolyData* createSinglePeakMarker(double x, double y, double z, double radius); + }; +} +} +#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h index 3ad5c3ef481d8d9911204acc6c10a6b9e7759bdc..b793eae000e3e1216cfe1b8a6546d801d8a46e9b 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h @@ -9,6 +9,9 @@ #include "MantidMDEvents/MDEventWorkspace.h" #include "MantidVatesAPI/ThresholdRange.h" #include "MantidVatesAPI/vtkDataSetFactory.h" +#include "MantidVatesAPI/MetaDataExtractorUtils.h" +#include "MantidVatesAPI/MetadataJsonManager.h" +#include "MantidVatesAPI/VatesConfigurations.h" #include <vtkPoints.h> #include <boost/shared_ptr.hpp> #include <boost/scoped_ptr.hpp> @@ -91,6 +94,9 @@ public: /// Getter for the instrument virtual const std::string& getInstrument(); + /// Set the appropriate field data + virtual void setMetadata(vtkFieldData* fieldData, vtkDataSet* dataSet); + private: template<typename MDE, size_t nd> @@ -108,6 +114,9 @@ private: /// Template Method pattern to validate the factory before use. virtual void validate() const; + /// Add metadata + void addMetadata() const; + /// Threshold range strategy. ThresholdRange_scptr m_thresholdRange; @@ -158,6 +167,12 @@ private: /// Meta data extractor boost::scoped_ptr<MetaDataExtractorUtils> m_metaDataExtractor; + + /// Meata data json manager + boost::scoped_ptr<MetadataJsonManager> m_metadataJsonManager; + + /// Vates configuration + boost::scoped_ptr<VatesConfigurations> m_vatesConfigurations; }; } diff --git a/Code/Mantid/Vates/VatesAPI/src/CompositePeaksPresenterVsi.cpp b/Code/Mantid/Vates/VatesAPI/src/CompositePeaksPresenterVsi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..83220f7a9d5265ae0773698e7b6c0e4536b9b731 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/CompositePeaksPresenterVsi.cpp @@ -0,0 +1,151 @@ +#include "MantidVatesAPI/CompositePeaksPresenterVsi.h" +#include "MantidVatesAPI/PeaksPresenterVsi.h" +#include "MantidVatesAPI/ViewFrustum.h" +#include "MantidAPI/IPeaksWorkspace.h" + +#include <vector> +#include <map> +namespace Mantid +{ +namespace VATES +{ + /// Constructor + CompositePeaksPresenterVsi::CompositePeaksPresenterVsi(){} + + /// Destructor + CompositePeaksPresenterVsi::~CompositePeaksPresenterVsi(){} + + /** + * Update the view frustum + * @param frustum The view frustum + */ + void CompositePeaksPresenterVsi::updateViewFrustum(ViewFrustum frustum) + { + for (std::vector<PeaksPresenterVsi_sptr>::iterator it = m_peaksPresenters.begin(); it != m_peaksPresenters.end(); ++it) { + (*it)->updateViewFrustum(frustum); + } + } + + /** + * Get the viewable peaks. Essentially copied from the slice viewer. + * @retruns A vector indicating which of the peaks are viewable. + */ + std::vector<bool> CompositePeaksPresenterVsi::getViewablePeaks() + { + return std::vector<bool>(); + } + + /** + * Get the name of all peaks workspaces as a vector + * @returns A vector of all peaks workspace names. + */ + std::vector<std::string> CompositePeaksPresenterVsi::getPeaksWorkspaceNames() { + std::vector<std::string> peaksWorkspaceNames; + for (std::vector<PeaksPresenterVsi_sptr>::iterator it = m_peaksPresenters.begin(); it != m_peaksPresenters.end(); ++it) { + peaksWorkspaceNames.push_back((*it)->getPeaksWorkspaceName()); + } + return peaksWorkspaceNames; + } + + /** + * Extract the peak information regarding position and radius of the peak. + * @param peaksWorkspace A pointer to the peaks workspace + * @param position A reference to extract the position. + * @param radius A reference to extract the radius. + */ + void CompositePeaksPresenterVsi::getPeaksInfo(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, int row, Mantid::Kernel::V3D& position, double& radius) { + for (std::vector<PeaksPresenterVsi_sptr>::iterator it = m_peaksPresenters.begin(); it != m_peaksPresenters.end(); ++it) { + if ((*it)->getPeaksWorkspace() == peaksWorkspace) { + (*it)->getPeaksInfo(peaksWorkspace, row, position, radius); + } + } + } + + /** + * Get the frame in which the peak workspaces are evaluated. Note that all will have the same frame, so only the first + * workspace needs to be probed. + * @returns The coordinate frame. + */ + std::string CompositePeaksPresenterVsi::getFrame() { + std::string frame; + for (std::vector<PeaksPresenterVsi_sptr>::iterator it = m_peaksPresenters.begin(); it != m_peaksPresenters.end(); ++it) { + frame = (*it)->getFrame(); + break; + } + return frame; + } + + /** + * Add a new peaks workspace presenter + * @param presenter Add a new presenter to the composite. + */ + void CompositePeaksPresenterVsi::addPresenter(PeaksPresenterVsi_sptr presenter) { + m_peaksPresenters.push_back(presenter); + } + + /** + * Get a vector with peak workspace pointers for which presenters exist. + * @returns A vector with peaks workspace pointers + */ + std::vector<Mantid::API::IPeaksWorkspace_sptr> CompositePeaksPresenterVsi::getPeaksWorkspaces() { + std::vector<Mantid::API::IPeaksWorkspace_sptr> peaksWorkspaces; + for (std::vector<PeaksPresenterVsi_sptr>::iterator it = m_peaksPresenters.begin(); it != m_peaksPresenters.end(); ++it) { + peaksWorkspaces.push_back((*it)->getPeaksWorkspace()); + } + return peaksWorkspaces; + } + + /** + * Get the initialized viewable peaks. For each presenter return a vector with true for each peak + * @returns A vector of bool-vectors for each peaks presenter. + */ + std::map<std::string, std::vector<bool>> CompositePeaksPresenterVsi::getInitializedViewablePeaks(){ + std::map<std::string, std::vector<bool>> viewablePeaks; + for (std::vector<PeaksPresenterVsi_sptr>::iterator it = m_peaksPresenters.begin(); it != m_peaksPresenters.end(); ++it) { + viewablePeaks.insert(std::pair<std::string, std::vector<bool>>((*it)->getPeaksWorkspace()->getName(), std::vector<bool>((*it)->getPeaksWorkspace()->getNumberPeaks(), true))); + } + return viewablePeaks; + } + + /** + * Remove the presenters which are based on a certain peaks workspace. + * @param peaksWorkspaceName + */ + void CompositePeaksPresenterVsi::removePresenter(std::string peaksWorkspaceName) { + std::vector<PeaksPresenterVsi_sptr>::iterator it = m_peaksPresenters.begin(); + for (; it != m_peaksPresenters.end();) { + if ((*it)->getPeaksWorkspaceName() == peaksWorkspaceName) { + it = m_peaksPresenters.erase(it); + } else { + ++it; + } + } + } + + /** + * Update the presenters by checking if a presenter is still present, which is not needed any longer. + * @param peaksWorkspaceNames The names of all currently active peak sources. + */ + void CompositePeaksPresenterVsi::updateWorkspaces(std::vector<std::string>peaksWorkspaceNames) { + std::vector<std::string> storedPeaksWorkspaces = getPeaksWorkspaceNames(); + for (std::vector<std::string>::iterator it = storedPeaksWorkspaces.begin(); it != storedPeaksWorkspaces.end(); ++it) { + size_t count = std::count(peaksWorkspaceNames.begin(), peaksWorkspaceNames.end(), *it); + if (count == 0) { + removePresenter(*it); + } + } + } + + /** + * Check if there are any peaks availble. + * @returns If there are any peaks availbale. + */ + bool CompositePeaksPresenterVsi::hasPeaks(){ + if (m_peaksPresenters.size() > 0) { + return true; + } else { + return false; + } + } +} +} \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/src/ConcretePeaksPresenterVsi.cpp b/Code/Mantid/Vates/VatesAPI/src/ConcretePeaksPresenterVsi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..65ea5a5bac646ebce5c500f2918f9ab3238a09bd --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/ConcretePeaksPresenterVsi.cpp @@ -0,0 +1,183 @@ +#include "MantidVatesAPI/ConcretePeaksPresenterVsi.h" +#include "MantidVatesAPI/ViewFrustum.h" +#include "MantidAPI/IPeaksWorkspace.h" +#include "MantidAPI/AlgorithmManager.h" +#include "MantidDataObjects/NoShape.h" +#include "MantidDataObjects/PeakShapeSpherical.h" +#include "MantidDataObjects/PeakShapeEllipsoid.h" +#include "MantidKernel/SpecialCoordinateSystem.h" +#include "MantidAPI/IPeak.h" +#include "MantidGeometry/Crystal/PeakShape.h" +namespace Mantid +{ +namespace VATES +{ + /** + * Constructor + * @param peaksWorkspace The peaks workspace. + * @param frustum The view frustum + * @param frame The coordinate frame + */ + ConcretePeaksPresenterVsi::ConcretePeaksPresenterVsi(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, + ViewFrustum frustum, + std::string frame) : m_viewableRegion(frustum), + m_peaksWorkspace(peaksWorkspace), + m_frame(frame) + { + } + + ///Destructor + ConcretePeaksPresenterVsi::~ConcretePeaksPresenterVsi() + { + } + + /** + * Update the view frustum + * @param frustum The view frustum. + */ + void ConcretePeaksPresenterVsi::updateViewFrustum(ViewFrustum frustum) + { + m_viewableRegion = frustum; + } + + /** + * Get the viewable peaks. Essentially copied from the slice viewer. + * @retruns A vector indicating which of the peaks are viewable. + */ + std::vector<bool> ConcretePeaksPresenterVsi::getViewablePeaks() + { + //Need to apply a transform. + // Don't bother to find peaks in the region if there are no peaks to find. + Mantid::API::ITableWorkspace_sptr outTable; + + if (this->m_peaksWorkspace->getNumberPeaks() >= 1) + { + double effectiveRadius = 1e-2; + std::string viewable = m_viewableRegion.toExtentsAsString(); + Mantid::API::IPeaksWorkspace_sptr peaksWS = m_peaksWorkspace; + + Mantid::API::IAlgorithm_sptr alg = Mantid::API::AlgorithmManager::Instance().create("PeaksInRegion"); + alg->setChild(true); + alg->setRethrows(true); + alg->initialize(); + alg->setProperty("InputWorkspace", peaksWS); + alg->setProperty("OutputWorkspace", peaksWS->name() + "_peaks_in_region"); + alg->setProperty("Extents", viewable); + alg->setProperty("CheckPeakExtents", true); + alg->setProperty("PeakRadius", effectiveRadius); + alg->setPropertyValue("CoordinateFrame", m_frame); + alg->execute(); + outTable = alg->getProperty("OutputWorkspace"); + std::vector<bool> viewablePeaks(outTable->rowCount()); + for (size_t i = 0; i < outTable->rowCount(); ++i) { + viewablePeaks[i] = outTable->cell<Mantid::API::Boolean>(i, 1); + } + m_viewablePeaks = viewablePeaks; + } + else{ + // No peaks will be viewable + m_viewablePeaks = std::vector<bool>(); + } + + return m_viewablePeaks; + } + + /** + * Get the underlying peaks workspace + * @returns A pointer to the underlying peaks workspace. + */ + Mantid::API::IPeaksWorkspace_sptr ConcretePeaksPresenterVsi::getPeaksWorkspace() + { + return m_peaksWorkspace; + } + + /** + * Get the frame + * @returns The frame. + */ + std::string ConcretePeaksPresenterVsi::getFrame() + { + return m_frame; + } + + /** + * Get the name of the underlying peaks workspace. + * @returns The name of the peaks workspace. + */ + std::string ConcretePeaksPresenterVsi::getPeaksWorkspaceName() + { + return m_peaksWorkspace->getName(); + } + + /** + * Get the peaks info for a single peak, defined by the row in the peaks table. + * @param peaksWorkspace A pointer to a peaks workspace. + * @param row The row in the peaks table. + * @param position A reference which holds the position of the peak. + * @param radius A reference which holds the radius of the peak. + */ + void ConcretePeaksPresenterVsi::getPeaksInfo(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, int row, Mantid::Kernel::V3D& position, double& radius) + { + // Extract the position + Mantid::Kernel::SpecialCoordinateSystem coordinateSystem = peaksWorkspace->getSpecialCoordinateSystem(); + + switch(coordinateSystem) + { + case(Mantid::Kernel::SpecialCoordinateSystem::QLab): + position = peaksWorkspace->getPeak(row).getQLabFrame(); + break; + case(Mantid::Kernel::SpecialCoordinateSystem::QSample): + position = peaksWorkspace->getPeak(row).getQSampleFrame(); + break; + case(Mantid::Kernel::SpecialCoordinateSystem::HKL): + position = peaksWorkspace->getPeak(row).getHKL(); + break; + default: + throw std::invalid_argument("The coordinate system is invalid.\n"); + } + + // Peak radius + Mantid::Geometry::PeakShape_sptr shape(peaksWorkspace->getPeakPtr(row)->getPeakShape().clone()); + radius = getMaxRadius(shape); + } + + /** + * Get the maximal radius + * @param shape The shape of a peak. + * @param The maximal radius of the peak. + */ + double ConcretePeaksPresenterVsi::getMaxRadius(Mantid::Geometry::PeakShape_sptr shape) + { + const double defaultRadius = 1.0; + boost::shared_ptr<Mantid::DataObjects::NoShape> nullShape = boost::dynamic_pointer_cast<Mantid::DataObjects::NoShape>(shape); + boost::shared_ptr<Mantid::DataObjects::PeakShapeEllipsoid> ellipsoidShape = boost::dynamic_pointer_cast<Mantid::DataObjects::PeakShapeEllipsoid>(shape); + boost::shared_ptr<Mantid::DataObjects::PeakShapeSpherical> sphericalShape = boost::dynamic_pointer_cast<Mantid::DataObjects::PeakShapeSpherical>(shape); + + if (nullShape) + { + return defaultRadius; + } + else if (ellipsoidShape) + { + std::vector<double> radius = ellipsoidShape->abcRadii(); + return *(std::max_element(radius.begin(),radius.end())); + } + else if (sphericalShape) + { + if (double radius = sphericalShape->radius()) + { + return radius; + } + else + { + return defaultRadius; + } + } + else + { + return defaultRadius; + } + } + +} +} \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/src/LoadVTK.cpp b/Code/Mantid/Vates/VatesAPI/src/LoadVTK.cpp index 29c450db97fe41320a5d3389771d92186f41742e..4bc43553b977c210ed5412e656e8d8ad8305dac5 100644 --- a/Code/Mantid/Vates/VatesAPI/src/LoadVTK.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/LoadVTK.cpp @@ -66,7 +66,7 @@ namespace Mantid { namespace VATES { - DECLARE_FILELOADER_ALGORITHM(LoadVTK); + DECLARE_FILELOADER_ALGORITHM(LoadVTK) /** * Return the confidence with with this algorithm can load the file diff --git a/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp index 97796ff8e705da963664f8e41af9e3ff8346578d..8eecf215dbb592f815e0c26326dc8588b597d220 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp @@ -118,6 +118,9 @@ namespace Mantid // Set the instrument which is associated with the workspace. m_metadataJsonManager->setInstrument(m_metaDataExtractor->extractInstrument(eventWs)); + + // Set the special coordinates + m_metadataJsonManager->setSpecialCoordinates(m_specialCoords); //Call base-class extraction method. this->extractMetadata(eventWs); diff --git a/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp index 82023d01a58636ed53077e2d86a57a101a5ba14e..961a2baab4a5177cc86385f2db083e932afde2c6 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp @@ -120,6 +120,9 @@ namespace Mantid // Set the instrument which is associated with the workspace. m_metadataJsonManager->setInstrument(m_metaDataExtractor->extractInstrument(histoWs)); + // Set the special coordinates + m_metadataJsonManager->setSpecialCoordinates(m_specialCoords); + //Call base-class extraction method. this->extractMetadata(histoWs); } diff --git a/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp b/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp index 11fba10cb877d71f98bd3ac81a2840aa3261fdd1..250ba22b74c71a6dd5b9032852577a92c4066c70 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp @@ -1,14 +1,14 @@ #include "MantidVatesAPI/MetadataJsonManager.h" -#include <jsoncpp/json/json.h> -#include <jsoncpp/json/writer.h> -#include <jsoncpp/json/reader.h> +#include <json/json.h> +#include <json/writer.h> +#include <json/reader.h> namespace Mantid { namespace VATES { // Note that we need to have a non-empty default string - MetadataJsonManager::MetadataJsonManager() : instrument("_EMPTY_"), minValue(0.0), maxValue(1.0) + MetadataJsonManager::MetadataJsonManager() : instrument("_EMPTY_"), minValue(0.0), maxValue(1.0), specialCoordinates(-1) { } @@ -29,6 +29,7 @@ namespace Mantid metadataContainer["instrument"] = instrument; metadataContainer["minValue"] = minValue; metadataContainer["maxValue"] = maxValue; + metadataContainer["specialCoordinates"] = specialCoordinates; return writer.write(metadataContainer); } @@ -75,6 +76,16 @@ namespace Mantid { instrument = "_EMPTY_"; } + + // Set the instrument + if (metadataContainer.isObject() && metadataContainer.isMember("specialCoordinates")) + { + specialCoordinates = metadataContainer["specialCoordinates"].asInt(); + } + else + { + specialCoordinates = -1; + } } } @@ -132,5 +143,23 @@ namespace Mantid { return instrument; } + + /** + * Set the special coordinates. + * @param specialCoordinates. The special coordinates. + */ + void MetadataJsonManager::setSpecialCoordinates(int specialCoordinates) + { + this->specialCoordinates = specialCoordinates; + } + + /** + * Get the special coordinates + * @returns The special coordinates. + */ + int MetadataJsonManager::getSpecialCoordinates() + { + return specialCoordinates; + } } } \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/src/ViewFrustum.cpp b/Code/Mantid/Vates/VatesAPI/src/ViewFrustum.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ad1a7317e4f7081b10ac40e29c97f0892b6d8d66 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/ViewFrustum.cpp @@ -0,0 +1,129 @@ +#include "MantidVatesAPI/ViewFrustum.h" +#include "MantidKernel/Matrix.h" +#include <sstream> +#include <cmath> +#include <cfloat> + +namespace Mantid +{ +namespace VATES +{ + /** + * Represents a view frustum. It contains the parameters for the six plane equations that define the view frustum. Note that the plane + * normals point into the box + * @param leftPlane The left plane. + * @param rightPlane The right plane. + * @param topPlane The top plane. + * @param bottomPlane The bottom plane. + * @param farPlane The far plane. + * @param nearPlane The near plane. + */ + ViewFrustum::ViewFrustum(const LeftPlane leftPlane, const RightPlane rightPlane, const BottomPlane bottomPlane, + const TopPlane topPlane, const FarPlane farPlane, const NearPlane nearPlane) : m_leftPlane(leftPlane), + m_rightPlane(rightPlane), + m_topPlane(topPlane), + m_bottomPlane(bottomPlane), + m_farPlane(farPlane), + m_nearPlane(nearPlane){} + /** + * Copy constructor for the view frustum. + * @param other The initializing view frustum. + */ + ViewFrustum::ViewFrustum(const ViewFrustum& other): m_leftPlane(other.m_leftPlane), + m_rightPlane(other.m_rightPlane), + m_topPlane(other.m_topPlane), + m_bottomPlane(other.m_bottomPlane), + m_farPlane(other.m_farPlane), + m_nearPlane(other.m_nearPlane){} + /// Destructor + ViewFrustum::~ViewFrustum(){} + + /** + * Assignment operator + * @param other The assigned view frustum. + */ + ViewFrustum& ViewFrustum::operator=(const ViewFrustum& other) + { + if (&other != this) + { + m_leftPlane = other.m_leftPlane; + m_rightPlane = other.m_rightPlane; + m_topPlane = other.m_topPlane; + m_bottomPlane = other.m_bottomPlane; + m_farPlane = other.m_farPlane; + m_nearPlane = other.m_nearPlane; + } + + return *this; + } + + /** + * Get the extents of the View frustum. We take the minimal rectangular box which in contains the + * view frustum fully. + * @returns A vector with the extents + */ + std::vector<std::pair<double, double>> ViewFrustum::toExtents() const + { + // Get the eight corner points of the view frustum + std::vector<std::vector<double>> frustumPoints; + frustumPoints.push_back(getIntersectionPointThreePlanes<LEFTPLANE, TOPPLANE, FARPLANE, double>(m_leftPlane, m_topPlane, m_farPlane)); + frustumPoints.push_back(getIntersectionPointThreePlanes<LEFTPLANE, TOPPLANE, NEARPLANE, double>(m_leftPlane, m_topPlane, m_nearPlane)); + + frustumPoints.push_back(getIntersectionPointThreePlanes<LEFTPLANE, BOTTOMPLANE, FARPLANE, double>(m_leftPlane, m_bottomPlane, m_farPlane)); + frustumPoints.push_back(getIntersectionPointThreePlanes<LEFTPLANE, BOTTOMPLANE, NEARPLANE, double>(m_leftPlane, m_bottomPlane, m_nearPlane)); + + frustumPoints.push_back(getIntersectionPointThreePlanes<RIGHTPLANE, TOPPLANE, FARPLANE, double>(m_rightPlane, m_topPlane, m_farPlane)); + frustumPoints.push_back(getIntersectionPointThreePlanes<RIGHTPLANE, TOPPLANE, NEARPLANE, double>(m_rightPlane, m_topPlane, m_nearPlane)); + + frustumPoints.push_back(getIntersectionPointThreePlanes<RIGHTPLANE, BOTTOMPLANE, FARPLANE, double>(m_rightPlane, m_bottomPlane, m_farPlane)); + frustumPoints.push_back(getIntersectionPointThreePlanes<RIGHTPLANE, BOTTOMPLANE, NEARPLANE, double>(m_rightPlane, m_bottomPlane, m_nearPlane)); + + std::vector<std::pair<double, double>> extents; + + for (int i = 0; i < 3; ++i) + { + std::pair<double, double> minMax(DBL_MAX, -DBL_MAX); + for (std::vector<std::vector<double>>::iterator it = frustumPoints.begin(); it != frustumPoints.end(); ++it) + { + if ((*it)[i] < minMax.first) + { + minMax.first = (*it)[i]; + } + + if ((*it)[i] > minMax.second) + { + minMax.second = (*it)[i]; + } + } + + extents.push_back(minMax); + } + + return extents; + } + + /** + * Get the extents as a concatenated string. + * @returns The extens of the view frustum as a concatenated string + */ + std::string ViewFrustum::toExtentsAsString() const + { + std::vector<std::pair<double, double>> extents = toExtents(); + + std::stringstream ss; + + for (std::vector<std::pair<double, double>>::iterator it = extents.begin(); it != extents.end(); ++it) + { + ss << it->first << "," << it->second; + + if ((it+1)!= extents.end()) + { + ss << ","; + } + } + + return ss.str(); + } + +} +} diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToPeaksFilteredDataSet.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToPeaksFilteredDataSet.cpp new file mode 100644 index 0000000000000000000000000000000000000000..833aa6ff9c370dbd2c453130ee6ae25cbdd28ee6 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToPeaksFilteredDataSet.cpp @@ -0,0 +1,308 @@ +#include "MantidVatesAPI/vtkDataSetToPeaksFilteredDataSet.h" +#include "MantidAPI/IPeak.h" +#include "MantidAPI/IPeaksWorkspace.h" +#include "MantidDataObjects/NoShape.h" +#include "MantidDataObjects/PeakShapeEllipsoid.h" +#include "MantidDataObjects/PeakShapeSpherical.h" +#include "MantidGeometry/Crystal/PeakShape.h" +#include "MantidKernel/SpecialCoordinateSystem.h" +#include "MantidKernel/V3D.h" +#include "MantidKernel/ReadLock.h" +#include "MantidKernel/WarningSuppressions.h" +#include "MantidVatesAPI/ProgressAction.h" + +#include <vtkExtractSelection.h> +#include <vtkIdTypeArray.h> +#include <vtkNew.h> +#include <vtkPoints.h> +#include <vtkSelection.h> +#include <vtkSelectionNode.h> +#include <vtkSmartPointer.h> +#include <vtkUnstructuredGrid.h> +#include <vtkFieldData.h> +#include <vtkIdList.h> +#include <vtkFieldData.h> + +#include <boost/shared_ptr.hpp> +#include <stdexcept> +#include <string> +#include <vector> +#include <algorithm> +#include <cmath> + + +namespace Mantid +{ +namespace VATES +{ + /** + * Standard constructor for object. + * @param input : The dataset to peaks filter + * @param output : The resulting peaks filtered dataset + */ + vtkDataSetToPeaksFilteredDataSet::vtkDataSetToPeaksFilteredDataSet(vtkUnstructuredGrid *input, + vtkUnstructuredGrid *output) : + m_inputData(input), + m_outputData(output), + m_isInitialised(false), + m_radiusNoShape(0.2), + m_radiusType(0), + m_radiusFactor(2), + m_defaultRadius(0.1), + m_coordinateSystem(0) + { + if (NULL == m_inputData) + { + throw std::runtime_error("Cannot construct vtkDataSetToPeaksFilteredDataSet with NULL input vtkUnstructuredGrid"); + } + if (NULL == m_outputData) + { + throw std::runtime_error("Cannot construct vtkDataSetToPeaksFilteredDataSet with NULL output vtkUnstructuredGrid"); + } + } + + + vtkDataSetToPeaksFilteredDataSet::~vtkDataSetToPeaksFilteredDataSet() + { + + } + + /** + * Set the value for the underlying peaks workspace + * @param peaksWorkspaces : A list of peak workspace names. + * @param radiusNoShape : The peak radius for no shape. + * @param radiusType : The type of the radius: Radius(0), Outer Radius(10, Inner Radius(1) + * @param coordinateSystem: A coordinate system. + */ + void vtkDataSetToPeaksFilteredDataSet::initialize(std::vector<Mantid::API::IPeaksWorkspace_sptr> peaksWorkspaces, double radiusNoShape, int radiusType, int coordinateSystem) + { + m_peaksWorkspaces = peaksWorkspaces; + m_radiusNoShape = radiusNoShape; + m_radiusType = radiusType; + m_isInitialised = true; + m_coordinateSystem = coordinateSystem; + } + + /** + * Process the input data. First, get all the peaks and their associated geometry. Then filter + * through the input to find the peaks which lie within a peak. Then apply then to the output data. + * Then update the metadata. See http://www.vtk.org/Wiki/VTK/Examples/Cxx/PolyData/ExtractSelection + * @param progressUpdating The handle for the progress bar. + */ + void vtkDataSetToPeaksFilteredDataSet::execute(ProgressAction& progressUpdating) + { + if (!m_isInitialised) + { + throw std::runtime_error("vtkDataSetToPeaksFilteredDataSet needs initialize run before executing"); + } + + // Get the peaks location and the radius information + std::vector<std::pair<Mantid::Kernel::V3D, double>> peaksInfo = getPeaksInfo(m_peaksWorkspaces); + + // Compare each element of the vtk data set and check which ones to keep + vtkPoints *points = m_inputData->GetPoints(); + + vtkSmartPointer<vtkIdTypeArray> ids = vtkSmartPointer<vtkIdTypeArray>::New(); + ids->SetNumberOfComponents(1); + + double progressFactor = 1.0/double(points->GetNumberOfPoints()); + for(int i = 0; i < points->GetNumberOfPoints(); i++) + { + progressUpdating.eventRaised(double(i)*progressFactor); + double point[3]; + points->GetPoint(i, point); + + // Compare to Peaks + const size_t numberOfPeaks = peaksInfo.size(); + size_t counter = 0; + while (counter < numberOfPeaks) + { + // Calcuate the differnce between the vtkDataSet point and the peak. Needs to be smaller than the radius + double squaredDifference = 0; + for (int k = 0; k <3; k++) + { + squaredDifference += (point[k] - peaksInfo[counter].first[k])* (point[k] - peaksInfo[counter].first[k]); + } + + if (squaredDifference <= (peaksInfo[counter].second*peaksInfo[counter].second)) + { + ids->InsertNextValue(i); + break; + } + counter++; + } + } + + // Now we have all ids for the points, we need to retrieve the ids of the cells + std::map<vtkIdType, vtkIdType> uniqueCellTester; + vtkSmartPointer<vtkIdTypeArray> cellIds = vtkSmartPointer<vtkIdTypeArray>::New(); + + for (int i = 0; i < ids->GetNumberOfTuples(); i++) { + vtkIdType pId = ids->GetValue(i); + + vtkSmartPointer<vtkIdList> cIdList = vtkSmartPointer<vtkIdList>::New(); + cIdList->Initialize(); + + m_inputData->GetPointCells(pId, cIdList); + + if (cIdList->GetNumberOfIds() == 0) { + continue; + } + + vtkIdType cId = cIdList->GetId(0); + + if (uniqueCellTester.count(cId) == 0) { + cellIds->InsertNextValue(cId); + uniqueCellTester.insert(std::pair<vtkIdType, vtkIdType>(cId, cId)); + } + } + + // Create the selection node and tell it the type of selection + vtkSmartPointer<vtkSelectionNode> selectionNode = vtkSmartPointer<vtkSelectionNode>::New(); + selectionNode->SetFieldType(vtkSelectionNode::CELL); + selectionNode->SetContentType(vtkSelectionNode::INDICES); + selectionNode->SetSelectionList(cellIds); + + vtkSmartPointer<vtkSelection> selection = vtkSmartPointer<vtkSelection>::New(); + selection->AddNode(selectionNode); + + // We are not setting up a pipeline here, cannot access vtkAlgorithmOutput + vtkSmartPointer<vtkExtractSelection> extractSelection = vtkSmartPointer<vtkExtractSelection>::New(); + extractSelection->SetInputData(0,m_inputData); + extractSelection->SetInputData(1, selection); + extractSelection->Update(); + + //Extract + m_outputData->ShallowCopy(extractSelection->GetOutput()); + } + + /** + * Get the peaks information which is the position and the largest radius of the peak. + * @param A list of peaks workspaces + * @returns A list of pair information which contains the position and the radius. + */ + std::vector<std::pair<Mantid::Kernel::V3D, double>> vtkDataSetToPeaksFilteredDataSet::getPeaksInfo(std::vector<Mantid::API::IPeaksWorkspace_sptr> peaksWorkspaces) + { + std::vector<std::pair<Mantid::Kernel::V3D, double>> peaksInfo; + // Iterate over all peaksworkspaces and add the their info to the output vector + for (std::vector<Mantid::API::IPeaksWorkspace_sptr>::iterator it = peaksWorkspaces.begin(); it != peaksWorkspaces.end(); ++it) + { + const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem = static_cast<Mantid::Kernel::SpecialCoordinateSystem>(m_coordinateSystem); + int numPeaks = (*it)->getNumberPeaks(); + + // Iterate over all peaks for the workspace + for (int i = 0; i < numPeaks ; i++) + { + Mantid::API::IPeak* peak = (*it)->getPeakPtr(i); + + addSinglePeak(peak, coordinateSystem, peaksInfo); + } + } + return peaksInfo; + } + +GCC_DIAG_OFF(strict-aliasing) + /** + * Add information for a single peak to the peakInfo vector. + * @param peak The peak from which the information will be extracted. + * @param coordinateSystem The coordinate system in which the peaks position should be retrieved. + * @param peaksInfo A reference to the vector containing peak information. + * @param index The index of the peak in the peaksInfo vector. + */ + void vtkDataSetToPeaksFilteredDataSet::addSinglePeak(Mantid::API::IPeak* peak, const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem, std::vector<std::pair<Mantid::Kernel::V3D, double>>& peaksInfo) + { + double radius = m_defaultRadius; + const Mantid::Geometry::PeakShape& shape = peak->getPeakShape(); + std::string shapeName = shape.shapeName(); + + // Get the radius and the position for the correct peak shape + if (shapeName == Mantid::DataObjects::PeakShapeSpherical::sphereShapeName()) + { + const Mantid::DataObjects::PeakShapeSpherical& sphericalShape = dynamic_cast<const Mantid::DataObjects::PeakShapeSpherical&>(shape); + if (m_radiusType == 0) + { + radius = sphericalShape.radius(); + } + else if (m_radiusType == 1) + { + boost::optional<double> radOut = sphericalShape.backgroundOuterRadius(); + if (radOut.is_initialized()) { + radius = radOut.get(); + } + } + else if (m_radiusType == 2) + { + boost::optional<double> radIn = sphericalShape.backgroundInnerRadius(); + if (radIn.is_initialized()) { + radius = radIn.get(); + } + } + else + { + throw std::invalid_argument("The shperical peak shape does not have a radius. \n"); + } + } + else if (shapeName == Mantid::DataObjects::PeakShapeEllipsoid::ellipsoidShapeName()) + { + const Mantid::DataObjects::PeakShapeEllipsoid& ellipticalShape = dynamic_cast<const Mantid::DataObjects::PeakShapeEllipsoid&>(shape); + if (m_radiusType == 0) + { + std::vector<double> radii(ellipticalShape.abcRadii()); + radius = *(std::max_element(radii.begin(), radii.end())); + } + else if (m_radiusType == 1) + { + std::vector<double> radii(ellipticalShape.abcRadiiBackgroundOuter()); + radius = *(std::max_element(radii.begin(), radii.end())); + } + else if (m_radiusType == 2) + { + std::vector<double> radii(ellipticalShape.abcRadiiBackgroundInner()); + radius = *(std::max_element(radii.begin(), radii.end())); + } + else + { + throw std::invalid_argument("The ellipsoidal peak shape does not have a radius. \n"); + } + } + else + { + radius = m_radiusNoShape; + } + + // Get the position in the correct frame. + switch(coordinateSystem) + { + case(Mantid::Kernel::SpecialCoordinateSystem::HKL): + peaksInfo.push_back(std::pair<Mantid::Kernel::V3D, double>(peak->getHKL(), radius*m_radiusFactor)); + break; + case(Mantid::Kernel::SpecialCoordinateSystem::QLab): + peaksInfo.push_back(std::pair<Mantid::Kernel::V3D, double>(peak->getQLabFrame(), radius*m_radiusFactor)); + break; + case(Mantid::Kernel::SpecialCoordinateSystem::QSample): + peaksInfo.push_back(std::pair<Mantid::Kernel::V3D, double>(peak->getQSampleFrame(), radius*m_radiusFactor)); + break; + default: + throw std::invalid_argument("The special coordinate systems don't match."); + } + } +//GCC_DIAG_ON(strict-aliasing) + /** + * Get the radiys for no shape + * @returns The shape of the radius. + */ + double vtkDataSetToPeaksFilteredDataSet::getRadiusNoShape(){ + return m_radiusNoShape; + } + + /** + * Get the radius factor which is used to calculate the radius of the culled data set around each peak + * The culling radius is the radius of the peak times the radius factor. + * @returns The radius factor. + */ + double vtkDataSetToPeaksFilteredDataSet::getRadiusFactor() { + return m_radiusFactor; + } +} +} + diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkEllipsoidTransformer.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkEllipsoidTransformer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6437744474d87fbe1539ae8c8c8abb288518c840 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/vtkEllipsoidTransformer.cpp @@ -0,0 +1,78 @@ +#include "MantidVatesAPI/vtkEllipsoidTransformer.h" +#include "MantidKernel/V3D.h" + +#include <vtkSmartPointer.h> +#include <vtkTransform.h> +#include <vector> +#include <cmath> + +namespace Mantid +{ +namespace VATES +{ + vtkEllipsoidTransformer::vtkEllipsoidTransformer(){} + + vtkEllipsoidTransformer::~vtkEllipsoidTransformer(){} + + /** + * Generates a transform based on the directions of the ellipsoid + * @param directions The directions of the ellipsoid. + * @returns A transform for the ellipsoid. + */ + vtkSmartPointer<vtkTransform> vtkEllipsoidTransformer::generateTransform(std::vector<Mantid::Kernel::V3D> directions) + { + // The original ellipsoid is set to have its principal axis along the x axis and the first minor axis along the y axis. + Mantid::Kernel::V3D principalAxisOriginal(1.0, 0.0, 0.0); + Mantid::Kernel::V3D principalAxisTransformed(directions[0]); + Mantid::Kernel::V3D minorAxisOriginal(0.0, 1.0, 0.0); + Mantid::Kernel::V3D minorAxisTransformed(directions[1]); + + // Compute the axis of rotation. This is the normal between the original and the transformed direction + Mantid::Kernel::V3D rotationAxis1 = principalAxisOriginal.cross_prod(principalAxisTransformed); + rotationAxis1 = rotationAxis1/rotationAxis1.norm(); + + // Compute the angle of rotation, i.e. the angle between the original and the transformed axis. + double angle1 = acos(principalAxisOriginal.scalar_prod(principalAxisTransformed) + /principalAxisOriginal.norm()/principalAxisTransformed.norm()); + + // After the prinicpal axis is rotated into its right position we need to rotate the (rotated) minor axis + // into its right position. The rotation axis is given by the new prinicipal rotation axis + Mantid::Kernel::V3D minorAxisOriginalRotated(rotateVector(minorAxisOriginal, rotationAxis1, angle1)); + + Mantid::Kernel::V3D rotationAxis2(minorAxisOriginalRotated.cross_prod(minorAxisTransformed)); + rotationAxis2 = rotationAxis2/rotationAxis2.norm(); + double angle2 = acos(minorAxisOriginalRotated.scalar_prod(minorAxisTransformed) + /minorAxisOriginalRotated.norm()/minorAxisTransformed.norm()); + + vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New(); + + double angle1Degree = angle1*180/M_PI; + double angle2Degree = angle2*180/M_PI; + + // The total transform is T = T_rot2*T_rot1. Note that we need to add the last operation first! + transform->RotateWXYZ(angle2Degree, rotationAxis2[0], rotationAxis2[1], rotationAxis2[2]); + transform->RotateWXYZ(angle1Degree, rotationAxis1[0], rotationAxis1[1], rotationAxis1[2]); + + return transform; + } + + /** + * Rotate the a given vector around a specified axis by a specified angle. See http://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula + * @param original The original vector + * @param rotationAxis The axis around which to rotate. + * @param angle The rotation angle. + * @returns The rotated vector. + */ + Mantid::Kernel::V3D vtkEllipsoidTransformer::rotateVector(Mantid::Kernel::V3D original, Mantid::Kernel::V3D rotationAxis, double angle) + { + Mantid::Kernel::V3D cross(rotationAxis.cross_prod(original)); + double scalar = rotationAxis.scalar_prod(original); + double cos = std::cos(angle); + double sin = std::sin(angle); + + Mantid::Kernel::V3D rotated = original*cos + cross*sin + rotationAxis*(scalar)*(1-cos); + + return rotated; + } +} +} \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkPeakMarkerFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkPeakMarkerFactory.cpp index 6171b6c9ac604ed0e38f72d089129064b791c7db..be22450371ac2316f269c44710fa64f2cb66e35a 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkPeakMarkerFactory.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkPeakMarkerFactory.cpp @@ -1,17 +1,35 @@ #include "MantidVatesAPI/vtkPeakMarkerFactory.h" #include "MantidVatesAPI/ProgressAction.h" +#include "MantidVatesAPI/vtkEllipsoidTransformer.h" #include <boost/math/special_functions/fpclassify.hpp> #include "MantidAPI/Workspace.h" #include "MantidAPI/IPeaksWorkspace.h" #include "MantidAPI/IPeak.h" +#include "MantidGeometry/Crystal/PeakShape.h" +#include "MantidDataObjects/PeakShapeSpherical.h" +#include "MantidDataObjects/PeakShapeEllipsoid.h" #include "MantidKernel/V3D.h" +#include "MantidKernel/ReadLock.h" + +#include <vtkAxes.h> +#include "vtkParametricEllipsoid.h" +#include "vtkParametricFunctionSource.h" +#include <vtkPolyDataAlgorithm.h> +#include <vtkAppendPolyData.h> #include <vtkVertex.h> #include <vtkGlyph3D.h> #include <vtkSphereSource.h> #include <vtkUnstructuredGrid.h> #include <vtkFloatArray.h> #include <vtkCellData.h> -#include "MantidKernel/ReadLock.h" +#include <vtkPolyData.h> +#include <vtkTransform.h> +#include <vtkTransformPolyDataFilter.h> +#include <vtkPVGlyphFilter.h> +#include <vtkSmartPointer.h> + +#include <vtkLineSource.h> +#include <cmath> using Mantid::API::IPeaksWorkspace; using Mantid::API::IPeak; @@ -91,12 +109,12 @@ namespace VATES } - /** + /** Create the vtkStructuredGrid from the provided workspace @param progressUpdating: Reporting object to pass progress information up the stack. @return vtkPolyData glyph. */ - vtkDataSet* vtkPeakMarkerFactory::create(ProgressAction& progressUpdating) const + vtkPolyData* vtkPeakMarkerFactory::create(ProgressAction& progressUpdating) const { validate(); @@ -105,28 +123,32 @@ namespace VATES // Acquire a scoped read-only lock to the workspace (prevent segfault from algos modifying ws) Mantid::Kernel::ReadLock lock(*m_workspace); - // Points generator - vtkPoints *points = vtkPoints::New(); - points->Allocate(static_cast<int>(numPeaks)); - - vtkFloatArray * signal = vtkFloatArray::New(); - signal->Allocate(numPeaks); - signal->SetName(m_scalarName.c_str()); - signal->SetNumberOfComponents(1); - - // What we'll return - vtkUnstructuredGrid *visualDataSet = vtkUnstructuredGrid::New(); - visualDataSet->Allocate(numPeaks); - visualDataSet->SetPoints(points); - visualDataSet->GetCellData()->SetScalars(signal); + vtkEllipsoidTransformer ellipsoidTransformer; + const int resolution = 8; double progressFactor = 1.0/double(numPeaks); + vtkAppendPolyData* appendFilter = vtkAppendPolyData::New(); // Go peak-by-peak for (int i=0; i < numPeaks; i++) { progressUpdating.eventRaised(double(i)*progressFactor); + // Point + vtkPoints *peakPoint = vtkPoints::New(); + peakPoint->Allocate(1); + + vtkFloatArray * peakSignal = vtkFloatArray::New(); + peakSignal->Allocate(1); + peakSignal->SetName(m_scalarName.c_str()); + peakSignal->SetNumberOfComponents(1); + + // What we'll return + vtkUnstructuredGrid *peakDataSet = vtkUnstructuredGrid::New(); + peakDataSet->Allocate(1); + peakDataSet->SetPoints(peakPoint); + peakDataSet->GetCellData()->SetScalars(peakSignal); + IPeak & peak = m_workspace->getPeak(i); // Choose the dimensionality of the position to show @@ -152,23 +174,115 @@ namespace VATES // One point per peak vtkVertex * vertex = vtkVertex::New(); - vtkIdType id_xyz = points->InsertNextPoint(x,y,z); + vtkIdType id_xyz = peakPoint->InsertNextPoint(x,y,z); vertex->GetPointIds()->SetId(0, id_xyz); - visualDataSet->InsertNextCell(VTK_VERTEX, vertex->GetPointIds()); + peakDataSet->InsertNextCell(VTK_VERTEX, vertex->GetPointIds()); // The integrated intensity = the signal on that point. - signal->InsertNextValue(static_cast<float>( peak.getIntensity() )); + peakSignal->InsertNextValue(static_cast<float>( peak.getIntensity() )); + peakPoint->Squeeze(); + peakDataSet->Squeeze(); - } // for each peak + // Add a glyph and append to the appendFilter + const Mantid::Geometry::PeakShape& shape = m_workspace->getPeakPtr(i)->getPeakShape(); - points->Squeeze(); - visualDataSet->Squeeze(); + // Pick the radius up from the factory if possible, otherwise use the user-provided value. + vtkPolyDataAlgorithm* shapeMarker = NULL; + if(shape.shapeName() == Mantid::DataObjects::PeakShapeSpherical::sphereShapeName()) + { + const Mantid::DataObjects::PeakShapeSpherical& sphericalShape = dynamic_cast<const Mantid::DataObjects::PeakShapeSpherical&>(shape); + double peakRadius = sphericalShape.radius(); + vtkSphereSource *sphere = vtkSphereSource::New(); + sphere->SetRadius(peakRadius); + sphere->SetPhiResolution(resolution); + sphere->SetThetaResolution(resolution); + shapeMarker = sphere; + } + else if (shape.shapeName() == Mantid::DataObjects::PeakShapeEllipsoid::ellipsoidShapeName()) + { + const Mantid::DataObjects::PeakShapeEllipsoid& ellipticalShape = dynamic_cast<const Mantid::DataObjects::PeakShapeEllipsoid&>(shape); + std::vector<double> radii = ellipticalShape.abcRadii(); + std::vector<Mantid::Kernel::V3D> directions; + + switch (m_dimensionToShow) + { + case Peak_in_Q_lab: + directions = ellipticalShape.directions(); + break; + case Peak_in_Q_sample: + { + Mantid::Kernel::Matrix<double> goniometerMatrix = peak.getGoniometerMatrix(); + if (goniometerMatrix.Invert()) + { + directions = ellipticalShape.getDirectionInSpecificFrame(goniometerMatrix); + } + else + { + directions = ellipticalShape.directions(); + } + } + break; + case Peak_in_HKL: + directions = ellipticalShape.directions(); + break; + default: + directions = ellipticalShape.directions(); + } + + vtkParametricEllipsoid* ellipsoid = vtkParametricEllipsoid::New(); + ellipsoid->SetXRadius(radii[0]); + ellipsoid->SetYRadius(radii[1]); + ellipsoid->SetZRadius(radii[2]); + + vtkParametricFunctionSource* ellipsoidSource = vtkParametricFunctionSource::New(); + ellipsoidSource->SetParametricFunction(ellipsoid); + ellipsoidSource->SetUResolution(resolution); + ellipsoidSource->SetVResolution(resolution); + ellipsoidSource->SetWResolution(resolution); + ellipsoidSource->Update(); + + vtkSmartPointer<vtkTransform> transform = ellipsoidTransformer.generateTransform(directions); + + vtkTransformPolyDataFilter* transformFilter = vtkTransformPolyDataFilter::New(); + transformFilter->SetTransform(transform); + transformFilter->SetInputConnection(ellipsoidSource->GetOutputPort()); + transformFilter->Update(); + shapeMarker = transformFilter; + } + else + { + vtkAxes* axis = vtkAxes::New(); + axis->SymmetricOn(); + axis->SetScaleFactor(0.3); + + vtkTransform* transform = vtkTransform::New(); + const double rotationDegrees = 45; + transform->RotateX(rotationDegrees); + transform->RotateY(rotationDegrees); + transform->RotateZ(rotationDegrees); + + vtkTransformPolyDataFilter* transformFilter = vtkTransformPolyDataFilter::New(); + transformFilter->SetTransform(transform); + transformFilter->SetInputConnection(axis->GetOutputPort()); + transformFilter->Update(); + shapeMarker = transformFilter; + } - return visualDataSet; - } + vtkPVGlyphFilter *glyphFilter = vtkPVGlyphFilter::New(); + glyphFilter->SetInputData(peakDataSet); + glyphFilter->SetSourceConnection(shapeMarker->GetOutputPort()); + glyphFilter->Update(); + vtkPolyData *glyphed = glyphFilter->GetOutput(); + appendFilter->AddInputData(glyphed); + } // for each peak + appendFilter->Update(); + vtkPolyData* polyData = appendFilter->GetOutput(); + + return polyData; + } vtkPeakMarkerFactory::~vtkPeakMarkerFactory() { diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkSinglePeakMarker.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkSinglePeakMarker.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9b4ae5ba2c90a53472d093c21f34132beefe84c6 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/vtkSinglePeakMarker.cpp @@ -0,0 +1,76 @@ +#include "MantidVatesAPI/vtkSinglePeakMarker.h" +#include <vtkPolyData.h> +#include "vtkFloatArray.h" +#include "vtkPoints.h" +#include "vtkUnstructuredGrid.h" +#include "vtkVertex.h" +#include "vtkPVGlyphFilter.h" +#include "vtkCellData.h" +#include "vtkSphereSource.h" +#include "vtkTransform.h" +#include "vtkTransformPolyDataFilter.h" + +namespace Mantid +{ +namespace VATES +{ + vtkSinglePeakMarker::vtkSinglePeakMarker(){ + } + + vtkSinglePeakMarker::~vtkSinglePeakMarker(){ + } + + vtkPolyData* vtkSinglePeakMarker::createSinglePeakMarker(double x, double y, double z, double radius){ + + // Point + vtkPoints *peakPoint = vtkPoints::New(); + peakPoint->Allocate(1); + + vtkFloatArray * peakSignal = vtkFloatArray::New(); + peakSignal->Allocate(1); + peakSignal->SetName("signal"); + peakSignal->SetNumberOfComponents(1); + + // What we'll return + vtkUnstructuredGrid *peakDataSet = vtkUnstructuredGrid::New(); + peakDataSet->Allocate(1); + peakDataSet->SetPoints(peakPoint); + peakDataSet->GetCellData()->SetScalars(peakSignal); + + // One point per peak + vtkVertex * vertex = vtkVertex::New(); + vtkIdType id_xyz = peakPoint->InsertNextPoint(x,y,z); + vertex->GetPointIds()->SetId(0, id_xyz); + + peakDataSet->InsertNextCell(VTK_VERTEX, vertex->GetPointIds()); + + // The integrated intensity = the signal on that point. + peakSignal->InsertNextValue(static_cast<float>(1.0)); + peakPoint->Squeeze(); + peakDataSet->Squeeze(); + + //Get the position info and create the glyph which is to be displayed. + vtkSphereSource* sphere = vtkSphereSource::New(); + const int resolution = 16; + sphere->SetRadius(radius); + sphere->SetPhiResolution(resolution); + sphere->SetThetaResolution(resolution); + + vtkTransform* transform = vtkTransform::New(); + transform->Translate(0, 0, 0); + + vtkTransformPolyDataFilter* transformFilter = vtkTransformPolyDataFilter::New(); + transformFilter->SetTransform(transform); + transformFilter->SetInputConnection(sphere->GetOutputPort()); + transformFilter->Update(); + + vtkPVGlyphFilter *glyphFilter = vtkPVGlyphFilter::New(); + glyphFilter->SetInputData(peakDataSet); + glyphFilter->SetSourceConnection(transformFilter->GetOutputPort()); + glyphFilter->Update(); + vtkPolyData *glyphed = glyphFilter->GetOutput(); + + return glyphed; + } +} +} \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp index 91606a695251cb06b5ebd2ebb1ef2d82ea4985f2..02c12390c53328d517d0c26b3c816e678de65180 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp @@ -9,6 +9,12 @@ #include "MantidGeometry/MDGeometry/MDHistoDimension.h" #include "MantidVatesAPI/ProgressAction.h" #include "MantidVatesAPI/Common.h" +#include "MantidVatesAPI/MetadataToFieldData.h" +#include "MantidVatesAPI/FieldDataToMetadata.h" +#include "MantidVatesAPI/MetaDataExtractorUtils.h" +#include "MantidVatesAPI/MetadataJsonManager.h" +#include "MantidVatesAPI/VatesConfigurations.h" +#include "MantidVatesAPI/VatesXMLDefinitions.h" #include <vtkCellData.h> #include <vtkFloatArray.h> @@ -59,7 +65,9 @@ namespace VATES m_buildSortedList(true), m_wsName(""), dataSet(NULL), slice(false), sliceMask(NULL), sliceImplicitFunction(NULL), m_time(0.0), - m_metaDataExtractor(new MetaDataExtractorUtils()) + m_metaDataExtractor(new MetaDataExtractorUtils()), + m_metadataJsonManager(new MetadataJsonManager()), + m_vatesConfigurations(new VatesConfigurations()) { } @@ -576,6 +584,9 @@ namespace VATES delete this->sliceImplicitFunction; } + // Add metadata in json format + this->addMetadata(); + // The macro does not allow return calls, so we used a member variable. return this->dataSet; } @@ -618,6 +629,66 @@ namespace VATES } } + /** + * Add meta data to the visual data set. + */ + void vtkSplatterPlotFactory::addMetadata() const { + const double defaultValue = 0.1; + + if (this->dataSet) + { + double* range = NULL; + range = dataSet->GetScalarRange(); + + if (range) + { + m_minValue = range[0]; + m_maxValue = range[1]; + } + else + { + m_minValue = defaultValue; + m_maxValue = defaultValue; + } + + m_metadataJsonManager->setMinValue(m_minValue); + m_metadataJsonManager->setMaxValue(m_maxValue); + m_metadataJsonManager->setInstrument(m_metaDataExtractor->extractInstrument(m_workspace)); + m_metadataJsonManager->setSpecialCoordinates(static_cast<int>(m_workspace->getSpecialCoordinateSystem())); + + // Append metadata + std::string jsonString = m_metadataJsonManager->getSerializedJson(); + vtkFieldData* outputFD = vtkFieldData::New(); + + //Add metadata to dataset. + MetadataToFieldData convert; + convert(outputFD, jsonString, m_vatesConfigurations->getMetadataIdJson().c_str()); + dataSet->SetFieldData(outputFD); + + outputFD->Delete(); + } + } + + /** + * Write the xml metadata from the underlying source into the vktArray of the + * @param fieldData The field data from the underlying source + * @param dataSet The splatterplot data set. + */ + void vtkSplatterPlotFactory::setMetadata(vtkFieldData* fieldData, vtkDataSet* dataSet) { + // Extract the xml-metadata part of the fieldData and the json-metadata from the dataset + FieldDataToMetadata convertFtoM; + std::string xmlString = convertFtoM(fieldData, XMLDefinitions::metaDataId()); + std::string jsonString = convertFtoM(dataSet->GetFieldData(), m_vatesConfigurations->getMetadataIdJson().c_str()); + + // Create a new field data array + MetadataToFieldData convertMtoF; + vtkFieldData* outputFD = vtkFieldData::New(); + convertMtoF(outputFD, xmlString, XMLDefinitions::metaDataId().c_str()); + convertMtoF(outputFD, jsonString, m_vatesConfigurations->getMetadataIdJson().c_str()); + dataSet->SetFieldData(outputFD); + outputFD->Delete(); + } + /** * Sets the number of points to show * @param points : The total number of points to plot. diff --git a/Code/Mantid/Vates/VatesAPI/test/CompositePeaksPresenterVsiTest.h b/Code/Mantid/Vates/VatesAPI/test/CompositePeaksPresenterVsiTest.h new file mode 100644 index 0000000000000000000000000000000000000000..a237129ebf5a1bb0f24e777e2ebbc645639f36b8 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/CompositePeaksPresenterVsiTest.h @@ -0,0 +1,116 @@ +#ifndef COMOPOSITE_PEAKS_PRESENTER_VSI_TEST_H_ +#define COMOPOSITE_PEAKS_PRESENTER_VSI_TEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidVatesAPI/CompositePeaksPresenterVsi.h" +#include "MantidVatesAPI/ConcretePeaksPresenterVsi.h" +#include "MantidAPI/IPeaksWorkspace.h" +#include "MantidDataObjects/PeaksWorkspace.h" + +#include <boost/shared_ptr.hpp> +#include <stdexcept> + +#include "MockObjects.h" +#include <gmock/gmock.h> +#include <gtest/gtest.h> + + +#include <string> + +using namespace ::testing; +using namespace Mantid::VATES; + +class MockPeaksWorkspaceComposite : public Mantid::DataObjects::PeaksWorkspace +{ +public: +}; + +class CompositePeaksPresenterVsiTest : public CxxTest::TestSuite { +public: + void testSetupPresenterCorrectly() { + + } + + void testThatGettingPeaksWorkspaceDirectlyIsNotAllowed() { + // Arrange + CompositePeaksPresenterVsi presenter; + // Assert + TS_ASSERT_THROWS(presenter.getPeaksWorkspace(), std::runtime_error); + } + + void testThatGettingPeaksWorkspaceNameDirectlyIsNotAllowed() { + // Arrange + CompositePeaksPresenterVsi presenter; + // Assert + TS_ASSERT_THROWS(presenter.getPeaksWorkspaceName(), std::runtime_error); + } + + void testThatGetListOfNamesOfSubPresenters() { + // Arrange + CompositePeaksPresenterVsi presenter; + + std::string frame = "testFrame"; + + LeftPlane left(1.0, 0.0, 0.0, 1.0); + + RightPlane right(-1.0, 0.0, 0.0, 1.0); + BottomPlane bottom(0.0, 1.0, 0.0, 1.0); + TopPlane top(0.0, -1.0, 0.0, 1.0); + FarPlane farPlane(0.0, 0.0, 1.0, 1.0); + NearPlane nearPlane(0.0, 0.0, -1.0,1.0); + ViewFrustum frustum(left, right, bottom, top, farPlane, nearPlane); + + boost::shared_ptr<MockPeaksWorkspaceComposite> pw_ptr(new MockPeaksWorkspaceComposite()); + std::string name = "pw1"; + PeaksPresenterVsi_sptr p1(new ConcretePeaksPresenterVsi(pw_ptr, frustum, frame)); + + + boost::shared_ptr<MockPeaksWorkspaceComposite> pw_ptr2(new MockPeaksWorkspaceComposite()); + std::string name2 = "pw2"; + PeaksPresenterVsi_sptr p2(new ConcretePeaksPresenterVsi(pw_ptr2, frustum, frame)); + + presenter.addPresenter(p1); + presenter.addPresenter(p2); + + // Act + std::vector<std::string> wsNames = presenter.getPeaksWorkspaceNames(); + + // Assert, cannot mock the getName function as it is not virtual + TSM_ASSERT_EQUALS("Should have two entries", wsNames.size(), 2); + } + + void testThatGetsAllPeaksWorkspaces() { + // Arrange + CompositePeaksPresenterVsi presenter; + + std::string frame = "testFrame"; + + LeftPlane left(1.0, 0.0, 0.0, 1.0); + + RightPlane right(-1.0, 0.0, 0.0, 1.0); + BottomPlane bottom(0.0, 1.0, 0.0, 1.0); + TopPlane top(0.0, -1.0, 0.0, 1.0); + FarPlane farPlane(0.0, 0.0, 1.0, 1.0); + NearPlane nearPlane(0.0, 0.0, -1.0,1.0); + ViewFrustum frustum(left, right, bottom, top, farPlane, nearPlane); + + boost::shared_ptr<MockPeaksWorkspaceComposite> pw_ptr(new MockPeaksWorkspaceComposite()); + std::string name = "pw1"; + PeaksPresenterVsi_sptr p1(new ConcretePeaksPresenterVsi(pw_ptr, frustum, frame)); + + boost::shared_ptr<MockPeaksWorkspaceComposite> pw_ptr2(new MockPeaksWorkspaceComposite()); + std::string name2 = "pw2"; + PeaksPresenterVsi_sptr p2(new ConcretePeaksPresenterVsi(pw_ptr2, frustum, frame)); + + presenter.addPresenter(p1); + presenter.addPresenter(p2); + + // Act + std::vector<Mantid::API::IPeaksWorkspace_sptr> ws = presenter.getPeaksWorkspaces(); + + // Assert + TSM_ASSERT_EQUALS("Should have two entries", ws.size(), 2); + } +}; + +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/test/ConcretePeaksPresenterVsiTest.h b/Code/Mantid/Vates/VatesAPI/test/ConcretePeaksPresenterVsiTest.h new file mode 100644 index 0000000000000000000000000000000000000000..5391f01e92b4303b311ce6e9dbbf627a9e6a6877 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/ConcretePeaksPresenterVsiTest.h @@ -0,0 +1,107 @@ +#ifndef CONCRETE_PEAKS_PRESENTER_VSI_TEST_H_ +#define CONCRETE_PEAKS_PRESENTER_VSI_TEST_H_ + +#include "MantidVatesAPI/ConcretePeaksPresenterVsi.h" +#include "MantidAPI/IPeaksWorkspace.h" +#include "MantidVatesAPI/ViewFrustum.h" +#include "MantidDataObjects/PeaksWorkspace.h" +#include "MantidGeometry/Crystal/PeakShape.h" +#include "MantidDataObjects/PeakShapeSpherical.h" +#include "MantidDataObjects/PeakShapeEllipsoid.h" +#include "MantidDataObjects/NoShape.h" +#include "MantidKernel/V3D.h" +#include "MockObjects.h" +#include <boost/shared_ptr.hpp> + +#include <cxxtest/TestSuite.h> +#include <gmock/gmock.h> +#include <gtest/gtest.h> + + +#include <string> + +using namespace ::testing; +using namespace Mantid::VATES; + +class MockPeakConcrete : public Mantid::DataObjects::Peak +{ +public: + MOCK_CONST_METHOD0(getHKL, Mantid::Kernel::V3D (void)); + MOCK_CONST_METHOD0(getQLabFrame, Mantid::Kernel::V3D (void)); + MOCK_CONST_METHOD0(getQSampleFrame, Mantid::Kernel::V3D (void)); +}; + +class MockPeaksWorkspaceConcrete : public Mantid::DataObjects::PeaksWorkspace +{ +public: + MOCK_CONST_METHOD0(getSpecialCoordinateSystem, Mantid::Kernel::SpecialCoordinateSystem()); + MOCK_METHOD1(getPeak, Mantid::DataObjects::Peak & (int peakNum)); + MOCK_CONST_METHOD1(getPeak, const Mantid::DataObjects::Peak & (int peakNum)); +}; + +class ConcretePeaksPresenterVsiTest : public CxxTest::TestSuite { +public: + void testSetupPresenterCorrectly() { + // Arrange + std::string frame = "testFrame"; + std::string name = "name"; + + LeftPlane left(1.0, 0.0, 0.0, 1.0); + + RightPlane right(-1.0, 0.0, 0.0, 1.0); + BottomPlane bottom(0.0, 1.0, 0.0, 1.0); + TopPlane top(0.0, -1.0, 0.0, 1.0); + FarPlane farPlane(0.0, 0.0, 1.0, 1.0); + NearPlane nearPlane(0.0, 0.0, -1.0,1.0); + ViewFrustum frustum(left, right, bottom, top, farPlane, nearPlane); + + boost::shared_ptr<MockPeaksWorkspaceConcrete> pw_ptr(new MockPeaksWorkspaceConcrete()); + // Act + ConcretePeaksPresenterVsi presenter(pw_ptr, frustum, frame); + + // Assert + TSM_ASSERT_EQUALS("Should have recorded the frame", presenter.getFrame(), frame); + } + + void testCorrectPeaksInfoIsExtractedForValidRow() { + // Arrange + std::string frame = "Q_SAMPLE"; + + LeftPlane left(1.0, 0.0, 0.0, 1.0); + RightPlane right(-1.0, 0.0, 0.0, 1.0); + BottomPlane bottom(0.0, 1.0, 0.0, 1.0); + TopPlane top(0.0, -1.0, 0.0, 1.0); + FarPlane farPlane(0.0, 0.0, 1.0, 1.0); + NearPlane nearPlane(0.0, 0.0, -1.0,1.0); + ViewFrustum frustum(left, right, bottom, top, farPlane, nearPlane); + + Mantid::Kernel::V3D coordinate(1,0,0); + double peakRadius = 10; + Mantid::Kernel::SpecialCoordinateSystem coordinateSystem = Mantid::Kernel::SpecialCoordinateSystem::QSample; + Mantid::Geometry::PeakShape_sptr shape(new Mantid::DataObjects::PeakShapeSpherical(peakRadius, coordinateSystem, "test", 1)); + MockPeakConcrete peak; + peak.setPeakShape(shape); + EXPECT_CALL(peak, getQLabFrame()).Times(0); + EXPECT_CALL(peak, getHKL()).Times(0); + EXPECT_CALL(peak, getQSampleFrame()).WillOnce(Return(coordinate)); + + + boost::shared_ptr<MockPeaksWorkspaceConcrete> pw_ptr(new MockPeaksWorkspaceConcrete()); + MockPeaksWorkspaceConcrete & pw = *pw_ptr; + + EXPECT_CALL(pw, getSpecialCoordinateSystem()).WillOnce(Return(coordinateSystem)); + EXPECT_CALL(pw, getPeak(_)).Times(2).WillRepeatedly(ReturnRef(peak)); + + // Act + ConcretePeaksPresenterVsi presenter(pw_ptr, frustum, frame); + double radius = 0; + Mantid::Kernel::V3D coord(0,0,0); + presenter.getPeaksInfo(pw_ptr,0,coord, radius); + + //Assert + TSM_ASSERT_EQUALS("Should have a radius of 10", radius, peakRadius); + TSM_ASSERT_EQUALS("Should have the same coordinate", coord, coordinate); + } +}; + +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h b/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h index e021b3bdce6585d78c65ab72a1bf010e9a3a0a49..078c6a009b89e5af1a8214000e9abcb55928179c 100644 --- a/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h @@ -10,7 +10,7 @@ #include <cxxtest/TestSuite.h> #include "MantidVatesAPI/MetadataJsonManager.h" #include <string> -#include <jsoncpp/json/reader.h> +#include <json/reader.h> using Mantid::VATES::MetadataJsonManager; diff --git a/Code/Mantid/Vates/VatesAPI/test/NullPeaksPresenterVsiTest.h b/Code/Mantid/Vates/VatesAPI/test/NullPeaksPresenterVsiTest.h new file mode 100644 index 0000000000000000000000000000000000000000..cade331b0d37876b912f35887d449bf7ac803d60 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/NullPeaksPresenterVsiTest.h @@ -0,0 +1,39 @@ +#ifndef NULL_PEAKS_PRESENTER_VSI_TEST_H_ +#define NULL_PEAKS_PRESENTER_VSI_TEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidVatesAPI/NullPeaksPresenterVsi.h" +#include "MantidKernel/V3D.h" +#include "MantidAPI/IPeaksWorkspace.h" +#include <stdexcept> + +using namespace Mantid::VATES; + +class NullPeaksPresenterVsiTest : public CxxTest::TestSuite +{ +public: + void testGettingPeaksWorkspaceThrows() { + NullPeaksPresenterVsi presenter; + TSM_ASSERT_THROWS("Should not implement this method", presenter.getPeaksWorkspace(), std::runtime_error); + } + + void testGettingUsablePeaksThrows() { + NullPeaksPresenterVsi presenter; + TSM_ASSERT_THROWS("Should not implement this method", presenter.getViewablePeaks(), std::runtime_error); + } + + void testGettingPeaksWorkspaceNameThrows() { + NullPeaksPresenterVsi presenter; + TSM_ASSERT_THROWS("Should not implement this method", presenter.getViewablePeaks(), std::runtime_error); + } + + void testGettingPeaksInfoThrows() { + NullPeaksPresenterVsi presenter; + int row = 0; + double radius; + Mantid::Kernel::V3D position; + Mantid::API::IPeaksWorkspace_sptr peaksWorkspace; + TSM_ASSERT_THROWS("Should not implement this method", presenter.getPeaksInfo(peaksWorkspace,row,position,radius), std::runtime_error); + } +}; +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/test/ViewFrustumTest.h b/Code/Mantid/Vates/VatesAPI/test/ViewFrustumTest.h new file mode 100644 index 0000000000000000000000000000000000000000..e4f2357e2d4963f0fb31a93563ea840d9fd19702 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/ViewFrustumTest.h @@ -0,0 +1,91 @@ +#ifndef VIEWFRUSTUM_TEST_H_ +#define VIEWFRUSTUM_TEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidVatesAPI/ViewFrustum.h" + +using namespace Mantid::VATES; + +class ViewFrustumTest: public CxxTest::TestSuite +{ +public: + void testThatExtentsAreFoundForStandardFrustum() + { + // Arrange + // Create a standard cube + LeftPlane left(1.0, 0.0, 0.0, 1.0); + RightPlane right(-1.0, 0.0, 0.0, 1.0); + + BottomPlane bottom(0.0, 1.0, 0.0, 1.0); + TopPlane top(0.0, -1.0, 0.0, 1.0); + + FarPlane far(0.0, 0.0, 1.0, 1.0); + NearPlane near(0.0, 0.0, -1.0,1.0); + + ViewFrustum frustum(left, right, bottom, top, far, near); + + //Act + std::vector<std::pair<double, double>> extents; + TSM_ASSERT_THROWS_NOTHING("Frustum is well defined, should not throw.", extents = frustum.toExtents()); + + //Assert + TSM_ASSERT_EQUALS("Extents should exist for x, y and z.", 3, extents.size()); + TSM_ASSERT_EQUALS("Frustum is well defined and should have xmin = -1", -1.0, extents[0].first); + TSM_ASSERT_EQUALS("Frustum is well defined and should have xmax = 1", 1.0, extents[0].second); + TSM_ASSERT_EQUALS("Frustum is well defined and should have ymin = -1", -1.0, extents[1].first); + TSM_ASSERT_EQUALS("Frustum is well defined and should have ymin = -1", 1.0, extents[1].second); + TSM_ASSERT_EQUALS("Frustum is well defined and should have zmin = -1", -1.0, extents[2].first); + TSM_ASSERT_EQUALS("Frustum is well defined and should have zmax = 1", 1.0, extents[2].second); + } + + void testThatExtentsAreFoundForFrustumWithRotation() + { + // Arrange + // Create skewed cube + LeftPlane left(1.0, -0.5, 0.0, 1.0); + RightPlane right(-1.0, 0.5, 0.0, 1.0); + + BottomPlane bottom(1.0, 0.5, 0.0, 1.0); + TopPlane top(-1.0, -0.5, 0.0, 1.0); + + FarPlane far(0.0, 0.0, 1.0, 1.0); + NearPlane near(0.0, 0.0, -1.0,1.0); + + ViewFrustum frustum(left, right, bottom, top, far, near); + + //Act + std::vector<std::pair<double, double>> extents; + TSM_ASSERT_THROWS_NOTHING("Frustum is well defined, should not throw.", extents = frustum.toExtents()); + + //Assert + TSM_ASSERT_EQUALS("Extents should exist for x, y and z.", 3, extents.size()); + TSM_ASSERT_EQUALS("Frustum is well defined and should have xmin = -1", -1.0, extents[0].first); + TSM_ASSERT_EQUALS("Frustum is well defined and should have xmax = 1", 1.0, extents[0].second); + TSM_ASSERT_EQUALS("Frustum is well defined and should have ymin = -1", -2.0, extents[1].first); + TSM_ASSERT_EQUALS("Frustum is well defined and should have ymin = -1", 2.0, extents[1].second); + TSM_ASSERT_EQUALS("Frustum is well defined and should have zmin = -1", -1.0, extents[2].first); + TSM_ASSERT_EQUALS("Frustum is well defined and should have zmax = 1", 1.0, extents[2].second); + } + + void testThatWrongPlanesThrowErrors() + { + // Arrange + // Just have one plane type. This should fail the calculation of intersection points + LeftPlane left(1.0, -0.5, 0.0, 1.0); + RightPlane right(1.0, -0.5, 0.0, 1.0); + + BottomPlane bottom(1.0, -0.5, 0.0, 1.0); + TopPlane top(1.0, -0.5, 0.0, 1.0); + + FarPlane far(1.0, -0.5, 0.0, 1.0); + NearPlane near(1.0, -0.5, 0.0, 1.0); + + ViewFrustum frustum(left, right, bottom, top, far, near); + + //Assert + TSM_ASSERT_THROWS("Frustum is not well defined, should throw error",frustum.toExtents(), std::runtime_error); + } + +}; + +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToNonOrthogonalDataSetTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToNonOrthogonalDataSetTest.h index 7bdafe9ce686b3c84f7c7c1d1dcf351cb05c949e..742dfdc8acac6aa47c871a20810f305ad4c541db 100644 --- a/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToNonOrthogonalDataSetTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToNonOrthogonalDataSetTest.h @@ -39,7 +39,6 @@ private: // information necessary for the non-orthogonal axes std::string wsName = "simpleWS"; IMDEventWorkspace_sptr ws = makeAnyMDEW<MDEvent<4>, 4>(1, 0.0, 1.0, 1, wsName); - // Set the coordinate system if (!wrongCoords) { @@ -51,9 +50,6 @@ private: } // Set the UB matrix - ExperimentInfo_sptr expInfo = ExperimentInfo_sptr(new ExperimentInfo()); - ws->addExperimentInfo(expInfo); - if (!forgetUB) { IAlgorithm_sptr alg = AlgorithmManager::Instance().create("SetUB"); diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToPeaksFilteredDataSetTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToPeaksFilteredDataSetTest.h new file mode 100644 index 0000000000000000000000000000000000000000..1e5e1080b6b3d3330592e1eae0da3a9907ca356b --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToPeaksFilteredDataSetTest.h @@ -0,0 +1,361 @@ +#ifndef MANTID_VATESAPI_VTKDATASETTOPEAKSFILTEREDDATASETTEST_H_ +#define MANTID_VATESAPI_VTKDATASETTOPEAKSFILTEREDDATASETTEST_H_ + +#include "MantidTestHelpers/MDEventsTestHelper.h" +#include "MantidVatesAPI/FieldDataToMetadata.h" +#include "MantidVatesAPI/MetadataJsonManager.h" +#include "MantidVatesAPI/MetadataToFieldData.h" +#include "MantidVatesAPI/VatesConfigurations.h" +#include "MantidVatesAPI/NoThresholdRange.h" +#include "MantidVatesAPI/vtkDataSetToPeaksFilteredDataSet.h" +#include "MantidVatesAPI/vtkSplatterPlotFactory.h" +#include "MantidVatesAPI/UserDefinedThresholdRange.h" +#include "MantidAPI/IPeaksWorkspace.h" +#include "MantidDataObjects/PeaksWorkspace.h" +#include "MantidGeometry/Crystal/PeakShape.h" +#include "MantidDataObjects/PeakShapeSpherical.h" +#include "MantidDataObjects/PeakShapeEllipsoid.h" +#include "MantidDataObjects/NoShape.h" +#include "MantidKernel/V3D.h" + +#include "MockObjects.h" +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <cxxtest/TestSuite.h> + +#include <vtkCellData.h> +#include <vtkDataSet.h> +#include <vtkFieldData.h> +#include <vtkFloatArray.h> +#include <vtkUnsignedCharArray.h> +#include <vtkUnstructuredGrid.h> + +#include <boost/shared_ptr.hpp> + + +using namespace Mantid::MDEvents; +using namespace Mantid::VATES; +using namespace ::testing; + +class MockPeakFilter : public Mantid::DataObjects::Peak +{ +public: + MOCK_CONST_METHOD0(getHKL, Mantid::Kernel::V3D (void)); + MOCK_CONST_METHOD0(getQLabFrame, Mantid::Kernel::V3D (void)); + MOCK_CONST_METHOD0(getQSampleFrame, Mantid::Kernel::V3D (void)); +}; + +class MockPeaksWorkspaceFilter : public Mantid::DataObjects::PeaksWorkspace +{ +public: + MOCK_CONST_METHOD0(getNumberPeaks, int()); + MOCK_METHOD1(getPeak, Mantid::DataObjects::Peak & (int peakNum)); + MOCK_CONST_METHOD1(getPeak, const Mantid::DataObjects::Peak & (int peakNum)); +}; + +struct PeaksFilterDataContainer { + double radius; + double radiusFactor; + Mantid::Kernel::V3D position; +}; + +class vtkDataSetToPeaksFilteredDataSetTest : public CxxTest::TestSuite +{ +private: + vtkUnstructuredGrid* makeSplatterSourceGrid() + { + FakeProgressAction progressUpdate; + Mantid::MDEvents::MDEventWorkspace3Lean::sptr ws = MDEventsTestHelper::makeMDEW<3>(10, -10.0, 10.0, 1); + vtkSplatterPlotFactory factory(ThresholdRange_scptr(new UserDefinedThresholdRange(0, 1)), "signal"); + factory.initialize(ws); + vtkDataSet* product = NULL; + TS_ASSERT_THROWS_NOTHING(product = factory.create(progressUpdate)); + vtkUnstructuredGrid* splatData = vtkUnstructuredGrid::SafeDownCast(product); + return splatData; + } + +public: + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static vtkDataSetToPeaksFilteredDataSetTest *createSuite() { return new vtkDataSetToPeaksFilteredDataSetTest(); } + static void destroySuite( vtkDataSetToPeaksFilteredDataSetTest *suite ) { delete suite; } + + void do_test_peak_inSphere(vtkPoints* points,int numberOfPoints, int& inside, int& outside, bool testingOutput, std::vector<PeaksFilterDataContainer> peakData) + { + for (int i = 0; i < numberOfPoints; i++) + { + double point[3]; + points->GetPoint(static_cast<vtkIdType>(i), point); + + bool isInSphere = false; + // Check if the point is any of the peaks + for (std::vector<PeaksFilterDataContainer>::iterator it = peakData.begin(); it != peakData.end(); ++it) { + double diffSquared = 0; + for (int k = 0; k <3; k++) { + diffSquared += (it->position[k]-point[k])*(it->position[k]-point[k]); + } + + isInSphere = ((it->radius*it->radius*it->radiusFactor*it->radiusFactor - diffSquared) >= 0) ? true : false; + // If the point is in a sphere, stop comparing + if (isInSphere) { + break; + } + } + + // Count if the point is in a sphere or not + isInSphere ? (inside++) : (outside++); + + // We expect only for the output, that all points are within the sphere + if (testingOutput) + { + TSM_ASSERT("Should be insinde the sphere.", isInSphere); + } + } + } + + void do_test_peaks(vtkUnstructuredGrid* in, vtkUnstructuredGrid* out, std::vector<PeaksFilterDataContainer> peakData) + { + vtkPoints* inPoints = in->GetPoints(); + vtkPoints* outPoints = out->GetPoints(); + + int numberOfInPoints = static_cast<int>(inPoints->GetNumberOfPoints()); + int numberOfOutPoints = static_cast<int>(outPoints->GetNumberOfPoints()); + + + int insideSphereInput = 0; + int outsideSphereInput = 0; + do_test_peak_inSphere(inPoints, numberOfInPoints, insideSphereInput , outsideSphereInput, false, peakData); + + int insideSphereOutput = 0; + int outsideSphereOutput = 0; + do_test_peak_inSphere(outPoints, numberOfOutPoints, insideSphereOutput , outsideSphereOutput, true, peakData); + + TSM_ASSERT("The number of elements inside the sphere should be the same for input and output.", insideSphereInput == insideSphereOutput); + } + + void do_test_execute(vtkDataSetToPeaksFilteredDataSet peaksFilter, std::vector<std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>> peakWsData, Mantid::Kernel::SpecialCoordinateSystem coordinateSystem) { + std::vector<Mantid::API::IPeaksWorkspace_sptr> peaksContainer; + for (std::vector<std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>>::iterator it = peakWsData.begin(); it != peakWsData.end(); ++it) { + // Set up the peak + switch(coordinateSystem) + { + case(Mantid::Kernel::SpecialCoordinateSystem::QLab): + EXPECT_CALL(*(it->first), getQLabFrame()).WillOnce(Return(it->second)); + EXPECT_CALL(*(it->first), getHKL()).Times(0); + EXPECT_CALL(*(it->first), getQSampleFrame()).Times(0); + break; + case(Mantid::Kernel::SpecialCoordinateSystem::HKL): + EXPECT_CALL(*(it->first), getQLabFrame()).Times(0); + EXPECT_CALL(*(it->first), getHKL()).WillOnce(Return(it->second)); + EXPECT_CALL(*(it->first), getQSampleFrame()).Times(0); + break; + case(Mantid::Kernel::SpecialCoordinateSystem::QSample): + EXPECT_CALL(*(it->first), getQLabFrame()).Times(0); + EXPECT_CALL(*(it->first), getHKL()).Times(0); + EXPECT_CALL(*(it->first), getQSampleFrame()).WillOnce(Return(it->second)); + break; + default: + break; + } + + // Set up the peaks workspace + boost::shared_ptr<MockPeaksWorkspaceFilter> pw_ptr(new MockPeaksWorkspaceFilter()); + MockPeaksWorkspaceFilter & pw = *pw_ptr; + + EXPECT_CALL(pw, getNumberPeaks()).Times(1).WillRepeatedly(Return(1)); + EXPECT_CALL(pw, getPeak(_)).WillOnce(ReturnRef(*(it->first))); + peaksContainer.push_back(pw_ptr); + } + + peaksFilter.initialize(peaksContainer, 0.5, 0, static_cast<int>(coordinateSystem)); + FakeProgressAction updateProgress; + TSM_ASSERT_THROWS_NOTHING("Should execute regularly.", peaksFilter.execute(updateProgress)); + } + + void testThrowIfInputNull() + { + vtkUnstructuredGrid *in = NULL; + vtkUnstructuredGrid *out = vtkUnstructuredGrid::New(); + TS_ASSERT_THROWS(vtkDataSetToPeaksFilteredDataSet peaksFilter(in, out), std::runtime_error); + } + + void testThrowIfOutputNull() + { + vtkUnstructuredGrid *in = vtkUnstructuredGrid::New(); + vtkUnstructuredGrid *out = NULL; + TS_ASSERT_THROWS(vtkDataSetToPeaksFilteredDataSet peaksFilter(in, out), std::runtime_error); + } + + void testExecThrowIfNoInit() + { + vtkUnstructuredGrid *in = vtkUnstructuredGrid::New(); + vtkUnstructuredGrid *out = vtkUnstructuredGrid::New(); + vtkDataSetToPeaksFilteredDataSet peaksFilter(in, out); + FakeProgressAction updateProgress; + TS_ASSERT_THROWS(peaksFilter.execute(updateProgress), std::runtime_error); + } + + void testExecutionWithSingleSphericalPeakInQSample() + { + // Arrange + vtkUnstructuredGrid *in = makeSplatterSourceGrid(); + vtkUnstructuredGrid *out = vtkUnstructuredGrid::New(); + vtkDataSetToPeaksFilteredDataSet peaksFilter(in, out); + + Mantid::Kernel::V3D coordinate(0,0,0); + // Note that the peak radius is not a 1-1 measure for which peaks will be culled and which not. + // The actual radius is multiplied by the radius factor. + double peakRadius = 5; + Mantid::Kernel::SpecialCoordinateSystem coordinateSystem = Mantid::Kernel::SpecialCoordinateSystem::QSample; + Mantid::Geometry::PeakShape_sptr shape(new Mantid::DataObjects::PeakShapeSpherical(peakRadius, coordinateSystem, "test", 1)); + boost::shared_ptr<MockPeakFilter> peak(new MockPeakFilter()); + peak->setPeakShape(shape); + + std::vector<std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>> fakeSinglePeakPeakWorkspaces; + fakeSinglePeakPeakWorkspaces.push_back(std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>(peak, coordinate)); + + std::vector<PeaksFilterDataContainer> peakData; + PeaksFilterDataContainer data1; + data1.position = coordinate; + data1.radius = peakRadius; + data1.radiusFactor = peaksFilter.getRadiusFactor(); + peakData.push_back(data1); + + // Act + do_test_execute(peaksFilter, fakeSinglePeakPeakWorkspaces, coordinateSystem); + + // Assert + do_test_peaks(in, out, peakData); + + in->Delete(); + out->Delete(); + } + + void testExecutionWithSingleEllipsoidPeakInQSample() + { + // Arrange + vtkUnstructuredGrid *in = makeSplatterSourceGrid(); + vtkUnstructuredGrid *out = vtkUnstructuredGrid::New(); + vtkDataSetToPeaksFilteredDataSet peaksFilter(in, out); + + Mantid::Kernel::V3D coordinate(0,0,0); + double peakRadiusMax = 7; + std::vector<double> radii; + radii.push_back(peakRadiusMax); + radii.push_back(6); + radii.push_back(5); + + std::vector<Mantid::Kernel::V3D> directions; + directions.push_back(Mantid::Kernel::V3D(0.0,1.0,0.0)); + directions.push_back(Mantid::Kernel::V3D(1.0,0.0,0.0)); + directions.push_back(Mantid::Kernel::V3D(0.0,0.0,1.0)); + + Mantid::Kernel::SpecialCoordinateSystem coordinateSystem = Mantid::Kernel::SpecialCoordinateSystem::QSample; + Mantid::Geometry::PeakShape_sptr shape(new Mantid::DataObjects::PeakShapeEllipsoid(directions, radii, radii, radii , coordinateSystem, "test", 1)); + boost::shared_ptr<MockPeakFilter> peak(new MockPeakFilter()); + peak->setPeakShape(shape); + + std::vector<std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>> fakeSinglePeakPeakWorkspaces; + fakeSinglePeakPeakWorkspaces.push_back(std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>(peak, coordinate)); + + std::vector<PeaksFilterDataContainer> peakData; + PeaksFilterDataContainer data1; + data1.position = coordinate; + data1.radius = peakRadiusMax; + data1.radiusFactor = peaksFilter.getRadiusFactor(); + peakData.push_back(data1); + + // Act + do_test_execute(peaksFilter, fakeSinglePeakPeakWorkspaces, coordinateSystem); + + // Assert + do_test_peaks(in, out, peakData); + + in->Delete(); + out->Delete(); + } + + void testExecutionWithSingleNoShapePeakInQSample() + { + // Arrange + vtkUnstructuredGrid *in = makeSplatterSourceGrid(); + vtkUnstructuredGrid *out = vtkUnstructuredGrid::New(); + vtkDataSetToPeaksFilteredDataSet peaksFilter(in, out); + + Mantid::Kernel::V3D coordinate(0,0,0); + + Mantid::Kernel::SpecialCoordinateSystem coordinateSystem = Mantid::Kernel::SpecialCoordinateSystem::QSample; + double radius = peaksFilter.getRadiusNoShape(); + Mantid::Geometry::PeakShape_sptr shape(new Mantid::DataObjects::NoShape()); + boost::shared_ptr<MockPeakFilter> peak(new MockPeakFilter()); + peak->setPeakShape(shape); + + std::vector<std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>> fakeSinglePeakPeakWorkspaces; + fakeSinglePeakPeakWorkspaces.push_back(std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>(peak, coordinate)); + + std::vector<PeaksFilterDataContainer> peakData; + PeaksFilterDataContainer data1; + data1.position = coordinate; + data1.radius = radius; + data1.radiusFactor = peaksFilter.getRadiusFactor(); + peakData.push_back(data1); + + // Act + do_test_execute(peaksFilter, fakeSinglePeakPeakWorkspaces, coordinateSystem); + + // Assert + do_test_peaks(in, out, peakData); + + in->Delete(); + out->Delete(); + } + + void testExecutionWithTwoWorkspacesWithSingleSphericalShapesInQSample() { + // Arrange + vtkUnstructuredGrid *in = makeSplatterSourceGrid(); + vtkUnstructuredGrid *out = vtkUnstructuredGrid::New(); + vtkDataSetToPeaksFilteredDataSet peaksFilter(in, out); + + // Peak 1 + Mantid::Kernel::V3D coordinate(0,0,0); + double peakRadius = 5; + Mantid::Kernel::SpecialCoordinateSystem coordinateSystem = Mantid::Kernel::SpecialCoordinateSystem::QSample; + Mantid::Geometry::PeakShape_sptr shape(new Mantid::DataObjects::PeakShapeSpherical(peakRadius, coordinateSystem, "test", 1)); + boost::shared_ptr<MockPeakFilter> peak(new MockPeakFilter()); + peak->setPeakShape(shape); + + // Peak 2 + Mantid::Kernel::V3D coordinate2(12,0,0); + double peakRadius2 = 5; + Mantid::Geometry::PeakShape_sptr shape2(new Mantid::DataObjects::PeakShapeSpherical(peakRadius2, coordinateSystem, "test", 1)); + boost::shared_ptr<MockPeakFilter> peak2(new MockPeakFilter()); + peak2->setPeakShape(shape2); + + std::vector<PeaksFilterDataContainer> peakData; + PeaksFilterDataContainer data1; + data1.position = coordinate; + data1.radius =peakRadius; + data1.radiusFactor = peaksFilter.getRadiusFactor(); + PeaksFilterDataContainer data2; + data2.position = coordinate2; + data2.radius = peakRadius2; + data2.radiusFactor = peaksFilter.getRadiusFactor(); + + peakData.push_back(data1); + peakData.push_back(data2); + + std::vector<std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>> fakeSinglePeakPeakWorkspaces; + fakeSinglePeakPeakWorkspaces.push_back(std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>(peak, coordinate)); + fakeSinglePeakPeakWorkspaces.push_back(std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>(peak2, coordinate2)); + + // Act + do_test_execute(peaksFilter, fakeSinglePeakPeakWorkspaces, coordinateSystem); + + // Assert + do_test_peaks(in, out, peakData); + + in->Delete(); + out->Delete(); + } +}; +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkEllipsoidTransformerTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkEllipsoidTransformerTest.h new file mode 100644 index 0000000000000000000000000000000000000000..680e75fac56261dc5a70ace78b17de8a250cfc65 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/vtkEllipsoidTransformerTest.h @@ -0,0 +1,252 @@ +#ifndef VTK_VATES_API_ELLIPSOIDTRANSFORMER_TEST +#define VTK_VATES_API_ELLIPSOIDTRANSFORMER_TEST + +#include <cxxtest/TestSuite.h> +#include "MantidVatesAPI/vtkEllipsoidTransformer.h" + +#include "MantidVatesAPI/vtkEllipsoidTransformer.h" +#include "MantidKernel/V3D.h" + +#include "MockObjects.h" +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +#include <vtkTransform.h> +#include <vtkSmartPointer.h> +#include <vtkLineSource.h> +#include <vtkTransformPolyDataFilter.h> +#include <vector> +#include <cmath> + +using namespace Mantid::VATES; + +class vtkEllipsoidTransformerTest : public CxxTest::TestSuite +{ +public: + void do_test(std::vector<Mantid::Kernel::V3D> directions, + std::vector<std::vector<double>> majorAxis, + std::vector<std::vector<double>> minorAxis, + std::vector<std::vector<double>> majorExpected, + std::vector<std::vector<double>> minorExpected) + { + // Arrange + vtkSmartPointer<vtkLineSource> major = vtkSmartPointer<vtkLineSource>::New(); + double majorPoint1[3] = {majorAxis[0][0], majorAxis[0][1], majorAxis[0][2]}; + double majorPoint2[3] = {majorAxis[1][0], majorAxis[1][1], majorAxis[1][2]}; + major->SetPoint1(majorPoint1); + major->SetPoint2(majorPoint2); + major->Update(); + + vtkSmartPointer<vtkLineSource> minor = vtkSmartPointer<vtkLineSource>::New(); + double minorPoint1[3] = {minorAxis[0][0], minorAxis[0][1], minorAxis[0][2]}; + double minorPoint2[3] = {minorAxis[1][0], minorAxis[1][1], minorAxis[1][2]}; + minor->SetPoint1(minorPoint1); + minor->SetPoint2(minorPoint2); + minor->Update(); + + // Act + vtkEllipsoidTransformer transformer; + vtkSmartPointer<vtkTransform> transform = transformer.generateTransform(directions); + + vtkTransformPolyDataFilter* transformFilter = vtkTransformPolyDataFilter::New(); + + transformFilter->SetTransform(transform); + transformFilter->SetInputConnection(major->GetOutputPort()); + transformFilter->Update(); + vtkPolyData* out = transformFilter->GetOutput(); + + double majorPoint1Rotated[3] = {0.0,0.0,0.0}; + double majorPoint2Rotated[3] = {0.0,0.0,0.0}; + out->GetPoint(0, majorPoint1Rotated); + out->GetPoint(1, majorPoint2Rotated); + + transformFilter->SetInputConnection(minor->GetOutputPort()); + transformFilter->Update(); + out = transformFilter->GetOutput(); + double minorPoint1Rotated[3] = {0.0,0.0,0.0}; + double minorPoint2Rotated[3] = {0.0,0.0,0.0}; + out->GetPoint(0, minorPoint1Rotated); + out->GetPoint(1, minorPoint2Rotated); + + // Assert + const double delta = 1e-5; + + TSM_ASSERT_DELTA("Point 1 of the major axis should not change", majorPoint1Rotated[0], majorExpected[0][0], delta); + TSM_ASSERT_DELTA("Point 1 of the major axis should not change", majorPoint1Rotated[1], majorExpected[0][1], delta); + TSM_ASSERT_DELTA("Point 1 of the major axis should not change", majorPoint1Rotated[2], majorExpected[0][2], delta); + + TSM_ASSERT_DELTA("Point 2 of the major axis should have changed", majorPoint2Rotated[0], majorExpected[1][0], delta); + TSM_ASSERT_DELTA("Point 2 of the major axis should have changed", majorPoint2Rotated[1], majorExpected[1][1], delta); + TSM_ASSERT_DELTA("Point 2 of the major axis should have changed", majorPoint2Rotated[2], majorExpected[1][2], delta); + + TSM_ASSERT_DELTA("Point 1 of the minor axis should not change", minorPoint1Rotated[0], minorExpected[0][0], delta); + TSM_ASSERT_DELTA("Point 1 of the minor axis should not change", minorPoint1Rotated[1], minorExpected[0][1], delta); + TSM_ASSERT_DELTA("Point 1 of the minor axis should not change", minorPoint1Rotated[2], minorExpected[0][2], delta); + + TSM_ASSERT_DELTA("Point 2 of the minor axis should have changed", minorPoint2Rotated[0], minorExpected[1][0], delta); + TSM_ASSERT_DELTA("Point 2 of the minor axis should have changed", minorPoint2Rotated[1], minorExpected[1][1], delta); + TSM_ASSERT_DELTA("Point 2 of the minor axis should have changed", minorPoint2Rotated[2], minorExpected[1][2], delta); + } + + void testGenerateTransformTiltedByNinetyDegrees() + { + // Arrange + Mantid::Kernel::V3D axis1(0.0,1.0,0.0); + Mantid::Kernel::V3D axis2(-1.0,0.0,0.0); + Mantid::Kernel::V3D axis3(0.0,0.0,1.0); + + std::vector<Mantid::Kernel::V3D> directions; + directions.push_back(axis1); + directions.push_back(axis2); + directions.push_back(axis3); + + // Major Axis + std::vector<double> point1Major; + point1Major.push_back(0.0); + point1Major.push_back(0.0); + point1Major.push_back(0.0); + + std::vector<double> point2Major; + point2Major.push_back(1.0); + point2Major.push_back(0.0); + point2Major.push_back(0.0); + + std::vector<std::vector<double>> major; + major.push_back(point1Major); + major.push_back(point2Major); + + // Minor Axis + std::vector<double> point1Minor; + point1Minor.push_back(0.0); + point1Minor.push_back(0.0); + point1Minor.push_back(0.0); + + std::vector<double> point2Minor; + point2Minor.push_back(0.0); + point2Minor.push_back(1.0); + point2Minor.push_back(0.0); + + std::vector<std::vector<double>> minor; + minor.push_back(point1Minor); + minor.push_back(point2Minor); + + std::vector<double> point1MajorExpected; + point1MajorExpected.push_back(0.0); + point1MajorExpected.push_back(0.0); + point1MajorExpected.push_back(0.0); + + std::vector<double> point2MajorExpected; + point2MajorExpected.push_back(0.0); + point2MajorExpected.push_back(1.0); + point2MajorExpected.push_back(0.0); + + std::vector<std::vector<double>> majorExpected; + majorExpected.push_back(point1MajorExpected); + majorExpected.push_back(point2MajorExpected); + + // Minor Axis + std::vector<double> point1MinorExpected; + point1MinorExpected.push_back(0.0); + point1MinorExpected.push_back(0.0); + point1MinorExpected.push_back(0.0); + + std::vector<double> point2MinorExpected; + point2MinorExpected.push_back(-1.0); + point2MinorExpected.push_back(0.0); + point2MinorExpected.push_back(0.0); + + std::vector<std::vector<double>> minorExpected; + minorExpected.push_back(point1MinorExpected); + minorExpected.push_back(point2MinorExpected); + + // Act + Assert + do_test(directions, major, minor, majorExpected, minorExpected); + } + + void testGenerateTransformInRandomDirection() + { + // Arrange + double xMajor = 1.3/sqrt(1.3*1.3 + 1.1*1.1 + 0.5*0.5); + double yMajor = -1.1/sqrt(1.3*1.3 + 1.1*1.1 + 0.5*0.5); + double zMajor = 0.5/sqrt(1.3*1.3 + 1.1*1.1 + 0.5*0.5); + + double xMinor = 1.1/1.3/sqrt(1*1 + (1.1/1.3)*(1.1/1.3)); + double yMinor = 1.0/sqrt(1*1 + (1.1/1.3)*(1.1/1.3)); + double zMinor = 0.0; + + Mantid::Kernel::V3D axis1(xMajor, yMajor, zMajor); + Mantid::Kernel::V3D axis2(xMinor,yMinor, zMinor); + // The third direction is not valid, but we don't need it for our calculations. + Mantid::Kernel::V3D axis3(0.0,0.0,1.0); + + std::vector<Mantid::Kernel::V3D> directions; + directions.push_back(axis1); + directions.push_back(axis2); + directions.push_back(axis3); + + // Major Axis + std::vector<double> point1Major; + point1Major.push_back(0.0); + point1Major.push_back(0.0); + point1Major.push_back(0.0); + + std::vector<double> point2Major; + point2Major.push_back(1.0); + point2Major.push_back(0.0); + point2Major.push_back(0.0); + + std::vector<std::vector<double>> major; + major.push_back(point1Major); + major.push_back(point2Major); + + // Minor Axis + std::vector<double> point1Minor; + point1Minor.push_back(0.0); + point1Minor.push_back(0.0); + point1Minor.push_back(0.0); + + std::vector<double> point2Minor; + point2Minor.push_back(0.0); + point2Minor.push_back(1.0); + point2Minor.push_back(0.0); + + std::vector<std::vector<double>> minor; + minor.push_back(point1Minor); + minor.push_back(point2Minor); + + std::vector<double> point1MajorExpected; + point1MajorExpected.push_back(0.0); + point1MajorExpected.push_back(0.0); + point1MajorExpected.push_back(0.0); + + std::vector<double> point2MajorExpected; + point2MajorExpected.push_back(xMajor); + point2MajorExpected.push_back(yMajor); + point2MajorExpected.push_back(zMajor); + + std::vector<std::vector<double>> majorExpected; + majorExpected.push_back(point1MajorExpected); + majorExpected.push_back(point2MajorExpected); + + // Minor Axis + std::vector<double> point1MinorExpected; + point1MinorExpected.push_back(0.0); + point1MinorExpected.push_back(0.0); + point1MinorExpected.push_back(0.0); + + std::vector<double> point2MinorExpected; + point2MinorExpected.push_back(xMinor); + point2MinorExpected.push_back(yMinor); + point2MinorExpected.push_back(zMinor); + + std::vector<std::vector<double>> minorExpected; + minorExpected.push_back(point1MinorExpected); + minorExpected.push_back(point2MinorExpected); + + // Act + Assert + do_test(directions, major, minor, majorExpected, minorExpected); + } +}; + + +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkPeakMarkerFactoryTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkPeakMarkerFactoryTest.h index 78406aba6e0e017bfdfe1c912e2f9c59dca87979..f71d3cd86a481c50d3ec3bf8d02bbf20381fc6ff 100644 --- a/Code/Mantid/Vates/VatesAPI/test/vtkPeakMarkerFactoryTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/vtkPeakMarkerFactoryTest.h @@ -5,6 +5,9 @@ #include "MantidDataObjects/PeaksWorkspace.h" #include "MantidVatesAPI/vtkPeakMarkerFactory.h" #include "MockObjects.h" + +#include <vtkPolyData.h> + #include <cxxtest/TestSuite.h> #include <gmock/gmock.h> #include <gtest/gtest.h> @@ -29,14 +32,13 @@ class MockPeaksWorkspace : public PeaksWorkspace { public: MOCK_METHOD1(setInstrument, void (Mantid::Geometry::Instrument_const_sptr inst)); - MOCK_CONST_METHOD0(getInstrument, Mantid::Geometry::Instrument_const_sptr ()); + //MOCK_METHOD0(getInstrument, Mantid::Geometry::Instrument_const_sptr ()); MOCK_CONST_METHOD0(clone, Mantid::DataObjects::PeaksWorkspace*()); MOCK_CONST_METHOD0(getNumberPeaks, int()); MOCK_METHOD1(removePeak, void (int peakNum) ); MOCK_METHOD1(addPeak, void (const IPeak& ipeak)); MOCK_METHOD1(getPeak, Mantid::DataObjects::Peak & (int peakNum)); MOCK_CONST_METHOD1(getPeak, const Mantid::DataObjects::Peak & (int peakNum)); - MOCK_CONST_METHOD2(createPeak, Mantid::API::IPeak* (Mantid::Kernel::V3D QLabFrame, boost::optional<double> detectorDistance)); }; //===================================================================================== @@ -59,12 +61,13 @@ public: vtkPeakMarkerFactory factory("signal", dims); factory.initialize(pw_ptr); - vtkDataSet * set = factory.create(updateProgress); + vtkPolyData * set = factory.create(updateProgress); + + // As the marker type are three axes(2 points), we expect 5*2*3 points + // The angle is 45degrees and the size is 0.3 + TS_ASSERT(set); - TS_ASSERT_EQUALS( set->GetNumberOfPoints(), 5); - TS_ASSERT_EQUALS(set->GetPoint(0)[0], 1.0); - TS_ASSERT_EQUALS(set->GetPoint(0)[1], 2.0); - TS_ASSERT_EQUALS(set->GetPoint(0)[2], 3.0); + TS_ASSERT_EQUALS(set->GetNumberOfPoints(), 30); TS_ASSERT(testing::Mock::VerifyAndClearExpectations(&pw)); TS_ASSERT(testing::Mock::VerifyAndClearExpectations(&peak1)); @@ -91,11 +94,10 @@ public: vtkPeakMarkerFactory factory("signal", vtkPeakMarkerFactory::Peak_in_Q_lab); factory.initialize(pw_ptr); - vtkDataSet * set = factory.create(mockProgress); + vtkPolyData * set = factory.create(mockProgress); set->Delete(); TSM_ASSERT("Progress Updates not used as expected.", Mock::VerifyAndClearExpectations(&mockProgress)); - } void test_q_lab() diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkSplatterPlotFactoryTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkSplatterPlotFactoryTest.h index 58c4a57432c29fdeccf056faf9971c1d8bb65975..ac5e17b344fdee8bd8d0a8ddfdfdd996386b85a2 100644 --- a/Code/Mantid/Vates/VatesAPI/test/vtkSplatterPlotFactoryTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/vtkSplatterPlotFactoryTest.h @@ -8,6 +8,10 @@ #include "MantidTestHelpers/MDEventsTestHelper.h" #include "MantidVatesAPI/UserDefinedThresholdRange.h" #include "MantidVatesAPI/vtkSplatterPlotFactory.h" +#include "MantidVatesAPI/MetadataToFieldData.h" +#include "MantidVatesAPI/FieldDataToMetadata.h" +#include "MantidVatesAPI/VatesConfigurations.h" +#include "MantidVatesAPI/MetadataJsonManager.h" #include "MockObjects.h" #include <cxxtest/TestSuite.h> #include <gmock/gmock.h> @@ -161,6 +165,45 @@ public: product->Delete(); } + void test_MetadataIsAddedCorrectly() + { + // Arrange + vtkFieldData* fakeInputFieldDataWithXML = vtkFieldData::New(); + std::string xmlString = "myXmlString"; + MetadataToFieldData converterMtoF; + converterMtoF(fakeInputFieldDataWithXML, xmlString, XMLDefinitions::metaDataId().c_str()); + + + FakeProgressAction progressUpdate; + Mantid::MDEvents::MDEventWorkspace3Lean::sptr ws = MDEventsTestHelper::makeMDEW<3>(10, 0.0, 10.0, 1); + vtkSplatterPlotFactory factory(ThresholdRange_scptr(new UserDefinedThresholdRange(0, 1)), "signal"); + factory.initialize(ws); + vtkDataSet* product = NULL; + + // Act + TS_ASSERT_THROWS_NOTHING(product = factory.create(progressUpdate)); + TS_ASSERT_THROWS_NOTHING(factory.setMetadata(fakeInputFieldDataWithXML, product)); + + // Assert + FieldDataToMetadata converterFtoM; + vtkFieldData* fd = product->GetFieldData(); + std::string xmlOut; + std::string jsonOut; + VatesConfigurations vatesConfigurations; + + TSM_ASSERT_EQUALS("One array expected on field data, one for XML and one for JSON!", 2, product->GetFieldData()->GetNumberOfArrays()); + + TSM_ASSERT_THROWS_NOTHING("There is XML metadata!", xmlOut = converterFtoM(fd, XMLDefinitions::metaDataId().c_str())); + TSM_ASSERT_THROWS_NOTHING("There is JSON metadata!", jsonOut = converterFtoM(fd, vatesConfigurations.getMetadataIdJson().c_str())); + + TSM_ASSERT("The xml string should be retrieved", xmlOut == xmlString); + + MetadataJsonManager manager; + manager.readInSerializedJson(jsonOut); + TSM_ASSERT("The instrument should be empty", manager.getInstrument().empty()); + TSM_ASSERT_EQUALS("The max value is 1", 1.0, manager.getMaxValue()); + TSM_ASSERT_EQUALS("The min value is 1", 1.0, manager.getMinValue()); + } }; #endif diff --git a/Code/Mantid/Vates/VatesSimpleGui/StandAloneExec/CMakeLists.txt b/Code/Mantid/Vates/VatesSimpleGui/StandAloneExec/CMakeLists.txt index f2af04d6f4fd3c63c5c5347edca31def4f45d1b8..bcb80bf44f188c723e56314f298d862aaa9a404f 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/StandAloneExec/CMakeLists.txt +++ b/Code/Mantid/Vates/VatesSimpleGui/StandAloneExec/CMakeLists.txt @@ -38,6 +38,8 @@ set( TEST_SUITES add_executable( ${PROJECT_NAME} ${INCLUDE_FILES} ${SOURCE_FILES} ${MOC_SRCS} ) +include_directories( SYSTEM ${PARAVIEW_INCLUDE_DIRS} ) + target_link_libraries( ${PROJECT_NAME} pqCore pqComponents pqApplicationComponents ${QT_LIBRARIES} diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt index 01b95a20f3fdaf8d840e1787b714a72f4f8490b0..98fb3b2fe5843f2f5051296c6f2b5bd42cb2cf2e 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt @@ -3,6 +3,7 @@ project( MantidVatesSimpleGuiViewWidgets ) # These are the C++ files to be compiled. set( INCLUDE_FILES inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h + inc/MantidVatesSimpleGuiViewWidgets/CameraManager.h inc/MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h inc/MantidVatesSimpleGuiViewWidgets/ColorMapManager.h inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h @@ -11,6 +12,9 @@ set( INCLUDE_FILES inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h inc/MantidVatesSimpleGuiViewWidgets/MultisliceView.h inc/MantidVatesSimpleGuiViewWidgets/RebinAlgorithmDialogProvider.h + inc/MantidVatesSimpleGuiViewWidgets/PeaksTableControllerVsi.h + inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.h + inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.h inc/MantidVatesSimpleGuiViewWidgets/SaveScreenshotReaction.h inc/MantidVatesSimpleGuiViewWidgets/RebinnedSourcesManager.h inc/MantidVatesSimpleGuiViewWidgets/StandardView.h @@ -23,6 +27,7 @@ set( INCLUDE_FILES set( SOURCE_FILES src/AutoScaleRangeGenerator.cpp + src/CameraManager.cpp src/BackgroundRgbProvider.cpp src/ColorMapManager.cpp src/ColorSelectionWidget.cpp @@ -30,6 +35,9 @@ set( SOURCE_FILES src/MdViewerWidget.cpp src/MultisliceView.cpp src/RebinAlgorithmDialogProvider.cpp + src/PeaksTableControllerVsi.cpp + src/PeaksTabWidget.cpp + src/PeaksWidget.cpp src/SaveScreenshotReaction.cpp src/RebinnedSourcesManager.cpp src/StandardView.cpp @@ -49,6 +57,9 @@ qt4_wrap_cpp( MOC_SOURCES inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h inc/MantidVatesSimpleGuiViewWidgets/MultisliceView.h + inc/MantidVatesSimpleGuiViewWidgets/PeaksTableControllerVsi.h + inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.h + inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.h inc/MantidVatesSimpleGuiViewWidgets/SaveScreenshotReaction.h inc/MantidVatesSimpleGuiViewWidgets/RebinnedSourcesManager.h inc/MantidVatesSimpleGuiViewWidgets/StandardView.h @@ -64,6 +75,8 @@ qt4_wrap_ui( UI_BUILT_SOURCES inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.ui inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.ui inc/MantidVatesSimpleGuiViewWidgets/MultisliceView.ui + inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.ui + inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.ui inc/MantidVatesSimpleGuiViewWidgets/StandardView.ui inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.ui inc/MantidVatesSimpleGuiViewWidgets/ThreesliceView.ui @@ -109,11 +122,14 @@ set_target_properties( VatesSimpleGuiViewWidgets PROPERTIES OUTPUT_NAME MantidVa # Add to the 'VatesSimpleGui' group in VS set_property( TARGET VatesSimpleGuiViewWidgets PROPERTY FOLDER MantidVatesSimpleGui ) + +include_directories( SYSTEM ${PARAVIEW_INCLUDE_DIRS} ) + target_link_libraries( VatesSimpleGuiViewWidgets -VatesSimpleGuiQtWidgets pqApplicationComponents pqComponents ${QT_LIBRARIES} +VatesSimpleGuiQtWidgets MantidQtAPI VatesAPI ${MANTID_SUBPROJECT_LIBS} diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h index 4aa78d305fba7a059e364a459b93e36e76b09715..387ea81f8f73b6827082d810029032f1015452d9 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h @@ -95,9 +95,9 @@ namespace Mantid /** * Callback function for background color changing events *@param caller Calling object. - *@param eventId Not used. - *@param clientData Not used. - *@parma callData Not used. + *@param vtkNotUsed(eventId) Not used. + *@param vtkNotUsed(clientData) Not used. + *@param vtkNotUsed(callData) Not used. */ static void backgroundColorChangeCallbackFunction(vtkObject* caller, long unsigned int vtkNotUsed(eventId), void* vtkNotUsed(clientData), void* vtkNotUsed(callData)); diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/CameraManager.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/CameraManager.h new file mode 100644 index 0000000000000000000000000000000000000000..9f0c5f9cdba1f3738e983b1ec7b3e91e874db78e --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/CameraManager.h @@ -0,0 +1,57 @@ +#ifndef CAMERAMANAGER_H_ +#define CAMERAMANAGER_H_ + +#include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h" +#include "MantidVatesAPI/ViewFrustum.h" + +namespace Mantid +{ +namespace Vates +{ +namespace SimpleGui +{ + + +/** + * + This class handles the camera of the view. + + @date 14/1/2015 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source + + 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://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ +class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS CameraManager +{ +public: + CameraManager(); + + ~CameraManager(); + + Mantid::VATES::ViewFrustum getCurrentViewFrustum(); + + void setCameraToPeak(double xpos, double ypos, double zpos, double peakRadius); +}; + +} +} +} + +#endif diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h index e24689aaecb588e58c90bdfad6cae19f1cb8bd2b..fcd8880ecfd02421d393af3a07effee553fef3bc 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h @@ -199,8 +199,6 @@ private: void resetCurrentView(int workspaceType, const std::string& instrumentName); /// Render rebinned workspace void prepareRebinnedWorkspace(const std::string rebinnedWorkspaceName, std::string sourceType); - /// Set visibility listener - void setVisibilityListener(); /// Handle drag and drop of peaks workspcaes void handleDragAndDropPeaksWorkspaces(QEvent* e, QString text, QStringList& wsNames); /// Set up the default color for the background of the view. diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.h new file mode 100644 index 0000000000000000000000000000000000000000..f24b54f7321f053936c870d08da15e3d837b6334 --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.h @@ -0,0 +1,47 @@ +#ifndef VSI_PEAKSTABWIDGET_H +#define VSI_PEAKSTABWIDGET_H + +#include "ui_PeaksTabWidget.h" +#include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h" +#include "MantidAPI/IPeaksWorkspace.h" + +#include <QWidget> +#include <string> +#include <vector> +#include <map> + +namespace Mantid +{ +namespace Vates +{ +namespace SimpleGui +{ + class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS PeaksTabWidget : public QWidget + { + Q_OBJECT + public: + PeaksTabWidget(std::vector<Mantid::API::IPeaksWorkspace_sptr> ws, const std::string& coordinateSystem, QWidget *parent = 0); + ~PeaksTabWidget(); + void setupMvc(std::map<std::string, std::vector<bool>> visiblePeaks); + void addNewPeaksWorkspace(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, std::vector<bool> visiblePeaks); + void updateTabs(std::map<std::string, std::vector<bool>> visiblePeaks); + signals: + void zoomToPeak(Mantid::API::IPeaksWorkspace_sptr ws, int row); + public slots: + void onZoomToPeak(Mantid::API::IPeaksWorkspace_sptr ws, int row); + private: + /// Update a certain tab. + void updateTab(std::vector<bool> visiblePeaks, int index); + /// Adds a new tab to the tab widget. + void addNewTab(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, std::string tabName, std::vector<bool> visiblePeaks); + /// Auto-generated UI controls. + Ui::PeaksTabWidget ui; + /// Peaks workspace to view. + std::vector<Mantid::API::IPeaksWorkspace_sptr> m_ws; + /// Coordinate system. + const std::string m_coordinateSystem; + }; +} //namespace +} +} +#endif // PEAKSWORKSPACEWIDGET_H diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.ui b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.ui new file mode 100644 index 0000000000000000000000000000000000000000..85322c8384fa453a252cee3b9c72adbdd56d91f9 --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.ui @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PeaksTabWidget</class> + <widget class="QWidget" name="PeaksTabWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>200</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>16777215</height> + </size> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <layout class="QHBoxLayout" name="tabLayout"> + <property name="spacing"> + <number>0</number> + </property> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="currentIndex"> + <number>-1</number> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTableControllerVsi.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTableControllerVsi.h new file mode 100644 index 0000000000000000000000000000000000000000..aaaac0a728ec97da188f75c2b24cb576e543b130 --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTableControllerVsi.h @@ -0,0 +1,62 @@ +#ifndef PeaksTableControllerVSI_H_ +#define PeaksTableControllerVSI_H_ + +#include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h" +#include "MantidVatesSimpleGuiViewWidgets/CameraManager.h" +#include "MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.h" +#include "MantidVatesAPI/CompositePeaksPresenterVsi.h" +#include "MantidAPI/PeakTransformSelector.h" +#include "MantidGeometry/Crystal/PeakShape.h" + +#include <QWidget> +#include <QPointer> +#include <boost/shared_ptr.hpp> + +class pqPipelineSource; + +namespace Mantid +{ +namespace Vates +{ +namespace SimpleGui +{ +class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS PeaksTableControllerVsi : public QWidget +{ + Q_OBJECT +public: + PeaksTableControllerVsi(boost::shared_ptr<CameraManager> cameraManager, QWidget *parent=0); + ~PeaksTableControllerVsi(); + std::vector<bool> getViewablePeaks(); + bool hasPeaks(); + void showFullTable(); + void removeTable(); + std::string getConcatenatedWorkspaceNames(std::string delimiter); + void updatePeaksWorkspaces(QList<QPointer<pqPipelineSource>> peakSources, pqPipelineSource* splatSource); +signals: + void setRotationToPoint(double x, double y, double z); +public slots: + void updateViewableArea(); + void onZoomToPeak(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, int row); + void destroySinglePeakSource(); + void onPeakMarkerDestroyed(); +private: + void addWorkspace(pqPipelineSource* source, QPointer<pqPipelineSource> splatSource); + std::vector<std::string> extractFrameFromSource(QPointer<pqPipelineSource> splatSource); + void generateSinglePeaksSource(double position1, double position2, double position3, double radius); + void resetSinglePeaksSource(double position1, double position2, double position3, double radius); + bool checkMatchingSources(pqPipelineSource* source, QPointer<pqPipelineSource> splatSource); + double getMaxRadius(Mantid::Geometry::PeakShape_sptr shape); + void removeLayout(QWidget *widget); + void createTable(bool full); + boost::shared_ptr<CameraManager> m_cameraManager; + boost::shared_ptr<Mantid::VATES::CompositePeaksPresenterVsi> m_presenter; + /// Object for choosing a PeakTransformFactory based on the workspace type. + Mantid::API::PeakTransformSelector m_peakTransformSelector; + PeaksTabWidget* m_peaksTabWidget; + pqPipelineSource* m_peakMarker; +}; + +} +} +} +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.h new file mode 100644 index 0000000000000000000000000000000000000000..9ef643246e1011c9c5d7b4046a7e5f664992070d --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.h @@ -0,0 +1,44 @@ +#ifndef VSI_PEAKSWORKWIDGET_H +#define VSI_PEAKSWORKWIDGET_H + +#include "ui_PeaksWidget.h" +#include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h" +#include "MantidAPI/IPeaksWorkspace.h" + +#include <QWidget> +#include <string> +#include <vector> +#include <map> + +namespace Mantid +{ +namespace Vates +{ +namespace SimpleGui +{ + class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS PeaksWidget : public QWidget + { + Q_OBJECT + public: + PeaksWidget(Mantid::API::IPeaksWorkspace_sptr ws, const std::string& coordinateSystem, QWidget *parent = 0); + void setupMvc(std::vector<bool> visiblePeaks); + void updateModel(std::vector<bool> visiblePeaks); + signals: + void zoomToPeak(Mantid::API::IPeaksWorkspace_sptr ws, int row); + public slots: + void onCurrentChanged(QModelIndex current, QModelIndex); + private: + /// Auto-generated UI controls. + Ui::PeaksWidget ui; + /// Peaks workspace to view. + Mantid::API::IPeaksWorkspace_sptr m_ws; + /// Coordinate system. + const std::string m_coordinateSystem; + /// Table width + int m_originalTableWidth; + }; + +} //namespace +} +} +#endif // PEAKSWORKSPACEWIDGET_H diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.ui b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.ui new file mode 100644 index 0000000000000000000000000000000000000000..4c1aa03e838cf079f246280a4f6244571f3b2088 --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.ui @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PeaksWidget</class> + <widget class="QWidget" name="PeaksWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>474</width> + <height>156</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>16777215</height> + </size> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2" stretch="1"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <layout class="QHBoxLayout" name="tableLayout"> + <item> + <widget class="QTableView" name="tblPeaks"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="autoScrollMargin"> + <number>7</number> + </property> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::SingleSelection</enum> + </property> + <property name="selectionBehavior"> + <enum>QAbstractItemView::SelectRows</enum> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <attribute name="horizontalHeaderStretchLastSection"> + <bool>true</bool> + </attribute> + <attribute name="verticalHeaderVisible"> + <bool>false</bool> + </attribute> + <attribute name="verticalHeaderStretchLastSection"> + <bool>false</bool> + </attribute> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.h index 7c44cfcb49acc6735f4c76346e95b89f96937a03..22312e91fa9e9ef8b2c5dc4db1e215db51e7a1e6 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.h @@ -4,11 +4,16 @@ #include "ui_SplatterPlotView.h" #include "MantidVatesSimpleGuiViewWidgets/ViewBase.h" #include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h" +#include "MantidVatesSimpleGuiViewWidgets/CameraManager.h" +#include "MantidVatesSimpleGuiViewWidgets/PeaksTableControllerVsi.h" +#include <boost/shared_ptr.hpp> +#include <string> #include <QList> #include <QPointer> class QWidget; +class QAction; class pqPipelineRepresentation; class pqPipelineSource; @@ -85,6 +90,10 @@ public: * ViewBase::resetDisplay() */ void resetDisplay(); + /** + * Destroy all sources in the view. + */ + virtual void destroyAllSourcesInView(); signals: /// Reset to the Standard View @@ -95,8 +104,10 @@ signals: public slots: /// Check the coordinates for the peaks overlay if necessary void checkPeaksCoordinates(); - /// Listen to destruction of peak sources - void onPeakSourceDestroyed(); + /// Remove the visible peaks table. + void onRemovePeaksTable(); + /// Show all peaks in table. + void onShowAllPeaksTable(); protected slots: /// Check state of toggle button with respect to peak coordinates. @@ -107,6 +118,10 @@ protected slots: * Create and apply a threshold filter to the data. */ void onThresholdButtonClicked(); + /// On peaks filter destroyed + void onPeaksFilterDestroyed(); + /// On peaks source destroyed + void onPeakSourceDestroyed(); private: Q_DISABLE_COPY(SplatterPlotView) @@ -119,6 +134,20 @@ private: bool eventFilter(QObject *obj, QEvent *ev); /// Read the coordinates and send to service. void readAndSendCoordinates(); + /// Setup the buttons for the visible peaks + void setupVisiblePeaksButtons(); + /// Create the peaks filter + void createPeaksFilter(); + /// Set the state of the peak button + void setPeakButton(bool state); + /// Set the frame for the peaks + void setPeakSourceFrame(pqPipelineSource* source); + /// Check if a peaks workspace is already part of the recorded peaks sources. + bool checkIfPeaksWorkspaceIsAlreadyBeingTracked(pqPipelineSource* source); + /// Update the peaks filter + void updatePeaksFilter(pqPipelineSource* filter); + /// Destroy splatter plot specific sources and filters + void destroyFiltersForSplatterPlotView(); bool noOverlay; ///< Flag to respond to overlay situation correctly QList<QPointer<pqPipelineSource> > peaksSource; ///< A list of peaks sources @@ -126,8 +155,14 @@ private: QPointer<pqPipelineRepresentation> splatRepr; ///< The splatter plot representation QPointer<pqPipelineSource> splatSource; ///< The splatter plot source QPointer<pqPipelineSource> threshSource; ///< The thresholding filter source + QPointer<pqPipelineSource> m_peaksFilter; ///< The peaks filter Ui::SplatterPlotView ui; ///< The splatter plot view'a UI form QPointer<pqRenderView> view; ///< The main view area + boost::shared_ptr<CameraManager> m_cameraManager; ///< The camera manager + PeaksTableControllerVsi* m_peaksTableController; ///< The peaks table controller + QAction* m_allPeaksAction;///<The action for showing all peaks in the table. + QAction* m_removePeaksAction; ///<The action for removing the peaks table. + std::string m_peaksWorkspaceNameDelimiter;///<Delimiter for peaks workspace strings. }; } // SimpleGui diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.ui b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.ui index d7b47a221a77f5d58bd8f8cdc523872f972a9e9a..49505fefb1c0d8addbb296cd4a0026556a0c41b1 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.ui +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.ui @@ -14,6 +14,15 @@ <string>Form</string> </property> <layout class="QVBoxLayout" name="verticalLayout"> + <property name="leftMargin"> + <number>9</number> + </property> + <property name="rightMargin"> + <number>9</number> + </property> + <property name="bottomMargin"> + <number>9</number> + </property> <item> <layout class="QHBoxLayout" name="horizontalLayout"> <item> @@ -59,6 +68,28 @@ </property> </widget> </item> + <item> + <widget class="QToolButton" name="peaksButton"> + <property name="minimumSize"> + <size> + <width>75</width> + <height>23</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Peaks</string> + </property> + <property name="arrowType"> + <enum>Qt::NoArrow</enum> + </property> + </widget> + </item> <item> <spacer name="horizontalSpacer_2"> <property name="orientation"> diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.h index 403df62c7576e76049cac09f4c0393eb8f2a61e3..4dee0413a3c6797aef47595c0f78f483773af357 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.h @@ -91,8 +91,6 @@ protected slots: void onBinMD(); /// On SliceMD button clicked void onSliceMD(); - /// On CutMD button clicked - void onCutMD(); private: Q_DISABLE_COPY(StandardView) @@ -109,7 +107,6 @@ private: QAction* m_binMDAction; QAction* m_sliceMDAction; - QAction* m_cutMDAction; QAction* m_unbinAction; }; diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h index 51a5607306f8fff67990f7d076d6b386c8f26b58..93ce9a1c73b272875bf8a520b493c812a2b33027 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h @@ -129,6 +129,14 @@ public: enum Direction {X, Y, Z}; /// Update settings virtual void updateSettings(); + // Destroy all sources in the view. + virtual void destroyAllSourcesInView(); + // Destroy all sources in a single linear pipeline. + virtual void destroySinglePipeline(pqPipelineSource * source); + /// Set visibility listener + void setVisibilityListener(); + /// Undo visibiltiy listener + void removeVisibilityListener(); QPointer<pqPipelineSource> origSrc; ///< The original source QPointer<pqPipelineRepresentation> origRep; ///< The original source representation diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp index 82101590b1bed5c5d0cd7612591385fc84f5ac89..8bb04709ace7bf305902120620028907daefc127 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp @@ -39,7 +39,7 @@ namespace SimpleGui { //Set the initial log scale state due to the mode m_mdSettings.setLastSessionLogScale(getLogScale()); - }; + } /** * Gets the log scale for the mode @@ -165,6 +165,13 @@ namespace SimpleGui // Set the color scale output VsiColorScale vsiColorScale; + // If either the min or max value are at the end of the double spectrum, we might only have a peak Ws visible, + // we need to hedge for that + if (minValue == DBL_MAX || maxValue == -DBL_MAX) { + minValue = defaultValue; + maxValue = defaultValue; + } + // Account for possible negative data. If min value is negative and max value is larger than 100, then set to default // else set to three orders of magnitude smaller than the max value if (minValue < 0 && maxValue > 100) @@ -201,7 +208,9 @@ namespace SimpleGui // Check if source is custom filter if (QString(proxy->GetXMLName()).contains("MantidParaViewScaleWorkspace") || QString(proxy->GetXMLName()).contains("MDEWRebinningCutter") || - QString(proxy->GetXMLName()).contains("MantidParaViewSplatterPlot")) + QString(proxy->GetXMLName()).contains("MantidParaViewSplatterPlot") || + QString(proxy->GetXMLName()).contains("MantidParaViewPeaksFilter")) + { minValue = vtkSMPropertyHelper(proxy,"MinValue").GetAsDouble(); maxValue = vtkSMPropertyHelper(proxy,"MaxValue").GetAsDouble(); @@ -220,7 +229,8 @@ namespace SimpleGui } // Check if Peak Workspace. This workspace should not contribute to colorscale - if (QString(proxy->GetXMLName()).contains("Peaks Source")) + if (QString(proxy->GetXMLName()).contains("Peaks Source") || + QString(proxy->GetXMLName()).contains("SinglePeakMarkerSource")) { minValue = DBL_MAX; maxValue = -DBL_MAX; diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/BackgroundRgbProvider.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/BackgroundRgbProvider.cpp index 7cba3778ed2e1c915e2229ddaf411ea3a1274a5b..59b0757a017629cff5dc453b01656a09b1bf9f23 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/BackgroundRgbProvider.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/BackgroundRgbProvider.cpp @@ -29,13 +29,13 @@ namespace Mantid BackgroundRgbProvider::BackgroundRgbProvider() { - }; + } BackgroundRgbProvider::~BackgroundRgbProvider() { // Need to record the background color update(); - }; + } std::vector<double> BackgroundRgbProvider::getRgb(bool viewSwitched) { diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/CameraManager.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/CameraManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..74010d9a7049d985c60b7d10daac9f4cf9d1215d --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/CameraManager.cpp @@ -0,0 +1,143 @@ +#include "MantidVatesSimpleGuiViewWidgets/CameraManager.h" +#include "MantidVatesAPI/ViewFrustum.h" +#include <stdexcept> +// Have to deal with ParaView warnings and Intel compiler the hard way. +#if defined(__INTEL_COMPILER) + #pragma warning disable 1170 +#endif + +#include <pqView.h> +#include <pqActiveView.h> +#include <vtkSMRenderViewProxy.h> +#include <vtkCamera.h> +#include <vtkRenderer.h> +#include <vtkRenderWindow.h> + +namespace Mantid +{ + namespace Vates + { + namespace SimpleGui + { + CameraManager::CameraManager() + { + } + + CameraManager::~CameraManager() + { + } + /** + * Get the plane equation for the view frustum. + * @param left The left plane. + * @param right The right plane. + * @param bottom The bottom plane. + * @param top The top plane. + * @param far The far plane. + * @param near The near plane. + */ + Mantid::VATES::ViewFrustum CameraManager::getCurrentViewFrustum() + { + double left[4]; + double right[4]; + double bottom[4]; + double top[4]; + double far[4]; + double near[4]; + + pqView * view = pqActiveView::instance().current(); + + vtkSMRenderViewProxy* proxy = NULL; + + if (view) + { + proxy = vtkSMRenderViewProxy::SafeDownCast(view->getViewProxy()); + } + + if (!proxy) + { + // no active view, or active view is not a render view. + throw std::invalid_argument("Invalid vtkSMRenderViewProxy."); + } + + // Get the aspect ratio of the renderer + vtkRenderer* renderer = proxy->GetRenderer(); + if (!renderer) + { + throw std::invalid_argument("Invalid vtkRenderer."); + } + + double aspectDimensions[2]; + renderer->GetAspect(aspectDimensions); + double aspectRatio = aspectDimensions[0]/aspectDimensions[1]; + + // Get the active camera + vtkCamera* camera = proxy->GetActiveCamera(); + + if (!camera) + { + throw std::invalid_argument("Invalid vtkCamera."); + } + + double planes[24]; + camera->GetFrustumPlanes(aspectRatio, planes); + + for (int k = 0; k < 4; ++k) + { + left[k] = planes[k]; + right[k] = planes[k + 4]; + + bottom[k] = planes[k + 8]; + top[k] = planes[k + 12]; + + near[k] = planes[k + 16]; + far[k] = planes[k + 20]; + } + Mantid::VATES::ViewFrustum frustum(Mantid::VATES::LeftPlane(left[0], left[1], left[2], left[3]), + Mantid::VATES::RightPlane(right[0], right[1], right[2], right[3]), + Mantid::VATES::BottomPlane(bottom[0], bottom[1], bottom[2], bottom[3]), + Mantid::VATES::TopPlane(top[0], top[1], top[2], top[3]), + Mantid::VATES::FarPlane(far[0], far[1], far[2], far[3]), + Mantid::VATES::NearPlane(near[0], near[1], near[2], near[3])); + + return frustum; + } + + /** + * Set the view onto a peak + * @param xpos X position of the peak. + * @param ypos Y position of the peak. + * @param zpos Z position of the peak. + * @param peakRadius The radius of the peak. + */ + void CameraManager::setCameraToPeak(double xpos, double ypos, double zpos, double peakRadius) + { + pqView * view = pqActiveView::instance().current(); + vtkSMRenderViewProxy* proxy = NULL; + + if (view) + { + proxy = vtkSMRenderViewProxy::SafeDownCast(view->getViewProxy()); + } + + if (!proxy) + { + // no active view, or active view is not a render view. + throw std::invalid_argument("Invalid vtkSMRenderViewProxy."); + } + + // Get the active camera + vtkCamera* camera = proxy->GetActiveCamera(); + + // Setup the focal point of the camera. we want this to be on the peak + camera->SetFocalPoint(xpos, ypos, zpos); + + // Setup the position of the camera. We want this to be + double zposCamera = zpos + peakRadius*3; + camera->SetPosition(xpos, ypos, zposCamera); + camera->SetViewUp(0.0, 1.0, 0.0); + + view->forceRender(); + } + } + } +} \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp index 6e8b6a79854972d426e4b78fdbcd11fc29d5479a..5b5fdd2c7dbe435b9295230b3e9e09052df3f15d 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp @@ -975,7 +975,7 @@ void MdViewerWidget::renderAndFinalSetup() this->currentView->checkView(this->initialView); this->currentView->updateAnimationControls(); this->setDestroyedListener(); - this->setVisibilityListener(); + this->currentView->setVisibilityListener(); this->currentView->onAutoScale(this->ui.colorSelectionWidget); } @@ -1056,7 +1056,7 @@ void MdViewerWidget::switchViews(ModeControlWidget::Views v) this->updateAppState(); this->initialView = v; this->setDestroyedListener(); - this->setVisibilityListener(); + this->currentView->setVisibilityListener(); } /** @@ -1093,10 +1093,7 @@ bool MdViewerWidget::eventFilter(QObject *obj, QEvent *ev) this->ui.colorSelectionWidget->reset(); this->currentView->setColorScaleState(this->ui.colorSelectionWidget); - - pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder(); - builder->destroySources(); - + this->currentView ->destroyAllSourcesInView(); this->currentView->updateSettings(); this->currentView->hide(); @@ -1381,6 +1378,9 @@ void MdViewerWidget::preDeleteHandle(const std::string &wsName, removeRebinning(src, true); return; } + + // Remove all visibility listeners + this->currentView->removeVisibilityListener(); emit this->requestClose(); } @@ -1437,29 +1437,12 @@ void MdViewerWidget::setDestroyedListener() } } -/** - * Set the listener for the visibility of the representations - */ -void MdViewerWidget::setVisibilityListener() -{ - // Set the connection to listen to a visibility change of the representation. - pqServer *server = pqActiveObjects::instance().activeServer(); - pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel(); - QList<pqPipelineSource *> sources; - sources = smModel->findItems<pqPipelineSource *>(server); - // Attach the visibilityChanged signal for all sources. - for (QList<pqPipelineSource *>::iterator source = sources.begin(); source != sources.end(); ++source) - { - QObject::connect((*source), SIGNAL(visibilityChanged(pqPipelineSource*, pqDataRepresentation*)), - this->currentView, SLOT(onVisibilityChanged(pqPipelineSource*, pqDataRepresentation*)), - Qt::UniqueConnection); - } -} + /** * Dectect when a PeaksWorkspace is dragged into the VSI. - * @param A drag event. + * @param e A drag event. */ void MdViewerWidget::dragEnterEvent(QDragEnterEvent *e) { QString name = e->mimeData()->objectName(); @@ -1475,7 +1458,7 @@ void MdViewerWidget::dragEnterEvent(QDragEnterEvent *e) { /** * React to dropping a PeaksWorkspace ontot the VSI. - * @param e A drop event. + * @param e Drop event. */ void MdViewerWidget::dropEvent(QDropEvent *e) { QString name = e->mimeData()->objectName(); @@ -1494,7 +1477,7 @@ void MdViewerWidget::dropEvent(QDropEvent *e) { * Handle the drag and drop events of peaks workspaces. * @param e The event. * @param text String containing information regarding the workspace name. - * @param wsNames A reference to a list of workspaces names, which are being extracted. + * @param wsNames Reference to a list of workspaces names, which are being extracted. */ void MdViewerWidget::handleDragAndDropPeaksWorkspaces(QEvent* e, QString text, QStringList& wsNames) { diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksTabWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksTabWidget.cpp new file mode 100644 index 0000000000000000000000000000000000000000..de208face716d97c26c6c7d7a3d386c50bac27fc --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksTabWidget.cpp @@ -0,0 +1,112 @@ +#include "MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.h" + +#include "MantidAPI/IPeaksWorkspace.h" +#include "MantidQtSliceViewer/QPeaksTableModel.h" +#include "MantidVatesSimpleGuiViewWidgets/PeaksWidget.h" + +#include <QWidget> +#include <QItemSelectionModel> +#include <QModelIndex> +#include <vector> +#include <string> +#include <map> + +namespace Mantid +{ +namespace Vates +{ +namespace SimpleGui +{ +/** +Constructor + +@param ws : Peaks Workspace (MODEL) +@param coordinateSystem : Name of coordinate system used +@param parent : parent widget +*/ +PeaksTabWidget::PeaksTabWidget(std::vector<Mantid::API::IPeaksWorkspace_sptr> ws, const std::string &coordinateSystem, QWidget *parent) : QWidget(parent), m_ws(ws), m_coordinateSystem(coordinateSystem){ + ui.setupUi(this); +} + +/// Destructor +PeaksTabWidget::~PeaksTabWidget(){ +} + +/** + * Setup the Table model + * @param visiblePeaks : A vector of lists of visible peaks for each peak workspace + */ +void PeaksTabWidget::setupMvc(std::map<std::string, std::vector<bool>> visiblePeaks) { + for (std::vector<Mantid::API::IPeaksWorkspace_sptr>::iterator it = m_ws.begin(); it != m_ws.end(); ++it) { + // Create new tab + std::string name((*it)->getName().c_str()); + + // Get visible peaks + if (visiblePeaks.count((*it)->getName()) > 0) { + addNewTab(*it, name, visiblePeaks[(*it)->getName()]); + } + } +} + +void PeaksTabWidget::addNewTab(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, std::string tabName, std::vector<bool> visiblePeaks) { + PeaksWidget* widget = new PeaksWidget(peaksWorkspace, m_coordinateSystem, this); + widget->setupMvc(visiblePeaks); + + // Connect to the output of the widget + QObject::connect(widget, SIGNAL(zoomToPeak(Mantid::API::IPeaksWorkspace_sptr, int)), + this, SLOT(onZoomToPeak(Mantid::API::IPeaksWorkspace_sptr, int))); + + // Add as a new tab + this->ui.tabWidget->addTab(widget, QString(tabName.c_str())); +} + +/** + * Zoom to the peak of interest + * @param ws The workspace pointer. + * @param row The row in the table. + */ +void PeaksTabWidget::onZoomToPeak(Mantid::API::IPeaksWorkspace_sptr ws, int row){ + emit zoomToPeak(ws, row); +} + +/** + * Update the models and remove the model if it is not required anymore. + * @param visiblePeaks A map with visible peaks for each workspace. + */ +void PeaksTabWidget::updateTabs(std::map<std::string, std::vector<bool>> visiblePeaks) { + // Iterate over all tabs + for (int i = 0; i < this->ui.tabWidget->count(); i++) { + QString label = this->ui.tabWidget->label(i); + + // Check if the peaks workspace still exists, if it does update, else delete the tab. + if (visiblePeaks.count(label.toStdString()) > 0) { + updateTab(visiblePeaks[label.toStdString()], i); + } + else + { + this->ui.tabWidget->removeTab(i); + } + } +} + +/** + * Update the tab + * @param visbiblePeaks Vector which determines which peaks are visible. + * @param index The tab index. + */ +void PeaksTabWidget::updateTab(std::vector<bool> visiblePeaks, int index) { + PeaksWidget* widget = qobject_cast<PeaksWidget*>(this->ui.tabWidget->widget(index)); + widget->updateModel(visiblePeaks); +} + +/** + * Add a new tabs widget + * @param peaksWorkspace A pointer to a peaksWorkspace + */ +void PeaksTabWidget::addNewPeaksWorkspace(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, std::vector<bool> visiblePeaks) { + m_ws.push_back(peaksWorkspace); + addNewTab(peaksWorkspace, peaksWorkspace->getName(), visiblePeaks); +} +} +} // namespace +} \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksTableControllerVsi.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksTableControllerVsi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..88dafd6383256bf1ad1f06b887f29ee5afe71f1d --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksTableControllerVsi.cpp @@ -0,0 +1,504 @@ +#include "MantidVatesSimpleGuiViewWidgets/PeaksTableControllerVsi.h" + +#include "MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.h" +#include "MantidVatesSimpleGuiViewWidgets/CameraManager.h" +#include "MantidAPI/IPeaksWorkspace.h" +#include "MantidAPI/IMDEventWorkspace.h" +#include "MantidAPI/AnalysisDataService.h" +#include "MantidAPI/PeakTransformHKL.h" +#include "MantidAPI/PeakTransformQSample.h" +#include "MantidAPI/PeakTransformQLab.h" +#include "MantidKernel/V3D.h" +#include "MantidVatesAPI/PeaksPresenterVsi.h" +#include "MantidVatesAPI/NullPeaksPresenterVsi.h" +#include "MantidVatesAPI/ConcretePeaksPresenterVsi.h" +#include "MantidVatesAPI/CompositePeaksPresenterVsi.h" +#include "MantidQtAPI/PlotAxis.h" +#include "MantidGeometry/MDGeometry/IMDDimension.h" +#include "MantidKernel/Logger.h" + +// Have to deal with ParaView warnings and Intel compiler the hard way. +#if defined(__INTEL_COMPILER) + #pragma warning disable 1170 +#endif +#include <pqActiveObjects.h> +#include <pqApplicationCore.h> +#include <pqObjectBuilder.h> +#include <pqPipelineSource.h> +#include <pqPipelineFilter.h> +#include <pqServer.h> +#include <vtkSMSourceProxy.h> +#include <vtkSMPropertyHelper.h> +#include <vtkSMProxy.h> + +#if defined(__INTEL_COMPILER) + #pragma warning enable 1170 +#endif + +#include <QString> +#include <QPointer> +#include <QVBoxLayout> +#include <QLayout> +#include <QLayoutItem> + +#include <boost/make_shared.hpp> +#include <boost/shared_ptr.hpp> +#include <stdexcept> +#include <algorithm> +#include <map> +#include <sstream> + +namespace Mantid +{ +namespace Vates +{ +namespace SimpleGui +{ + +namespace +{ + Mantid::Kernel::Logger g_log("PeakViewerVsi"); +} + + /** + * Constructor + * @param cameraManager A cameraManager pointer. + * @param parent A pointer to a QWidget parent. + */ + PeaksTableControllerVsi::PeaksTableControllerVsi(boost::shared_ptr<CameraManager> cameraManager, QWidget *parent) : QWidget(parent), + m_cameraManager(cameraManager), + m_presenter(new Mantid::VATES::CompositePeaksPresenterVsi()), + m_peaksTabWidget(NULL), + m_peakMarker(NULL) + { + m_peakTransformSelector.registerCandidate(boost::make_shared<Mantid::API::PeakTransformHKLFactory>()); + m_peakTransformSelector.registerCandidate(boost::make_shared<Mantid::API::PeakTransformQSampleFactory>()); + m_peakTransformSelector.registerCandidate(boost::make_shared<Mantid::API::PeakTransformQLabFactory>()); + } + + PeaksTableControllerVsi::~PeaksTableControllerVsi() + { + destroySinglePeakSource(); + } + + /** + * Check for viewable peaks. + * @returns A vector of the peak indices which are visible and which are not visible. + */ + std::vector<bool> PeaksTableControllerVsi::getViewablePeaks() + { + std::vector<bool> viewablePeaks; + if (m_presenter) + { + // Get the up to date area + updateViewableArea(); + + //Get a list with viewable peak coordinates + try + { + viewablePeaks = m_presenter->getViewablePeaks(); + } + catch(...) + { + g_log.warning() << "The viewable peaks could not be retrieved. \n"; + } + } + return viewablePeaks; + } + + /** + * Add a new workspace + * @param source A new peaks source + * @param splatSource A pointer to the splatter source + */ + void PeaksTableControllerVsi::addWorkspace(pqPipelineSource* source, QPointer<pqPipelineSource> splatSource) + { + try + { + if (!source || !splatSource) + { + throw std::invalid_argument("The pqPipelineSource of the peaks workspace does not exist."); + } + + // Get the pointer to the peaks workspace + std::string wsName(vtkSMPropertyHelper(source->getProxy(), "WorkspaceName", true).GetAsString()); + std::string peaksFrame(vtkSMPropertyHelper(source->getProxy(), "Peak Dimensions", true).GetAsString()); + + // Get dimensions from splattersource + std::vector<std::string> dimInfo = extractFrameFromSource(splatSource); + if (dimInfo.size() < 2) + { + throw std::invalid_argument("The workspace needs to have at least two dimensions"); + } + + std::string dimCompare = dimInfo[0]; + std::transform(dimCompare.begin(), dimCompare.end(),dimCompare.begin(), ::toupper); + std::transform(peaksFrame.begin(), peaksFrame.end(),peaksFrame.begin(), ::toupper); + // Check if frames match + if (dimCompare.find(peaksFrame) == std::string::npos) + { + throw std::runtime_error("The workspaces do not match."); + } + + Mantid::API::IPeaksWorkspace_sptr peaksWorkspace = Mantid::API::AnalysisDataService::Instance().retrieveWS<Mantid::API::IPeaksWorkspace>(wsName); + + Mantid::API::PeakTransformFactory_sptr transformFactory = m_peakTransformSelector.makeChoice(dimInfo[0], dimInfo[1]); + Mantid::API::PeakTransform_sptr transform = transformFactory->createTransform(dimInfo[0], dimInfo[1]); + std::string frame = transform->getFriendlyName(); + + m_presenter->addPresenter(boost::make_shared<Mantid::VATES::ConcretePeaksPresenterVsi>(peaksWorkspace, m_cameraManager->getCurrentViewFrustum(), frame)); + + // If the tab widget is visible, then update it + if (m_peaksTabWidget) { + std::map<std::string, std::vector<bool>> viewablePeaks = m_presenter->getInitializedViewablePeaks(); + m_peaksTabWidget->addNewPeaksWorkspace(peaksWorkspace, viewablePeaks[peaksWorkspace->getName()]); + m_peaksTabWidget->updateTabs(viewablePeaks); + } + } + catch(Mantid::Kernel::Exception::NotFoundError&) + { + g_log.warning() << "Could not retrieve the peaks workspace.\n"; + throw; + } + catch(std::invalid_argument &ex) + { + g_log.warning() << ex.what(); + throw; + } + catch(std::runtime_error &ex) + { + g_log.warning() << ex.what(); + throw; + } + } + + /** + * Update the view region for the presenters + */ + void PeaksTableControllerVsi::updateViewableArea() + { + Mantid::VATES::ViewFrustum frustum = m_cameraManager->getCurrentViewFrustum(); + m_presenter->updateViewFrustum(frustum); + } + + /** + * Extract the frame from the source + * @param splatSource A pointer to a splatter plot source. + */ + std::vector<std::string> PeaksTableControllerVsi::extractFrameFromSource(QPointer<pqPipelineSource> splatSource) + { + pqPipelineFilter* filter = qobject_cast<pqPipelineFilter*>(splatSource); + + if (!filter) + { + throw std::invalid_argument("The splatter source is not a filter."); + } + + // Check the original source + pqPipelineSource* originalSource = filter->getInput(0); + if (!originalSource) + { + throw std::invalid_argument("The original source cannot be found."); + } + + std::string xmlName(originalSource->getProxy()->GetXMLName()); + if (!(xmlName.find("MDEW") != std::string::npos)) + { + throw std::invalid_argument("The original source cannot be found."); + } + + std::string wsName(vtkSMPropertyHelper(originalSource->getProxy(), "WorkspaceName", true).GetAsString()); + Mantid::API::IMDEventWorkspace_sptr eventWorkspace = Mantid::API::AnalysisDataService::Instance().retrieveWS<Mantid::API::IMDEventWorkspace>(wsName); + + std::vector<std::string> dimensionInfo; + for (size_t i = 0; i < eventWorkspace->getNumDims(); i++) + { + dimensionInfo.push_back(MantidQt::API::PlotAxis(*(eventWorkspace->getDimension(i))).title().toStdString()); + } + + return dimensionInfo; + } + + /** + * Check if the peaks viewer has a peaks workspace loaded. + * @returns If the a peaks workspace is loaded. + */ + bool PeaksTableControllerVsi::hasPeaks() + { + if (!m_presenter || !m_presenter->hasPeaks()) + { + return false; + } + else + { + return true; + } + } + + /** + * Show all peaks in the table. + */ + void PeaksTableControllerVsi::showFullTable() + { + createTable(true); + } + + /** + * Create the table + * @param full If the full table is to be displayed or only visible peaks. + */ + void PeaksTableControllerVsi::createTable(bool full) + { + // Create the table if it does not exist + if (hasPeaks()) + { + if (layout()) + { + removeLayout(this); + } + + // Create new widget + try + { + // Set the layout of the table + this->setLayout(new QVBoxLayout); + + PeaksTabWidget* widget = new PeaksTabWidget(m_presenter->getPeaksWorkspaces(), m_presenter->getFrame(), this); + QObject::connect(widget, SIGNAL(zoomToPeak(Mantid::API::IPeaksWorkspace_sptr, int)), + this, SLOT(onZoomToPeak(Mantid::API::IPeaksWorkspace_sptr, int))); + + // Initialize the viewablePeaks to be true + std::map<std::string, std::vector<bool>> viewablePeaks = m_presenter->getInitializedViewablePeaks(); + + if (!full) + { + // + //viewablePeaks = getViewablePeaks(); + } + + widget->setupMvc(viewablePeaks); + layout()->addWidget(widget); + m_peaksTabWidget = widget; + } + catch(std::runtime_error &ex) + { + g_log.warning() << "Could not setup the the peaks widget for the splatterplot: " << ex.what() << "\n"; + } + catch(...) + { + g_log.warning() << "Could not setup the the peaks widget for the splatterplot.\n"; + } + } + } + + /** + * Remove the layout + * @param widget + */ + void PeaksTableControllerVsi::removeLayout(QWidget *widget) { + QLayout *layout = widget->layout(); + if (layout != 0) { + QLayoutItem *item; + while ((item = layout->takeAt(0)) != 0){ + layout->removeItem(item); + delete item->widget(); + } + delete layout; + } + } + + /** + * Remove the table. + */ + void PeaksTableControllerVsi::removeTable() + { + destroySinglePeakSource(); + if (m_peaksTabWidget) { + m_peaksTabWidget->deleteLater(); + } + m_peaksTabWidget = NULL; + } + + /** + * Zoom to a specific peak + * @param peaksWorkspace The peaksworkspace which is currently being displayed. + * @param row The selected row. + */ + void PeaksTableControllerVsi::onZoomToPeak(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, int row) + { + try + { + double radius; + Mantid::Kernel::V3D position; + m_presenter->getPeaksInfo(peaksWorkspace, row, position, radius); + + // Reset camera + m_cameraManager->setCameraToPeak(position[0], position[1], position[2], radius); + + // Place a marker glyph at the position + if (!m_peakMarker) + { + generateSinglePeaksSource(position[0], position[1], position[2], radius); + } + else + { + resetSinglePeaksSource(position[0], position[1], position[2], radius); + } + + emit setRotationToPoint(position[0], position[1], position[2]); + } + catch (std::invalid_argument &ex) + { + g_log.warning() << ex.what(); + emit setRotationToPoint(0.0, 0.0, 0.0); + } + } + + /** + * Generate a single peak glyph + * @param position1 Position 1 of the glyph. + * @param position2 Position 2 of the glyph. + * @param position3 Position 3 of the glyph. + * @param radius The radius of the peak. + */ + void PeaksTableControllerVsi::generateSinglePeaksSource(double position1, double position2, double position3, double radius) + { + // Create the source from the plugin + pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder(); + pqServer *server = pqActiveObjects::instance().activeServer(); + pqPipelineSource *src = builder->createSource("sources", "SinglePeakMarkerSource", server); + vtkSMPropertyHelper(src->getProxy(), "Position1").Set(position1); + vtkSMPropertyHelper(src->getProxy(), "Position2").Set(position2); + vtkSMPropertyHelper(src->getProxy(), "Position3").Set(position3); + vtkSMPropertyHelper(src->getProxy(), "RadiusMarker").Set(radius); + + vtkSMSourceProxy *srcProxy = vtkSMSourceProxy::SafeDownCast(src->getProxy()); + srcProxy->UpdateVTKObjects(); + srcProxy->Modified(); + srcProxy->UpdatePipelineInformation(); + src->updatePipeline(); + + pqDataRepresentation *drep = builder->createDataRepresentation(src->getOutputPort(0), pqActiveObjects::instance().activeView()); + vtkSMPropertyHelper(drep->getProxy(), "Representation").Set("Surface"); + srcProxy->UpdateVTKObjects(); + srcProxy->Modified(); + srcProxy->UpdatePipelineInformation(); + src->updatePipeline(); + + pqActiveObjects::instance().activeView()->forceRender(); + + m_peakMarker = src; + + //We need to make sure we detect when the source is destroyed, as the user can delete it in the pipeline browser + QObject::connect(m_peakMarker, SIGNAL(destroyed()), + this, SLOT(onPeakMarkerDestroyed())); + + } + + /** + * Destroy a single peaks source. + */ + void PeaksTableControllerVsi::destroySinglePeakSource() + { + if (m_peakMarker) + { + pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder(); + builder->destroy(m_peakMarker); + + m_peakMarker = NULL; + } + } + + /** + * On Single Peak Marker destroyed + */ + void PeaksTableControllerVsi::onPeakMarkerDestroyed() + { + m_peakMarker = NULL; + } + + /** + * Reset the single peak source + * @param position1 Position 1 of the glyph. + * @param position2 Position 2 of the glyph. + * @param position3 Position 3 of the glyph. + * @param radius The radius of the peak. + */ + void PeaksTableControllerVsi::resetSinglePeaksSource(double position1, double position2, double position3, double radius) + { + vtkSMPropertyHelper(m_peakMarker->getProxy(), "Position1").Set(position1); + vtkSMPropertyHelper(m_peakMarker->getProxy(), "Position2").Set(position2); + vtkSMPropertyHelper(m_peakMarker->getProxy(), "Position3").Set(position3); + vtkSMPropertyHelper(m_peakMarker->getProxy(), "RadiusMarker").Set(radius); + + vtkSMSourceProxy *srcProxy = vtkSMSourceProxy::SafeDownCast(m_peakMarker->getProxy()); + srcProxy->UpdateVTKObjects(); + srcProxy->Modified(); + srcProxy->UpdatePipelineInformation(); + m_peakMarker->updatePipeline(); + + pqActiveObjects::instance().activeView()->forceRender(); + } + + /** + * Get the workspace names as a concatenated string + * @param delimiter The delimiter to concatenate workspace names. + * @returns The concatenated workspace names. + */ + std::string PeaksTableControllerVsi::getConcatenatedWorkspaceNames(std::string delimiter) { + std::vector<std::string> peaksWorkspaceNames = m_presenter->getPeaksWorkspaceNames(); + std::stringstream stream; + for (size_t i = 0; i < peaksWorkspaceNames.size(); i++) { + stream << peaksWorkspaceNames[i]; + // Don't add a delimiter after the last element + if (i != (peaksWorkspaceNames.size()-1)) { + stream << delimiter; + } + } + return stream.str(); + } + + /** + * Update the presenters with the available peak workspaces + * @param peakSources A list with available peak sources + * @param splatSource The splatterplot source + */ + void PeaksTableControllerVsi::updatePeaksWorkspaces(QList<QPointer<pqPipelineSource>> peakSources, pqPipelineSource* splatSource) { + // Check if the which presenters exist and which need to be added + std::vector<std::string> peaksWorkspaceNames; + + std::vector<pqPipelineSource*> nonTrackedWorkspaces; + std::vector<std::string> trackedWorkspaceNames = m_presenter->getPeaksWorkspaceNames(); + for (QList<QPointer<pqPipelineSource>>::Iterator it = peakSources.begin(); it != peakSources.end(); ++it) { + std::string workspaceName(vtkSMPropertyHelper((*it)->getProxy(), "WorkspaceName").GetAsString()); + + peaksWorkspaceNames.push_back(workspaceName); + + int count = static_cast<int>(std::count(trackedWorkspaceNames.begin(), trackedWorkspaceNames.end(), workspaceName)); + + if (count == 0) { + nonTrackedWorkspaces.push_back(*it); + } + } + + if (splatSource) { + // Add the workspaces which are missing in the presenter + for (std::vector<pqPipelineSource*>::iterator it = nonTrackedWorkspaces.begin(); it != nonTrackedWorkspaces.end(); ++it) { + addWorkspace(*it, splatSource); + } + } + + // Now update all the presenter + m_presenter->updateWorkspaces(peaksWorkspaceNames); + if (!peakSources.empty() && m_peaksTabWidget) { + m_peaksTabWidget->updateTabs(m_presenter->getInitializedViewablePeaks()); + } + + // If there are no presenters left, we want to destroy the table + if (!hasPeaks()) { + removeTable(); + } + } +} +} +} \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksWidget.cpp new file mode 100644 index 0000000000000000000000000000000000000000..28b87daf264234bbcf2913bee27c075064bffae2 --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksWidget.cpp @@ -0,0 +1,99 @@ +#include "MantidVatesSimpleGuiViewWidgets/PeaksWidget.h" +#include "MantidAPI/IPeaksWorkspace.h" +#include "MantidQtSliceViewer/QPeaksTableModel.h" + +#include <QWidget> +#include <QItemSelectionModel> +#include <QModelIndex> +#include <vector> +#include <string> +#include <map> + +namespace Mantid +{ +namespace Vates +{ +namespace SimpleGui +{ +/** +Constructor + +@param ws : Peaks Workspace (MODEL) +@param coordinateSystem : Name of coordinate system used +@param parent : parent widget +*/ +PeaksWidget::PeaksWidget(Mantid::API::IPeaksWorkspace_sptr ws, const std::string &coordinateSystem, QWidget *parent) : QWidget(parent), m_ws(ws), m_coordinateSystem(coordinateSystem){ + ui.setupUi(this); +} + +/** + * Setup the Table model + * @param visiblePeaks : A vector of lists of visible peaks for each peak workspace + */ +void PeaksWidget::setupMvc(std::vector<bool> visiblePeaks) +{ + // Create new table view + MantidQt::SliceViewer::QPeaksTableModel* model = new MantidQt::SliceViewer::QPeaksTableModel(m_ws); + ui.tblPeaks->setModel(model); + const std::vector<int> hideCols = model->defaultHideCols(); + for (auto it = hideCols.begin(); it != hideCols.end(); ++it) + ui.tblPeaks->setColumnHidden(*it, true); + ui.tblPeaks->verticalHeader()->setResizeMode(QHeaderView::Interactive); + ui.tblPeaks->horizontalHeader()->setResizeMode(QHeaderView::Interactive); + m_originalTableWidth = ui.tblPeaks->horizontalHeader()->length(); + // calculate the average width (in pixels) of numbers + QString allNums("0123456789"); + double char_width = + static_cast<double>( + ui.tblPeaks->fontMetrics().boundingRect(allNums).width()) / + static_cast<double>(allNums.size()); + // set the starting width of each column + for (int i = 0; i < m_originalTableWidth; ++i) { + double width = + static_cast<double>(model->numCharacters(i) + 3) * char_width; + ui.tblPeaks->horizontalHeader()->resizeSection(i, static_cast<int>(width)); + } + + // Set the visible rows + for (size_t i = 0; i < visiblePeaks.size(); i++) { + if (visiblePeaks[i]){ + ui.tblPeaks->showRow(static_cast<int>(i)); + } + else + { + ui.tblPeaks->hideRow(static_cast<int>(i)); + } + } + QItemSelectionModel* selectionModel = ui.tblPeaks->selectionModel(); + connect(selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(onCurrentChanged(QModelIndex, QModelIndex))); +} + +/** + * Detects a newly selectedd peaks workspace. + * @param current The currently selected index. + */ +void PeaksWidget::onCurrentChanged(QModelIndex current, QModelIndex) { + if (current.isValid()) + { + emit zoomToPeak(m_ws, current.row()); + } +} + +/** + * Update the visibility of the underlying model + * @param visiblePeaks A vector indicating which peaks are visible. + */ +void PeaksWidget::updateModel(std::vector<bool> visiblePeaks) { + for (size_t i = 0; i < visiblePeaks.size(); i++) { + if (visiblePeaks[i]){ + ui.tblPeaks->showRow(static_cast<int>(i)); + } + else + { + ui.tblPeaks->hideRow(static_cast<int>(i)); + } + } +} +} // namespace +} +} diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinAlgorithmDialogProvider.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinAlgorithmDialogProvider.cpp index 346e4f949b46a62138c58ffd71a84fcbe4e597cd..494f211d022486ca654e544e3fe41bdd52bff83f 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinAlgorithmDialogProvider.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinAlgorithmDialogProvider.cpp @@ -125,6 +125,7 @@ namespace Mantid * @param algorithm The algorithm which is to be used. * @param inputWorkspace The name of the input workspace. * @param outputWorkspace The name of the output workspace. + * @param algorithmType The algorithm type. * @returns The algorithm dialog */ MantidQt::API::AlgorithmDialog* RebinAlgorithmDialogProvider::createDialog(Mantid::API::IAlgorithm_sptr algorithm, diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinnedSourcesManager.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinnedSourcesManager.cpp index f45d0c2f9be960545c6e934172096edfc4bdbf9f..19dda8218a3876aac992014e27710638b1742a96 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinnedSourcesManager.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinnedSourcesManager.cpp @@ -94,7 +94,6 @@ namespace Mantid /** * Catch the deletion of either the rebinned or the original workspace. * @param wsName The name of the workspace. - * @param ws The handle to the workspace */ void RebinnedSourcesManager::preDeleteHandle(const std::string &wsName, const boost::shared_ptr<Mantid::API::Workspace>) { @@ -153,6 +152,7 @@ namespace Mantid /** * Get workspace name and type + * @param source The pipeline source. * @param workspaceName Reference to workspace name. * @param workspaceType Reference to workspace type. */ @@ -382,7 +382,7 @@ namespace Mantid /** * Stop keeping tabs on the specific workspace pair - * @param rebinnedWorspace The name of the rebinned workspace. + * @param rebinnedWorkspace The name of the rebinned workspace. */ void RebinnedSourcesManager::untrackWorkspaces(std::string rebinnedWorkspace) { diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp index 7f357727b7d6bf85f1ac49565fde8f0fd2d2992a..9c9b9a27398d9aea6a7fab8ddb1b8b0534480f83 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp @@ -1,9 +1,14 @@ #include "MantidVatesSimpleGuiViewWidgets/SplatterPlotView.h" - +#include "MantidVatesSimpleGuiViewWidgets/CameraManager.h" +#include "MantidVatesSimpleGuiViewWidgets/PeaksTableControllerVsi.h" #include "MantidAPI/IMDEventWorkspace.h" #include "MantidQtAPI/SelectionNotificationService.h" #include "MantidVatesAPI/ADSWorkspaceProvider.h" #include "MantidVatesAPI/vtkPeakMarkerFactory.h" +#include "MantidVatesAPI/ViewFrustum.h" +#include "MantidKernel/Logger.h" +#include <boost/shared_ptr.hpp> +#include <boost/make_shared.hpp> // Have to deal with ParaView warnings and Intel compiler the hard way. #if defined(__INTEL_COMPILER) @@ -30,6 +35,9 @@ #include <QKeyEvent> #include <QMessageBox> +#include <QToolButton> +#include <QMenu> +#include <QAction> using namespace MantidQt::API; using namespace Mantid::VATES; @@ -41,11 +49,29 @@ namespace Vates namespace SimpleGui { -SplatterPlotView::SplatterPlotView(QWidget *parent) : ViewBase(parent) +namespace +{ + Mantid::Kernel::Logger g_log("SplatterPlotView"); +} + + +SplatterPlotView::SplatterPlotView(QWidget *parent) : ViewBase(parent), + m_cameraManager(boost::make_shared<CameraManager>()), + m_peaksTableController(NULL), + m_peaksWorkspaceNameDelimiter(";") { this->noOverlay = false; this->ui.setupUi(this); + // Setup the peaks viewer + m_peaksTableController = new PeaksTableControllerVsi(m_cameraManager, this); + m_peaksTableController->setMaximumHeight(150); + //this->ui.tableLayout->addWidget(m_peaksTableController); + this->ui.verticalLayout->addWidget(m_peaksTableController); + m_peaksTableController->setVisible(true); + QObject::connect(m_peaksTableController, SIGNAL(setRotationToPoint(double, double, double)), + this, SLOT(onResetCenterToPoint(double, double, double))); + // Set the threshold button to create a threshold filter on data QObject::connect(this->ui.thresholdButton, SIGNAL(clicked()), this, SLOT(onThresholdButtonClicked())); @@ -64,6 +90,9 @@ SplatterPlotView::SplatterPlotView(QWidget *parent) : ViewBase(parent) this->view = this->createRenderView(this->ui.renderFrame); this->installEventFilter(this); + + setupVisiblePeaksButtons(); + } SplatterPlotView::~SplatterPlotView() @@ -100,24 +129,10 @@ bool SplatterPlotView::eventFilter(QObject *obj, QEvent *ev) void SplatterPlotView::destroyView() { + destroyFiltersForSplatterPlotView(); + + // Destroy the view. pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder(); - if (!this->peaksSource.isEmpty()) - { - this->destroyPeakSources(); - pqActiveObjects::instance().setActiveSource(this->origSrc); - } - if (this->probeSource) - { - builder->destroy(this->probeSource); - } - if (this->threshSource) - { - builder->destroy(this->threshSource); - } - if (this->splatSource) - { - builder->destroy(this->splatSource); - } builder->destroy(this->view); } @@ -160,11 +175,23 @@ void SplatterPlotView::render() } else { + // We don't want to load the same peak workspace twice into the splatterplot mode + if (checkIfPeaksWorkspaceIsAlreadyBeingTracked(src)) { + QMessageBox::warning(this, QApplication::tr("Duplicate Peaks Workspace"), + QApplication::tr("You cannot load the same "\ + "Peaks Workpsace multiple times.")); + builder->destroy(src); + pqActiveObjects::instance().setActiveSource(this->splatSource); + return; + } + this->peaksSource.append(src); + setPeakSourceFrame(src); renderType = "Wireframe"; - // Connect the peak source to a listener, to detect its destruction - QObject::connect(src, SIGNAL(destroyed()), + // Start listening if the source was destroyed + QObject::connect(src, SIGNAL(destroyed()), this, SLOT(onPeakSourceDestroyed())); + setPeakButton(true); } // Show the data @@ -193,6 +220,25 @@ void SplatterPlotView::render() { this->renderAll(); } + + // Add peaksSource to the peak controller and the peak filter + if (isPeaksWorkspace) + { + try + { + m_peaksTableController->updatePeaksWorkspaces(this->peaksSource, this->splatSource); + + if (m_peaksFilter) + { + updatePeaksFilter(m_peaksFilter); + } + } + catch (...) + { + setPeakButton(false); + } + } + emit this->triggerAccept(); } @@ -295,6 +341,9 @@ void SplatterPlotView::resetCamera() void SplatterPlotView::destroyPeakSources() { + // First remove the peaks table, since it makes use of the peaks workspace. + onRemovePeaksTable(); + pqServer *server = pqActiveObjects::instance().activeServer(); pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder(); pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel(); @@ -311,33 +360,6 @@ void SplatterPlotView::destroyPeakSources() this->peaksSource.clear(); } -/** - * React to the destruction of a peak source, mainly unregister it from the peakSource container - */ -void SplatterPlotView::onPeakSourceDestroyed() { - pqServer *server = pqActiveObjects::instance().activeServer(); - pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel(); - QList<pqPipelineSource *> sources; - sources = smModel->findItems<pqPipelineSource *>(server); - - // Check for each source in the peakSource container, if it still is an existing source - for (QList<QPointer<pqPipelineSource>>::Iterator it = peaksSource.begin(); it != peaksSource.end();) { - bool foundSource = false; - for (QList<pqPipelineSource*>::Iterator source = sources.begin(); source != sources.end(); ++source) { - // Check if the source registered in PV matches our current peak source - if ((*source) == (*it)) { - foundSource = true; - } - } - - if (!foundSource) { - it = peaksSource.erase(it); - } - else { - ++it; - } - } -} /** * This function reads the coordinates from the probe point plugin and @@ -375,6 +397,287 @@ void SplatterPlotView::readAndSendCoordinates() } } +/** + * Set up the buttons for the visible peaks. + */ +void SplatterPlotView::setupVisiblePeaksButtons() +{ + // Populate the rebin button + QMenu* peaksMenu = new QMenu(this->ui.peaksButton); + + m_allPeaksAction = new QAction("Show all peaks in table", peaksMenu); + m_allPeaksAction->setIconVisibleInMenu(false); + + m_removePeaksAction = new QAction("Remove table", peaksMenu); + m_removePeaksAction->setIconVisibleInMenu(false); + + peaksMenu->addAction(m_allPeaksAction); + peaksMenu->addAction(m_removePeaksAction); + + this->ui.peaksButton->setPopupMode(QToolButton::InstantPopup); + this->ui.peaksButton->setMenu(peaksMenu); + setPeakButton(false); + + QObject::connect(m_allPeaksAction, SIGNAL(triggered()), + this, SLOT(onShowAllPeaksTable()), Qt::QueuedConnection); + + QObject::connect(m_removePeaksAction, SIGNAL(triggered()), + this, SLOT(onRemovePeaksTable()), Qt::QueuedConnection); +} + + +/** + * On show all peaks + */ +void SplatterPlotView::onShowAllPeaksTable() +{ + createPeaksFilter(); + + if (m_peaksTableController->hasPeaks()) + { + m_peaksTableController->showFullTable(); + m_peaksTableController->show(); + } +} + + +/** + * Remove the visible peaks table. + */ +void SplatterPlotView::onRemovePeaksTable() +{ + if (m_peaksTableController->hasPeaks()) + { + m_peaksTableController->removeTable(); + } + + if (m_peaksFilter) + { + pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder(); + builder->destroy(m_peaksFilter); + } +} + + +/** + * Create the peaks filter + */ +void SplatterPlotView::createPeaksFilter() +{ + // If the peaks filter already exists, then stay idle. + if (m_peaksFilter) + { + return; + } + + // If the there is no peaks workspace, then stay idle. + if (peaksSource.isEmpty()) + { + return; + } + + // Create the peak filter + pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder(); + + // Set the peaks workspace name. We need to trigger accept in order to log the workspace in the filter + try + { + m_peaksFilter = builder->createFilter("filters","MantidParaViewPeaksFilter", this->splatSource); + QObject::connect(m_peaksFilter, SIGNAL(destroyed()), + this, SLOT(onPeaksFilterDestroyed())); + + // Setup the peaks filter + updatePeaksFilter(m_peaksFilter); + + // Create point representation of the source and set the point size + const double pointSize = 4; + pqDataRepresentation *dataRepresentation = m_peaksFilter->getRepresentation(this->view); + vtkSMPropertyHelper(dataRepresentation->getProxy(), "Representation").Set("Points"); + vtkSMPropertyHelper(dataRepresentation->getProxy(), "PointSize").Set(pointSize); + dataRepresentation->getProxy()->UpdateVTKObjects(); + + pqPipelineRepresentation *pipelineRepresentation = qobject_cast<pqPipelineRepresentation*>(dataRepresentation); + pipelineRepresentation->colorByArray("signal", vtkDataObject::FIELD_ASSOCIATION_CELLS); + this->resetDisplay(); + this->setVisibilityListener(); + this->renderAll(); + } catch(std::runtime_error &ex) + { + // Destroy peak filter + if (m_peaksFilter) + { + builder->destroy(m_peaksFilter); + } + g_log.warning() << ex.what(); + } +} + +/* On peaks source destroyed + * @param source The reference to the destroyed source + */ +void SplatterPlotView::onPeakSourceDestroyed() +{ + // For each peak Source check if there is a "true" source available. + // If it is not availble then remove it from the peakSource storage. + for (QList<QPointer<pqPipelineSource>>::Iterator it = peaksSource.begin(); it != peaksSource.end();) { + pqServer *server = pqActiveObjects::instance().activeServer(); + pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel(); + QList<pqPipelineSource *> sources; + sources = smModel->findItems<pqPipelineSource *>(server); + + bool foundSource = false; + for (QList<pqPipelineSource *>::iterator src = sources.begin(); src != sources.end(); ++src) { + if ((*src) == (*it)) { + foundSource = true; + } + } + + if (!foundSource) { + it = peaksSource.erase(it); + } + else { + ++it; + } + } + + if (peaksSource.isEmpty()) + { + setPeakButton(false); + } + + // Update the availbale peaksTableController with the available workspaces + m_peaksTableController->updatePeaksWorkspaces(peaksSource, splatSource); + + // Update the peaks filter + try + { + updatePeaksFilter(m_peaksFilter); + } + catch(std::runtime_error &ex) + { + g_log.warning() << ex.what(); + } + + // Set an active source + if (peaksSource.isEmpty()) { + pqActiveObjects::instance().setActiveSource(this->splatSource); + } + else { + pqActiveObjects::instance().setActiveSource(this->peaksSource[0]); + } +} + +/** + * Sets the visibility of the peak button. + * @param state The visibility state of the peak button. + */ +void SplatterPlotView::setPeakButton(bool state) +{ + this->ui.peaksButton->setEnabled(state); +} + +/** + * Set the frame of the peak source + * @param source The peak source + */ +void SplatterPlotView::setPeakSourceFrame(pqPipelineSource* source) +{ + int peakViewCoords = vtkSMPropertyHelper(this->origSrc->getProxy(), "SpecialCoordinates").GetAsInt(); + peakViewCoords--; + vtkSMPropertyHelper(source->getProxy(), "Peak Dimensions").Set(peakViewCoords); +} + +/** + * Check if a peaks workspace is already tracked by the peaksSource list. + */ +bool SplatterPlotView::checkIfPeaksWorkspaceIsAlreadyBeingTracked(pqPipelineSource* source) { + bool isContained = false; + std::string sourceName(vtkSMPropertyHelper(source->getProxy(), "WorkspaceName").GetAsString()); + for (QList<QPointer<pqPipelineSource>>::Iterator it = peaksSource.begin(); it != peaksSource.end(); ++it) { + std::string trackedName(vtkSMPropertyHelper((*it)->getProxy(), "WorkspaceName").GetAsString()); + if ((*it == source) || (sourceName == trackedName)) { + isContained = true; + break; + } + } + return isContained; +} + +/** + * Updates the peaks filter, i.e. supplies the filter with a list of peaks workspaces and delimiter + * @param filter The peaks filter. + */ +void SplatterPlotView::updatePeaksFilter(pqPipelineSource* filter) { + if (!filter){ + return; + } + + // If there are no peaks, then destroy the filter, else update it. + if (peaksSource.isEmpty()) { + pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder(); + builder->destroy(filter); + } + else { + std::string workspaceNamesConcatentated = m_peaksTableController->getConcatenatedWorkspaceNames(m_peaksWorkspaceNameDelimiter); + if (workspaceNamesConcatentated.empty()) + { + throw std::runtime_error("The peaks viewer does not contain a valid peaks workspace."); + } + + vtkSMPropertyHelper(filter->getProxy(), "PeaksWorkspace").Set(workspaceNamesConcatentated.c_str()); + vtkSMPropertyHelper(filter->getProxy(), "Delimiter").Set(m_peaksWorkspaceNameDelimiter.c_str()); + emit this->triggerAccept(); + filter->updatePipeline(); + this->resetCamera(); + } +} + +/** + * Reacts to a destroyed peaks filter, mainly for setting the peak filter pointer to NULL. + * We need to do this, since PV can destroy the filter in a general destorySources command. + */ +void SplatterPlotView::onPeaksFilterDestroyed() { + m_peaksFilter = NULL; +} + +/** + * Destroy all sources in the splatterplot view. We need to delete the filters before + * we can delete the underlying sources + */ +void SplatterPlotView::destroyAllSourcesInView() { + destroyFiltersForSplatterPlotView(); + + // Destroy the remaning sources and filters + pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder(); + builder->destroySources(); +} + + +void SplatterPlotView::destroyFiltersForSplatterPlotView(){ + pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder(); + if (this->m_peaksFilter) + { + builder->destroy(this->m_peaksFilter); + } + if (!this->peaksSource.isEmpty()) + { + this->destroyPeakSources(); + pqActiveObjects::instance().setActiveSource(this->origSrc); + } + if (this->probeSource) + { + builder->destroy(this->probeSource); + } + if (this->threshSource) + { + builder->destroy(this->threshSource); + } + if (this->splatSource) + { + builder->destroy(this->splatSource); + } +} + } // SimpleGui } // Vates } // Mantid diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/StandardView.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/StandardView.cpp index 09817b9f5ad9beee7fef6b2c1892ac0a8475dc30..e9c3809f654d0c5dea4b45b98a827d6c5d59d4bf 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/StandardView.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/StandardView.cpp @@ -42,7 +42,6 @@ namespace SimpleGui */ StandardView::StandardView(QWidget *parent) : ViewBase(parent),m_binMDAction(NULL), m_sliceMDAction(NULL), - m_cutMDAction(NULL), m_unbinAction(NULL) { this->ui.setupUi(this); @@ -86,15 +85,12 @@ void StandardView::setupViewButtons() m_sliceMDAction = new QAction("SliceMD", rebinMenu); m_sliceMDAction->setIconVisibleInMenu(false); - m_cutMDAction = new QAction("CutMD", rebinMenu); - m_cutMDAction->setIconVisibleInMenu(false); m_unbinAction = new QAction("Remove Rebinning", rebinMenu); m_unbinAction->setIconVisibleInMenu(false); rebinMenu->addAction(m_binMDAction); rebinMenu->addAction(m_sliceMDAction); - rebinMenu->addAction(m_cutMDAction); rebinMenu->addAction(m_unbinAction); this->ui.rebinToolButton->setPopupMode(QToolButton::InstantPopup); @@ -104,18 +100,11 @@ void StandardView::setupViewButtons() this, SLOT(onBinMD()), Qt::QueuedConnection); QObject::connect(m_sliceMDAction, SIGNAL(triggered()), this, SLOT(onSliceMD()), Qt::QueuedConnection); - QObject::connect(m_cutMDAction, SIGNAL(triggered()), - this, SLOT(onCutMD()), Qt::QueuedConnection); // Set the unbinbutton to remove the rebinning on a workspace // which was binned in the VSI QObject::connect(m_unbinAction, SIGNAL(triggered()), this, SIGNAL(unbin()), Qt::QueuedConnection); - - // Populate the slice button - - // Populate the cut button - } void StandardView::destroyView() @@ -269,13 +258,11 @@ void StandardView::setRebinAndUnbinButtons() { this->m_binMDAction->setEnabled(false); this->m_sliceMDAction->setEnabled(false); - this->m_cutMDAction->setEnabled(false); } else { this->m_binMDAction->setEnabled(true); this->m_sliceMDAction->setEnabled(true); - this->m_cutMDAction->setEnabled(false); } // If there are no temporary workspaces the button should be disabled. @@ -306,13 +293,6 @@ void StandardView::onSliceMD() emit rebin("SliceMD"); } -/** - * Reacts to the user selecting the CutMD algorithm - */ -void StandardView::onCutMD() -{ - emit rebin("CutMD"); -} /** * Listen for a change of the active source in order to check if the the @@ -325,7 +305,6 @@ void StandardView::activeSourceChangeListener(pqPipelineSource* source) { this->m_binMDAction->setEnabled(false); this->m_sliceMDAction->setEnabled(false); - this->m_cutMDAction->setEnabled(false); this->m_unbinAction->setEnabled(false); return; } @@ -347,21 +326,18 @@ void StandardView::activeSourceChangeListener(pqPipelineSource* source) { this->m_binMDAction->setEnabled(true); this->m_sliceMDAction->setEnabled(true); - this->m_cutMDAction->setEnabled(false); this->m_unbinAction->setEnabled(true); } else if (workspaceType.find("MDEW Source") != std::string::npos) { this->m_binMDAction->setEnabled(true); this->m_sliceMDAction->setEnabled(true); - this->m_cutMDAction->setEnabled(false); this->m_unbinAction->setEnabled(false); } else { this->m_binMDAction->setEnabled(false); this->m_sliceMDAction->setEnabled(false); - this->m_cutMDAction->setEnabled(false); this->m_unbinAction->setEnabled(false); } } diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp index fc09884575eca7239cac825138057c61da06faa4..17cc2e0c856421f86c463603921acc4d93b06eee 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp @@ -12,6 +12,7 @@ #include <pqDataRepresentation.h> #include <pqObjectBuilder.h> #include <pqPipelineSource.h> +#include <pqPipelineFilter.h> #include <pqPipelineRepresentation.h> #include <pqPVApplicationCore.h> #include <pqRenderView.h> @@ -329,7 +330,7 @@ void ViewBase::checkView(ModeControlWidget::Views initialView) /** * This metod sets the status of the splatterplot button explictly to a desired value - * @param visiblity The state of the the splatterplot view button. + * @param visibility The state of the the splatterplot view button. */ void ViewBase::setSplatterplot(bool visibility) { @@ -338,7 +339,7 @@ void ViewBase::setSplatterplot(bool visibility) /** * This metod sets the status of the standard view button explictly to a desired value - * @param visiblity The state of the the standard view button. + * @param visibility The state of the the standard view button. */ void ViewBase::setStandard(bool visibility) { @@ -801,6 +802,96 @@ void ViewBase::onSourceDestroyed() { } +/** + * Destroy all sources in the view. + */ +void ViewBase::destroyAllSourcesInView() { + pqServer *server = pqActiveObjects::instance().activeServer(); + pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel(); + QList<pqPipelineSource *> sources = smModel->findItems<pqPipelineSource *>(server); + + // Out of all pqPipelineSources, find the "true" sources, which were + // created by a Source Plugin, i.e. MDEW Source, MDHW Source, PeakSource + QList<pqPipelineSource*> trueSources; + for (QList<pqPipelineSource *>::iterator source = sources.begin(); source != sources.end(); ++source) { + if (!qobject_cast<pqPipelineFilter*>(*source)) { + trueSources.push_back(*source); + } + } + + // For each true source, go to the end of the pipeline and destroy it on the way back + // to the start. This assumes linear pipelines. + for (QList<pqPipelineSource *>::iterator trueSource = trueSources.begin(); trueSource != trueSources.end(); ++trueSource) { + destroySinglePipeline(*trueSource); + } +} + + +/** + * Destroy a single, linear pipeline + * @param source A true pqPiplineSource, i.e. not a filter. + */ +void ViewBase::destroySinglePipeline(pqPipelineSource * source) { + + pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder(); + + // Move to the end of the pipeline + pqPipelineSource *sourceBuffer = source; + while(sourceBuffer->getNumberOfConsumers() > 0) { + sourceBuffer = sourceBuffer->getConsumer(0); + } + + // Now destroy the pipeline coming back again + pqPipelineFilter* filter = qobject_cast<pqPipelineFilter*>(sourceBuffer); + while(filter) { + sourceBuffer = filter->getInput(0); + builder->destroy(filter); + filter = qobject_cast<pqPipelineFilter*>(sourceBuffer); + } + + builder->destroy(sourceBuffer); +} + +/** + * Set the listener for the visibility of the representations + */ +void ViewBase::setVisibilityListener() +{ + // Set the connection to listen to a visibility change of the representation. + pqServer *server = pqActiveObjects::instance().activeServer(); + pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel(); + QList<pqPipelineSource *> sources; + sources = smModel->findItems<pqPipelineSource *>(server); + + // Attach the visibilityChanged signal for all sources. + for (QList<pqPipelineSource *>::iterator source = sources.begin(); source != sources.end(); ++source) + { + QObject::connect((*source), SIGNAL(visibilityChanged(pqPipelineSource*, pqDataRepresentation*)), + this, SLOT(onVisibilityChanged(pqPipelineSource*, pqDataRepresentation*)), + Qt::UniqueConnection); + } +} + +/** + * Disconnects the visibility listener connection for all sources + */ +void ViewBase::removeVisibilityListener() { + // Set the connection to listen to a visibility change of the representation. + pqServer *server = pqActiveObjects::instance().activeServer(); + pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel(); + QList<pqPipelineSource *> sources; + sources = smModel->findItems<pqPipelineSource *>(server); + + // Attach the visibilityChanged signal for all sources. + for (QList<pqPipelineSource *>::iterator source = sources.begin(); source != sources.end(); ++source) + { + QObject::disconnect((*source), SIGNAL(visibilityChanged(pqPipelineSource*, pqDataRepresentation*)), + this, SLOT(onVisibilityChanged(pqPipelineSource*, pqDataRepresentation*))); + } +} + + + } // namespace SimpleGui } // namespace Vates } // namespace Mantid diff --git a/Code/Mantid/docs/source/algorithms/AddPeak-v1.rst b/Code/Mantid/docs/source/algorithms/AddPeak-v1.rst index eddd7ddb415126d728446b85a2ca6877c2a4795b..f1774a3d93ffa3306ff1a4e808b4a3076dc6ffba 100644 --- a/Code/Mantid/docs/source/algorithms/AddPeak-v1.rst +++ b/Code/Mantid/docs/source/algorithms/AddPeak-v1.rst @@ -9,7 +9,7 @@ Description ----------- -Adds a peak to a :ref:`PeaksWorkspace <PeaksWorkspace>`__. +Adds a peak to a :ref:`PeaksWorkspace <PeaksWorkspace>`. Usage ----- diff --git a/Code/Mantid/docs/source/algorithms/AddPeakHKL-v1.rst b/Code/Mantid/docs/source/algorithms/AddPeakHKL-v1.rst index 3428f32e330a3075bfdac710825247c4c55d25bd..ab768f8c24c9793bc57186c7a4f12c7adb521a09 100644 --- a/Code/Mantid/docs/source/algorithms/AddPeakHKL-v1.rst +++ b/Code/Mantid/docs/source/algorithms/AddPeakHKL-v1.rst @@ -10,7 +10,7 @@ Description ----------- -Add a peak in the HKL frame to an existing :ref:`PeaksWorkspace <PeaksWorkspace>`__. The OrientedLattice must be provided and the Goniometer should be set correctly before running the algorithm. +Add a peak in the HKL frame to an existing :ref:`PeaksWorkspace <PeaksWorkspace>`. The OrientedLattice must be provided and the Goniometer should be set correctly before running the algorithm. The peak is added to the existing PeaksWorkspace. Run information and goniometer setting and the UB matrix are taken from the provided PeaksWorkspace. diff --git a/Code/Mantid/docs/source/algorithms/AddSampleLogMultiple-v1.rst b/Code/Mantid/docs/source/algorithms/AddSampleLogMultiple-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..0941ff4ce65836c220a4b624a1eb3ebf1605f3eb --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/AddSampleLogMultiple-v1.rst @@ -0,0 +1,49 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +This algorithm provides a way of adding multiple sample log entries to a +workspace at once by making multiple calls to the :ref:`algm-AddSampleLog` +algorithm. + +Typically this is for use in workflow algorithms and scripts. + +Usage +----- + +**Example - Add multiple sample logs** + +.. testcode:: AddSampleLogMultipleExample + + # Create a host workspace + demo_ws = CreateWorkspace(DataX=range(0,3), DataY=(0,2)) + + # Add sample logs + log_names = ['x', 'y', 'z'] + log_values = ['test', 5, 1.6e-7] + AddSampleLogMultiple(Workspace=demo_ws, + LogNames=log_names, + LogValues=log_values) + + # Print the log values + run = demo_ws.getRun() + print run.getLogData('x').value + print run.getLogData('y').value + print run.getLogData('z').value + +Output: + +.. testoutput:: AddSampleLogMultipleExample + + test + 5 + 1.6e-07 + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/ApplyPaalmanPingsCorrection-v1.rst b/Code/Mantid/docs/source/algorithms/ApplyPaalmanPingsCorrection-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..40af9ecafb8fd56c2fab386b2f1f30d917c01d21 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/ApplyPaalmanPingsCorrection-v1.rst @@ -0,0 +1,76 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Applies absorption corrections calculated in the Paalman & Pings absorption +factor format: :math:`A_{s,s}` (correction factor for scattering and absorption +in sample), :math:`A_{s,sc}` (scattering in sample and absorption in sample and +container), :math:`A_{c,sc}` (scattering in container and absorption in sample +and container) and :math:`A_{c,c}` (scattering and absorption in container). + +This algorithm can be used to apply absorption corrections calculated with +either the :ref:`algm-CylinderPaalmanPingsCorrection` and +:ref:`algm-FlatPlatePaalmanPingsCorrection` algorithms as well as the legacy +indirect calculate correcteions routine, providing that the sample and container +are first converted to wavelength and the corrections are interpolated to match +the sample as demonstrated in the example below. + +Usage +----- + +**Example: using with legacy indirect corrections data** + +.. testcode:: exSampleAndCanIRISLegacyCorrections + + # Load the sample and can + sample_ws = Load('irs26176_graphite002_red.nxs') + can_ws = Load('irs26173_graphite002_red.nxs') + + # Convert sample and container workspaces to wavelength + sample_ws = ConvertUnits(InputWorkspace=sample_ws, + Target='Wavelength', + EMode='Indirect', + EFixed=1.845) + can_ws = ConvertUnits(InputWorkspace=can_ws, + Target='Wavelength', + EMode='Indirect', + EFixed=1.845) + + # Load the corrections workspace + corrections_ws = Load('irs26176_graphite002_cyl_Abs.nxs') + + # Interpolate each of the correction factor workspaces to match the + # binning of the smaple + # Required to use corrections from the old indirect calculate + # corrections routines + for factor_ws in corrections_ws: + SplineInterpolation(WorkspaceToMatch=sample_ws, + WorkspaceToInterpolate=factor_ws, + OutputWorkspace=factor_ws, + OutputWorkspaceDeriv='') + + corr = ApplyPaalmanPingsCorrection(SampleWorkspace=sample_ws, + CorrectionsWorkspace=corrections_ws, + CanWorkspace=can_ws) + + print 'Corrected workspace has %d spectra over %d bins' % ( + corr.getNumberHistograms(), corr.blocksize()) + + print 'Type of correction applied: %s' % ( + corr.getRun()['corrections_type'].value) + +Output: + +.. testoutput:: exSampleAndCanIRISLegacyCorrections + + Corrected workspace has 10 spectra over 1905 bins + Type of correction applied: sample_and_can_corrections + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst b/Code/Mantid/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst index 58bbefcd73e40284bd3ef125d5f6f1fd88d5cc35..adc45fcce602ce461688b34fc864942138f33ac4 100644 --- a/Code/Mantid/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst +++ b/Code/Mantid/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst @@ -13,6 +13,11 @@ This algorithms is to collect the all the counts on the detectors among a set of measurements, which belong to a same experiment run, and bin them according to detector's position, i.e., :math:`2\theta`. +In this algorithm's name, ConvertCWPDMDToSpectra, *CW* stands for constant wave +(reactor-source instrument); *PD* stands for powder diffraction; and *MD* +stands for MDEventWorkspace because the input of this algorithms are two +MDEventWorkspaces. + This algorithm takes 2 MDEventWorkspaces as inputs. One stores the detectors' counts; and the other stores the monitors' counts. diff --git a/Code/Mantid/docs/source/algorithms/CreateCalibrationWorkspace-v1.rst b/Code/Mantid/docs/source/algorithms/CreateCalibrationWorkspace-v1.rst deleted file mode 100644 index a4e5a0fe2af57af9615b513b46a2d5e3d63d0a7a..0000000000000000000000000000000000000000 --- a/Code/Mantid/docs/source/algorithms/CreateCalibrationWorkspace-v1.rst +++ /dev/null @@ -1,49 +0,0 @@ -.. algorithm:: - -.. summary:: - -.. alias:: - -.. properties:: - -Description ------------ - -Creates a calibration workspace to be used with inelastic indirect reductions, -allowing for the correction of relative detector intensities. - -Usage ------ - -**Example - create calibration workspace for IRIS** - -.. include:: ../usagedata-note.txt - -.. testcode:: ExCreateCalibrationWorkspaceSimple - - import os - - # Create a calibration workspace - cal_ws = CreateCalibrationWorkspace(InputFiles='IRS26173.raw', - DetectorRange='3,53', - PeakRange='62500,65000', - BackgroundRange='59000,61500') - - # Save the workspace to a NeXus file - calib_file = 'iris_calibration.nxs' - SaveNexus(InputWorkspace=cal_ws, Filename=calib_file) - - # Check the output file - print "File Exists:", os.path.exists(calib_file) - -Output: - -.. testoutput:: ExCreateCalibrationWorkspaceSimple - - File Exists: True - -.. testcleanup:: ExCreateCalibrationWorkspaceSimple - - os.remove(calib_file) - -.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/CutMD-v1.rst b/Code/Mantid/docs/source/algorithms/CutMD-v1.rst index 4f1dea9a34b774cd4cd0061c0543215d62bd10d4..da2f0f251e15456314cd10bdb50cc2a8e139241e 100644 --- a/Code/Mantid/docs/source/algorithms/CutMD-v1.rst +++ b/Code/Mantid/docs/source/algorithms/CutMD-v1.rst @@ -9,11 +9,20 @@ Description ----------- -This algorithm performs slicing of multiDimensional data according to a chosen projection, and binning choice. The algorithm uses :ref:`algm-BinMD` or -:ref:`algm-SliceMD` to achieve the binning of the data. The choice of child algorithm used for the slicing is controlled by the NoPix option. +This algorithm performs slicing of multiDimensional data according to a chosen +projection, and binning choice. The algorithm uses :ref:`algm-BinMD` or +:ref:`algm-SliceMD` to achieve the binning of the data. The choice of child +algorithm used for the slicing is controlled by the NoPix option. The synax is similar to that used by `Horace <http://horace.isis.rl.ac.uk/Manipulating_and_extracting_data_from_SQW_files_and_objects#cut_sqw>`__. +Unlike most Mantid algorithms, CutMD can accept a list of workspaces as the +input workspace, given as the name of a workspace in the analysis data service +or the path to a workspace, or simply a workspace object in python. These will +all then be processed sequentially with the same options. The only requirement +is that the same number of output workspaces are also given so that CutMD knows +what to call each output workspace created. + Usage ----- @@ -37,8 +46,12 @@ Usage projection = Projection([1,1,0], [-1,1,0]) proj_ws = projection.createWorkspace() - # Apply the cut - out_md = CutMD(to_cut, Projection=proj_ws, P1Bin=[0.1], P2Bin=[0.1], P3Bin=[0.1], P4Bin=[-5,5], NoPix=True) + # Apply the cut (PBins property sets the P1Bin, P2Bin, etc. properties for you) + out_md = CutMD(to_cut, Projection=proj_ws, PBins=([0.1], [0.1], [0.1], [-5,5]), NoPix=True) + + #Another way we can call CutMD: + #[out1, out2, out3] = CutMD([to_cut, "some_other_file.nxs", "some_workspace_name"], ...) + print 'number of dimensions', out_md.getNumDims() print 'number of dimensions not integrated', len(out_md.getNonIntegratedDimensions()) dim_dE = out_md.getDimension(3) diff --git a/Code/Mantid/docs/source/algorithms/CylinderPaalmanPingsCorrection-v1.rst b/Code/Mantid/docs/source/algorithms/CylinderPaalmanPingsCorrection-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..b1e4a48ccfef235fda24488dbdf9b0242b0f07ec --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/CylinderPaalmanPingsCorrection-v1.rst @@ -0,0 +1,64 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Calculates absorption corrections for a cylindrical or annular sample giving +output in the Paalman & Pings absorption factors: :math:`A_{s,s}` (correction +factor for scattering and absorption in sample), :math:`A_{s,sc}` (scattering in +sample and absorption in sample and container), :math:`A_{c,sc}` (scattering in +container and absorption in sample and container) and :math:`A_{c,c}` +(scattering and absorption in container). + +Restrictions on the input workspace +################################### + +The input workspace must have a fully defined instrument that has X axis units +of wavelength. + +Usage +----- + +**Example:** + +.. code-block:: python + + # Create a sample workspace + sample = CreateSampleWorkspace(NumBanks=1, BankPixelWidth=1, + XUnit='Wavelength', + XMin=6.8, XMax=7.9, + BinWidth=0.1) + + # Copy and scale it to make a can workspace + can = CloneWorkspace(InputWorkspace=sample) + can = Scale(InputWorkspace=can, Factor=1.2) + + # Calculate absorption corrections + corr = CylinderPaalmanPingsCorrection(SampleWorkspace=sample, + SampleChemicalFormula='H2-O', + SampleInnerRadius=0.05, + SampleOuterRadius=0.1, + CanWorkspace=can, + CanChemicalFormula='V', + CanOuterRadius=0.15, + BeamHeight=0.1, + BeamWidth=0.1, + StepSize=0.002, + Emode='Indirect', + Efixed=1.845) + + print 'Correction workspaces: %s' % (', '.join(corr.getNames())) + +Output: + +.. code-block:: none + + Correction workspaces: corr_ass, corr_assc, corr_acsc, corr_acc + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/ElasticWindow-v1.rst b/Code/Mantid/docs/source/algorithms/ElasticWindow-v1.rst index bcda27e46b08556339e0a1111854458a40ab4db9..84d9fc230ce4b60640cfae80b1cbd9bcbb3ee7a9 100644 --- a/Code/Mantid/docs/source/algorithms/ElasticWindow-v1.rst +++ b/Code/Mantid/docs/source/algorithms/ElasticWindow-v1.rst @@ -10,7 +10,7 @@ Description ----------- This algorithm Integrates over the range specified, converts the -spectrum axis into units of Q and Q^2 and Transposes the result +spectrum axis into units of Q and Q^{2} and transposes the result workspaces. There are two output workspaces. @@ -18,20 +18,42 @@ There are two output workspaces. Subalgorithms used ################## -This algorithm uses the :ref:`algm-Integration`, :ref:`algm-ConvertSpectrumAxis` and :ref:`algm-Transpose` algorithms. +This algorithm uses the :ref:`algm-Integration`, :ref:`algm-ConvertSpectrumAxis` +and :ref:`algm-Transpose` algorithms. Usage ----- -.. testcode:: +.. testcode:: exElasticWindowSimple # Prepare a workspace that has all necessary settings to work with ElasticWindow - ws = CreateSampleWorkspace(Function='User Defined',UserDefinedFunction='name=Lorentzian,Amplitude=100,PeakCentre=27500,FWHM=20',XMin=27000,XMax=28000,BinWidth=10,NumBanks=1) - ws = ConvertUnits(ws,'DeltaE',EMode='Indirect',EFixed=1.555) - ws = Rebin(ws,[-0.2,0.004,0.2]) - SetInstrumentParameter(ws,'Efixed',DetectorList=range(100,200),ParameterType='Number',Value='1.555') + ws = CreateSampleWorkspace(Function='User Defined', + UserDefinedFunction='name=Lorentzian,Amplitude=100,PeakCentre=27500,FWHM=20', + XMin=27000, + XMax=28000, + BinWidth=10, + NumBanks=1) + + ws = ConvertUnits(ws, 'DeltaE', + EMode='Indirect', + EFixed=1.555) + + ws = Rebin(ws, [-0.2,0.004,0.2]) + + SetInstrumentParameter(ws, 'Efixed', + DetectorList=range(100,200), + ParameterType='Number', + Value='1.555') # Run the algorithm - inQ, inQ2 = ElasticWindow(ws, -0.1,0.1) + q, q2 = ElasticWindow(ws, -0.1, 0.1) + + print q.getAxis(0).getUnit().caption() + print q2.getAxis(0).getUnit().caption() + +.. testoutput:: exElasticWindowSimple + + q + Q2 .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/EstimatePeakErrors-v1.rst b/Code/Mantid/docs/source/algorithms/EstimatePeakErrors-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..df06d774613de3f24f955af488933db8ef83553e --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/EstimatePeakErrors-v1.rst @@ -0,0 +1,38 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +This algorithm takes a function after it has been optimized by the Fit algorithm and calculates peak parameter and associated errors for all peaks in this function. The peak parameters are its centre, height, FWHM and intensity. The output workspace is a table with three columns: parameter name, parameter value and parameter error. + +Usage +----- +(*At the moment the algorithm works properly if run from C++ only.*) + + import numpy as np + + # Create a data set + x = np.linspace(-10,10,100) + y = 10 * 2.0 / (2.0**2 + (x+4)**2 ) + 10 * 3.0 / (3.0**2 + (x-3)**2 ) + 3.0 + e = np.ones_like(x) + ws = CreateWorkspace(x,y,e) + + # Define a fitting function. + fun = "name=Lorentzian,Amplitude=10,PeakCentre=-4,FWHM=2;"+\ + "name=Lorentzian,Amplitude=10,PeakCentre=3,FWHM=3;"+\ + "name=FlatBackground,A0=3" + + # Fit the function. + Fit(fun,ws) + + # Calculate peak parameter error estimates for the two Lorentzians. + params = EstimatePeakErrors(fun) + + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/FlatPlatePaalmanPingsCorrection-v1.rst b/Code/Mantid/docs/source/algorithms/FlatPlatePaalmanPingsCorrection-v1.rst index 415db1d13ded7be90fe6b58ef0005bddd81c7a83..47da311b90228afe23bd4799a76b12cdb1e909a9 100644 --- a/Code/Mantid/docs/source/algorithms/FlatPlatePaalmanPingsCorrection-v1.rst +++ b/Code/Mantid/docs/source/algorithms/FlatPlatePaalmanPingsCorrection-v1.rst @@ -23,7 +23,8 @@ available in `RAL Technical Report 74-103 Restrictions on the input workspace ################################### -The input workspace must have units of wavelength. +The input workspace must have a fully defined instrument that has X axis units +of wavelength. Usage ----- diff --git a/Code/Mantid/docs/source/algorithms/Fury-v1.rst b/Code/Mantid/docs/source/algorithms/Fury-v1.rst deleted file mode 100644 index a82a566e5ec784ab5326137903881925e7dee98c..0000000000000000000000000000000000000000 --- a/Code/Mantid/docs/source/algorithms/Fury-v1.rst +++ /dev/null @@ -1,24 +0,0 @@ -.. algorithm:: - -.. summary:: - -.. alias:: - -.. properties:: - -Description ------------ - -The model that is being fitted is that of a delta-function (elastic component) of amplitude :math:`A(0)` and Lorentzians of amplitude :math:`A(j)` and HWHM :math:`W(j)` where :math:`j=1,2,3`. The whole function is then convolved with the resolution function. The -function and Lorentzians are intrinsically -normalised to unity so that the amplitudes represent their integrated areas. - -For a Lorentzian, the Fourier transform does the conversion: :math:`1/(x^{2}+\delta^{2}) \Leftrightarrow exp[-2\pi(\delta k)]`. -If :math:`x` is identified with energy :math:`E` and :math:`2\pi k` with :math:`t/\hbar` where t is time then: :math:`1/[E^{2}+(\hbar / \tau )^{2}] \Leftrightarrow exp[-t /\tau]` and :math:`\sigma` is identified with :math:`\hbar / \tau`. -The program estimates the quasielastic components of each of the groups of spectra and requires the resolution file and optionally the normalisation file created by ResNorm. - -For a Stretched Exponential, the choice of several Lorentzians is replaced with a single function with the shape : :math:`\psi\beta(x) \Leftrightarrow exp[-2\pi(\sigma k)\beta]`. This, in the energy to time FT transformation, is :math:`\psi\beta(E) \Leftrightarrow exp[-(t/\tau)\beta]`. So \sigma is identified with :math:`(2\pi)\beta\hbar/\tau`. -The model that is fitted is that of an elastic component and the stretched exponential and the program gives the best estimate for the :math:`\beta` parameter and the width for each group of spectra. - -This routine was originally part of the MODES package. - -.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..2f1343fcdcf645d6de0258c38027a3b4c1bbb9ea --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst @@ -0,0 +1,109 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Calculates and applies corrections for scattering abs absorption in a annular +sample for a run on an indirect inelastic instrument, optionally allowing for +the subtraction or corrections of the container. + +The correction factor workspace is a workspace group containing the correction +factors in the Paalman and Pings format, note that only :math:`{A_{s,s}}` and +:math:`A_{c,c}` factors are calculated by thsi algorithm. + +Usage +----- + +.. include:: ../usagedata-note.txt + +**Example - Sample corrections for IRIS:** + +.. testcode:: SampleCorrectionsWithCanSubtraction + + red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs') + can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs') + + corrected, fact = IndirectAnnulusAbsorption(SampleWorkspace=red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=can_ws, + CanScaleFactor=0.8, + CanInnerRadius=0.19, + SampleInnerRadius=0.2, + SampleOuterRadius=0.25, + CanOuterRadius=0.26, + Events=200) + + ass = fact[0] + + print ('Corrected workspace is intensity against %s' + % (corrected.getAxis(0).getUnit().caption())) + + print ('Ass workspace is %s against %s' + % (ass.YUnitLabel(), ass.getAxis(0).getUnit().caption())) + +.. testcleanup:: SampleCorrectionsWithCanSubtraction + + DeleteWorkspace(red_ws) + DeleteWorkspace(can_ws) + DeleteWorkspace(corrected) + DeleteWorkspace(fact) + +**Output:** + +.. testoutput:: SampleCorrectionsWithCanSubtraction + + Corrected workspace is intensity against Energy transfer + Ass workspace is Attenuation factor against Wavelength + +**Example - Sample corrections for IRIS:** + +.. testcode:: SampleAndCanCorrections + + red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs') + can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs') + + corrected, fact = IndirectAnnulusAbsorption(SampleWorkspace=red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=can_ws, + CanChemicalFormula='H2-O', + CanInnerRadius=0.19, + SampleInnerRadius=0.2, + SampleOuterRadius=0.25, + CanOuterRadius=0.26, + Events=200, + UseCanCorrections=True) + + ass = fact[0] + acc = fact[1] + + print ('Corrected workspace is intensity against %s' + % (corrected.getAxis(0).getUnit().caption())) + + print ('Ass workspace is %s against %s' + % (ass.YUnitLabel(), ass.getAxis(0).getUnit().caption())) + + print ('Acc workspace is %s against %s' + % (acc.YUnitLabel(), acc.getAxis(0).getUnit().caption())) + +.. testcleanup:: SampleAndCanCorrections + + DeleteWorkspace(red_ws) + DeleteWorkspace(can_ws) + DeleteWorkspace(corrected) + DeleteWorkspace(fact) + +**Output:** + +.. testoutput:: SampleAndCanCorrections + + Corrected workspace is intensity against Energy transfer + Ass workspace is Attenuation factor against Wavelength + Acc workspace is Attenuation factor against Wavelength + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/IndirectCalibration-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectCalibration-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..b977f34baf5a5fb9449bf7996a4029731e5325c7 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/IndirectCalibration-v1.rst @@ -0,0 +1,44 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Creates a calibration workspace to be used with inelastic indirect reductions, +allowing for the correction of relative detector intensities. + +Either a single run file or range of runs in *.raw* format can be given to the +algorithm which are then merged into a single run using :ref:`MergeRuns +<algm-MergeRuns>`, a flat background is then calculated and normalised to give +the output workspace. + +Usage +----- + +**Example - create calibration workspace for IRIS** + +.. include:: ../usagedata-note.txt + +.. testcode:: ExIndirectCalibrationSimple + + # Create a calibration workspace + cal_ws = IndirectCalibration(InputFiles='IRS26173.raw', + DetectorRange='3,53', + PeakRange='62500,65000', + BackgroundRange='59000,61500') + + print 'Calibration workspace has %d bin(s) and %d spectra.' % ( + cal_ws.blocksize(), cal_ws.getNumberHistograms()) + +Output: + +.. testoutput:: ExIndirectCalibrationSimple + + Calibration workspace has 1 bin(s) and 51 spectra. + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..ef2b38b704093025d74550b2c0ede9033bfca67e --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst @@ -0,0 +1,106 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Calculates and applies corrections for scattering and absorption in a +cylindrical sample for a run on an indirect inelastic instrument, optionally +allowing for the subtraction or corrections of the container. + +The correction factor workspace is a workspace group containing the correction +factors in the Paalman and Pings format, note that only :math:`{A_{s,s}}` and +:math:`A_{c,c}` factors are calculated by thsi algorithm. + +Usage +----- + +.. include:: ../usagedata-note.txt + +**Example - Sample corrections for IRIS:** + +.. testcode:: SampleCorrectionsWithCanSubtraction + + red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs') + can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs') + + corrected, fact = IndirectCylinderAbsorption(SampleWorkspace=red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=can_ws, + CanScaleFactor=0.8, + SampleRadius=0.2, + UseCanCorrections=False, + Events=100) + + ass = fact[0] + + print ('Corrected workspace is intensity against %s' + % (corrected.getAxis(0).getUnit().caption())) + + print ('Ass workspace is %s against %s' + % (ass.YUnitLabel(), ass.getAxis(0).getUnit().caption())) + +.. testcleanup:: SampleCorrectionsWithCanSubtraction + + DeleteWorkspace(red_ws) + DeleteWorkspace(can_ws) + DeleteWorkspace(corrected) + DeleteWorkspace(fact) + +**Output:** + +.. testoutput:: SampleCorrectionsWithCanSubtraction + + Corrected workspace is intensity against Energy transfer + Ass workspace is Attenuation factor against Wavelength + +**Example - Sample and container corrections for IRIS:** + +.. testcode:: SampleAndCanCorrections + + red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs') + can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs') + + corrected, fact = IndirectCylinderAbsorption(SampleWorkspace=red_ws, + SampleChemicalFormula='H2-O', + SampleRadius=0.2, + CanWorkspace=can_ws, + CanScaleFactor=0.8, + CanChemicalFormula='V', + CanRadius=0.22, + UseCanCorrections=True, + Events=100) + + ass = fact[0] + acc = fact[1] + + print ('Corrected workspace is intensity against %s' + % (corrected.getAxis(0).getUnit().caption())) + + print ('Ass workspace is %s against %s' + % (ass.YUnitLabel(), ass.getAxis(0).getUnit().caption())) + + print ('Acc workspace is %s against %s' + % (acc.YUnitLabel(), acc.getAxis(0).getUnit().caption())) + +.. testcleanup:: SampleAndCanCorrections + + DeleteWorkspace(red_ws) + DeleteWorkspace(can_ws) + DeleteWorkspace(corrected) + DeleteWorkspace(fact) + +**Output:** + +.. testoutput:: SampleAndCanCorrections + + Corrected workspace is intensity against Energy transfer + Ass workspace is Attenuation factor against Wavelength + Acc workspace is Attenuation factor against Wavelength + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..7e83f5ec675d28a666b8a34aedc750e328be1114 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst @@ -0,0 +1,109 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Calculates and applies corrections for scattering abs absorption in a flat plate +sample for a run on an indirect inelastic instrument, optionally allowing for +the subtraction or corrections of the container. + +The correction factor workspace is a workspace group containing the correction +factors in the Paalman and Pings format, note that only :math:`{A_{s,s}}` and +:math:`A_{c,c}` factors are calculated by thsi algorithm. + +Usage +----- + +.. include:: ../usagedata-note.txt + +**Example - Sample corrections for IRIS:** + +.. testcode:: SampleCorrectionsWithCanSubtraction + + red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs') + can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs') + + corrected, fact = IndirectFlatPlateAbsorption(SampleWorkspace=red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=can_ws, + CanScaleFactor=0.8, + SampleHeight=1, + SampleWidth=1, + SampleThickness=1, + ElementSize=1, + UseCanCorrections=False) + + ass = fact[0] + + print ('Corrected workspace is intensity against %s' + % (corrected.getAxis(0).getUnit().caption())) + + print ('Ass workspace is %s against %s' + % (ass.YUnitLabel(), ass.getAxis(0).getUnit().caption())) + +.. testcleanup:: SampleCorrectionsWithCanSubtraction + + DeleteWorkspace(red_ws) + DeleteWorkspace(can_ws) + DeleteWorkspace(corrected) + DeleteWorkspace(fact) + +**Output:** + +.. testoutput:: SampleCorrectionsWithCanSubtraction + + Corrected workspace is intensity against Energy transfer + Ass workspace is Attenuation factor against Wavelength + +**Example - Sample and container corrections for IRIS:** + +.. testcode:: SampleAndCanCorrections + + red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs') + can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs') + + corrected, fact = IndirectFlatPlateAbsorption(SampleWorkspace=red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=can_ws, + CanChemicalFormula='V', + CanScaleFactor=0.8, + SampleHeight=1, + SampleWidth=1, + SampleThickness=1, + ElementSize=1, + UseCanCorrections=True) + + ass = fact[0] + acc = fact[1] + + print ('Corrected workspace is intensity against %s' + % (corrected.getAxis(0).getUnit().caption())) + + print ('Ass workspace is %s against %s' + % (ass.YUnitLabel(), ass.getAxis(0).getUnit().caption())) + + print ('Acc workspace is %s against %s' + % (acc.YUnitLabel(), acc.getAxis(0).getUnit().caption())) + +.. testcleanup:: SampleAndCanCorrections + + DeleteWorkspace(red_ws) + DeleteWorkspace(can_ws) + DeleteWorkspace(corrected) + DeleteWorkspace(fact) + +**Output:** + +.. testoutput:: SampleAndCanCorrections + + Corrected workspace is intensity against Energy transfer + Ass workspace is Attenuation factor against Wavelength + Acc workspace is Attenuation factor against Wavelength + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/IndirectResolution-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectResolution-v1.rst index 6bb35679ff6e16e324fd2e9f8e8dc08648a01d14..f43a161e2832af1d30a3710c6b780fbf14ed337d 100644 --- a/Code/Mantid/docs/source/algorithms/IndirectResolution-v1.rst +++ b/Code/Mantid/docs/source/algorithms/IndirectResolution-v1.rst @@ -9,7 +9,11 @@ Description ----------- -Creates a resolution workspace for an inelastic indirect sample run. +Creates a resolution workspace for an inelastic indirect sample run by +summing all spectra in the energy transfer and subtracting a flat background to +give a single resolution curve. + +Rebinning and intensity scaling can optionally be applied to the result. Usage ----- @@ -26,12 +30,14 @@ Usage BackgroundRange=[-0.16, -0.14], RebinParam='-0.175,0.002,0.175') - print mtd.doesExist('resolution') + print 'Number of histograms: %d' % resolution.getNumberHistograms() + print 'Number of bins: %d' % resolution.blocksize() Output: .. testoutput:: ExIndirectResolutionSimple - True + Number of histograms: 1 + Number of bins: 175 .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/IndirectTransmissionMonitor-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectTransmissionMonitor-v1.rst index 572e9a207449b2da96342de52abc2c51ccb35764..59f76e9419796f0b6d0557eb31bb39e5ec3010ad 100644 --- a/Code/Mantid/docs/source/algorithms/IndirectTransmissionMonitor-v1.rst +++ b/Code/Mantid/docs/source/algorithms/IndirectTransmissionMonitor-v1.rst @@ -9,11 +9,15 @@ Description ----------- -Calculates the sample transmission using the raw data files of the sample and its background or container. +Calculates the sample transmission using the raw data files of the sample and +its background or container by dividing the monitor spectrum of the sample +workspace by that of the container. -For more details, see `Indirect:Transmission <http://www.mantidproject.org/Indirect:Transmission>`_. +If the instrument has both incident and transmission monitors then the incident +monitor is first divided by the transmission monitor. -Output workspace will default to [instument][run number]_[analyser][reflection]_Transmission if not set. +It is assumed that the name of the incident monitor is *monitor2* and the name +of the transmission monitor is *monitor1*. Usage ----- @@ -22,20 +26,17 @@ Usage .. testcode:: exIRISTransmission - sample_file = 'IRS26176.RAW' - can_file = 'IRS26173.RAW' - - sample_ws = Load(sample_file) - can_ws = Load(can_file) + sample_ws = Load('IRS26176.RAW') + can_ws = Load('IRS26173.RAW') transmission_ws = IndirectTransmissionMonitor(SampleWorkspace=sample_ws, CanWorkspace=can_ws) - print transmission_ws.getNames() + print ', '.join(transmission_ws.getNames()) **Output:** .. testoutput:: exIRISTransmission - ['sample_ws_Sam','sample_ws_Can','sample_ws_Trans'] + sample_ws_Sam, sample_ws_Can, sample_ws_Trans .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/IntegrateEllipsoids-v1.rst b/Code/Mantid/docs/source/algorithms/IntegrateEllipsoids-v1.rst index c64b003e766818d4182edddb6a8e23a1cf076013..831d0c6d5d858af5fb5ce90a6b224ede544d19e6 100644 --- a/Code/Mantid/docs/source/algorithms/IntegrateEllipsoids-v1.rst +++ b/Code/Mantid/docs/source/algorithms/IntegrateEllipsoids-v1.rst @@ -162,7 +162,7 @@ Usage **Example - IntegrateEllipsoids:** -The code iteslef works but disabled from doc tests as takes too long to complete. User should provide its own +The code itself works but disabled from doc tests as takes too long to complete. User should provide its own event nexus file instead of **TOPAZ_3132_event.nxs** used within this example. The original **TOPAZ_3132_event.nxs** file is availible in `Mantid system tests repository <https://github.com/mantidproject/systemtests/tree/master/Data/TOPAZ_3132_event.nxs>`_. diff --git a/Code/Mantid/docs/source/algorithms/IntegratePeaksMD-v2.rst b/Code/Mantid/docs/source/algorithms/IntegratePeaksMD-v2.rst index 704b3cf2ce53deaaf40819d51773d39376e16bb4..20ec4aae8a90ee567c814fd446119c9c6716dd14 100644 --- a/Code/Mantid/docs/source/algorithms/IntegratePeaksMD-v2.rst +++ b/Code/Mantid/docs/source/algorithms/IntegratePeaksMD-v2.rst @@ -129,7 +129,7 @@ Usage **Example - IntegratePeaks:** -The code iteslef works but disabled from doc tests as takes too long to complete. User should provide its own +The code itself works but disabled from doc tests as takes too long to complete. User should provide its own event nexus file instead of **TOPAZ_3132_event.nxs** used within this example. The original **TOPAZ_3132_event.nxs** file is availible in `Mantid system tests repository <https://github.com/mantidproject/systemtests/tree/master/Data/TOPAZ_3132_event.nxs>`_. diff --git a/Code/Mantid/docs/source/algorithms/JumpFit-v1.rst b/Code/Mantid/docs/source/algorithms/JumpFit-v1.rst index f89c399239412473cf8bcbe1bda4a599b6a2339d..55d6d679b2c0aea08e1c3ef79c14b9b3fb4ed297 100644 --- a/Code/Mantid/docs/source/algorithms/JumpFit-v1.rst +++ b/Code/Mantid/docs/source/algorithms/JumpFit-v1.rst @@ -9,10 +9,37 @@ Description ----------- -Performs jump fitting on a workspace created by either ConvFit (Indirct Data Analysis) -or Quasi (Indirect Bayes). +Fits the Q variation of the fitted widths from either ConvFit or Quasi to one +of 4 models (the fit function used is given in brackets): -For more details, see the `Indirect Bayes docs -<http://www.mantidproject.org/IndirectBayes:JumpFit>`_. +- Chudley-Elliott model (ChudelyElliott) +- Hall-Ross model (HallRoss) +- Simple Fick Diffusion (FickDiffusion) +- Teixeira's model for water (TeixeiraWater) + +Usage +----- + +**Example - Chudley-Elliot fit** + +.. testcode:: exChudleyElliotFit + + data = Load(Filename='irs26176_graphite002_conv_2LFixF_s0_to_9_Result.nxs') + + JumpFit(InputWorkspace=data, + FUnction='ChudleyElliot', + QMin=0.6, + QMax=1.8) + + fit = mtd['data_ChudleyElliot_fit_Workspace'] + params = mtd['data_ChudleyElliot_fit_Parameters'] + + print 'Fit parameters: %s' % ', '.join(params.column(0)) + +**Output:** + +.. testoutput:: exChudleyElliotFit + + Fit parameters: Tau, L, Cost function value .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/LoadDNSLegacy-v1.rst b/Code/Mantid/docs/source/algorithms/LoadDNSLegacy-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..369b381acf627d81d508958d0cf9efaeec993993 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/LoadDNSLegacy-v1.rst @@ -0,0 +1,39 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Loads a DNS legacy .d_dat data file into a :ref:`Workspace2D <Workspace2D>` with +the given name. + +The loader rotates the detector bank in the position given in the data file. + +This algorithm only supports DNS instrument in its configuration before major upgrade. + +Usage +----- + +**Example - Load a DNS legacy .d_dat file:** + +.. code-block:: python + + # data file. + datafile = 'dn134011vana.d_dat' + + # Load dataset + ws = LoadDNSLegacy(datafile) + + print "This workspace has", ws.getNumDims(), "dimensions and has", \ + ws.getNumberHistograms(), "histograms." + +Output: + + This workspace has 2 dimensions and has 24 histograms. + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/LoadFITS-v1.rst b/Code/Mantid/docs/source/algorithms/LoadFITS-v1.rst index 557447bc10fd2b485125fe0b816072e009c36e29..1184957082ea3bb9cc5fcd8427abafca0877988f 100644 --- a/Code/Mantid/docs/source/algorithms/LoadFITS-v1.rst +++ b/Code/Mantid/docs/source/algorithms/LoadFITS-v1.rst @@ -9,6 +9,86 @@ Description ----------- -Load data from FITS files +Load FITS files, which typically contain images, into a +:ref:`WorkspaceGroup <WorkspaceGroup>`. FITS stands for Flexible Image +Transport System, see http://en.wikipedia.org/wiki/FITS. A new +workspace (of type :ref:`Workspace2D <Workspace2D>`) is created for +every FITS file loaded with this algorithm, and these workspaces are +added into a :ref:`WorkspaceGroup <WorkspaceGroup>`. The group +workspace is named as indicated in the OutputWorkspace input +property. The workspaces included in the group are named with the same +name and an appendix _1, _2, etc., incremented sequentially as new +files are loaded with the same OutputWorkspace property. + +The current implementation of this algorithm only supports 2D files +(FITS images with two axes), and it should in principle be able to +load FITS files from different sources. + +The workspaces created by this algorithm contain one spectrum per +pixel. The first spectrum correspond to the top-left corner and the +last spectrum to the bottom-right corner. + +FITS header entries +################### + +At a very minimum, the standard header entries SIMPLE, BITPIX, NAXIS, +NAXIS1, and NAXIS2 must be present in the file. + +This algorithm interprets extension headers defined for the IMAT +instrument (ISIS facility). The set of extension headers for the IMAT +instrument is being defined as of this writing and specific support +and/or functionality related to additional headers might be added in +this algorithm. + +Child algorithms used +##################### + +This algorithm uses one child algorithm: + +- :ref:`algm-LoadInstrument`, which looks for a description of the + instrument in the facilities definition file and if found reads it. + This algorithm is used only once when loading a set of FITS file + corresponding to the same instrument. + +Usage +----- + +**Example** + +.. testcode:: LoadFITS + + ws_name = 'FITSws' + wsg = LoadFITS(Filename='FITS_small_01.fits', OutputWorkspace=ws_name) + ws = wsg.getItem(0) + + # A couple of standard FITS header entries + bpp_log = '_BITPIX' + try: + log = ws.getRun().getLogData(bpp_log).value + print "Bits per pixel: %s" % int(log) + except RuntimeError: + print "Could not find the keyword '%s' in this FITS file" % bpp_log + + axis1_log = '_NAXIS1' + axis2_log = '_NAXIS2' + try: + log1 = ws.getRun().getLogData(axis1_log).value + log2 = ws.getRun().getLogData(axis2_log).value + print "FITS image size: %s x %s pixels" % (int(log1), int(log2)) + print "Number of spectra in the output workspace: %d" % ws.getNumberHistograms() + except RuntimeError: + print "Could not find the keywords '%s' and '%s' in this FITS file" % (axis1_log, axis2_log) + +.. testcleanup:: LoadFITS + + DeleteWorkspace(ws_name) + +Output: + +.. testoutput:: LoadFITS + + Bits per pixel: 16 + FITS image size: 512 x 512 pixels + Number of spectra in the output workspace: 262144 .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/LoadSpiceAscii-v1.rst b/Code/Mantid/docs/source/algorithms/LoadSpiceAscii-v1.rst index ddbdd07345bf16c4155643c9d04b443b2e889369..4f91c1e8c1bd17f4234bdc458adf8cefe524c7a2 100644 --- a/Code/Mantid/docs/source/algorithms/LoadSpiceAscii-v1.rst +++ b/Code/Mantid/docs/source/algorithms/LoadSpiceAscii-v1.rst @@ -55,7 +55,10 @@ Usage print "Number of measuring points = %d" % (datatbws.rowCount()) print "Number of columns in data workspace = %d" % (datatbws.columnCount()) - print "Number of run information = %d" % (len(infows.getRun().getProperties())) + propertylist = infows.getRun().getProperties() + print "Number of run information = %d" % (len(propertylist)) + for i in xrange(len(propertylist)): + print "Property %d: Name = %-20s." % (i, propertylist[i].name) print "Sum of Counts = %d" % (infows.getRun().getProperty("Sum of Counts").value) print "Center of Mass = %.5f +/- %.5f" % (infows.getRun().getProperty("Center of Mass").value, infows.getRun().getProperty("Center of Mass.error").value) @@ -71,7 +74,42 @@ Output: Number of measuring points = 61 Number of columns in data workspace = 70 - Number of run information = 34 + Number of run information = 35 + Property 0: Name = Center of Mass . + Property 1: Name = Center of Mass.error. + Property 2: Name = Full Width Half-Maximum. + Property 3: Name = Full Width Half-Maximum.error. + Property 4: Name = Sum of Counts . + Property 5: Name = analyzer . + Property 6: Name = builtin_command . + Property 7: Name = col_headers . + Property 8: Name = collimation . + Property 9: Name = command . + Property 10: Name = date . + Property 11: Name = def_x . + Property 12: Name = def_y . + Property 13: Name = experiment . + Property 14: Name = experiment_number . + Property 15: Name = latticeconstants . + Property 16: Name = local_contact . + Property 17: Name = mode . + Property 18: Name = monochromator . + Property 19: Name = preset_channel . + Property 20: Name = preset_type . + Property 21: Name = preset_value . + Property 22: Name = proposal . + Property 23: Name = runend . + Property 24: Name = samplemosaic . + Property 25: Name = samplename . + Property 26: Name = sampletype . + Property 27: Name = scan . + Property 28: Name = scan_title . + Property 29: Name = sense . + Property 30: Name = time . + Property 31: Name = ubconf . + Property 32: Name = ubmatrix . + Property 33: Name = users . + Property 34: Name = run_start . Sum of Counts = 1944923 Center of Mass = 9.00076 +/- 0.00921 diff --git a/Code/Mantid/docs/source/algorithms/MSDFit-v1.rst b/Code/Mantid/docs/source/algorithms/MSDFit-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..358c9f42d8af1ced158ad28fab7c3aecffd57870 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/MSDFit-v1.rst @@ -0,0 +1,47 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Fits :math:`log(intensity)` vs :math:`Q^{2}` with a straight line for each run +to obtain the mean square displacement for a given range of runs. + +This algorithm operates on the QSquared workspace (*_q2*) generated by the +:ref:`ElasticWindowMultiple <algm-ElasticWindowMultiple>` algorithm. + +Usage +----- + +**Example - Performing MSDFit on simulated data.** + +.. testcode:: ExGeneratedDataFit + + # Create some data that is similar to the output of ElasticWindowMultiple + sample = CreateSampleWorkspace(Function='User Defined', + UserDefinedFunction='name=ExpDecay,Height=1,Lifetime=6', + NumBanks=1, BankPixelWidth=1, XUnit='QSquared', XMin=0.0, + XMax=5.0, BinWidth=0.1) + + msd, param, fit = MSDFit(InputWorkspace=sample, + XStart=0.0, XEnd=5.0, + SpecMin=0, SpecMax=0) + + print ', '.join(msd.getNames()) + print 'A0: ' + str(msd.getItem(0).readY(0)) + print 'A1: ' + str(msd.getItem(1).readY(0)) + +Output: + +.. testoutput:: ExGeneratedDataFit + + msd_A0, msd_A1 + A0: [ 0.95908058] + A1: [ 0.11014908] + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/PawleyFit-v1.rst b/Code/Mantid/docs/source/algorithms/PawleyFit-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..3e59022cd0409c6da999672d5aa8503719eaad40 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/PawleyFit-v1.rst @@ -0,0 +1,101 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +The algorithm performs a fit of lattice parameters using the principle approach described in a paper by Pawley [Pawley]_. In this approach the reflection positions are calculated from lattice parameters and the reflection's Miller indices (:math:`hkl`), while the other profile parameters for each peak are freely refined. + +PawleyFit requires a MatrixWorkspace with at least one spectrum in terms of either :math:`d` or :math:`Q`, the index of the spectrum can be supplied to the algorithm as a parameter. Furthermore, the range which is used for refinement can be changed by setting the corresponding properties. + +In addition, a TableWorkspace with information about the reflections that are found in the spectrum must be passed as well. There must be four columns with the captions "HKL", "d", "FWHM (rel.)" and "Intensity". The HKL column can be supplied either as V3D or as a string with 3 numbers separated by space, comma or semi-colon and possibly surrounded by square brackets. One way to obtain such a table is to use three algorithms that are used in analysis of POLDI data, which produce tables in a suitable format. Details are given in the usage example section. + +Along with the workspaces containing fit results and parameter values, the algorithm also outputs the reduced :math:`\chi^2`-value, which is also written in the log. + +Usage +----- + +.. include:: ../usagedata-note.txt + +For the usage example there is a calculated, theoretical diffraction pattern (including a bit of noise) for Silicon, which crystallizes in space group :math:`Fd\overline{3}m` and has a cubic cell with lattice parameter :math:`a=5.4311946\,\mathrm{\AA{}}`. + +.. testcode:: ExPawleySilicon + + import numpy as np + + # Load spectrum for Silicon in the d-range down to 0.7 + si_spectrum = Load("PawleySilicon.nxs") + + # In order to index the peaks later on, generate reflection for Si + Si = PoldiCreatePeaksFromCell(SpaceGroup='F d -3 m', + Atoms='Si 0 0 0 1.0 0.05', + a=5.43, LatticeSpacingMin=0.7) + + print "Silicon has", Si.rowCount(), "unique reflections with d > 0.7." + + # Find peaks in the spectrum + si_peaks = PoldiPeakSearch(si_spectrum) + + # Index the peaks, will generate a workspace named 'Indexed_Si' + indexed = PoldiIndexKnownCompounds(si_peaks, CompoundWorkspaces='Si') + + si_peaks_indexed = AnalysisDataService.retrieve('Indexed_Si') + + # 3 peaks have two possibilities for indexing, because their d-values are identical + print "The number of peaks that were indexed:", si_peaks_indexed.rowCount() + + # Run the actual fit with lattice parameters that are slightly off + si_fitted, si_cell, si_params, chi_square = PawleyFit(si_spectrum, + CrystalSystem='Cubic', + InitialCell='5.436 5.436 5.436', + PeakTable=si_peaks_indexed) + + si_cell = AnalysisDataService.retrieve("si_cell") + + a = np.round(si_cell.cell(0, 1), 6) + a_err = np.round(si_cell.cell(0, 2), 6) + a_diff = np.round(np.fabs(a - 5.4311946), 6) + + print "The lattice parameter was refined to a =", a, "+/-", a_err + print "The deviation from the actual parameter (a=5.4311946) is:", a_diff + print "This difference corresponds to", np.round(a_diff / a_err, 2), "standard deviations." + print "The reduced chi square of the fit is:", np.round(chi_square, 3) + +Running this script will generate a bit of output about the results of the different steps. At the end the lattice parameter differs less than one standard deviation from the actual value. + +.. testoutput:: ExPawleySilicon + + Silicon has 18 unique reflections with d > 0.7. + The number of peaks that were indexed: 15 + The lattice parameter was refined to a = 5.431205 +/- 1.6e-05 + The deviation from the actual parameter (a=5.4311946) is: 1e-05 + This difference corresponds to 0.63 standard deviations. + The reduced chi square of the fit is: 1.04 + +.. testcleanup:: ExPawleySilicon + + AnalysisDataService.remove("si_spectrum") + AnalysisDataService.remove("Si") + AnalysisDataService.remove("si_peaks") + AnalysisDataService.remove("indexed") + AnalysisDataService.remove("si_fitted") + AnalysisDataService.remove("si_cell") + AnalysisDataService.remove("si_params") + +It's important to check the output data, which is found in the workspace labeled si_fitted. Plotting it should show that the residuals are just containing background noise and no systematic deviations. Of course, depending on the sample and the measurement this will differ between cases. + +.. figure:: /images/PawleyFitResultTheoreticalSilicon.png + :figwidth: 15 cm + :align: center + :alt: Result of the Pawley fit example with silicon. + + Result of the Pawley fit example with silicon. + +.. [Pawley] Pawley, G. S. “Unit-Cell Refinement from Powder Diffraction Scans.â€, J. Appl. Crystallogr. 14, 1981, 357. doi:10.1107/S0021889881009618. + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/PoldiCreatePeaksFromFile-v1.rst b/Code/Mantid/docs/source/algorithms/PoldiCreatePeaksFromFile-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..a25b5e8d3f8b3607adb6f579a7aab1a8662d6fa6 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/PoldiCreatePeaksFromFile-v1.rst @@ -0,0 +1,87 @@ + +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Some steps in the analysis of POLDI data require that detected peaks are indexed. This can be done by using +:ref:`algm-PoldiIndexKnownCompounds`, which accepts a table with unindexed peaks and one or more workspaces with +calculated peaks corresponding to the crystal structures that are expected in the sample. These can be calculated +using the algorithm :ref:`algm-PoldiCreatePeaksFromCell`. Calling this algorithm over and over with the same +parameters is not practical, but storing the tables is not practical either, since lattice parameters may change +slightly from sample to sample. + +PoldiCreatePeaksFromFile reads a text file which contains one or more crystal structure definitions. Since the +analysis requires information mainly about the lattice and the symmetry, the format is very simple. The following +block shows how such a file would look when there are two compounds: + +.. code-block:: none + + # The name may contain letters, numbers and _ + Iron_FCC { + # Up to 6 values in the order a, b, c, alpha, beta, gamma. + # Lattice parameters are given in Angstrom. + Lattice: 3.65 + Spacegroup: F m -3 m + Atoms: { + # Element x y z are mandatory. Optional occupancy and isotropic ADP (in Angstrom^2) + Fe 0.0 0.0 0.0 + } + } + + Iron_BCC { + Lattice: 2.88 + Spacegroup: F m -3 m + Atoms: { + Fe 0.0 0.0 0.0 + } + } + +Note that only the atoms in the asymmetric unit need to be specified, the space group is used to generate all +equivalent atoms. This information is used to determine systematic absences, while the space group is also used by +some POLDI algorithms to obtain the point group to get reflection multiplicities and more. Anything that follows the +`#`-character is considered a comment and is ignored by the parser to allow documentation of the crystal structures +if necessary. + +The algorithm will always produce a WorkspaceGroup which contains as many peak tables as compounds specified in the +file. + +Usage +----- + +.. include:: ../usagedata-note.txt + +The following usage example takes up the file showed above and passes it to the algorithm. + +.. testcode:: + + # Create two tables with expected peaks directly from a file + compounds = PoldiCreatePeaksFromFile('PoldiCrystalFileExample.dat', LatticeSpacingMin=0.7) + + compound_count = compounds.getNumberOfEntries() + print 'Number of loaded compounds:', compound_count + + for i in range(compound_count): + ws = compounds.getItem(i) + print 'Compound ' + str(i + 1) +':', ws.getName(), 'has', ws.rowCount(), 'reflections in the resolution range.' + + +The script produces a WorkspaceGroup which contains a table with reflections for each compound in the file: + +.. testoutput:: + + Number of loaded compounds: 2 + Compound 1: Iron_FCC has 11 reflections in the resolution range. + Compound 2: Iron_BCC has 8 reflections in the resolution range. + +.. testcleanup:: + + DeleteWorkspace('compounds') + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/SCDCalibratePanels-v1.rst b/Code/Mantid/docs/source/algorithms/SCDCalibratePanels-v1.rst index 0ddba6913fe7ea9f4d9a99d6b3b81326d8d5b01c..1f98aa15a476e3838012d2570b2cee52b2ba01b5 100644 --- a/Code/Mantid/docs/source/algorithms/SCDCalibratePanels-v1.rst +++ b/Code/Mantid/docs/source/algorithms/SCDCalibratePanels-v1.rst @@ -95,4 +95,17 @@ algorithm. To do so select the workspace, which you have calibrated as the InputWorkspace and the workspace you want to copy the calibration to, the OutputWorkspace. +Usage +------ + +**Example - SCDCalibratePanels:** + + LoadIsawPeaks(Filename='MANDI_801.peaks', OutputWorkspace='peaks') + SCDCalibratePanels(PeakWorkspace='peaks',DetCalFilename='mandi_801.DetCal',XmlFilename='mandi_801.xml',a=74,b=74.5,c=99.9,alpha=90,beta=90,gamma=60) + Load(Filename='MANDI_801_event.nxs', OutputWorkspace='MANDI_801_event') + CloneWorkspace(InputWorkspace='MANDI_801_event', OutputWorkspace='MANDI_801_event_xml') + LoadParameterFile(Workspace='MANDI_801_event_xml', Filename='mandi_801.xml') + RenameWorkspace(InputWorkspace='MANDI_801_event_xml', OutputWorkspace='MANDI_801_event_DetCal') + LoadIsawDetCal(InputWorkspace='MANDI_801_event_DetCal', Filename='mandi_801.DetCal') + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/TransformToIqt-v1.rst b/Code/Mantid/docs/source/algorithms/TransformToIqt-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..83480d11785c64b0edfd40982bb5bcdf0ad8006d --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/TransformToIqt-v1.rst @@ -0,0 +1,112 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +This algorithm transforms either a reduced (*_red*) or S(Q, w) (*_sqw*) +workspace to a I(Q, t) workspace. + +Theory +------ + +The measured spectrum :math:`I(Q, \omega)` is proportional to the four +dimensional convolution of the scattering law :math:`S(Q, \omega)` with the +resolution function :math:`R(Q, \omega)` of the spectrometer via :math:`I(Q, +\omega) = S(Q, \omega) ⊗ R(Q, \omega)`, so :math:`S(Q, \omega)` can be obtained, +in principle, by a deconvolution in :math:`Q` and :math:`\omega`. The method +employed here is based on the Fourier Transform (FT) technique [6,7]. On Fourier +transforming the equation becomes :math:`I(Q, t) = S(Q, t) x R(Q, t)` where the +convolution in :math:`\omega`-space is replaced by a simple multiplication in +:math:`t`-space. The intermediate scattering law :math:`I(Q, t)` is then +obtained by simple division and the scattering law :math:`S(Q, \omega)` itself +can be obtained by back transformation. The latter however is full of pitfalls +for the unwary. The advantage of this technique over that of a fitting procedure +such as SWIFT is that a functional form for :math:`I(Q, t)` does not have to be +assumed. On IRIS the resolution function is close to a Lorentzian and the +scattering law is often in the form of one or more Lorentzians. The FT of a +Lorentzian is a decaying exponential, :math:`exp(-\alpha t)` , so that plots of +:math:`ln(I(Q, t))` against t would be straight lines thus making interpretation +easier. + +In general, the origin in energy for the sample run and the resolution run need +not necessarily be the same or indeed be exactly zero in the conversion of the +RAW data from time-of-flight to energy transfer. This will depend, for example, +on the sample and vanadium shapes and positions and whether the analyser +temperature has changed between the runs. The procedure takes this into account +automatically, without using an arbitrary fitting procedure, in the following +way. From the general properties of the FT, the transform of an offset +Lorentzian has the form :math:`(cos(\omega_{0}t) + isin(\omega_{0}t))exp(-\Gamma +t)` , thus taking the modulus produces the exponential :math:`exp(-\Gamma t)` +which is the required function. If this is carried out for both sample and +resolution, the difference in the energy origin is automatically removed. The +results of this procedure should however be treated with some caution when +applied to more complicated spectra in which it is possible for :math:`I(Q, t)` +to become negative, for example, when inelastic side peaks are comparable in +height to the elastic peak. + +The interpretation of the data must also take into account the propagation of +statistical errors (counting statistics) in the measured data as discussed by +Wild et al [1]. If the count in channel :math:`k` is :math:`X_{k}` , then +:math:`X_{k}=<X_{k}>+\Delta X_{k}` where :math:`<X_{k}>` is the mean value and +:math:`\Delta X_{k}` the error. The standard deviation for channel :math:`k` is +:math:`\sigma k` :math:`2=<\Delta X_{k}>2` which is assumed to be given by +:math:`\sigma k=<X_{k}>`. The FT of :math:`X_{k}` is defined by +:math:`X_{j}=<X_{j}>+\Delta X_{j}` and the real and imaginary parts denoted by +:math:`X_{j} I` and :math:`X_{j} I` respectively. The standard deviations on +:math:`X_{j}` are then given by :math:`\sigma 2(X_{j} R)=1/2 X0 R + 1/2 X2j R` +and :math:`\sigma 2(X_{j} I)=1/2 X0 I - 1/2 X2j I`. + +Note that :math:`\sigma 2(X_{0} R) = X_{0} R` and from the properties of FT +:math:`X_{0} R = X_{k}`. Thus the standard deviation of the first coefficient +of the FT is the square root of the integrated intensity of the spectrum. In +practice, apart from the first few coefficients, the error is nearly constant +and close to :math:`X_{0} R`. A further point to note is that the errors make +the imaginary part of :math:`I(Q, t)` non-zero and that, although these will be +distributed about zero, on taking the modulus of :math:`I(Q, t)`, they become +positive at all times and are distributed about a non-zero positive value. When +:math:`I(Q, t)` is plotted on a log-scale the size of the error bars increases +with time (coefficient) and for the resolution will reach a point where the +error on a coefficient is comparable to its value. This region must therefore be +treated with caution. For a true deconvolution by back transforming, the data +would be truncated to remove this poor region before back transforming. If the +truncation is severe the back transform may contain added ripples, so an +automatic back transform is not provided. + +References +---------- + +1. U P Wild, R Holzwarth & H P Good, Rev Sci Instr 48 1621 (1977) + +Usage +----- + +**Example - TransformToIqt with IRIS data.** + +.. testcode:: exTransformToIqtIRIS + + sample = Load('irs26176_graphite002_red.nxs') + can = Load('irs26173_graphite002_red.nxs') + + params, iqt = TransformToIqt(SampleWorkspace=sample, + ResolutionWorkspace=can, + EnergyMin=-0.5, + EnergyMax=0.5, + BinReductionFactor=10) + + print 'Number of output bins: %d' % (params.cell('SampleOutputBins', 0)) + print 'Resolution bins: %d' % (params.cell('ResolutionBins', 0)) + +Output: + +.. testoutput:: exTransformToIqtIRIS + + Number of output bins: 172 + Resolution bins: 6 + +.. categories:: diff --git a/Code/Mantid/docs/source/concepts/Analysis_Data_Service.rst b/Code/Mantid/docs/source/concepts/AnalysisDataService.rst similarity index 100% rename from Code/Mantid/docs/source/concepts/Analysis_Data_Service.rst rename to Code/Mantid/docs/source/concepts/AnalysisDataService.rst diff --git a/Code/Mantid/docs/source/concepts/Create_an_IDF.rst b/Code/Mantid/docs/source/concepts/CreateanIDF.rst similarity index 100% rename from Code/Mantid/docs/source/concepts/Create_an_IDF.rst rename to Code/Mantid/docs/source/concepts/CreateanIDF.rst diff --git a/Code/Mantid/docs/source/concepts/Data_Service.rst b/Code/Mantid/docs/source/concepts/DataService.rst similarity index 100% rename from Code/Mantid/docs/source/concepts/Data_Service.rst rename to Code/Mantid/docs/source/concepts/DataService.rst diff --git a/Code/Mantid/docs/source/concepts/Dynamic_Factory.rst b/Code/Mantid/docs/source/concepts/DynamicFactory.rst similarity index 100% rename from Code/Mantid/docs/source/concepts/Dynamic_Factory.rst rename to Code/Mantid/docs/source/concepts/DynamicFactory.rst diff --git a/Code/Mantid/docs/source/concepts/Error_Propagation.rst b/Code/Mantid/docs/source/concepts/ErrorPropagation.rst similarity index 100% rename from Code/Mantid/docs/source/concepts/Error_Propagation.rst rename to Code/Mantid/docs/source/concepts/ErrorPropagation.rst diff --git a/Code/Mantid/docs/source/concepts/EventWorkspace.rst b/Code/Mantid/docs/source/concepts/EventWorkspace.rst index 7e8712b18582552f9147ff9e1d0d9f5c3c19a403..09b7e0428229fe7f16ed0f89627d2a2e02a235d9 100644 --- a/Code/Mantid/docs/source/concepts/EventWorkspace.rst +++ b/Code/Mantid/docs/source/concepts/EventWorkspace.rst @@ -1,7 +1,7 @@ .. _EventWorkspace: -EventWorkspace -============== +Event Workspace +=============== Quick Summary For Users ----------------------- diff --git a/Code/Mantid/docs/source/concepts/Facilities_File.rst b/Code/Mantid/docs/source/concepts/FacilitiesFile.rst similarity index 100% rename from Code/Mantid/docs/source/concepts/Facilities_File.rst rename to Code/Mantid/docs/source/concepts/FacilitiesFile.rst diff --git a/Code/Mantid/docs/source/concepts/Framework_Manager.rst b/Code/Mantid/docs/source/concepts/FrameworkManager.rst similarity index 100% rename from Code/Mantid/docs/source/concepts/Framework_Manager.rst rename to Code/Mantid/docs/source/concepts/FrameworkManager.rst diff --git a/Code/Mantid/docs/source/concepts/Geometry_of_Position.rst b/Code/Mantid/docs/source/concepts/GeometryofPosition.rst similarity index 99% rename from Code/Mantid/docs/source/concepts/Geometry_of_Position.rst rename to Code/Mantid/docs/source/concepts/GeometryofPosition.rst index b6cbf2f310b3c80a4092d82c12ebdee9d2c1e86f..4451b15f80217ab2b8ca7b19aa725fe5967d9a61 100644 --- a/Code/Mantid/docs/source/concepts/Geometry_of_Position.rst +++ b/Code/Mantid/docs/source/concepts/GeometryofPosition.rst @@ -1,6 +1,6 @@ .. _Geometry of Position: -Geometry_of_Position +Geometry of Position ==================== What is it? diff --git a/Code/Mantid/docs/source/concepts/Geometry_of_Shape.rst b/Code/Mantid/docs/source/concepts/GeometryofShape.rst similarity index 100% rename from Code/Mantid/docs/source/concepts/Geometry_of_Shape.rst rename to Code/Mantid/docs/source/concepts/GeometryofShape.rst diff --git a/Code/Mantid/docs/source/concepts/HowToDefineGeometricShape.rst b/Code/Mantid/docs/source/concepts/HowToDefineGeometricShape.rst index b85cee29f6c3209c50a4065efb8aa3024b770c91..b70b96b0003b1a3befe406dc494d2af58658b3ca 100644 --- a/Code/Mantid/docs/source/concepts/HowToDefineGeometricShape.rst +++ b/Code/Mantid/docs/source/concepts/HowToDefineGeometricShape.rst @@ -31,11 +31,11 @@ algebra that follows the following notation: +------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+ | Operator | Description | Example | +============+================================================================================================================================================================+======================================================================================================+ -| | Union (i.e two or more things making up one shape). See e.g. also `1 <http://en.wikipedia.org/wiki/Union_(set_theory)>`__ | a body = legs : torso : arms : head | +| : | Union (i.e two or more things making up one shape). See e.g. also `1 <http://en.wikipedia.org/wiki/Union_(set_theory)>`__ | a body = legs : torso : arms : head | +------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+ | " " | "space" shared between shapes, i,e. intersection (the common region of shapes). See e.g. also `2 <http://en.wikipedia.org/wiki/Intersection_(set_theory)>`__ | "small-circle = big-circle small-circle" (where the small circle placed within the big-circle) | +------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+ -| #. | Complement | #. sphere = shape defined by all points outside sphere | +| \# | Complement | \# sphere = shape defined by all points outside sphere | +------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+ | ( ) | Brackets are used to emphasise which shapes an operation should be applied to. | box1 (# box2) is the intersection between box1 and the shape defined by all points not inside box2 | +------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+ diff --git a/Code/Mantid/docs/source/concepts/Instrument_Data_Service.rst b/Code/Mantid/docs/source/concepts/InstrumentDataService.rst similarity index 100% rename from Code/Mantid/docs/source/concepts/Instrument_Data_Service.rst rename to Code/Mantid/docs/source/concepts/InstrumentDataService.rst diff --git a/Code/Mantid/docs/source/concepts/LET_Sample_IDF.rst b/Code/Mantid/docs/source/concepts/LETSampleIDF.rst similarity index 99% rename from Code/Mantid/docs/source/concepts/LET_Sample_IDF.rst rename to Code/Mantid/docs/source/concepts/LETSampleIDF.rst index 84f33546f669182a8992da0853dc0f8f8e92ee0a..cd8fc2847fce37ab09664f9e6f6047a4ba4b9607 100644 --- a/Code/Mantid/docs/source/concepts/LET_Sample_IDF.rst +++ b/Code/Mantid/docs/source/concepts/LETSampleIDF.rst @@ -3,7 +3,7 @@ .. role:: xml(literal) :class: highlight -IDF-ISIS-SANS2D-annotated +IDF ISIS LET annotated ========================= This page annotates the direct inelastic instrument LET, with the purpose of (hopefully) quickly learn the basis of creating a similar IDF. diff --git a/Code/Mantid/docs/source/concepts/MDHistoWorkspace.rst b/Code/Mantid/docs/source/concepts/MDHistoWorkspace.rst index 96b00dbbdf396a62650d1d7bc944cc4c63ffc5e6..af2e92bd3ca3d6608ab213b244718959713c7c75 100644 --- a/Code/Mantid/docs/source/concepts/MDHistoWorkspace.rst +++ b/Code/Mantid/docs/source/concepts/MDHistoWorkspace.rst @@ -1,9 +1,9 @@ .. _MDHistoWorkspace: -MDHistoWorkspace -================ +MD Histogram Workspace +====================== -The MDHistoWorkspace is a simple multi-dimensional workspace. In +The MD Histogram Workspace[MDHistoWorkspace] is a simple multi-dimensional workspace. In contrast to the :ref:`MDWorkspace <MDWorkspace>`, which contains points in space, the MDHistoWorkspace consists of a signal and error spread around space on a regular grid. diff --git a/Code/Mantid/docs/source/concepts/MDWorkspace.rst b/Code/Mantid/docs/source/concepts/MDWorkspace.rst index 0a0510e528fbb40e71d582d7e5a6a80699341cf8..1319e4009e67062c24557cfbbb8af78eb345a444 100644 --- a/Code/Mantid/docs/source/concepts/MDWorkspace.rst +++ b/Code/Mantid/docs/source/concepts/MDWorkspace.rst @@ -1,9 +1,9 @@ .. _MDWorkspace: -MDWorkspace -=========== +MD Workspace +============ -The MDWorkspace (short for "Multi-Dimensional" Workspace) is a generic +The MD Workspace [MDWorkspace] (short for "Multi-Dimensional" Workspace) is a generic data structure holdings points (MDEvents) that are defined by their position in several dimensions. See also :ref:`MDHistoWorkspace <MDHistoWorkspace>`. diff --git a/Code/Mantid/docs/source/concepts/MatrixWorkspace.rst b/Code/Mantid/docs/source/concepts/MatrixWorkspace.rst index ff20b14741e329dc0b0cfedad1f1887584aaeb3e..244e23d5a98a093c09d39ad795340c9a7ec3d75d 100644 --- a/Code/Mantid/docs/source/concepts/MatrixWorkspace.rst +++ b/Code/Mantid/docs/source/concepts/MatrixWorkspace.rst @@ -1,7 +1,7 @@ .. _MatrixWorkspace: -MatrixWorkspace -=============== +Matrix Workspace +================ What information is in a MatrixWorkspace ---------------------------------------- diff --git a/Code/Mantid/docs/source/concepts/Nexus_file.rst b/Code/Mantid/docs/source/concepts/NexusFile.rst similarity index 97% rename from Code/Mantid/docs/source/concepts/Nexus_file.rst rename to Code/Mantid/docs/source/concepts/NexusFile.rst index 8c22396d56d76ffa003b01df862a56f9744b461e..9cf8a3c5a6ffab7383074736e5cb5f6e6e38b73d 100644 --- a/Code/Mantid/docs/source/concepts/Nexus_file.rst +++ b/Code/Mantid/docs/source/concepts/NexusFile.rst @@ -1,6 +1,6 @@ .. _Nexus file: -Nexus_file +Nexus File ========== A **Nexus file** is a type of data file used by ISIS traget station 2 diff --git a/Code/Mantid/docs/source/concepts/PeaksWorkspace.rst b/Code/Mantid/docs/source/concepts/PeaksWorkspace.rst index e6a32575ab9aa7c40a5cf015f4f33603802fdf1e..d6c43dbd29df77dd17d972089f366459c41f7c73 100644 --- a/Code/Mantid/docs/source/concepts/PeaksWorkspace.rst +++ b/Code/Mantid/docs/source/concepts/PeaksWorkspace.rst @@ -1,4 +1,6 @@ -PeaksWorkspace +.. _PeaksWorkspace: + +Peaks Workspace =============== The PeaksWorkspace is a special Workspace that holds a list of single crystal Peak objects. diff --git a/Code/Mantid/docs/source/concepts/Point_groups.rst b/Code/Mantid/docs/source/concepts/PointGroups.rst similarity index 96% rename from Code/Mantid/docs/source/concepts/Point_groups.rst rename to Code/Mantid/docs/source/concepts/PointGroups.rst index e43e722665c1fc392a059bc285b7f3adff20c89d..65a6c9540f93e3ae3b9d7921620a24832d972c1d 100644 --- a/Code/Mantid/docs/source/concepts/Point_groups.rst +++ b/Code/Mantid/docs/source/concepts/PointGroups.rst @@ -1,6 +1,6 @@ .. _Point groups: -Point groups +Point Groups ============ This document explains how crystallographic point groups are used in Mantid. @@ -42,7 +42,7 @@ As mentioned before, point groups can describe the symmetry of a lattice, includ To describe the rotational and translational components of the symmetry operation, a matrix :math:`\mathbf{W}_i` and a vector :math:`\mathbf{w}_i` are used. In three dimensions :math:`\mathbf{h}` has three elements, so :math:`\mathbf{W}_i` is a :math:`3\times3`-matrix and the symmetry operation is applied like this: .. math:: - \mathbf{h}' = \mathbf{W}_i^{-1}^T \cdot \mathbf{h} + \mathbf{h}' = {\mathbf{W}_i^{-1}}^T \cdot \mathbf{h} Note that the translational component is not used for transforming HKLs and :math:`\mathbf{W}_i` is inverted and transposed. Coordinates :math:`\mathbf{x}` are transformed differently, they are affected by the translational component: @@ -170,10 +170,12 @@ Which results in the following output: .. testoutput :: ExQueryPointGroups - All point groups: ['-1','-3','-3 h','-31m','-3m','-3m1','-4','-42m','-43m','-4m2','-6','-62m','-6m2','1','112/m','2','2/m','222','23','3','3 h','312','31m','32','321','3m','3m1','4','4/m','4/mmm','422','432','4mm','6','6/m','6/mmm','622','6mm','m','m-3','m-3m','mm2','mmm'] + All point groups: ['-1','-3','-3 r','-31m','-3m r','-3m1','-4','-42m','-43m','-4m2','-6','-62m','-6m2','1','112/m','2','2/m','222','23','3','3 r','312','31m','32 r','321','3m r','3m1','4','4/m','4/mmm','422','432','4mm','6','6/m','6/mmm','622','6mm','m','m-3','m-3m','mm2','mmm'] Cubic point groups: ['-43m','23','432','m-3','m-3m'] Tetragonal point groups: ['-4','-42m','-4m2','4','4/m','4/mmm','422','4mm'] +The point groups with an extra ``r`` at the end are trigonal point groups with rhombohedral axes. Trigonal point groups without that additional letter use the hexagonal coordinate system. + After having obtained a ``PointGroup``-object, it can be used for working with reflection data, more specifically :math:`hkl`-indices. It's possible to check whether two reflections are equivalent in a certain point group: .. testcode :: ExIsEquivalent diff --git a/Code/Mantid/docs/source/concepts/Properties_File.rst b/Code/Mantid/docs/source/concepts/PropertiesFile.rst similarity index 100% rename from Code/Mantid/docs/source/concepts/Properties_File.rst rename to Code/Mantid/docs/source/concepts/PropertiesFile.rst diff --git a/Code/Mantid/docs/source/concepts/RAW_File.rst b/Code/Mantid/docs/source/concepts/RAWFile.rst similarity index 99% rename from Code/Mantid/docs/source/concepts/RAW_File.rst rename to Code/Mantid/docs/source/concepts/RAWFile.rst index 1b917b56ab569d1b2059e9157abd3e1df3babe6c..b28f1a47b384ac9191111acae7a2428ade19465b 100644 --- a/Code/Mantid/docs/source/concepts/RAW_File.rst +++ b/Code/Mantid/docs/source/concepts/RAWFile.rst @@ -1,6 +1,6 @@ .. _RAW File: -RAW_File +RAW File ======== The RAW file format has been for many years the primary data format of diff --git a/Code/Mantid/docs/source/concepts/RectangularDetector.rst b/Code/Mantid/docs/source/concepts/RectangularDetector.rst index 99453e3a800eeb976686299007a4bee46ec8f0c3..c27036adf4a7f45e809a2910a71c063b3957cf08 100644 --- a/Code/Mantid/docs/source/concepts/RectangularDetector.rst +++ b/Code/Mantid/docs/source/concepts/RectangularDetector.rst @@ -1,7 +1,7 @@ .. _RectangularDetector: -RectangularDetector -=================== +Rectangular Detector +==================== The rectangular detector is a detector bank that is marked as being a regular rectangular bank. It is a particular class in Mantid (RectangularDetector). diff --git a/Code/Mantid/docs/source/concepts/SANS2D_Sample_IDF.rst b/Code/Mantid/docs/source/concepts/SANS2DSampleIDF.rst similarity index 99% rename from Code/Mantid/docs/source/concepts/SANS2D_Sample_IDF.rst rename to Code/Mantid/docs/source/concepts/SANS2DSampleIDF.rst index ae95060335dd6b920f72e74a4f730c33044ce866..0982fccd04039c82e6dba0f0583da98e6e0d2e9d 100644 --- a/Code/Mantid/docs/source/concepts/SANS2D_Sample_IDF.rst +++ b/Code/Mantid/docs/source/concepts/SANS2DSampleIDF.rst @@ -4,7 +4,7 @@ .. role:: xml(literal) :class: highlight -IDF-ISIS-SANS2D-annotated +IDF ISIS SANS2D annotated ========================= This page annotates the small angle scattering SANS2D IDF, with the purpose of (hopefully) quickly learn the basis of creating a similar IDF. diff --git a/Code/Mantid/docs/source/concepts/Shared_Pointer.rst b/Code/Mantid/docs/source/concepts/SharedPointer.rst similarity index 100% rename from Code/Mantid/docs/source/concepts/Shared_Pointer.rst rename to Code/Mantid/docs/source/concepts/SharedPointer.rst diff --git a/Code/Mantid/docs/source/concepts/Table_Workspaces.rst b/Code/Mantid/docs/source/concepts/TableWorkspaces.rst similarity index 100% rename from Code/Mantid/docs/source/concepts/Table_Workspaces.rst rename to Code/Mantid/docs/source/concepts/TableWorkspaces.rst diff --git a/Code/Mantid/docs/source/concepts/Unit_Factory.rst b/Code/Mantid/docs/source/concepts/UnitFactory.rst similarity index 99% rename from Code/Mantid/docs/source/concepts/Unit_Factory.rst rename to Code/Mantid/docs/source/concepts/UnitFactory.rst index 0dae6818787fe3b98874849562a59218a5a43c4d..9ab93a73903065006f7ac82c524852e4d65948ed 100644 --- a/Code/Mantid/docs/source/concepts/Unit_Factory.rst +++ b/Code/Mantid/docs/source/concepts/UnitFactory.rst @@ -1,6 +1,6 @@ .. _Unit Factory: -Unit_Factory +Unit Factory ============ What is it? diff --git a/Code/Mantid/docs/source/concepts/Using_XML_Schema.rst b/Code/Mantid/docs/source/concepts/UsingXMLSchema.rst similarity index 100% rename from Code/Mantid/docs/source/concepts/Using_XML_Schema.rst rename to Code/Mantid/docs/source/concepts/UsingXMLSchema.rst diff --git a/Code/Mantid/docs/source/concepts/Workflow_Algorithm.rst b/Code/Mantid/docs/source/concepts/WorkflowAlgorithm.rst similarity index 98% rename from Code/Mantid/docs/source/concepts/Workflow_Algorithm.rst rename to Code/Mantid/docs/source/concepts/WorkflowAlgorithm.rst index 0fdc680fa1f7eafeb29cb3987293806524b8260f..c7241d46bbdfd4bca610281e99c33d3e282f94c2 100644 --- a/Code/Mantid/docs/source/concepts/Workflow_Algorithm.rst +++ b/Code/Mantid/docs/source/concepts/WorkflowAlgorithm.rst @@ -1,6 +1,6 @@ .. _Workflow Algorithm: -Workflow_Algorithm +Workflow Algorithm ================== A workflow algorithm is a special subset of algorithms that perform diff --git a/Code/Mantid/docs/source/concepts/WorkspaceGroup.rst b/Code/Mantid/docs/source/concepts/WorkspaceGroup.rst index 7c095bcf14566161f0b99060cc49efdb233e96a3..467a65ceb38f59aa63850d477e11c0a8355b7aff 100644 --- a/Code/Mantid/docs/source/concepts/WorkspaceGroup.rst +++ b/Code/Mantid/docs/source/concepts/WorkspaceGroup.rst @@ -1,7 +1,7 @@ .. _WorkspaceGroup: -WorkspaceGroup -============== +Workspace Group +=============== A WorkspaceGroup is a group of workspaces. diff --git a/Code/Mantid/docs/source/fitfunctions/PawleyFunction.rst b/Code/Mantid/docs/source/fitfunctions/PawleyFunction.rst new file mode 100644 index 0000000000000000000000000000000000000000..f4b6333060230d39fb450710b9e144e16b6fd996 --- /dev/null +++ b/Code/Mantid/docs/source/fitfunctions/PawleyFunction.rst @@ -0,0 +1,20 @@ +.. _func-PawleyFunction: + +============== +PawleyFunction +============== + +.. index:: PawleyFunction + +Description +----------- + +The basic principle of fitting unit cell parameters to a complete powder diffraction pattern has been described by Pawley. Instead allowing each peak to have a freely selectable position, these positions are calculated as a result from the unit cell parameters. All other parameters of the peaks are refined independently. The implementation of the function differs from the method described in the paper in some points, for example the number of parameters can not change during the refinement (no reflections will be added or removed). + +Since the function requires special setup (assignment of HKLs, selection of crystal system and profile function), there is an algorithm that can perform a Pawley-type fit with different input data. Please see the documentation of :ref:`algm-PawleyFit` for details on how to use it. + +.. attributes:: + +.. properties:: + +.. categories:: diff --git a/Code/Mantid/docs/source/images/PawleyFitResultTheoreticalSilicon.png b/Code/Mantid/docs/source/images/PawleyFitResultTheoreticalSilicon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce92ee4e37bea1e5ef4ac39eafce559922ab41ed Binary files /dev/null and b/Code/Mantid/docs/source/images/PawleyFitResultTheoreticalSilicon.png differ diff --git a/Code/Mantid/docs/source/interfaces/Indirect_DataAnalysis.rst b/Code/Mantid/docs/source/interfaces/Indirect_DataAnalysis.rst index 2b86b909ba4edab24db00a8e9ca2bcdf11748c06..604af290896c8db370d5f459624f1e31f1f7b1e1 100644 --- a/Code/Mantid/docs/source/interfaces/Indirect_DataAnalysis.rst +++ b/Code/Mantid/docs/source/interfaces/Indirect_DataAnalysis.rst @@ -92,9 +92,9 @@ MSD Fit :widget: tabMSD Given either a saved NeXus file or workspace generated using the ElWin tab, this -tab fits :math:`log(intensity)` vs. :math:`Q2` with a straight line for each run -specified to give the Mean Square Displacement (MSD). It then plots the MSD as -function of run number. +tab fits :math:`log(intensity)` vs. :math:`Q^{2}` with a straight line for each +run specified to give the Mean Square Displacement (MSD). It then plots the MSD +as function of run number. MSDFit searches for the log files named <runnumber>_sample.txt in your chosen raw file directory (the name ‘sample’ is for OSIRIS). If they exist the @@ -103,7 +103,7 @@ exist the MSD is plotted versus run number (last 3 digits). The fitted parameters for all runs are in _msd_Table and the <u2> in _msd. To run the Sequential fit a workspace named <inst><first-run>_to_<last-run>_lnI is -created of :math:`ln(I)` v. :math:`Q2` for all runs. A contour or 3D plot of +created of :math:`ln(I)` v. :math:`Q^{2}` for all runs. A contour or 3D plot of this may be of interest. A sequential fit is run by clicking the Run button at the bottom of the tab, a @@ -144,7 +144,7 @@ Fury :widget: tabFury Given sample and resolution inputs, carries out a fit as per the theory detailed -below. +in the :ref:`TransformToIqt <algm-TransformToIqt>` algorithm. Options ~~~~~~~ @@ -194,76 +194,6 @@ ResolutionBins Number of bins in the resolution after rebinning, typically this should be at least 5 and a warning will be shown if it is less. -Theory -~~~~~~ - -The measured spectrum :math:`I(Q, \omega)` is proportional to the four -dimensional convolution of the scattering law :math:`S(Q, \omega)` with the -resolution function :math:`R(Q, \omega)` of the spectrometer via :math:`I(Q, -\omega) = S(Q, \omega) ⊗ R(Q, \omega)`, so :math:`S(Q, \omega)` can be obtained, -in principle, by a deconvolution in :math:`Q` and :math:`\omega`. The method -employed here is based on the Fourier Transform (FT) technique [6,7]. On Fourier -transforming the equation becomes :math:`I(Q, t) = S(Q, t) x R(Q, t)` where the -convolution in :math:`\omega`-space is replaced by a simple multiplication in -:math:`t`-space. The intermediate scattering law :math:`I(Q, t)` is then -obtained by simple division and the scattering law :math:`S(Q, \omega)` itself -can be obtained by back transformation. The latter however is full of pitfalls -for the unwary. The advantage of this technique over that of a fitting procedure -such as SWIFT is that a functional form for :math:`I(Q, t)` does not have to be -assumed. On IRIS the resolution function is close to a Lorentzian and the -scattering law is often in the form of one or more Lorentzians. The FT of a -Lorentzian is a decaying exponential, :math:`exp(-\alpha t)` , so that plots of -:math:`ln(I(Q, t))` against t would be straight lines thus making interpretation -easier. - -In general, the origin in energy for the sample run and the resolution run need -not necessarily be the same or indeed be exactly zero in the conversion of the -RAW data from time-of-flight to energy transfer. This will depend, for example, -on the sample and vanadium shapes and positions and whether the analyser -temperature has changed between the runs. The procedure takes this into account -automatically, without using an arbitrary fitting procedure, in the following -way. From the general properties of the FT, the transform of an offset -Lorentzian has the form :math:`(cos(\omega_{0}t) + isin(\omega_{0}t))exp(-\Gamma -t)` , thus taking the modulus produces the exponential :math:`exp(-\Gamma t)` -which is the required function. If this is carried out for both sample and -resolution, the difference in the energy origin is automatically removed. The -results of this procedure should however be treated with some caution when -applied to more complicated spectra in which it is possible for :math:`I(Q, t)` -to become negative, for example, when inelastic side peaks are comparable in -height to the elastic peak. - -The interpretation of the data must also take into account the propagation of -statistical errors (counting statistics) in the measured data as discussed by -Wild et al [1]. If the count in channel :math:`k` is :math:`X_{k}` , then -:math:`X_{k}=<X_{k}>+\Delta X_{k}` where :math:`<X_{k}>` is the mean value and -:math:`\Delta X_{k}` the error. The standard deviation for channel :math:`k` is -:math:`\sigma k` :math:`2=<\Delta X_{k}>2` which is assumed to be given by -:math:`\sigma k=<X_{k}>`. The FT of :math:`X_{k}` is defined by -:math:`X_{j}=<X_{j}>+\Delta X_{j}` and the real and imaginary parts denoted by -:math:`X_{j} I` and :math:`X_{j} I` respectively. The standard deviations on -:math:`X_{j}` are then given by :math:`\sigma 2(X_{j} R)=1/2 X0 R + 1/2 X2j R` -and :math:`\sigma 2(X_{j} I)=1/2 X0 I - 1/2 X2j I`. - -Note that :math:`\sigma 2(X_{0} R) = X_{0} R` and from the properties of FT -:math:`X_{0} R = X_{k}`. Thus the standard deviation of the first coefficient -of the FT is the square root of the integrated intensity of the spectrum. In -practice, apart from the first few coefficients, the error is nearly constant -and close to :math:`X_{0} R`. A further point to note is that the errors make -the imaginary part of :math:`I(Q, t)` non-zero and that, although these will be -distributed about zero, on taking the modulus of :math:`I(Q, t)`, they become -positive at all times and are distributed about a non-zero positive value. When -:math:`I(Q, t)` is plotted on a log-scale the size of the error bars increases -with time (coefficient) and for the resolution will reach a point where the -error on a coefficient is comparable to its value. This region must therefore be -treated with caution. For a true deconvolution by back transforming, the data -would be truncated to remove this poor region before back transforming. If the -truncation is severe the back transform may contain added ripples, so an -automatic back transform is not provided. - -References: - -1. U P Wild, R Holzwarth & H P Good, Rev Sci Instr 48 1621 (1977) - Fury Fit -------- diff --git a/Code/Mantid/docs/source/interfaces/Muon_ALC.rst b/Code/Mantid/docs/source/interfaces/Muon_ALC.rst new file mode 100644 index 0000000000000000000000000000000000000000..44496c7921e25d0e3fc4ea2c866ac87332169f62 --- /dev/null +++ b/Code/Mantid/docs/source/interfaces/Muon_ALC.rst @@ -0,0 +1,124 @@ +Muon ALC +======== + +.. contents:: Table of Contents + :local: + +Overview +-------- + +The Muon ALC interface, which is short for Avoided Level Crossing, aims at +handling frequent analysis on e.g. HIFI. It uses simple point-and-click to +analyse a sequence of datasets collected with different parameter values, for +instance different magnetic fields, temperature, etc, and study how this +affects asymmetry. There are currently three steps in the analysis. + +Data Loading +------------ + +The Data Loading step, provides an interface for the +:ref:`PlotAsymmetryByLogValue <algm-PlotAsymmetryByLogValue>` algorithm, +in which a sequence of runs are loaded through the fields +*First* and *Last*. All datasets with run number between these limits will be +loaded, and an error message will be shown if any of them is missing. The +user must supply the log data that will be used as X parameter from the list +of available log values. + +.. interface:: ALC + :widget: dataLoadingView + :align: center + :width: 800 + +Options +~~~~~~~ + +First + First run of the sequence of datasets. + +Last + Last run of the sequence of datasets. + +Log + Log value to use as X parameter + +Dead Time Correction + Type of dead time corrections to apply. Options are *None*, in which case no + corrections will be applied, *From Data File*, to load corrections from + the input dataset itself, or *From Custom File*, to load corrections from a + specified nexus file. + +Grouping + Detector grouping to apply. *Auto* will load the grouping information contained + in the run file, while *Custom* allows to specify the list of spectra for both the + forward and backward groups. + +Periods + Period number to use as red data. The *Subtract* option, if checked, allows to + select the green period number that will be subtracted to the red data. + +Calculation + Type of calculation, *Integral* or *Differential*, together with the time limits. + +? + Shows this help page. + +Load + Computes the asymmetry according to selected options and displays it against the + chosen log value. + +Baseline Modelling +------------------ + +In the Baseline Modelling step, the user can fit the baseline by selecting which +sections of the data should be used in the fit, and what the baseline fit +function should be. To select a baseline function, right-click on the *Function* +region, then *Add function* and choose among the different possibilities. Then +pick the desired fitting sections. + +.. interface:: ALC + :widget: baselineModellingView + :align: center + :width: 400 + +Options +~~~~~~~ + +Function + Right-click on the blank area to add a baseline function. + +Sections + Right-click on the blank area to add as many sections as needed to + select the ranges to fit. + +? + Shows this help page. + +Fit + Fits the data. + +Peak Fitting +------------ + +In the Peak Fitting step, data with the baseline subtracted are shown in +the right panel. The user can study the peaks of interest all with the same simple +interface. To add a new peak, right-click on the Peaks region, then select +*Add function* and choose among the different possibilities in the category Peak. + +.. interface:: ALC + :widget: peakFittingView + :align: center + :width: 600 + +Options +~~~~~~~ + +Peaks + Right-click on the blank area to add a peak function. + +? + Shows this help page. + +Fit + Fits the data. + +.. categories:: Interfaces Muon diff --git a/Code/Mantid/instrument/ALF_Definition.xml b/Code/Mantid/instrument/ALF_Definition.xml index 331f26d6a83d6e62b358c57cec515bdab2477f10..f9c2c35766952edb35428d9613ad15e9dacdead0 100644 --- a/Code/Mantid/instrument/ALF_Definition.xml +++ b/Code/Mantid/instrument/ALF_Definition.xml @@ -5,8 +5,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd" name="ALF" valid-from ="1900-01-31 23:59:59" - valid-to ="2100-01-31 23:59:59" - last-modified="2009-01-15 00:00:00"> + valid-to ="2015-03-16 23:59:59" + last-modified="2015-03-27 00:00:00"> <defaults> <length unit="meter"/> diff --git a/Code/Mantid/instrument/ALF_Definition_20130317-.xml b/Code/Mantid/instrument/ALF_Definition_20130317-.xml new file mode 100644 index 0000000000000000000000000000000000000000..034b567050c4302a4700d12d652fe2e0b40d5820 --- /dev/null +++ b/Code/Mantid/instrument/ALF_Definition_20130317-.xml @@ -0,0 +1,789 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- For help on the notation used to specify an Instrument Definition File + see http://www.mantidproject.org/IDF --> +<instrument xmlns="http://www.mantidproject.org/IDF/1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd" + name="ALF" valid-from ="2015-03-17 00:00:00" + valid-to ="2100-01-31 23:59:59" + last-modified="2015-03-27 00:00:00"> + + <defaults> + <length unit="meter"/> + <angle unit="degree"/> + <location r="0.0" t="0.0" p="0.0" ang="0.0" axis-x="0.0" axis-y="0.0" axis-z="1.0"/> + <reference-frame> + <!-- The z-axis is set parallel to and in the direction of the beam. the + y-axis points up and the coordinate system is right handed. --> + <along-beam axis="z"/> + <pointing-up axis="y"/> + <handedness val="right"/> + <origin val="beam" /> + </reference-frame> + <!-- Comment "components-are-facing" out if you dont want the + components defined in this file to face a position by default --> + <components-are-facing x="0.0" y="0.0" z="0.0" /> + <default-view view="cylindrical_y"/> + </defaults> + <!-- LIST OF PHYSICAL COMPONENTS (which the instrument consists of) --> + <!-- detector components --> + <properties> + </properties> + + <component type="monitors" idlist="monitors"> + <location/> + </component> +<!-- +<component type="ALFpack1" idlist="ALFpack1"> +<location /> +</component> +<component type="ALFpack2" idlist="ALFpack2"> +<location /> +</component> +<component type="ALFpack3" idlist="ALFpack3"> +<location /> +</component> --> +<component type="ALFdetectors" idlist="ALFdetectors"> +<location /> +</component> + +<!-- +<component type="ALFextratube1" idlist="ALFextratube1"> +<location /> +</component> +<component type="ALFextratube2" idlist="ALFextratube2"> +<location /> +</component> +--> +<!-- source and sample-position components --> + <component type="undulator"> + <location z="-14.9165"> <facing val="none"/> </location> + </component> + + <component type="nickel-holder"> + <location> <facing val="none"/> </location> + </component> + + <!-- DEFINITION OF TYPES --> + <!-- Source types --> + <type name="undulator" is="Source"> + <properties /> + <cylinder id="some-shape"> + <centre-of-bottom-base r="0.0" t="0.0" p="0.0" /> + <axis x="0.0" y="0.0" z="1.0" /> + <radius val="0.01" /> + <height val="0.03" /> + </cylinder> + <algebra val="some-shape" /> + </type> + + <!-- Sample-position types --> + <type name="nickel-holder" is="SamplePos"> + <properties /> + <sphere id="some-shape"> + <centre x="0.0" y="0.0" z="0.0" /> + <radius val="0.03" /> + </sphere> + <algebra val="some-shape" /> + </type> + + <!-- Detectors types --> + <type name="monitors"> + <component type="monitor"> + <location r="2.03" t="180.0" p="0.0" name="monitor1" /> + <location r="1.54" t="0.0" p="0.0" name="monitor2" /> + <location r="4.0" t="0.0" p="0.0" name="monitor3" /> + </component> + </type> + +<type name="ALFdetectors"> + <component type="ALF24tubes"> +<location x="0.7309 " z=" 1.3328 "> <facing x="0" y="0" z="0"/> </location> + </component> + </type> + +<!-- <type name="ALFpack1"> + <component type="ALFpack"> +<location x="0.52833 " z=" 1.4252 "> <facing x="0" y="0" z="0"/> </location> + </component> + </type> +<type name="ALFpack2"> + <component type="ALFpack"> +<location x="0.7309 " z=" 1.3328 "> <facing x="0" y="0" z="0"/> </location> + </component> + </type> +<type name="ALFpack3"> + <component type="ALFpack"> +<location x="0.91857 " z=" 1.21105 "> <facing x="0" y="0" z="0"/> </location> + </component> + </type> --> +<!-- +<type name="ALFextratube1"> + <component type="ALFtube"> +<location x="1.52 " z=" -0.0200 "> <facing x="0" y="0" z="0"/> </location> + </component> + </type> +<type name="ALFextratube2"> + <component type="ALFtube"> +<location x="1.52 " z=" 0.0200 "> <facing x="0" y="0" z="0"/> </location> + </component> + </type> +--> + + <type name="ALF24tubes"> + <properties /> + <component type="ALFtube" > +<location x=" -0.3220 " z=" 0.00000" name="tube1" /> +<location x=" -0.2940 " z=" 0.00000" name="tube2" /> +<location x=" -0.2660 " z=" 0.00000" name="tube3" /> +<location x=" -0.2380 " z=" 0.00000" name="tube4" /> +<location x=" -0.2100 " z=" 0.00000" name="tube5" /> +<location x=" -0.1820 " z=" 0.00000" name="tube6" /> +<location x=" -0.1540 " z=" 0.00000" name="tube7" /> +<location x=" -0.1260 " z=" 0.00000" name="tube8" /> +<location x=" -0.0980 " z=" 0.00000" name="tube9" /> +<location x=" -0.0700 " z=" 0.00000" name="tube10" /> +<location x=" -0.0420 " z=" 0.00000" name="tube11" /> +<location x=" -0.0140 " z=" 0.00000" name="tube12" /> +<location x=" 0.01400 " z=" 0.00000" name="tube13" /> +<location x=" 0.04200 " z=" 0.00000" name="tube14" /> +<location x=" 0.07000 " z=" 0.00000" name="tube15" /> +<location x=" 0.09800 " z=" 0.00000" name="tube16" /> +<location x=" 0.12600 " z=" 0.00000" name="tube17" /> +<location x=" 0.15400 " z=" 0.00000" name="tube18" /> +<location x=" 0.18200 " z=" 0.00000" name="tube19" /> +<location x=" 0.21000 " z=" 0.00000" name="tube20" /> +<location x=" 0.23800 " z=" 0.00000" name="tube21" /> +<location x=" 0.26600 " z=" 0.00000" name="tube22" /> +<location x=" 0.29400 " z=" 0.00000" name="tube23" /> +<location x=" 0.32200 " z=" 0.00000" name="tube24" /> + + </component> + </type> + +<!-- + <type name="ALFpack"> + <properties /> + <component type="ALFtube" > +<location x=" -0.0980 " z=" 0.00000" name="tube1" /> +<location x=" -0.0700 " z=" 0.00000" name="tube2" /> +<location x=" -0.0420 " z=" 0.00000" name="tube3" /> +<location x=" -0.0140 " z=" 0.00000" name="tube4" /> +<location x=" 0.01400 " z=" 0.00000" name="tube5" /> +<location x=" 0.04200 " z=" 0.00000" name="tube6" /> +<location x=" 0.07000 " z=" 0.00000" name="tube7" /> +<location x=" 0.09800 " z=" 0.00000" name="tube8" /> + </component> + </type> --> + +<type name="ALFtube" outline="yes"> + <component type="pixel"> +<location y=" -0.498047" /> +<location y=" -0.496094" /> +<location y=" -0.494141" /> +<location y=" -0.492188" /> +<location y=" -0.490234" /> +<location y=" -0.488281" /> +<location y=" -0.486328" /> +<location y=" -0.484375" /> +<location y=" -0.482422" /> +<location y=" -0.480469" /> +<location y=" -0.478516" /> +<location y=" -0.476563" /> +<location y=" -0.474609" /> +<location y=" -0.472656" /> +<location y=" -0.470703" /> +<location y=" -0.468750" /> +<location y=" -0.466797" /> +<location y=" -0.464844" /> +<location y=" -0.462891" /> +<location y=" -0.460938" /> +<location y=" -0.458984" /> +<location y=" -0.457031" /> +<location y=" -0.455078" /> +<location y=" -0.453125" /> +<location y=" -0.451172" /> +<location y=" -0.449219" /> +<location y=" -0.447266" /> +<location y=" -0.445313" /> +<location y=" -0.443359" /> +<location y=" -0.441406" /> +<location y=" -0.439453" /> +<location y=" -0.437500" /> +<location y=" -0.435547" /> +<location y=" -0.433594" /> +<location y=" -0.431641" /> +<location y=" -0.429688" /> +<location y=" -0.427734" /> +<location y=" -0.425781" /> +<location y=" -0.423828" /> +<location y=" -0.421875" /> +<location y=" -0.419922" /> +<location y=" -0.417969" /> +<location y=" -0.416016" /> +<location y=" -0.414063" /> +<location y=" -0.412109" /> +<location y=" -0.410156" /> +<location y=" -0.408203" /> +<location y=" -0.406250" /> +<location y=" -0.404297" /> +<location y=" -0.402344" /> +<location y=" -0.400391" /> +<location y=" -0.398438" /> +<location y=" -0.396484" /> +<location y=" -0.394531" /> +<location y=" -0.392578" /> +<location y=" -0.390625" /> +<location y=" -0.388672" /> +<location y=" -0.386719" /> +<location y=" -0.384766" /> +<location y=" -0.382813" /> +<location y=" -0.380859" /> +<location y=" -0.378906" /> +<location y=" -0.376953" /> +<location y=" -0.375000" /> +<location y=" -0.373047" /> +<location y=" -0.371094" /> +<location y=" -0.369141" /> +<location y=" -0.367188" /> +<location y=" -0.365234" /> +<location y=" -0.363281" /> +<location y=" -0.361328" /> +<location y=" -0.359375" /> +<location y=" -0.357422" /> +<location y=" -0.355469" /> +<location y=" -0.353516" /> +<location y=" -0.351563" /> +<location y=" -0.349609" /> +<location y=" -0.347656" /> +<location y=" -0.345703" /> +<location y=" -0.343750" /> +<location y=" -0.341797" /> +<location y=" -0.339844" /> +<location y=" -0.337891" /> +<location y=" -0.335938" /> +<location y=" -0.333984" /> +<location y=" -0.332031" /> +<location y=" -0.330078" /> +<location y=" -0.328125" /> +<location y=" -0.326172" /> +<location y=" -0.324219" /> +<location y=" -0.322266" /> +<location y=" -0.320313" /> +<location y=" -0.318359" /> +<location y=" -0.316406" /> +<location y=" -0.314453" /> +<location y=" -0.312500" /> +<location y=" -0.310547" /> +<location y=" -0.308594" /> +<location y=" -0.306641" /> +<location y=" -0.304688" /> +<location y=" -0.302734" /> +<location y=" -0.300781" /> +<location y=" -0.298828" /> +<location y=" -0.296875" /> +<location y=" -0.294922" /> +<location y=" -0.292969" /> +<location y=" -0.291016" /> +<location y=" -0.289063" /> +<location y=" -0.287109" /> +<location y=" -0.285156" /> +<location y=" -0.283203" /> +<location y=" -0.281250" /> +<location y=" -0.279297" /> +<location y=" -0.277344" /> +<location y=" -0.275391" /> +<location y=" -0.273438" /> +<location y=" -0.271484" /> +<location y=" -0.269531" /> +<location y=" -0.267578" /> +<location y=" -0.265625" /> +<location y=" -0.263672" /> +<location y=" -0.261719" /> +<location y=" -0.259766" /> +<location y=" -0.257813" /> +<location y=" -0.255859" /> +<location y=" -0.253906" /> +<location y=" -0.251953" /> +<location y=" -0.250000" /> +<location y=" -0.248047" /> +<location y=" -0.246094" /> +<location y=" -0.244141" /> +<location y=" -0.242188" /> +<location y=" -0.240234" /> +<location y=" -0.238281" /> +<location y=" -0.236328" /> +<location y=" -0.234375" /> +<location y=" -0.232422" /> +<location y=" -0.230469" /> +<location y=" -0.228516" /> +<location y=" -0.226563" /> +<location y=" -0.224609" /> +<location y=" -0.222656" /> +<location y=" -0.220703" /> +<location y=" -0.218750" /> +<location y=" -0.216797" /> +<location y=" -0.214844" /> +<location y=" -0.212891" /> +<location y=" -0.210938" /> +<location y=" -0.208984" /> +<location y=" -0.207031" /> +<location y=" -0.205078" /> +<location y=" -0.203125" /> +<location y=" -0.201172" /> +<location y=" -0.199219" /> +<location y=" -0.197266" /> +<location y=" -0.195313" /> +<location y=" -0.193359" /> +<location y=" -0.191406" /> +<location y=" -0.189453" /> +<location y=" -0.187500" /> +<location y=" -0.185547" /> +<location y=" -0.183594" /> +<location y=" -0.181641" /> +<location y=" -0.179688" /> +<location y=" -0.177734" /> +<location y=" -0.175781" /> +<location y=" -0.173828" /> +<location y=" -0.171875" /> +<location y=" -0.169922" /> +<location y=" -0.167969" /> +<location y=" -0.166016" /> +<location y=" -0.164063" /> +<location y=" -0.162109" /> +<location y=" -0.160156" /> +<location y=" -0.158203" /> +<location y=" -0.156250" /> +<location y=" -0.154297" /> +<location y=" -0.152344" /> +<location y=" -0.150391" /> +<location y=" -0.148438" /> +<location y=" -0.146484" /> +<location y=" -0.144531" /> +<location y=" -0.142578" /> +<location y=" -0.140625" /> +<location y=" -0.138672" /> +<location y=" -0.136719" /> +<location y=" -0.134766" /> +<location y=" -0.132813" /> +<location y=" -0.130859" /> +<location y=" -0.128906" /> +<location y=" -0.126953" /> +<location y=" -0.125000" /> +<location y=" -0.123047" /> +<location y=" -0.121094" /> +<location y=" -0.119141" /> +<location y=" -0.117188" /> +<location y=" -0.115234" /> +<location y=" -0.113281" /> +<location y=" -0.111328" /> +<location y=" -0.109375" /> +<location y=" -0.107422" /> +<location y=" -0.105469" /> +<location y=" -0.103516" /> +<location y=" -0.101563" /> +<location y=" -0.099609" /> +<location y=" -0.097656" /> +<location y=" -0.095703" /> +<location y=" -0.093750" /> +<location y=" -0.091797" /> +<location y=" -0.089844" /> +<location y=" -0.087891" /> +<location y=" -0.085938" /> +<location y=" -0.083984" /> +<location y=" -0.082031" /> +<location y=" -0.080078" /> +<location y=" -0.078125" /> +<location y=" -0.076172" /> +<location y=" -0.074219" /> +<location y=" -0.072266" /> +<location y=" -0.070313" /> +<location y=" -0.068359" /> +<location y=" -0.066406" /> +<location y=" -0.064453" /> +<location y=" -0.062500" /> +<location y=" -0.060547" /> +<location y=" -0.058594" /> +<location y=" -0.056641" /> +<location y=" -0.054688" /> +<location y=" -0.052734" /> +<location y=" -0.050781" /> +<location y=" -0.048828" /> +<location y=" -0.046875" /> +<location y=" -0.044922" /> +<location y=" -0.042969" /> +<location y=" -0.041016" /> +<location y=" -0.039063" /> +<location y=" -0.037109" /> +<location y=" -0.035156" /> +<location y=" -0.033203" /> +<location y=" -0.031250" /> +<location y=" -0.029297" /> +<location y=" -0.027344" /> +<location y=" -0.025391" /> +<location y=" -0.023438" /> +<location y=" -0.021484" /> +<location y=" -0.019531" /> +<location y=" -0.017578" /> +<location y=" -0.015625" /> +<location y=" -0.013672" /> +<location y=" -0.011719" /> +<location y=" -0.009766" /> +<location y=" -0.007812" /> +<location y=" -0.005859" /> +<location y=" -0.003906" /> +<location y=" -0.001953" /> +<location y=" 0.000000" /> +<location y=" 0.001953" /> +<location y=" 0.003906" /> +<location y=" 0.005859" /> +<location y=" 0.007813" /> +<location y=" 0.009766" /> +<location y=" 0.011719" /> +<location y=" 0.013672" /> +<location y=" 0.015625" /> +<location y=" 0.017578" /> +<location y=" 0.019531" /> +<location y=" 0.021484" /> +<location y=" 0.023438" /> +<location y=" 0.025391" /> +<location y=" 0.027344" /> +<location y=" 0.029297" /> +<location y=" 0.031250" /> +<location y=" 0.033203" /> +<location y=" 0.035156" /> +<location y=" 0.037109" /> +<location y=" 0.039063" /> +<location y=" 0.041016" /> +<location y=" 0.042969" /> +<location y=" 0.044922" /> +<location y=" 0.046875" /> +<location y=" 0.048828" /> +<location y=" 0.050781" /> +<location y=" 0.052734" /> +<location y=" 0.054688" /> +<location y=" 0.056641" /> +<location y=" 0.058594" /> +<location y=" 0.060547" /> +<location y=" 0.062500" /> +<location y=" 0.064453" /> +<location y=" 0.066406" /> +<location y=" 0.068359" /> +<location y=" 0.070313" /> +<location y=" 0.072266" /> +<location y=" 0.074219" /> +<location y=" 0.076172" /> +<location y=" 0.078125" /> +<location y=" 0.080078" /> +<location y=" 0.082031" /> +<location y=" 0.083984" /> +<location y=" 0.085938" /> +<location y=" 0.087891" /> +<location y=" 0.089844" /> +<location y=" 0.091797" /> +<location y=" 0.093750" /> +<location y=" 0.095703" /> +<location y=" 0.097656" /> +<location y=" 0.099609" /> +<location y=" 0.101563" /> +<location y=" 0.103516" /> +<location y=" 0.105469" /> +<location y=" 0.107422" /> +<location y=" 0.109375" /> +<location y=" 0.111328" /> +<location y=" 0.113281" /> +<location y=" 0.115234" /> +<location y=" 0.117188" /> +<location y=" 0.119141" /> +<location y=" 0.121094" /> +<location y=" 0.123047" /> +<location y=" 0.125000" /> +<location y=" 0.126953" /> +<location y=" 0.128906" /> +<location y=" 0.130859" /> +<location y=" 0.132813" /> +<location y=" 0.134766" /> +<location y=" 0.136719" /> +<location y=" 0.138672" /> +<location y=" 0.140625" /> +<location y=" 0.142578" /> +<location y=" 0.144531" /> +<location y=" 0.146484" /> +<location y=" 0.148438" /> +<location y=" 0.150391" /> +<location y=" 0.152344" /> +<location y=" 0.154297" /> +<location y=" 0.156250" /> +<location y=" 0.158203" /> +<location y=" 0.160156" /> +<location y=" 0.162109" /> +<location y=" 0.164063" /> +<location y=" 0.166016" /> +<location y=" 0.167969" /> +<location y=" 0.169922" /> +<location y=" 0.171875" /> +<location y=" 0.173828" /> +<location y=" 0.175781" /> +<location y=" 0.177734" /> +<location y=" 0.179688" /> +<location y=" 0.181641" /> +<location y=" 0.183594" /> +<location y=" 0.185547" /> +<location y=" 0.187500" /> +<location y=" 0.189453" /> +<location y=" 0.191406" /> +<location y=" 0.193359" /> +<location y=" 0.195313" /> +<location y=" 0.197266" /> +<location y=" 0.199219" /> +<location y=" 0.201172" /> +<location y=" 0.203125" /> +<location y=" 0.205078" /> +<location y=" 0.207031" /> +<location y=" 0.208984" /> +<location y=" 0.210938" /> +<location y=" 0.212891" /> +<location y=" 0.214844" /> +<location y=" 0.216797" /> +<location y=" 0.218750" /> +<location y=" 0.220703" /> +<location y=" 0.222656" /> +<location y=" 0.224609" /> +<location y=" 0.226563" /> +<location y=" 0.228516" /> +<location y=" 0.230469" /> +<location y=" 0.232422" /> +<location y=" 0.234375" /> +<location y=" 0.236328" /> +<location y=" 0.238281" /> +<location y=" 0.240234" /> +<location y=" 0.242188" /> +<location y=" 0.244141" /> +<location y=" 0.246094" /> +<location y=" 0.248047" /> +<location y=" 0.250000" /> +<location y=" 0.251953" /> +<location y=" 0.253906" /> +<location y=" 0.255859" /> +<location y=" 0.257813" /> +<location y=" 0.259766" /> +<location y=" 0.261719" /> +<location y=" 0.263672" /> +<location y=" 0.265625" /> +<location y=" 0.267578" /> +<location y=" 0.269531" /> +<location y=" 0.271484" /> +<location y=" 0.273438" /> +<location y=" 0.275391" /> +<location y=" 0.277344" /> +<location y=" 0.279297" /> +<location y=" 0.281250" /> +<location y=" 0.283203" /> +<location y=" 0.285156" /> +<location y=" 0.287109" /> +<location y=" 0.289063" /> +<location y=" 0.291016" /> +<location y=" 0.292969" /> +<location y=" 0.294922" /> +<location y=" 0.296875" /> +<location y=" 0.298828" /> +<location y=" 0.300781" /> +<location y=" 0.302734" /> +<location y=" 0.304688" /> +<location y=" 0.306641" /> +<location y=" 0.308594" /> +<location y=" 0.310547" /> +<location y=" 0.312500" /> +<location y=" 0.314453" /> +<location y=" 0.316406" /> +<location y=" 0.318359" /> +<location y=" 0.320313" /> +<location y=" 0.322266" /> +<location y=" 0.324219" /> +<location y=" 0.326172" /> +<location y=" 0.328125" /> +<location y=" 0.330078" /> +<location y=" 0.332031" /> +<location y=" 0.333984" /> +<location y=" 0.335938" /> +<location y=" 0.337891" /> +<location y=" 0.339844" /> +<location y=" 0.341797" /> +<location y=" 0.343750" /> +<location y=" 0.345703" /> +<location y=" 0.347656" /> +<location y=" 0.349609" /> +<location y=" 0.351563" /> +<location y=" 0.353516" /> +<location y=" 0.355469" /> +<location y=" 0.357422" /> +<location y=" 0.359375" /> +<location y=" 0.361328" /> +<location y=" 0.363281" /> +<location y=" 0.365234" /> +<location y=" 0.367188" /> +<location y=" 0.369141" /> +<location y=" 0.371094" /> +<location y=" 0.373047" /> +<location y=" 0.375000" /> +<location y=" 0.376953" /> +<location y=" 0.378906" /> +<location y=" 0.380859" /> +<location y=" 0.382813" /> +<location y=" 0.384766" /> +<location y=" 0.386719" /> +<location y=" 0.388672" /> +<location y=" 0.390625" /> +<location y=" 0.392578" /> +<location y=" 0.394531" /> +<location y=" 0.396484" /> +<location y=" 0.398438" /> +<location y=" 0.400391" /> +<location y=" 0.402344" /> +<location y=" 0.404297" /> +<location y=" 0.406250" /> +<location y=" 0.408203" /> +<location y=" 0.410156" /> +<location y=" 0.412109" /> +<location y=" 0.414063" /> +<location y=" 0.416016" /> +<location y=" 0.417969" /> +<location y=" 0.419922" /> +<location y=" 0.421875" /> +<location y=" 0.423828" /> +<location y=" 0.425781" /> +<location y=" 0.427734" /> +<location y=" 0.429688" /> +<location y=" 0.431641" /> +<location y=" 0.433594" /> +<location y=" 0.435547" /> +<location y=" 0.437500" /> +<location y=" 0.439453" /> +<location y=" 0.441406" /> +<location y=" 0.443359" /> +<location y=" 0.445313" /> +<location y=" 0.447266" /> +<location y=" 0.449219" /> +<location y=" 0.451172" /> +<location y=" 0.453125" /> +<location y=" 0.455078" /> +<location y=" 0.457031" /> +<location y=" 0.458984" /> +<location y=" 0.460938" /> +<location y=" 0.462891" /> +<location y=" 0.464844" /> +<location y=" 0.466797" /> +<location y=" 0.468750" /> +<location y=" 0.470703" /> +<location y=" 0.472656" /> +<location y=" 0.474609" /> +<location y=" 0.476563" /> +<location y=" 0.478516" /> +<location y=" 0.480469" /> +<location y=" 0.482422" /> +<location y=" 0.484375" /> +<location y=" 0.486328" /> +<location y=" 0.488281" /> +<location y=" 0.490234" /> +<location y=" 0.492188" /> +<location y=" 0.494141" /> +<location y=" 0.496094" /> +<location y=" 0.498047" /> +<location y=" 0.500000" /> + </component> + </type> + + <type name="monitor" is="monitor"> + <properties/> + <cylinder id="some-shape"> + <centre-of-bottom-base r="0.0" t="0.0" p="0.0" /> + <axis x="0.0" y="0.0" z="1.0" /> + <radius val="0.01" /> + <height val="0.03" /> + </cylinder> + <algebra val="some-shape" /> + </type> + + <type name="pixel" is="detector"> + <cylinder id="cyl-approx"> + <centre-of-bottom-base r="0.0" t="0.0" p="0.0" /> + <axis x="0.0" y="0.2" z="0.0" /> + <radius val="0.0127" /> + <height val=" 0.002" /> + </cylinder> + <algebra val="cyl-approx" /> + </type> + + + +<!-- MONITOR ID LISTS --> + <idlist idname="monitors"> + <id start="1" end="3" /> + </idlist> + <!-- DETECTOR ID LISTS --> + <idlist idname="ALFdetectors"> + <id start="3103000" end="3103511" /> + <id start="3105000" end="3105511" /> + <id start="3109000" end="3109511" /> + <id start="3111000" end="3111511" /> + <id start="3113000" end="3113511" /> + <id start="3115000" end="3115511" /> + <id start="3119000" end="3119511" /> + <id start="3121000" end="3121511" /> + <id start="3203000" end="3203511" /> + <id start="3205000" end="3205511" /> + <id start="3209000" end="3209511" /> + <id start="3211000" end="3211511" /> + <id start="3213000" end="3213511" /> + <id start="3215000" end="3215511" /> + <id start="3219000" end="3219511" /> + <id start="3221000" end="3221511" /> + <id start="3303000" end="3303511" /> + <id start="3305000" end="3305511" /> + <id start="3309000" end="3309511" /> + <id start="3311000" end="3311511" /> + <id start="3313000" end="3313511" /> + <id start="3315000" end="3315511" /> + <id start="3319000" end="3319511" /> + <id start="3321000" end="3321511" /> + </idlist> + +<!-- <idlist idname="ALFpack1"> + <id start="1" end="256" /> + <id start="257" end="512" /> + <id start="513" end="768" /> + <id start="769" end="1024" /> + <id start="1025" end="1280" /> + <id start="1281" end="1536" /> + <id start="1537" end="1792" /> + <id start="1793" end="2048" /> + </idlist> + <idlist idname="ALFpack2"> + <id start="2049" end="2304" /> + <id start="2305" end="2560" /> + <id start="2561" end="2816" /> + <id start="2817" end="3072" /> + <id start="3073" end="3328" /> + <id start="3329" end="3584" /> + <id start="3585" end="3840" /> + <id start="3841" end="4096" /> + </idlist> + <idlist idname="ALFpack3"> + <id start="4097" end="4352" /> + <id start="4353" end="4608" /> + <id start="4609" end="4864" /> + <id start="4865" end="5120" /> + <id start="5121" end="5376" /> + <id start="5377" end="5632" /> + <id start="5633" end="5888" /> + <id start="5889" end="6144" /> + </idlist> --> +<!-- + <idlist idname="ALFextratube1"> + <id start="6145" end="6400" /> + </idlist> + <idlist idname="ALFextratube2"> + <id start="6401" end="6656" /> + </idlist> +--> +</instrument> diff --git a/Code/Mantid/instrument/DNS_Definition_PAonly.xml b/Code/Mantid/instrument/DNS_Definition_PAonly.xml new file mode 100644 index 0000000000000000000000000000000000000000..b9949f4781afadaf90bf51091f12d43616b2b0cd --- /dev/null +++ b/Code/Mantid/instrument/DNS_Definition_PAonly.xml @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- For help on the notation used to specify an Instrument Definition File see http://www.mantidproject.org/IDF --> +<instrument name="DNS" valid-from="1900-01-31 23:59:59" valid-to="2100-01-31 23:59:59" last-modified="2015-03-25 10:17:17"> + <!-- Author: m.ganeva@fz-juelich.de --> + <defaults> + <length unit="meter" /> + <angle unit="degree" /> + <reference-frame> + <!-- The z-axis is set parallel to and in the direction of the beam. the + y-axis points up and the coordinate system is right handed. --> + <along-beam axis="z" /> + <pointing-up axis="y" /> + <handedness val="right" /> + </reference-frame> + </defaults> + <!-- moderator --> + <component type="moderator"> + <location z="-2.27" /> + </component> + <type name="moderator" is="Source"></type> + <!-- monitor --> + <component type="monitor" idlist="monitor"> + <location z="-0.229" /> + </component> + <type name="monitor" is="monitor"></type> + <idlist idname="monitor"> + <id val="-1"/> + </idlist> + <!-- Sample position --> + <component type="sample-position"> + <location y="0.0" x="0.0" z="0.0" /> + </component> + <type name="sample-position" is="SamplePos" /> + <idlist idname="detectors"> + <id start="1" end="24" /> + </idlist> + <!-- Detector list def --> + <component type="detectors" idlist="detectors"> + <location /> + </component> + <!-- Detector Banks --> + <type name="detectors"> + <component type="bank0"> + <location> + <parameter name="r-position"> + <value val="0"/> + </parameter> + <parameter name="t-position"> + <logfile id="deterota" eq="0.0+value" extract-single-value-as="first_value"/> + </parameter> + <parameter name="p-position"> + <value val="0"/> + </parameter> + <parameter name="rotx"> + <value val="0"/> + </parameter> + <parameter name="roty"> + <logfile id="deterota" eq="0.0+value" extract-single-value-as="first_value"/> + </parameter> + <parameter name="rotz"> + <value val="0"/> + </parameter> + </location> + </component> + </type> + <!-- Definition of the PA detector bank (made of 24 tubes) --> + <type name="bank0"> + <component type="standard_tube"> + <locations r="0.800000" t="0.000000" t-end="-115.0" p="0.0" name="tube_" n-elements="24" /> + </component> + </type> + <!-- Definition of standard_tube --> + <type name="standard_tube"> + <component type="standard_pixel"> + <location y="0.0" /> + </component> + </type> + <type name="standard_pixel" is="detector"> + <cylinder id="shape"> + <centre-of-bottom-base x="0.0" y="-0.075" z="0.0" /> + <axis x="0.0" y="1.0" z="0.0" /> + <radius val="0.0127" /> + <height val=".15" /> + </cylinder> + <algebra val="shape" /> + </type> +</instrument> diff --git a/Code/Mantid/instrument/Facilities.xml b/Code/Mantid/instrument/Facilities.xml index 5b7c6c8b41a29ad5343a1cd3314291b9d4703f2c..1213adaf37862f103db1ccae6db21105283eec1a 100644 --- a/Code/Mantid/instrument/Facilities.xml +++ b/Code/Mantid/instrument/Facilities.xml @@ -6,7 +6,7 @@ <archiveSearch plugin="ISISDataSearch" /> </archive> - <computeResource name="SCARF@STFC"> + <computeResource name="SCARF@STFC" JobManagerType="SCARFLSFJobManager"> <baseURL>https://portal.scarf.rl.ac.uk</baseURL> </computeResource> diff --git a/Code/Mantid/instrument/LET_Parameters_dr2to12.xml b/Code/Mantid/instrument/LET_Parameters_dr2to12.xml index 299501ef862dd8cd02e6e2c7b9f5abc33ee6a673..0404c64a28b719a95c9017711d82d3399a5573ba 100644 --- a/Code/Mantid/instrument/LET_Parameters_dr2to12.xml +++ b/Code/Mantid/instrument/LET_Parameters_dr2to12.xml @@ -128,7 +128,7 @@ These detectors locations are used to identify TOF range, contributing into each energy range in multirep mode --> <parameter name="multirep_tof_specta_list" type="string"> - <value val="12416,21761"/> + <value val="1,128"/> </parameter> diff --git a/Code/Mantid/instrument/MAPS_Definition.xml b/Code/Mantid/instrument/MAPS_Definition.xml index 5bef2b032e4eb8cd001902eace891e0d78747a31..5945f1ff1bdb314b8188dd48326e052f114087e9 100644 --- a/Code/Mantid/instrument/MAPS_Definition.xml +++ b/Code/Mantid/instrument/MAPS_Definition.xml @@ -6,7 +6,7 @@ xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd" name="MAPS" valid-from ="1900-01-31 23:59:59" valid-to ="2100-01-31 23:59:59" - last-modified="2011-09-30 13:30:00"> + last-modified="2015-03-01 13:30:00"> <defaults> <length unit="meter"/> diff --git a/Code/Mantid/instrument/MAPS_Parameters.xml b/Code/Mantid/instrument/MAPS_Parameters.xml index 0e961f2d2e597dab1ada0b56388b229a47b48e5b..eabd02d8f5eae12c97d3e45520699193ed0e5637 100644 --- a/Code/Mantid/instrument/MAPS_Parameters.xml +++ b/Code/Mantid/instrument/MAPS_Parameters.xml @@ -391,7 +391,7 @@ </parameter> <!-- The semicolon separated list of possible log names, containing information on crystl rotation. - First found log will be used togethere with motor_offset to identify crystal rotation + First found log will be used togethere with motor_offset to identify crystal rotation (psi in Horace) --> <parameter name="motor_log_names" type="string"> <value val="wccr;Rot"/> diff --git a/Code/Mantid/instrument/MARI_Definition.xml b/Code/Mantid/instrument/MARI_Definition.xml index 8f4aa117c1733876e4a94839a840e5107ae35916..b4e2f79bd9885fc25b5748eda3987589331b13b5 100644 --- a/Code/Mantid/instrument/MARI_Definition.xml +++ b/Code/Mantid/instrument/MARI_Definition.xml @@ -6,7 +6,7 @@ xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd" name="MARI" valid-from ="1900-01-31 23:59:59" valid-to ="2100-01-31 23:59:59" - last-modified="2009-09-15 00:00:00"> + last-modified="2015-03-01 00:00:00"> <defaults> <length unit="meter"/> @@ -45,6 +45,12 @@ <component type="fermi-chopper"> <location y="-0.1" z="-1.689" /> + <parameter name="Speed (Hz)"> + <logfile id="fermi_speed" extract-single-value-as="last_value" /> + </parameter> + <parameter name="Delay (us)"> + <logfile id="fermi_delay" extract-single-value-as="last_value" /> + </parameter> </component> <type name="fermi-chopper" is="chopper"> <cylinder id="body"> @@ -57,6 +63,9 @@ <component type="disc-chopper"> <location y="-0.18" z="-3.0" /> + <parameter name="Speed (Hz)"> + <logfile id="diskchopper" extract-single-value-as="last_value" /> + </parameter> </component> <type name="disc-chopper" is="chopper"> <cylinder id="body"> diff --git a/Code/Mantid/instrument/MERLIN_Definition_after2013_4.xml b/Code/Mantid/instrument/MERLIN_Definition_after2013_4.xml index c87581b895a84e9531eb4ab767201b35af1b6856..fd69107e5c7fdd2600996cd426f5dfb5fb84af57 100644 --- a/Code/Mantid/instrument/MERLIN_Definition_after2013_4.xml +++ b/Code/Mantid/instrument/MERLIN_Definition_after2013_4.xml @@ -6,7 +6,7 @@ xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd" name="MERLIN" valid-from ="2014-02-10 00:00:01" valid-to ="2100-01-31 23:59:59" - last-modified="2012-03-19 12:00:05"> + last-modified="2015-03-01 12:00:05"> <defaults> <length unit="meter"/> @@ -27,7 +27,7 @@ The data for Merlin was obtained from Robert Bewley. 2012-05-17 - added names to tubes - 2013-11-14 - use locations tag in tube definitions + 2013-11-14 - use locations tag in tube definitions --> diff --git a/Code/Mantid/instrument/REF_L_Parameters.xml b/Code/Mantid/instrument/REF_L_Parameters.xml index 5330d332c4f81a91dd8e8d8ce9444fbc1818f2cc..3cf57dceaa4527d091fd18e99b4836aa9354c073 100644 --- a/Code/Mantid/instrument/REF_L_Parameters.xml +++ b/Code/Mantid/instrument/REF_L_Parameters.xml @@ -1,17 +1,17 @@ <?xml version="1.0" encoding="UTF-8" ?> -<parameter-file instrument = "REF" valid-from="2011-12-08 11:36:21.935542" valid-to="2100-01-31 23:59:59"> +<parameter-file instrument = "REF_L" valid-from="2011-12-08 11:36:21.935542" valid-to="2014-10-10 00:00:01"> - <component-link name = "REF"> - - <parameter name="number-of-x-pixels"> - <value val="304"/> - </parameter> - - <parameter name="number-of-y-pixels"> - <value val="256"/> - </parameter> - - </component-link> + <component-link name = "REF_L"> + + <parameter name="number-of-x-pixels"> + <value val="304"/> + </parameter> + + <parameter name="number-of-y-pixels"> + <value val="256"/> + </parameter> + +</component-link> </parameter-file> diff --git a/Code/Mantid/instrument/REF_L_Parameters_after_10102014.xml b/Code/Mantid/instrument/REF_L_Parameters_after_10102014.xml new file mode 100644 index 0000000000000000000000000000000000000000..b6884401adb429e9e610a3208462b54f5aa09336 --- /dev/null +++ b/Code/Mantid/instrument/REF_L_Parameters_after_10102014.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<parameter-file instrument = "REF_L" valid-from="2014-10-10 00:00:02" valid-to="2100-01-31 23:59:59"> + + <component-link name = "REF_L"> + + <parameter name="number-of-x-pixels"> + <value val="256"/> + </parameter> + + <parameter name="number-of-y-pixels"> + <value val="304"/> + </parameter> + + </component-link> + +</parameter-file> + diff --git a/Code/Mantid/scripts/Inelastic/Direct/DirectEnergyConversion.py b/Code/Mantid/scripts/Inelastic/Direct/DirectEnergyConversion.py index 8d841b68595539d6fb8e3410b103fcb3e847ad00..d6e3f5352f0fc883cd33a91e0640b55fa8a3bcc8 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/DirectEnergyConversion.py +++ b/Code/Mantid/scripts/Inelastic/Direct/DirectEnergyConversion.py @@ -204,8 +204,8 @@ class DirectEnergyConversion(object): # data file. SNS or 1 to 1 maps may probably avoid this # stuff and can load masks directly white_data = white.get_ws_clone('white_ws_clone') - - diag_mask = LoadMask(Instrument=self.instr_name,InputFile=self.hard_mask_file,\ + idf_file = api.ExperimentInfo.getInstrumentFilename(self.instr_name) + diag_mask = LoadMask(Instrument=idf_file,InputFile=self.hard_mask_file,\ OutputWorkspace='hard_mask_ws') MaskDetectors(Workspace=white_data, MaskedWorkspace=diag_mask) white.add_masked_ws(white_data) @@ -342,7 +342,9 @@ class DirectEnergyConversion(object): # inform user on what parameters have changed from script or gui # if monovan present, check if abs_norm_ parameters are set self.prop_man.log_changed_values('notice') - + # before trying to process new results, let's remove from memory old results + # if any present and they are not needed any more (user have not renamed them) + self._clear_old_results() start_time = time.time() @@ -366,7 +368,7 @@ class DirectEnergyConversion(object): masks_done = False if not prop_man.run_diagnostics: header = "*** Diagnostics including hard masking is skipped " - masks_done = Treu + masks_done = True #if Reducer.save_and_reuse_masks : # SAVE AND REUSE MASKS if self.spectra_masks: @@ -383,7 +385,7 @@ class DirectEnergyConversion(object): masking = self.spectra_masks # estimate and report the number of failing detectors - nMaskedSpectra = get_failed_spectra_list_from_masks(masking) + nMaskedSpectra = get_failed_spectra_list_from_masks(masking,prop_man) if masking: nSpectra = masking.getNumberHistograms() else: @@ -420,7 +422,9 @@ class DirectEnergyConversion(object): num_ei_cuts = len(self.incident_energy) if self.check_background: # find the count rate seen in the regions of the histograms defined - # as the background regions, if the user defined such region + # as the background regions, if the user defined such region. + # In multirep mode this has to be done here, as workspace + # will be cut in chunks and bg regions -- removed ws_base = PropertyManager.sample_run.get_workspace() bkgd_range = self.bkgd_range bkgr_ws = self._find_or_build_bkgr_ws(ws_base,bkgd_range[0],bkgd_range[1]) @@ -430,7 +434,9 @@ class DirectEnergyConversion(object): else: self._multirep_mode = False num_ei_cuts = 0 - +#------------------------------------------------------------------------------------------ +# Main loop over incident energies +#------------------------------------------------------------------------------------------ cut_ind = 0 # do not do enumerate if it generates all sequence at once # -- code below uses current energy state from PropertyManager.incident_energy for ei_guess in PropertyManager.incident_energy: @@ -475,6 +481,7 @@ class DirectEnergyConversion(object): if out_ws_name: if self._multirep_mode: result.append(deltaE_ws_sample) + self._old_runs_list.append(deltaE_ws_sample.name()) else: results_name = deltaE_ws_sample.name() if results_name != out_ws_name: @@ -483,6 +490,9 @@ class DirectEnergyConversion(object): else: # delete workspace if no output is requested self.sample_run = None #end_for +#------------------------------------------------------------------------------------------ +# END Main loop over incident energies +#------------------------------------------------------------------------------------------ end_time = time.time() prop_man.log("*** Elapsed time = {0} sec".format(end_time - start_time),'notice') @@ -492,8 +502,6 @@ class DirectEnergyConversion(object): #prop_man.wb_run = None # clear combined mask self.spectra_masks = None - if 'masking' in mtd: - DeleteWorkspace(masking) return result def _do_abs_corrections(self,deltaE_ws_sample,cashed_mono_int,ei_guess,\ @@ -840,13 +848,16 @@ class DirectEnergyConversion(object): workspace = PropertyManager.sample_run.get_workspace() spectra_id = self.prop_man.multirep_tof_specta_list - if not spectra_id: + if not spectra_id or len(spectra_id) == 0: + self.prop_man.log("*** WARNING! no multirep spectra found in IDF! using first existing spectra number\n"\ + " This is wrong unless sample-detector distances of the instrument are all equal.",\ + 'warning') spectra_id = [1] eMin,dE,eMax = PropertyManager.energy_bins.get_abs_range(self.prop_man) ei = PropertyManager.incident_energy.get_current() en_list = [eMin,eMin + dE,eMax - dE,eMax] - TOF_range = DirectEnergyConversion.get_TOF_for_energies(workspace,en_list,spectra_id,ei) + TOF_range = self.get_TOF_for_energies(workspace,en_list,spectra_id,ei) def process_block(tof_range): @@ -869,15 +880,16 @@ class DirectEnergyConversion(object): else: tof_min,t_step,tof_max = process_block(TOF_range) #end - return (tof_min,t_step,tof_max) + # add 5% for detectors specified in Par file are shifted a bit and not min-max det any more + return (0.95*tof_min,t_step,1.05*tof_max) + #return (tof_min,t_step,tof_max) # - @staticmethod - def get_TOF_for_energies(workspace,energy_list,specID_list,ei=None,debug_mode=False): + def get_TOF_for_energies(self,workspace,energy_list,specID_list,ei=None,debug_mode=False): """ Method to find what TOF range corresponds to given energy range for given workspace and detectors. Input: - workspace pointer to workspace with instrument attached. + workspace handler for the workspace with instrument attached. energy_list the list of input energies to process detID_list list of detectors to find ei incident energy. If present, TOF range is calculated in direct mode, @@ -886,6 +898,37 @@ class DirectEnergyConversion(object): Returns: list of TOF corresponding to input energies list. """ + if ei: + ei_guess = PropertyManager.incident_energy.get_current() + fix_ei = self.fix_ei + ei_mon_spectra = self.ei_mon_spectra + monitor_ws = PropertyManager.sample_run.get_monitors_ws(ei_mon_spectra,workspace) + if monitor_ws is None: # no shifting to monitor position + src_name = None + mon1_peak = 0 + else: + mon_2_spec_ID = int(ei_mon_spectra[0]) + # Calculate the incident energy and TOF when the particles access Monitor1 + try: + ei,mon1_peak,mon1_index,tzero = \ + GetEi(InputWorkspace=monitor_ws, Monitor1Spec=mon_2_spec_ID, + Monitor2Spec=int(ei_mon_spectra[1]), + EnergyEstimate=ei_guess,FixEi=fix_ei) + mon1_det = monitor_ws.getDetector(mon1_index) + mon1_pos = mon1_det.getPos() + src_name = monitor_ws.getInstrument().getSource().getName() + except : + src_name = None + mon1_peak = 0 + en_bin = [energy_list[0],energy_list[1]-energy_list[0],energy_list[3]] + self.prop_man.log("*** WARNING: message from multirep chunking procedure: get_TOF_for_energies:\n"\ + " not able to identify energy peak looking for TOF range for incident energy: {0}meV, binning: {1}\n"\ + " Continuing under assumption that incident neutrons arrive at source at time=0".\ + format(ei_guess,en_bin),'warning') + else: + mon1_peak = 0 + #end if + template_ws_name = '_energy_range_ws' range_ws_name = '_TOF_range_ws' y = [1] * (len(energy_list) - 1) @@ -895,11 +938,14 @@ class DirectEnergyConversion(object): ExtractSingleSpectrum(InputWorkspace=workspace, OutputWorkspace=template_ws_name, WorkspaceIndex=ind) if ei: CreateWorkspace(OutputWorkspace=range_ws_name,NSpec = 1,DataX=energy_list,DataY=y,UnitX='DeltaE',ParentWorkspace=template_ws_name) + if src_name: + MoveInstrumentComponent(Workspace=range_ws_name,ComponentName= src_name, X=mon1_pos.getX(), + Y=mon1_pos.getY(), Z=mon1_pos.getZ(), RelativePosition=False) range_ws = ConvertUnits(InputWorkspace=range_ws_name,OutputWorkspace=range_ws_name,Target='TOF',EMode='Direct',EFixed=ei) else: CreateWorkspace(OutputWorkspace=range_ws_name,NSpec = 1,DataX=energy_list,DataY=y,UnitX='Energy',ParentWorkspace=template_ws_name) range_ws = ConvertUnits(InputWorkspace=range_ws_name,OutputWorkspace=range_ws_name,Target='TOF',EMode='Elastic') - x = range_ws.dataX(0) + x = range_ws.dataX(0)+mon1_peak TOF_range.append(x.tolist()) if not debug_mode: @@ -982,18 +1028,37 @@ class DirectEnergyConversion(object): ######### @property def spectra_masks(self): - """ The property keeps a workspace with masks, stored for further usage """ + """ The property keeps a workspace with masks workspace name, + stored for further usage""" # check if spectra masks is defined if hasattr(self,'_spectra_masks'): - return self._spectra_masks + if not self._spectra_masks is None and self._spectra_masks in mtd: + return mtd[self._spectra_masks] + else: + self._spectra_masks = None + return None else: return None @spectra_masks.setter def spectra_masks(self,value): """ set up spectra masks """ - self._spectra_masks = value + if value is None: + if hasattr(self,'_spectra_masks') and not self._spectra_masks is None: + if self._spectra_masks in mtd: + DeleteWorkspace(self._spectra_masks) + self._spectra_masks=None + elif isinstance(value,api.Workspace): + self._spectra_masks = value.name() + elif isinstance(value,str): + if value in mtd: + self._spectra_masks = value + else: + self._spectra_masks = None + else: + self._spectra_masks = None + return #------------------------------------------------------------------------------- def apply_absolute_normalization(self,sample_ws,monovan_run=None,ei_guess=None,wb_mono=None,abs_norm_factor_is=None): """ Function applies absolute normalization factor to the target workspace @@ -1207,11 +1272,15 @@ class DirectEnergyConversion(object): # workspace # processed object.__setattr__(self,'_multirep_mode',False) + # list of workspace names, processed earlier + object.__setattr__(self,'_old_runs_list',[]) + all_methods = dir(self) # define list of all existing properties, which have descriptors object.__setattr__(self,'_descriptors',extract_non_system_names(all_methods)) + if instr_name: self.initialise(instr_name,reload_instrument) #end @@ -1451,7 +1520,7 @@ class DirectEnergyConversion(object): #------------------------------------------------------------------------------- def _get_wb_inegrals(self,run): """Obtain white bean vanadium integrals either by integrating - workspace in question or cashed value + workspace in question or using cashed value """ run = self.get_run_descriptor(run) white_ws = run.get_workspace() @@ -1514,8 +1583,16 @@ class DirectEnergyConversion(object): low,upp = self.wb_integr_range white_tag = 'NormBy:{0}_IntergatedIn:{1:0>10.2f}:{2:0>10.2f}'.format(self.normalise_method,low,upp) return white_tag - -def get_failed_spectra_list_from_masks(masked_wksp): + # + def _clear_old_results(self): + """Remove workspaces, processed earlier and not used any more""" + ws_list = self._old_runs_list + for ws_name in ws_list: + if ws_name in mtd: + DeleteWorkspace(ws_name) + object.__setattr__(self,'_old_runs_list',[]) + # +def get_failed_spectra_list_from_masks(masked_wksp,prop_man): """Compile a list of spectra numbers that are marked as masked in the masking workspace @@ -1526,6 +1603,11 @@ def get_failed_spectra_list_from_masks(masked_wksp): failed_spectra = [] if masked_wksp is None: return (failed_spectra,0) + try: + name = masked_wksp.name() + except Exeption as ex: + prop_man.log("***WARNING: cached mask workspace invalidated. Incorrect masking reported") + return (failed_spectra,0) masking_wksp,sp_list = ExtractMask(masked_wksp) DeleteWorkspace(masking_wksp) diff --git a/Code/Mantid/scripts/Inelastic/Direct/NonIDF_Properties.py b/Code/Mantid/scripts/Inelastic/Direct/NonIDF_Properties.py index 31916d02a2ab8c11f5fa5f8bdf8de48cb9c05a42..8dcc95516524cd17e573c33f1bd1f94bc1c85285 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/NonIDF_Properties.py +++ b/Code/Mantid/scripts/Inelastic/Direct/NonIDF_Properties.py @@ -36,7 +36,6 @@ class NonIDF_Properties(object): object.__setattr__(self,'_log_to_mantid',False) object.__setattr__(self,'_current_log_level',3) - object.__setattr__(self,'_save_file_name',None) self._set_instrument_and_facility(Instrument,run_workspace) diff --git a/Code/Mantid/scripts/Inelastic/Direct/PropertiesDescriptors.py b/Code/Mantid/scripts/Inelastic/Direct/PropertiesDescriptors.py index 6087fdad365d0ed921a9e631b2f42d5d99d52d68..fbf3397571c7e2fc527ee6498bb924b075efee2b 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/PropertiesDescriptors.py +++ b/Code/Mantid/scripts/Inelastic/Direct/PropertiesDescriptors.py @@ -316,7 +316,7 @@ class SaveFileName(PropDescriptor): if instance is None: return self if not self._custom_print is None: - return self._custom_print(instance,owner) + return self._custom_print() if self._file_name: return self._file_name diff --git a/Code/Mantid/scripts/Inelastic/Direct/PropertyManager.py b/Code/Mantid/scripts/Inelastic/Direct/PropertyManager.py index 5b72a5818980f75fe98d670543dba492716166fc..435d98eb403f96512989dba358aaa5e79a823756 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/PropertyManager.py +++ b/Code/Mantid/scripts/Inelastic/Direct/PropertyManager.py @@ -584,7 +584,7 @@ class PropertyManager(NonIDF_Properties): ok,mess= self._check_ouptut_dir() if not ok: - mess = '*** WARNING: saving results: --> {1}'.format(mess) + mess = '*** WARNING: saving results: --> {0}'.format(mess) if fail_on_errors: self.log(mess,'warning') diff --git a/Code/Mantid/scripts/Inelastic/Direct/ReductionWrapper.py b/Code/Mantid/scripts/Inelastic/Direct/ReductionWrapper.py index d3c7ff4af87cffceee1b2c09d1c0600a96edd8b2..35a7e72238653e60840eb37a4c6e756924cbcfcf 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/ReductionWrapper.py +++ b/Code/Mantid/scripts/Inelastic/Direct/ReductionWrapper.py @@ -338,11 +338,17 @@ class ReductionWrapper(object): nruns = len(runfiles) for num,file in enumerate(runfiles): red_ws = self.reduce(file) - if nruns > 1: - out_name = out_ws_name + '#{0}of{1}'.format(num + 1,nruns) - RenameWorkspace(InputWorkspace=red_ws,OutputWorkspace=out_name) - red_ws = mtd[out_name] - results.append(red_ws) + if isinstance(red_ws,list): + for ws in red_ws: + results.append(ws) + else: + if nruns == 1: + RenameWorkspace(InputWorkspace=red_ws,OutputWorkspace=out_ws_name) + results.append(mtd[out_ws_name]) + else: + OutWSName = '{0}#{1}of{2}'.format(out_ws_name,num+1,nruns) + RenameWorkspace(InputWorkspace=red_ws,OutputWorkspace=OutWSName) + results.append(mtd[OutWSName]) #end if len(results) == 1: return results[0] diff --git a/Code/Mantid/scripts/Inelastic/Direct/RunDescriptor.py b/Code/Mantid/scripts/Inelastic/Direct/RunDescriptor.py index 0612ae94e29757f58a78532f1bca9c6043fc91f0..a146d0a0c99de03dd1258a4409e8cb2b2c158b70 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/RunDescriptor.py +++ b/Code/Mantid/scripts/Inelastic/Direct/RunDescriptor.py @@ -455,7 +455,10 @@ class RunDescriptor(PropDescriptor): self._run_list.set_last_ind2sum(ind) self._run_number = run_num self._run_file_path = file_path - self._fext = main_fext + if fext is None: + self._fext = None + else: + self._fext = main_fext self._ws_name = self._build_ws_name() def run_number(self): @@ -775,13 +778,16 @@ class RunDescriptor(PropDescriptor): return origin #-------------------------------------------------------------------------------------------------------------------- - def get_monitors_ws(self,monitor_ID=None): + def get_monitors_ws(self,monitors_ID=None,otherWS=None): """Get pointer to a workspace containing monitors. Explores different ways of finding monitor workspace in Mantid and returns the python pointer to the workspace which contains monitors. """ - data_ws = self.get_workspace() + if otherWS: + data_ws = otherWS + else: + data_ws = self.get_workspace() if not data_ws: return None @@ -798,25 +804,26 @@ class RunDescriptor(PropDescriptor): for specID in spec_to_mon: mon_ws = self.copy_spectrum2monitors(data_ws,mon_ws,specID) - if monitor_ID: - try: - ws_index = mon_ws.getIndexFromSpectrumNumber(monitor_ID) - except: # - mon_ws = None + if monitors_ID: + if isinstance(monitors_ID,list): + mon_list = monitors_ID + else: + mon_list = [monitors_ID] else: mon_list = self._holder.get_used_monitors_list() - for monID in mon_list: + # + for monID in mon_list: + try: + ws_ind = mon_ws.getIndexFromSpectrumNumber(int(monID)) + except: try: - ws_ind = mon_ws.getIndexFromSpectrumNumber(int(monID)) - except: - try: - monws_name = mon_ws.name() - except: - monws_name = 'None' - RunDescriptor._logger('*** Monitor workspace {0} does not have monitor with ID {1}. Monitor workspace set to None'.\ + monws_name = mon_ws.name() + except: + monws_name = 'None' + RunDescriptor._logger('*** Monitor workspace {0} does not have monitor with ID {1}. Monitor workspace set to None'.\ format(monws_name,monID),'warning') - mon_ws = None - break + mon_ws = None + break return mon_ws #-------------------------------------------------------------------------------------------------------------------- def is_existing_ws(self): @@ -1023,19 +1030,31 @@ class RunDescriptor(PropDescriptor): # x_param = mon_ws.readX(0) - bins = [x_param[0],x_param[1] - x_param[0],x_param[-1]] + homo_binning,dx_min=RunDescriptor._is_binning_homogeneous(x_param) + bins = [x_param[0],dx_min,x_param[-1]] ExtractSingleSpectrum(InputWorkspace=data_ws,OutputWorkspace='tmp_mon',WorkspaceIndex=ws_index) Rebin(InputWorkspace='tmp_mon',OutputWorkspace='tmp_mon',Params=bins,PreserveEvents='0') - # should be vice versa but Conjoin invalidate ws pointers and hopefully - # nothing could happen with workspace during conjoining - #AddSampleLog(Workspace=monWS,LogName=done_log_name,LogText=str(ws_index),LogType='Number') mon_ws_name = mon_ws.getName() - ConjoinWorkspaces(InputWorkspace1=mon_ws,InputWorkspace2='tmp_mon') + if not homo_binning: + Rebin(InputWorkspace=mon_ws_name,OutputWorkspace=mon_ws_name,Params=bins,PreserveEvents='0') + ConjoinWorkspaces(InputWorkspace1=mon_ws_name,InputWorkspace2='tmp_mon') mon_ws = mtd[mon_ws_name] if 'tmp_mon' in mtd: DeleteWorkspace(WorkspaceName='tmp_mon') return mon_ws + # + @staticmethod + def _is_binning_homogeneous(x_param): + """Verify if binning in monitor workspace is homogeneous""" + dx=x_param[1:]-x_param[0:-1] + dx_min=min(dx) + dx_max=max(dx) + if dx_max-dx_min>1.e-9: + return False,dx_min + else: + return True,dx_min + #-------------------------------------------------------------------------------------------------------------------- def clear_monitors(self): """ method removes monitor workspace form analysis data service if it is there diff --git a/Code/Mantid/scripts/Inelastic/Direct/dgreduce.py b/Code/Mantid/scripts/Inelastic/Direct/dgreduce.py index fd1318c9e6707dcb75146325f1518f75a441f079..0e261a7d34558240e0b0a1d8a04049259056691a 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/dgreduce.py +++ b/Code/Mantid/scripts/Inelastic/Direct/dgreduce.py @@ -3,7 +3,7 @@ import Direct.DirectEnergyConversion as DRC from mantid.simpleapi import * from mantid.kernel import funcreturns - +from mantid import api # the class which is responsible for data reduction global Reducer @@ -134,6 +134,7 @@ def arb_units(wb_run,sample_run,ei_guess,rebin,map_file='default',monovan_run=No # -------------------------------------------------------------------------------------------------------- if sample_run: Reducer.sample_run = sample_run + sample_run = None try: n,r=funcreturns.lhs_info('both') wksp_out=r[0] @@ -149,7 +150,37 @@ def arb_units(wb_run,sample_run,ei_guess,rebin,map_file='default',monovan_run=No return res - +def runs_are_equal(ws1,ws2): + """Compare two run numbers, provided either as run numbers, + or as workspaces or as ws names""" + if ws1 == ws2: + return True + #----------------------------------------------- + def get_run_num(name_or_ws): + err = None + try: + if isinstance(name_or_ws,api.MatrixWorkspace): + run_num = name_or_ws.getRunNumber() + elif name_or_ws in mtd: # this is also throw Boost.Python.ArgumentError error if mtd not accepts it + ws = mtd[name_or_ws] + run_num = ws.getRunNumber() + else: + raise AttributeError + except Exception as err: + pass + if not err is None: + raise AttributeError("Input parameter is neither workspace nor ws name") + return run_num + #----------------------------------------------- + try: + run_num1 = get_run_num(ws1) + except AttributeError: + return False + try: + run_num2 = get_run_num(ws2) + except AttributeError: + return False + return run_num1==run_num2 def abs_units(wb_for_run,sample_run,monovan_run,wb_for_monovanadium,samp_rmm,samp_mass,ei_guess,rebin,map_file='default',monovan_mapfile='default',**kwargs): """ @@ -240,13 +271,14 @@ def abs_units(wb_for_run,sample_run,monovan_run,wb_for_monovanadium,samp_rmm,sam if sample_run: Reducer.sample_run = sample_run + sample_run = None try: n,r=funcreturns.lhs_info('both') results_name=r[0] except: results_name = Reducer.prop_man.get_sample_ws_name() - if wb_for_run == wb_for_monovanadium: # wb_for_monovanadium property does not accept duplicated workspace + if runs_are_equal(wb_for_run,wb_for_monovanadium):# wb_for_monovanadium property does not accept duplicated workspace wb_for_monovanadium = None # if this value is none, it is constructed to be equal to wb_for_run wksp_out = arb_units(wb_for_run,sample_run,ei_guess,rebin,map_file,monovan_run,wb_for_monovanadium,**kwargs) diff --git a/Code/Mantid/scripts/Inelastic/IndirectAbsCor.py b/Code/Mantid/scripts/Inelastic/IndirectAbsCor.py index bd2855548e4a6196cb2d27547ab29e7d28284c34..3f7b40f777eb10a18243316b4de8b0d6d37bb77c 100644 --- a/Code/Mantid/scripts/Inelastic/IndirectAbsCor.py +++ b/Code/Mantid/scripts/Inelastic/IndirectAbsCor.py @@ -193,25 +193,28 @@ def AbsRun(inputWS, geom, beam, ncan, size, density, sigs, siga, avar, Save): accWS = name + '_acc' fname = name + '_abs' + log_names = [item[0] for item in sample_logs] + log_values = [item[1] for item in sample_logs] + CreateWorkspace(OutputWorkspace=assWS, DataX=dataX, DataY=dataA1, NSpec=ndet, UnitX='Wavelength', VerticalAxisUnit=v_axis_unit, VerticalAxisValues=v_axis_values) - addSampleLogs(assWS, sample_logs) + AddSampleLogMultiple(Workspace=assWS, LogNames=log_names, LogValues=log_values) CreateWorkspace(OutputWorkspace=asscWS, DataX=dataX, DataY=dataA2, NSpec=ndet, UnitX='Wavelength', VerticalAxisUnit=v_axis_unit, VerticalAxisValues=v_axis_values) - addSampleLogs(asscWS, sample_logs) + AddSampleLogMultiple(Workspace=asscWS, LogNames=log_names, LogValues=log_values) CreateWorkspace(OutputWorkspace=acscWS, DataX=dataX, DataY=dataA3, NSpec=ndet, UnitX='Wavelength', VerticalAxisUnit=v_axis_unit, VerticalAxisValues=v_axis_values) - addSampleLogs(acscWS, sample_logs) + AddSampleLogMultiple(Workspace=acscWS, LogNames=log_names, LogValues=log_values) CreateWorkspace(OutputWorkspace=accWS, DataX=dataX, DataY=dataA4, NSpec=ndet, UnitX='Wavelength', VerticalAxisUnit=v_axis_unit, VerticalAxisValues=v_axis_values) - addSampleLogs(accWS, sample_logs) + AddSampleLogMultiple(Workspace=accWS, LogNames=log_names, LogValues=log_values) group = assWS + ',' + asscWS + ',' + acscWS + ',' + accWS GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=fname) diff --git a/Code/Mantid/scripts/Inelastic/IndirectCommon.py b/Code/Mantid/scripts/Inelastic/IndirectCommon.py index 7804beeac9c0d789bfdf57db35304691f364d11c..b96219f3b30d0ad6eb8f76acbf3fcef637b0db26 100644 --- a/Code/Mantid/scripts/Inelastic/IndirectCommon.py +++ b/Code/Mantid/scripts/Inelastic/IndirectCommon.py @@ -545,23 +545,3 @@ def convertParametersToWorkspace(params_table, x_column, param_names, output_nam axis.setLabel(i, name) mtd[output_name].replaceAxis(1, axis) - -def addSampleLogs(ws, sample_logs): - """ - Add a dictionary of logs to a workspace. - - The type of the log is inferred by the type of the value passed to the log. - - @param ws - workspace to add logs too. - @param sample_logs - dictionary of logs to append to the workspace. - """ - - for key, value in sample_logs.iteritems(): - if isinstance(value, bool): - log_type = 'String' - elif isinstance(value, (int, long, float)): - log_type = 'Number' - else: - log_type = 'String' - - AddSampleLog(Workspace=ws, LogName=key, LogType=log_type, LogText=str(value)) diff --git a/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py b/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py index a6a3af0d3dc368d454617dfe8a7ee90a887d9b21..a1d11b69033a13cadda975757e3775e6e857fbc1 100644 --- a/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py +++ b/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py @@ -98,26 +98,28 @@ def confitSeq(inputWS, func, startX, endX, ftype, bgd, temperature=None, specMin axis = mtd[wsname].getAxis(0) axis.setUnit("MomentumTransfer") + # Handle sample logs + temp_correction = temperature is not None + CopyLogs(InputWorkspace=inputWS, OutputWorkspace=wsname) - AddSampleLog(Workspace=wsname, LogName='convolve_members', - LogType='String', LogText=str(convolve)) - AddSampleLog(Workspace=wsname, LogName="fit_program", - LogType="String", LogText='ConvFit') - AddSampleLog(Workspace=wsname, LogName='background', - LogType='String', LogText=str(bgd)) - AddSampleLog(Workspace=wsname, LogName='delta_function', - LogType='String', LogText=str(using_delta_func)) - AddSampleLog(Workspace=wsname, LogName='lorentzians', - LogType='String', LogText=str(lorentzians)) - CopyLogs(InputWorkspace=wsname, OutputWorkspace=output_workspace + "_Workspaces") + sample_logs = [('convolve_members', convolve), + ('fit_program', 'ConvFit'), + ('background', bgd), + ('delta_function', using_delta_func), + ('lorentzians', lorentzians), + ('temperature_correction', temp_correction)] - temp_correction = temperature is not None - AddSampleLog(Workspace=wsname, LogName='temperature_correction', - LogType='String', LogText=str(temp_correction)) if temp_correction: - AddSampleLog(Workspace=wsname, LogName='temperature_value', - LogType='String', LogText=str(temperature)) + sample_logs.append(('temperature_value', temperature)) + + log_names = [log[0] for log in sample_logs] + log_values = [log[1] for log in sample_logs] + AddSampleLogMultiple(Workspace=wsname, + LogNames=log_names, + LogValues=log_values) + + CopyLogs(InputWorkspace=wsname, OutputWorkspace=output_workspace + "_Workspaces") RenameWorkspace(InputWorkspace=output_workspace, OutputWorkspace=output_workspace + "_Parameters") @@ -200,8 +202,10 @@ def furyfitSeq(inputWS, func, ftype, startx, endx, spec_min=0, spec_max=None, in CopyLogs(InputWorkspace=inputWS, OutputWorkspace=fit_group) CopyLogs(InputWorkspace=inputWS, OutputWorkspace=result_workspace) - addSampleLogs(fit_group, sample_logs) - addSampleLogs(result_workspace, sample_logs) + log_names = [item[0] for item in sample_logs] + log_values = [item[1] for item in sample_logs] + AddSampleLogMultiple(Workspace=result_workspace, LogNames=log_names, LogValues=log_values) + AddSampleLogMultiple(Workspace=fit_group, LogNames=log_names, LogValues=log_values) if Save: save_workspaces = [result_workspace, fit_group] @@ -270,8 +274,10 @@ def furyfitMult(inputWS, function, ftype, startx, endx, spec_min=0, spec_max=Non CopyLogs(InputWorkspace=inputWS, OutputWorkspace=result_workspace) CopyLogs(InputWorkspace=inputWS, OutputWorkspace=fit_group) - addSampleLogs(result_workspace, sample_logs) - addSampleLogs(fit_group, sample_logs) + log_names = [item[0] for item in sample_logs] + log_values = [item[1] for item in sample_logs] + AddSampleLogMultiple(Workspace=result_workspace, LogNames=log_names, LogValues=log_values) + AddSampleLogMultiple(Workspace=fit_group, LogNames=log_names, LogValues=log_values) DeleteWorkspace(tmp_fit_workspace) @@ -282,7 +288,7 @@ def furyfitMult(inputWS, function, ftype, startx, endx, spec_min=0, spec_max=Non if Plot != 'None': furyfitPlotSeq(result_workspace, Plot) - EndTime('FuryFit Multi') + EndTime('TransformToIqtFit Multi') return result_workspace @@ -328,111 +334,6 @@ def furyfitPlotSeq(ws, plot): plotParameters(ws, *param_names) -############################################################################## -# MSDFit -############################################################################## - -def msdfitPlotSeq(inputWS, xlabel): - workspace = mtd[inputWS + '_A1'] - if len(workspace.readX(0)) > 1: - msd_plot = MTD_PLOT.plotSpectrum(inputWS+'_A1',0,True) - msd_layer = msd_plot.activeLayer() - msd_layer.setAxisTitle(MTD_PLOT.Layer.Bottom,xlabel) - msd_layer.setAxisTitle(MTD_PLOT.Layer.Left,'<u2>') - -def msdfit(ws, startX, endX, spec_min=0, spec_max=None, Save=False, Plot=True): - StartTime('msdFit') - workdir = getDefaultWorkingDirectory() - - num_spectra = mtd[ws].getNumberHistograms() - if spec_max is None: - spec_max = num_spectra - 1 - - if spec_min < 0 or spec_max >= num_spectra: - raise ValueError("Invalid spectrum range: %d - %d" % (spec_min, spec_max)) - - xlabel = '' - ws_run = mtd[ws].getRun() - - if 'vert_axis' in ws_run: - xlabel = ws_run.getLogData('vert_axis').value - - mname = ws[:-4] - msdWS = mname+'_msd' - - #fit line to each of the spectra - function = 'name=LinearBackground, A0=0, A1=0' - input_params = [ ws+',i%d' % i for i in xrange(spec_min, spec_max+1)] - input_params = ';'.join(input_params) - PlotPeakByLogValue(Input=input_params, OutputWorkspace=msdWS, Function=function, - StartX=startX, EndX=endX, FitType='Sequential', CreateOutput=True) - - DeleteWorkspace(msdWS + '_NormalisedCovarianceMatrices') - DeleteWorkspace(msdWS + '_Parameters') - msd_parameters = msdWS+'_Parameters' - RenameWorkspace(msdWS, OutputWorkspace=msd_parameters) - - params_table = mtd[msd_parameters] - - #msd value should be positive, but the fit output is negative - msd = params_table.column('A1') - for i, value in enumerate(msd): - params_table.setCell('A1', i, value * -1) - - #create workspaces for each of the parameters - group = [] - - ws_name = msdWS + '_A0' - group.append(ws_name) - ConvertTableToMatrixWorkspace(msd_parameters, OutputWorkspace=ws_name, - ColumnX='axis-1', ColumnY='A0', ColumnE='A0_Err') - xunit = mtd[ws_name].getAxis(0).setUnit('Label') - xunit.setLabel('Temperature', 'K') - - ws_name = msdWS + '_A1' - group.append(ws_name) - ConvertTableToMatrixWorkspace(msd_parameters, OutputWorkspace=ws_name, - ColumnX='axis-1', ColumnY='A1', ColumnE='A1_Err') - - SortXAxis(ws_name, OutputWorkspace=ws_name) - - xunit = mtd[ws_name].getAxis(0).setUnit('Label') - xunit.setLabel('Temperature', 'K') - - GroupWorkspaces(InputWorkspaces=','.join(group),OutputWorkspace=msdWS) - - #add sample logs to output workspace - fit_workspaces = msdWS + '_Workspaces' - CopyLogs(InputWorkspace=ws, OutputWorkspace=msdWS) - AddSampleLog(Workspace=msdWS, LogName="start_x", LogType="Number", LogText=str(startX)) - AddSampleLog(Workspace=msdWS, LogName="end_x", LogType="Number", LogText=str(endX)) - CopyLogs(InputWorkspace=msdWS + '_A0', OutputWorkspace=fit_workspaces) - - if Plot: - msdfitPlotSeq(msdWS, xlabel) - if Save: - msd_path = os.path.join(workdir, msdWS+'.nxs') # path name for nxs file - SaveNexusProcessed(InputWorkspace=msdWS, Filename=msd_path, Title=msdWS) - logger.information('Output msd file : '+msd_path) - - EndTime('msdFit') - return fit_workspaces - -def plotInput(inputfiles,spectra=[]): - OneSpectra = False - if len(spectra) != 2: - spectra = [spectra[0], spectra[0]] - OneSpectra = True - workspaces = [] - for in_file in inputfiles: - root = LoadNexus(Filename=in_file) - if not OneSpectra: - GroupDetectors(root, root, DetectorList=range(spectra[0],spectra[1]+1) ) - workspaces.append(root) - if len(workspaces) > 0: - graph = MTD_PLOT.plotSpectrum(workspaces,0) - graph.activeLayer().setTitle(", ".join(workspaces)) - ############################################################################## # Corrections ############################################################################## diff --git a/Code/Mantid/scripts/SCD_Reduction/ReduceSCD.config b/Code/Mantid/scripts/SCD_Reduction/ReduceSCD.config index 67b5014828afe4eb8502b3a4816760b39390420c..324b3883589caf24d49f3ea2b12b0f784a38cdd6 100644 --- a/Code/Mantid/scripts/SCD_Reduction/ReduceSCD.config +++ b/Code/Mantid/scripts/SCD_Reduction/ReduceSCD.config @@ -43,6 +43,8 @@ calibration_file_2 None # data_directory None output_directory /SNS/TOPAZ/IPTS-9890/shared/SPAnH +# Change to true for data with lots of peaks. Use False for ISAW ASCII output +output_nexus False # # If use_monitor_counts is True, then the integrated beam monitor diff --git a/Code/Mantid/scripts/SCD_Reduction/ReduceSCD_OneRun.py b/Code/Mantid/scripts/SCD_Reduction/ReduceSCD_OneRun.py index da992481ba3ac2c36cd0634d9073a5a3f2989c71..8ae81127207be15b6d7bff3d4f079f5d9f55bd07 100644 --- a/Code/Mantid/scripts/SCD_Reduction/ReduceSCD_OneRun.py +++ b/Code/Mantid/scripts/SCD_Reduction/ReduceSCD_OneRun.py @@ -72,6 +72,7 @@ calibration_file_1 = params_dictionary.get('calibration_file_1', None) calibration_file_2 = params_dictionary.get('calibration_file_2', None) data_directory = params_dictionary[ "data_directory" ] output_directory = params_dictionary[ "output_directory" ] +output_nexus = params_dictionary.get( "output_nexus", False) min_tof = params_dictionary[ "min_tof" ] max_tof = params_dictionary[ "max_tof" ] use_monitor_counts = params_dictionary[ "use_monitor_counts" ] @@ -145,7 +146,10 @@ print "\nProcessing File: " + full_name + " ......\n" # Name the files to write for this run # run_niggli_matrix_file = output_directory + "/" + run + "_Niggli.mat" -run_niggli_integrate_file = output_directory + "/" + run + "_Niggli.integrate" +if output_nexus: + run_niggli_integrate_file = output_directory + "/" + run + "_Niggli.nxs" +else: + run_niggli_integrate_file = output_directory + "/" + run + "_Niggli.integrate" # # Load the run data and find the total monitor counts @@ -219,7 +223,10 @@ IndexPeaks( PeaksWorkspace=peaks_ws, Tolerance=tolerance) # see these partial results # SaveIsawUB( InputWorkspace=peaks_ws,Filename=run_niggli_matrix_file ) -SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, +if output_nexus: + SaveNexus( InputWorkspace=peaks_ws, Filename=run_niggli_integrate_file ) +else: + SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, Filename=run_niggli_integrate_file ) # @@ -327,7 +334,10 @@ elif use_cylindrical_integration: # This is the only file needed, for the driving script to get a combined # result. # -SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, +if output_nexus: + SaveNexus( InputWorkspace=peaks_ws, Filename=run_niggli_integrate_file ) +else: + SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, Filename=run_niggli_integrate_file ) # Print warning if user is trying to integrate using the cylindrical method and transorm the cell @@ -342,13 +352,20 @@ else: if (not cell_type is None) and (not centering is None) : run_conventional_matrix_file = output_directory + "/" + run + "_" + \ cell_type + "_" + centering + ".mat" - run_conventional_integrate_file = output_directory + "/" + run + "_" + \ + if output_nexus: + run_conventional_integrate_file = output_directory + "/" + run + "_" + \ + cell_type + "_" + centering + ".nxs" + else: + run_conventional_integrate_file = output_directory + "/" + run + "_" + \ cell_type + "_" + centering + ".integrate" SelectCellOfType( PeaksWorkspace=peaks_ws,\ CellType=cell_type, Centering=centering,\ AllowPermutations=allow_perm,\ Apply=True, Tolerance=tolerance ) - SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False,\ + if output_nexus: + SaveNexus( InputWorkspace=peaks_ws, Filename=run_conventional_integrate_file ) + else: + SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False,\ Filename=run_conventional_integrate_file ) SaveIsawUB( InputWorkspace=peaks_ws, Filename=run_conventional_matrix_file ) diff --git a/Code/Mantid/scripts/SCD_Reduction/ReduceSCD_Parallel.py b/Code/Mantid/scripts/SCD_Reduction/ReduceSCD_Parallel.py index 16a978089c34d4a2f4c1ad37234f8ce01d269a62..804358531b1d668af187c5aedeea8ff4958e5339 100644 --- a/Code/Mantid/scripts/SCD_Reduction/ReduceSCD_Parallel.py +++ b/Code/Mantid/scripts/SCD_Reduction/ReduceSCD_Parallel.py @@ -84,6 +84,7 @@ params_dictionary = ReduceDictionary.LoadDictionary( *config_files ) exp_name = params_dictionary[ "exp_name" ] output_directory = params_dictionary[ "output_directory" ] +output_nexus = params_dictionary.get( "output_nexus", False) reduce_one_run_script = params_dictionary[ "reduce_one_run_script" ] slurm_queue_name = params_dictionary[ "slurm_queue_name" ] max_processes = int(params_dictionary[ "max_processes" ]) @@ -94,6 +95,7 @@ cell_type = params_dictionary[ "cell_type" ] centering = params_dictionary[ "centering" ] allow_perm = params_dictionary[ "allow_perm" ] run_nums = params_dictionary[ "run_nums" ] +data_directory = params_dictionary[ "data_directory" ] use_cylindrical_integration = params_dictionary[ "use_cylindrical_integration" ] instrument_name = params_dictionary[ "instrument_name" ] @@ -153,14 +155,44 @@ print "*********************************************************************** # appending them to a combined output file. # niggli_name = output_directory + "/" + exp_name + "_Niggli" -niggli_integrate_file = niggli_name + ".integrate" +if output_nexus: + niggli_integrate_file = niggli_name + ".nxs" +else: + niggli_integrate_file = niggli_name + ".integrate" niggli_matrix_file = niggli_name + ".mat" first_time = True + +if output_nexus: + #Only need this for instrument for peaks_total + short_filename = "%s_%s_event.nxs" % (instrument_name, str(run_nums[0])) + if data_directory is not None: + full_name = data_directory + "/" + short_filename + else: + candidates = FileFinder.findRuns(short_filename) + full_name = "" + for item in candidates: + if os.path.exists(item): + full_name = str(item) + + if not full_name.endswith('nxs'): + print "Exiting since the data_directory was not specified and" + print "findnexus failed for event NeXus file: " + instrument_name + " " + str(run) + exit(0) + # + # Load the first data file to find instrument + # + wksp = LoadEventNexus( Filename=full_name, FilterByTofMin=0, FilterByTofMax=0 ) + peaks_total = CreatePeaksWorkspace(NumberOfPeaks=0, InstrumentWorkspace=wksp) + if not use_cylindrical_integration: for r_num in run_nums: - one_run_file = output_directory + '/' + str(r_num) + '_Niggli.integrate' - peaks_ws = LoadIsawPeaks( Filename=one_run_file ) + if output_nexus: + one_run_file = output_directory + '/' + str(r_num) + '_Niggli.nxs' + peaks_ws = Load( Filename=one_run_file ) + else: + one_run_file = output_directory + '/' + str(r_num) + '_Niggli.integrate' + peaks_ws = LoadIsawPeaks( Filename=one_run_file ) if first_time: if UseFirstLattice and not read_UB: # Find a UB (using FFT) for the first run to use in the FindUBUsingLatticeParameters @@ -171,17 +203,27 @@ if not use_cylindrical_integration: uc_alpha = peaks_ws.sample().getOrientedLattice().alpha() uc_beta = peaks_ws.sample().getOrientedLattice().beta() uc_gamma = peaks_ws.sample().getOrientedLattice().gamma() - SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, Filename=niggli_integrate_file ) - + if output_nexus: + peaks_total = CombinePeaksWorkspaces(LHSWorkspace=peaks_total, RHSWorkspace=peaks_ws) + SaveNexus( InputWorkspace=peaks_ws, Filename=niggli_integrate_file ) + else: + SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, Filename=niggli_integrate_file ) first_time = False else: - SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=True, Filename=niggli_integrate_file ) + if output_nexus: + peaks_total = CombinePeaksWorkspaces(LHSWorkspace=peaks_total, RHSWorkspace=peaks_ws) + SaveNexus( InputWorkspace=peaks_total, Filename=niggli_integrate_file ) + else: + SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=True, Filename=niggli_integrate_file ) # # Load the combined file and re-index all of the peaks together. # Save them back to the combined Niggli file (Or selcted UB file if in use...) # - peaks_ws = LoadIsawPeaks( Filename=niggli_integrate_file ) + if output_nexus: + peaks_ws = Load( Filename=niggli_integrate_file ) + else: + peaks_ws = LoadIsawPeaks( Filename=niggli_integrate_file ) # # Find a Niggli UB matrix that indexes the peaks in this run @@ -206,7 +248,10 @@ if not use_cylindrical_integration: FindUBUsingFFT( PeaksWorkspace=peaks_ws, MinD=min_d, MaxD=max_d, Tolerance=tolerance ) IndexPeaks( PeaksWorkspace=peaks_ws, Tolerance=tolerance ) - SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, Filename=niggli_integrate_file ) + if output_nexus: + SaveNexus( InputWorkspace=peaks_ws, Filename=niggli_integrate_file ) + else: + SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, Filename=niggli_integrate_file ) SaveIsawUB( InputWorkspace=peaks_ws, Filename=niggli_matrix_file ) # @@ -216,12 +261,18 @@ if not use_cylindrical_integration: if not use_cylindrical_integration: if (not cell_type is None) and (not centering is None) : conv_name = output_directory + "/" + exp_name + "_" + cell_type + "_" + centering - conventional_integrate_file = conv_name + ".integrate" + if output_nexus: + conventional_integrate_file = conv_name + ".nxs" + else: + conventional_integrate_file = conv_name + ".integrate" conventional_matrix_file = conv_name + ".mat" SelectCellOfType( PeaksWorkspace=peaks_ws, CellType=cell_type, Centering=centering,\ AllowPermutations=allow_perm, Apply=True, Tolerance=tolerance ) - SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, Filename=conventional_integrate_file ) + if output_nexus: + SaveNexus( InputWorkspace=peaks_ws, Filename=conventional_integrate_file ) + else: + SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, Filename=conventional_integrate_file ) SaveIsawUB( InputWorkspace=peaks_ws, Filename=conventional_matrix_file ) if use_cylindrical_integration: diff --git a/Code/Mantid/scripts/test/DirectEnergyConversionTest.py b/Code/Mantid/scripts/test/DirectEnergyConversionTest.py index 9c8e3439a26d91c9d6b32940c8c18e0b1a7810b5..c8f735d78d24c63759e8d676865d68bf5dc98691 100644 --- a/Code/Mantid/scripts/test/DirectEnergyConversionTest.py +++ b/Code/Mantid/scripts/test/DirectEnergyConversionTest.py @@ -183,8 +183,10 @@ class DirectEnergyConversionTest(unittest.TestCase): """ Test for old interface """ run_ws = CreateSampleWorkspace( Function='Multiple Peaks', NumBanks=1, BankPixelWidth=4, NumEvents=10000) LoadInstrument(run_ws,InstrumentName='MARI') + #mono_ws = CloneWorkspace(run_ws) wb_ws = CloneWorkspace(run_ws) + AddSampleLog(wb_ws,LogName='run_number',LogText='300',LogType='Number') #wb_ws=CreateSampleWorkspace( Function='Multiple Peaks', NumBanks=1, BankPixelWidth=4, NumEvents=10000) dgreduce.setup('MAR') @@ -199,6 +201,30 @@ class DirectEnergyConversionTest(unittest.TestCase): ws = dgreduce.abs_units(wb_ws,run_ws,None,wb_ws,10,100,8.8,[-10,0.1,7],None,None,**par) self.assertTrue(isinstance(ws,api.MatrixWorkspace)) + def test_dgreduce_works_with_name(self): + """ Test for old interface """ + run_ws = CreateSampleWorkspace( Function='Multiple Peaks', NumBanks=1, BankPixelWidth=4, NumEvents=10000) + LoadInstrument(run_ws,InstrumentName='MARI') + AddSampleLog(run_ws,LogName='run_number',LogText='200',LogType='Number') + #mono_ws = CloneWorkspace(run_ws) + wb_ws = CloneWorkspace(run_ws) + AddSampleLog(wb_ws,LogName='run_number',LogText='100',LogType='Number') + #wb_ws=CreateSampleWorkspace( Function='Multiple Peaks', NumBanks=1, BankPixelWidth=4, NumEvents=10000) + + dgreduce.setup('MAR') + par = {} + par['ei_mon_spectra']=[4,5] + par['abs_units_van_range']=[-4000,8000] + # overwrite parameters, which are necessary from command line, but we want them to have test values + dgreduce.getReducer().map_file=None + dgreduce.getReducer().monovan_mapfile=None + dgreduce.getReducer().mono_correction_factor = 1 + #abs_units(wb_for_run,sample_run,monovan_run,wb_for_monovanadium,samp_rmm,samp_mass,ei_guess,rebin,map_file='default',monovan_mapfile='default',**kwargs): + ws = dgreduce.abs_units('wb_ws','run_ws',None,wb_ws,10,100,8.8,[-10,0.1,7],None,None,**par) + self.assertTrue(isinstance(ws,api.MatrixWorkspace)) + + + ## tReducet.di def test_energy_to_TOF_range(self): @@ -281,37 +307,48 @@ class DirectEnergyConversionTest(unittest.TestCase): def test_tof_range(self): run=CreateSampleWorkspace(Function='Multiple Peaks', NumBanks=6, BankPixelWidth=1, NumEvents=10,\ - XUnit='DeltaE', XMin=-20, XMax=65, BinWidth=0.2) + XUnit='Energy', XMin=5, XMax=75, BinWidth=0.2) LoadInstrument(run,InstrumentName='MARI') red = DirectEnergyConversion(run.getInstrument()) - red.prop_man.incident_energy = 67 - red.prop_man.energy_bins = [-20,0.2,65] - red.prop_man.multirep_tof_specta_list = [5,5] + red.prop_man.incident_energy = 26.2 + red.prop_man.energy_bins = [-20,0.1,20] + red.prop_man.multirep_tof_specta_list = [4,5,6] + MoveInstrumentComponent(Workspace='run', ComponentName='Detector', DetectorID=1102, Z=3) + MoveInstrumentComponent(Workspace='run', ComponentName='Detector', DetectorID=1103,Z=6) - tof_range = red.find_tof_range_for_multirep(run) + run_tof = ConvertUnits(run,Target='TOF',EMode='Elastic') + + tof_range = red.find_tof_range_for_multirep(run_tof) self.assertEqual(len(tof_range),3) - run_tof = ConvertUnits(run,Target='TOF',EMode='Direct',EFixed=67.) - x = run_tof.readX(4) + x = run_tof.readX(3) dx=abs(x[1:]-x[:-1]) xMin = min(x) - xMax = max(x) dt = min(dx) + x = run_tof.readX(5) + xMax = max(x) - self.assertAlmostEqual(tof_range[0],xMin) - self.assertAlmostEqual(tof_range[1],dt) - self.assertAlmostEqual(tof_range[2],xMax) + + self.assertTrue(tof_range[0]>xMin) + #self.assertAlmostEqual(tof_range[1],dt) + self.assertTrue(tof_range[2]<xMax) # check another working mode - red.prop_man.multirep_tof_specta_list = 5 - tof_range1 = red.find_tof_range_for_multirep(run) + red.prop_man.multirep_tof_specta_list = 4 + red.prop_man.incident_energy = 47.505 + red.prop_man.energy_bins = [-20,0.1,45] + + tof_range1 = red.find_tof_range_for_multirep(run_tof) + + self.assertTrue(tof_range1[0]>xMin) + self.assertTrue(tof_range1[2]<xMax) - self.assertAlmostEqual(tof_range[0],tof_range1[0]) - self.assertAlmostEqual(tof_range[1],tof_range1[1]) - self.assertAlmostEqual(tof_range[2],tof_range1[2]) + self.assertTrue(tof_range1[2]<tof_range[2]) + self.assertTrue(tof_range1[0]<tof_range[0]) + self.assertTrue(tof_range1[1]<tof_range[1]) def test_multirep_mode(self): # create test workspace @@ -326,6 +363,9 @@ class DirectEnergyConversionTest(unittest.TestCase): run = CreateSampleWorkspace( Function='Multiple Peaks',WorkspaceType='Event',NumBanks=8, BankPixelWidth=1,\ NumEvents=100000, XUnit='TOF',xMin=tMin,xMax=tMax) LoadInstrument(run,InstrumentName='MARI') + MoveInstrumentComponent(Workspace='run', ComponentName='Detector', DetectorID=1102,Z=1) + # MoveInstrumentComponent(Workspace='run', ComponentName='Detector', DetectorID=1103,Z=4) + # MoveInstrumentComponent(Workspace='run', ComponentName='Detector', DetectorID=1104,Z=5) # do second run2 = CloneWorkspace(run) @@ -339,6 +379,7 @@ class DirectEnergyConversionTest(unittest.TestCase): tReducer.hard_mask_file=None tReducer.map_file=None tReducer.save_format=None + tReducer.multirep_tof_specta_list = [4,5] result = tReducer.convert_to_energy(wb_ws,run,[67.,122.],[-2,0.02,0.8]) @@ -405,6 +446,7 @@ class DirectEnergyConversionTest(unittest.TestCase): tReducer.prop_man.normalise_method='monitor-1' tReducer.norm_mon_integration_range=[tMin,tMax] + result = tReducer.convert_to_energy(wb_ws,run,[67.,122.],[-2,0.02,0.8],None,mono) self.assertEqual(len(result),2) diff --git a/Code/Mantid/scripts/test/DirectPropertyManagerTest.py b/Code/Mantid/scripts/test/DirectPropertyManagerTest.py index 344df3a9d670fa6835630b79044b1e6f32f516a7..3cde32203d62d3f31d2418f1448dbec9dd845d73 100644 --- a/Code/Mantid/scripts/test/DirectPropertyManagerTest.py +++ b/Code/Mantid/scripts/test/DirectPropertyManagerTest.py @@ -1088,14 +1088,14 @@ class DirectPropertyManagerTest(unittest.TestCase): propman.sample_run = 1000 propman.incident_energy = 20. - def custom_print(propman,PropertyManager): + def custom_print(propman): ei = propman.incident_energy run_n = PropertyManager.sample_run.run_number() name = "RUN{0}atEi{1:<4.1f}meV_One2One".format(run_n,ei) return name - PropertyManager.save_file_name.set_custom_print(custom_print) + PropertyManager.save_file_name.set_custom_print(lambda : custom_print(self.prop_man)) self.assertEqual(propman.save_file_name,'RUN1000atEi20.0meV_One2One') diff --git a/Code/Mantid/scripts/test/IndirectCommonTests.py b/Code/Mantid/scripts/test/IndirectCommonTests.py index 48b88d94cdbcfd17c9ca79127b289d06d92d8704..a0bbe462f14254221715448ab0b8b70d7269affa 100644 --- a/Code/Mantid/scripts/test/IndirectCommonTests.py +++ b/Code/Mantid/scripts/test/IndirectCommonTests.py @@ -285,23 +285,6 @@ class IndirectCommonTests(unittest.TestCase): self.assert_matrix_workspace_dimensions(params_workspace.name(), expected_num_histograms=3, expected_blocksize=5) - def test_addSampleLogs(self): - ws = CreateSampleWorkspace() - logs = {} - logs['FloatLog'] = 3.149 - logs['IntLog'] = 42 - logs['StringLog'] = "A String Log" - logs['BooleanLog'] = True - - indirect_common.addSampleLogs(ws, logs) - - self.assert_logs_match_expected(ws.name(), logs) - - def test_addSampleLogs_empty_dict(self): - ws = CreateSampleWorkspace() - logs = {} - self.assert_does_not_raise(Exception, indirect_common.addSampleLogs, ws, logs) - #----------------------------------------------------------- # Custom assertion functions #----------------------------------------------------------- diff --git a/Code/Mantid/scripts/test/ReductionWrapperTest.py b/Code/Mantid/scripts/test/ReductionWrapperTest.py index 83f558655efabda3fe01cec3898df7c0e03a9841..d9ba91438a67778aac58c91a50f32d65456c9a77 100644 --- a/Code/Mantid/scripts/test/ReductionWrapperTest.py +++ b/Code/Mantid/scripts/test/ReductionWrapperTest.py @@ -4,13 +4,72 @@ import os,sys from mantid.simpleapi import * from mantid import api,config -from Direct.ReductionWrapper import ReductionWrapper +from Direct.ReductionWrapper import * import MariReduction as mr # import unittest +class test_helper(ReductionWrapper): + def __init__(self,web_var=None): + """ sets properties defaults for the instrument with Name""" + ReductionWrapper.__init__(self,'MAR',web_var) + + def set_custom_output_filename(self): + """define custom name of output files if standard one is not satisfactory + In addition to that, example of accessing reduction properties + Changing them if necessary + """ + def custom_name(prop_man): + """ sample function which builds filename from + incident energy and run number and adds some auxiliary information + to it. + """ + + # Note -- properties have the same names as the list of advanced and + # main properties + ei = PropertyManager.incident_energy.get_current() + # sample run is more then just list of runs, so we use + # the formalization below to access its methods + run_num = prop_man.sample_run + name = "SOMETHING{0}_{1:<3.2f}meV_rings".format(run_num ,ei) + return name + + # Uncomment this to use custom filename function + # Note: the properties are stored in prop_man class accessed as + # below. + return lambda: custom_name(self.reducer.prop_man) + # use this method to use standard file name generating function + #return None + @iliad + def reduce(self, input_file = None, output_directory = None): + + self.reducer._clear_old_results() + if input_file: + self.reducer.prop_man.sample_run = input_file + run = self.reducer.prop_man.sample_run + + result = [] + if PropertyManager.incident_energy.multirep_mode(): + en_range = self.reducer.prop_man.incident_energy + for ind,en in enumerate(en_range): + ws=CreateSampleWorkspace() + AddSampleLog(ws,LogName = 'run_number',LogText=str(run)) + PropertyManager.sample_run.set_action_suffix('#{0}_reduced'.format(ind+1)) + PropertyManager.sample_run.synchronize_ws(ws) + result.append(ws) + self.reducer._old_runs_list.append(ws.name()) + else: + ws=CreateSampleWorkspace() + AddSampleLog(ws,LogName = 'run_number',LogText=str(run)) + PropertyManager.sample_run.set_action_suffix('_reduced') + PropertyManager.sample_run.synchronize_ws(ws) + result.append(ws) + + if len(result) == 1: + result = result[0] + return result #----------------------------------------------------------------------------------------------------------------------------------------- #----------------------------------------------------------------------------------------------------------------------------------------- #----------------------------------------------------------------------------------------------------------------------------------------- @@ -34,8 +93,6 @@ class ReductionWrapperTest(unittest.TestCase): self.assertRaises(NotImplementedError,red.def_advanced_properties) self.assertTrue('reduce' in dir(red)) - - def test_export_advanced_values(self): red = mr.ReduceMARI() @@ -50,6 +107,14 @@ class ReductionWrapperTest(unittest.TestCase): test_dir = config['defaultsave.directory'] file = os.path.join(test_dir,'reduce_vars.py') + #clear up previous rubbish may be present from other runs + if os.path.isfile(file): + os.remove(file) + fbase,fext = os.path.splitext(file) + fcomp = fbase+'.pyc' + if os.path.isfile(fcomp): + os.remove(fcomp) + # save wen variables red.save_web_variables(file) self.assertTrue(os.path.isfile(file)) @@ -126,6 +191,74 @@ class ReductionWrapperTest(unittest.TestCase): self.assertEqual(level,1) self.assertEqual(len(errors),1) + def test_custom_print_name(self): + th=test_helper() + th.reducer.prop_man.sample_run = 100 + th.reducer.prop_man.incident_energy=[10.01,20] + + th.reduce() + + save_file = th.reducer.prop_man.save_file_name + # such strange name because custom print function above access workspace, + # generated by reduction + self.assertEqual(save_file,'SOMETHINGSR_MAR000100#2_reduced_10.01meV_rings') + + PropertyManager.incident_energy.next() + save_file = th.reducer.prop_man.save_file_name + # now reduction have not been run, and the name is generated from run number + self.assertEqual(save_file,'SOMETHINGSR_MAR000100#2_reduced_20.00meV_rings') + + def test_return_run_list(self): + th=test_helper() + + th.reducer.prop_man.sample_run=200 + th.run_reduction() + # standard reduction would save and delete workspace but our simplified one + # will just keep it + name = 'SR_MAR000200_reduced' + self.assertTrue(name in mtd) + + th.reducer.prop_man.sample_run=300 + # new run deletes the old one + self.assertFalse(name in mtd) + + rez = th.run_reduction() + self.assertTrue(isinstance(rez,api.Workspace)) + self.assertTrue('rez' in mtd) + self.assertEqual(rez.name(),'rez') + + th.reducer.prop_man.sample_run=[300,400] + th.run_reduction() + self.assertFalse('SR_MAR000300_reduced' in mtd) + self.assertTrue('SR_MAR000400_reduced' in mtd) + + th.reducer.prop_man.sample_run=[500,600] + self.assertFalse('SR_MAR000400_reduced' in mtd) + th.run_reduction() + self.assertFalse('SR_MAR000500_reduced' in mtd) + self.assertTrue('SR_MAR000600_reduced' in mtd) + + th.reducer.prop_man.sample_run=[300,400] + runs = th.run_reduction() + self.assertTrue('runs#1of2' in mtd) + self.assertTrue('runs#2of2' in mtd) + self.assertEqual(runs[0].name(),'runs#1of2') + self.assertEqual(runs[1].name(),'runs#2of2') + + th.reducer.prop_man.incident_energy=[10,20] + th.reducer.prop_man.sample_run=300 + th.run_reduction() + self.assertTrue('SR_MAR000300#1_reduced' in mtd) + self.assertTrue('SR_MAR000300#2_reduced' in mtd) + th.reducer.prop_man.sample_run=400 + th.run_reduction() + self.assertFalse('SR_MAR000300#1_reduced' in mtd) + self.assertFalse('SR_MAR000300#2_reduced' in mtd) + self.assertTrue('SR_MAR000400#1_reduced' in mtd) + self.assertTrue('SR_MAR000400#2_reduced' in mtd) + + + if __name__=="__main__": diff --git a/Code/Mantid/scripts/test/RunDescriptorTest.py b/Code/Mantid/scripts/test/RunDescriptorTest.py index 1515fbf1a04084c5c7e770035d8afb853c7f38e2..1a8956188d831f8528713b6652ad8d616819aebc 100644 --- a/Code/Mantid/scripts/test/RunDescriptorTest.py +++ b/Code/Mantid/scripts/test/RunDescriptorTest.py @@ -155,6 +155,34 @@ class RunDescriptorTest(unittest.TestCase): self.assertEqual(mon_ws.getNumberHistograms(),3) self.assertEqual(mon_ws.getIndexFromSpectrumNumber(3),2) + def test_copy_spectra2monitors_heterogen(self): + propman = self.prop_man + run_ws = CreateSampleWorkspace( Function='Multiple Peaks', WorkspaceType = 'Event',NumBanks=1, BankPixelWidth=5, NumEvents=100) + run_ws_monitors = CreateSampleWorkspace( Function='Multiple Peaks', WorkspaceType = 'Histogram',NumBanks=2, BankPixelWidth=1, NumEvents=100) + + run_ws_monitors = Rebin(run_ws_monitors,Params='1,-0.01,20000') + x=run_ws_monitors.readX(0) + dx = x[1:]-x[:-1] + min_step0 = min(dx) + + propman.monovan_run = run_ws + propman.spectra_to_monitors_list = 3 + + mon_ws = PropertyManager.monovan_run.get_monitors_ws() + self.assertTrue(isinstance(mon_ws, api.Workspace)) + self.assertEqual(mon_ws.getNumberHistograms(),3) + self.assertEqual(mon_ws.getIndexFromSpectrumNumber(3),2) + + x=mon_ws.readX(0) + dx = x[1:]-x[:-1] + min_step1 = min(dx) + max_step1 = max(dx) + + self.assertAlmostEqual(min_step0,min_step1,5) + self.assertAlmostEqual(max_step1,min_step1,5) + + + def test_ws_name(self): run_ws = CreateSampleWorkspace( Function='Multiple Peaks', NumBanks=1, BankPixelWidth=4, NumEvents=100) propman = self.prop_man diff --git a/Code/Tools/DOI/authors.py b/Code/Tools/DOI/authors.py index 98bc7ecc607318db22e531003d24ff620c3aff83..a9418f58841cc6fd56e6990321b7a60022516eda 100644 --- a/Code/Tools/DOI/authors.py +++ b/Code/Tools/DOI/authors.py @@ -73,7 +73,7 @@ _translations = { 'Roman Tolchenov' : 'Tolchenov, Roman', 'MichaelWedel' : 'Wedel, Michael', 'Michael Wedel' : 'Wedel, Michael', - 'Ross Whitfield' : 'Whitfield, Robert', + 'Ross Whitfield' : 'Whitfield, Ross', 'Robert Whitley' : 'Whitley, Robert', 'Michael Whitty' : 'Whitty, Michael', 'Steve Williams' : 'Williams, Steve',